Prace s grafickým zobrazením scén
Všechny 3D obsah v Aspose.3D FOSS pro TypeScript žije uvnitř Scene objekt organizovaný jako strom Node Pochopení této hierarchie je základem pro budování, načítání a zpracování jakéhokoli 3D souboru.
Instalace
Před spuštěním jakéhokoli kódu v této příručce instalujte balíček z npm:
asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.Zajistěte, aby vaše tsconfig.json zahrnuje: "module": "commonjs" a) "moduleResolution": "node" pro správné rozlišení při dovozu podcestu.
Koncepce grafu scény
Graf scény má tři úrovně:
| Růstné hodnoty | Třída | Úloha: |
|---|---|---|
| Scéna | Scene | Kontejner nejvyšší úrovně. rootNode, animationClips,a) assetInfo. |
| Vstupní uzel | Node | Může mít dětské uzly, entitu, transformaci a materiály. |
| Účetní jednotka | Mesh, Camera, Light, … | Obsah připojený k uzlu. Uzel obsahuje nejvýše jednu entitu. |
Řetězec dědictví hlavních stavebních bloků je:
A3DObject
└─ SceneObject
├─ Node (tree structure)
└─ Entity
└─ Geometry
└─ Mesh (polygon geometry)scene.rootNode Není to vytvořeno ručně, vytváříte pod ním dětské uzly.
Krok 1: Vytvořte scénu
import { Scene } from '@aspose/3d';
const scene = new Scene();
console.log(scene.rootNode.name); // '' (empty string — the root node is created with no name)
Nový . Scene Začíná se prázdným kořenovým uzlem a bez animačních klipů. Vytváříte obsah připojením dětských uzlů .
Krok 2: Přidání dětských uzlů
Použití: createChildNode() Metodou se vrací nový druh. Node, takže můžete dál volání řetězce z jakékoliv úrovně:
import { Scene } from '@aspose/3d';
const scene = new Scene();
const parent = scene.rootNode.createChildNode('parent');
const child = parent.createChildNode('child');
console.log(scene.rootNode.childNodes.length); // 1 (parent)
console.log(parent.childNodes.length); // 1 (child)
Jména uzlů jsou svobodné řetězce. Jmena nemusí být jedinečná, ale použití smysluplných jmen usnadňuje debugging průchodu kódem.
Krok 3: Vytvořte si síť a nastavit vrcholky
Mesh je primární geometrie třída. Přidejte pozice vrcholů stisknutím Vector4 hodnoty do mesh.controlPoints, tak zavolej . createPolygon() pro definici obličejů podle indexu vrcholu:
import { Scene } from '@aspose/3d';
import { Mesh } from '@aspose/3d/entities';
import { Vector4 } from '@aspose/3d/utilities';
const scene = new Scene();
const child = scene.rootNode.createChildNode('parent').createChildNode('child');
const mesh = new Mesh('cube');
mesh.controlPoints.push(new Vector4(0, 0, 0, 1));
mesh.controlPoints.push(new Vector4(1, 0, 0, 1));
mesh.controlPoints.push(new Vector4(1, 1, 0, 1));
mesh.controlPoints.push(new Vector4(0, 1, 0, 1));
mesh.createPolygon(0, 1, 2, 3); // quad face using all four vertices
child.entity = mesh;
console.log(mesh.controlPoints.length); // 4
console.log(mesh.polygonCount); // 1
Vector4 používá homogenní souřadnice: w složka je: 1 pro pozice a 0 pro směřovací vektory.
Krok 4: Nastavit transformace uzlů
Každý uzel má transform majetek s translation, rotation,a) scaling.- Nastavení . translation přesunout uzel ve vztahu k jeho rodiči:
import { Scene } from '@aspose/3d';
import { Mesh } from '@aspose/3d/entities';
import { Vector4, Vector3 } from '@aspose/3d/utilities';
const scene = new Scene();
const parent = scene.rootNode.createChildNode('parent');
const child = parent.createChildNode('child');
const mesh = new Mesh('cube');
mesh.controlPoints.push(new Vector4(0, 0, 0, 1));
mesh.controlPoints.push(new Vector4(1, 0, 0, 1));
mesh.controlPoints.push(new Vector4(1, 1, 0, 1));
mesh.controlPoints.push(new Vector4(0, 1, 0, 1));
mesh.createPolygon(0, 1, 2, 3);
child.entity = mesh;
child.transform.translation = new Vector3(2.0, 0.0, 0.0);globalTransform poskytuje matici transformace světového prostoru (pouze pro čtení), vypočítanou spojením všech předků.
Krok 5: Přes strom
Napíšejte rekurzivní funkci, která navštíví každý uzel. node.entity a) node.childNodes na každé úrovni:
function traverse(node: any, depth = 0): void {
const indent = ' '.repeat(depth);
const entityType = node.entity ? node.entity.constructor.name : 'none';
console.log(`${indent}${node.name} [${entityType}]`);
for (const child of node.childNodes) {
traverse(child, depth + 1);
}
}
traverse(scene.rootNode);Pro hierarchii vytvořenou výše bude výsledek:
[none]
parent [none]
child [Mesh]Název kořenového uzlu je prázdný řetěz, protože Scene Vytvoří to bez názvu argumentu.
Vždy chránit přístup k entitě s nulovou kontrolou před odkládáním na konkrétní typ. Ne každý uzel nese entity.
Krok 6: Uložení do GLT nebo GLB
Použití: GltfSaveOptions Nastavit nastavení. binaryMode = true k výrobě jediného samostatného, .glb - Nechte to. false pro JSON .gltf + .bin dvojice boční vozíků:
import { Scene } from '@aspose/3d';
import { Mesh } from '@aspose/3d/entities';
import { Vector4, Vector3 } from '@aspose/3d/utilities';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';
const scene = new Scene();
const parent = scene.rootNode.createChildNode('parent');
const child = parent.createChildNode('child');
const mesh = new Mesh('cube');
mesh.controlPoints.push(new Vector4(0, 0, 0, 1));
mesh.controlPoints.push(new Vector4(1, 0, 0, 1));
mesh.controlPoints.push(new Vector4(1, 1, 0, 1));
mesh.controlPoints.push(new Vector4(0, 1, 0, 1));
mesh.createPolygon(0, 1, 2, 3);
child.entity = mesh;
child.transform.translation = new Vector3(2.0, 0.0, 0.0);
const saveOpts = new GltfSaveOptions();
saveOpts.binaryMode = true; // write a single .glb file
scene.save('scene.glb', GltfFormat.getInstance(), saveOpts);
console.log('Scene saved to scene.glb');Procházející. GltfFormat.getInstance() jako argument formátu, takže knihovna používá správný kódovač bez ohledu na rozšíření souboru.
Tipy a nejlepší postupy
- Použití:
createChildNode()místo toho, aby se stavěla.Nodepřímo:createChildNode()automaticky propojí vztah rodič-děť a zaregistruje uzel v stromu. - Ček.
node.entitypřed přístupem k vlastnostem subjektu: mnoho uzlů (zde jsou: skupinové, kostní a lokalizační) nesou žádné entity. Vždy se střeďte nulovou kontrolkou neboinstanceoftest. - Sestavení:
translationna dětských uzlech, ne na vrcholy ok.: změnatransform.translationje nedestruktivní a komposibilní s základními transformy. - Preferovat
binaryMode = truepro GLB:Jednotná:.glbsoubor je jednodušší distribuovat, naložit v prohlížečích a importovat do herních motorů než rozdělení..gltf+.binformát. - Procházet přes
for...ofPřesně.childNodes: vyhnout se číselnému indexování; pro budoucí kompatibilitu používat přímo iterovatelné.
Obvyklé problémy
| Příznak: | Pravděpodobná příčina | Opravy |
|---|---|---|
child.entity = mesh nemá vliv na vývoz | Entita přiřazena na špatnou úroveň uzlu | Přidělit entity k uzlu listů, ne ke skupinovému uznu. |
node.entity je vždy null | Jenom kontroluji. rootNode sama o sobě | Přístup k node.childNodes; rootNode typicky nemá žádnou entitu. |
| Transformace není odrážena v zobrazovači GLB | globalTransform Neaktualizované | globalTransform je vypočten na uložení; set transform.translation před voláním . scene.save() |
GLB vyrábí samostatný .bin nádrž | binaryMode Způsoby, které jsou v rozporu s false | Sestavení: saveOpts.binaryMode = true |
Viz také:
- Charakteristika a funkčnost: úplná referenční API pro všechny oblasti charakteristik.
- Podpora formátu: podporované 3D formáty, možnost čtení/psaní a možnosti formátu.
- Jak programově vytvořit 3D síť?