A Scene Graph használata
Az összes 3D tartalom a Aspose.3D FOSS TypeScript-hez egy Scene objektumban, amely egy fa struktúráját alkot Node objektumok. Ennek a hierarchiának a megértése a kiindulópont a bármely 3D fájl építéséhez, betöltéséhez és feldolgozásához.
Telepítés
Telepítsd a csomagot az npm‑ről, mielőtt a útmutató bármely kódját futtatnád:
npm install @aspose/3dGyőződj meg róla, hogy a tsconfig.json tartalmaz "module": "commonjs" és "moduleResolution": "node" a helyes alútvonal import feloldásához.
Scene Graph koncepciói
A scene graph három szintből áll:
| Szint | Osztály | Szerep |
|---|---|---|
| Jelenet | Scene | Legfelső szintű tároló. Tartalmaz rootNode, animationClips, és assetInfo. |
| Csomópont | Node | Nevet kapott fa csomópont. Lehetnek benne gyermekcsomópontok, egy entitás, egy transzformáció és anyagok. |
| Entitás | Mesh, Camera, Light, … | Tartalom, amely egy csomóponthoz van csatolva. Egy csomópont legfeljebb egy entitást tartalmaz. |
A fő építőelemek öröklődési lánca:
A3DObject
└─ SceneObject
├─ Node (tree structure)
└─ Entity
└─ Geometry
└─ Mesh (polygon geometry)scene.rootNode automatikusan létrejön. Nem hozod létre manuálisan; gyermekcsomópontokat hozol létre alatta.
1. lépés: Jelenet létrehozása
import { Scene } from '@aspose/3d';
const scene = new Scene();
console.log(scene.rootNode.name); // '' (empty string — the root node is created with no name)
Egy új Scene egy üres gyökércsomóponttal és animációs klipek nélkül indul. Tartalmat építesz gyermekcsomópontok csatolásával.
2. lépés: Gyermeknode-ok hozzáadása
Használja createChildNode() a fa növeléséhez. A metódus visszaadja az új Node, így bármely szintről láncolhat további hívásokat:
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)
A node nevek tetszőleges karakterláncok. Nem kell egyedieknek lenniük, de értelmes nevek használata megkönnyíti a bejáró kód hibakeresését.
3. lépés: Mesh létrehozása és csúcsok beállítása
Mesh az elsődleges geometria osztály. Adj csúcspozíciókat úgy, hogy beteszed Vector4 értékeket a mesh.controlPoints, majd hívd createPolygon() a felületek meghatározásához csúcsindex alapján:
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 homogén koordinátákat használ: a w komponens 1 pozíciókhoz és 0 irányvektorokhoz.
4. lépés: Csomópont transzformációk beállítása
Minden csomópont rendelkezik egy transform tulajdonsággal, amely translation, rotation, és scaling. Állítsd be translation a csomópont mozgatásához a szülőhöz képest:
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 biztosítja a world-space transzformációs mátrixot (csak olvasható), amelyet az összes ős transzformáció összefűzésével számolnak.
5. lépés: A fa bejárása
Írj egy rekurzív függvényt, amely minden csomópontot felkeres. Ellenőrizd node.entity és node.childNodes minden szinten:
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);A fent létrehozott hierarchiára a kimenet a következő lesz:
[none]
parent [none]
child [Mesh]A gyökércsomópont neve egy üres karakterlánc, mert Scene létrehozza azt név argumentum nélkül.
Mindig védd az entitáshoz való hozzáférést null-ellenőrzéssel, mielőtt egy adott típusra castelnél. Nem minden csomópont tartalmaz entitást.
6. lépés: Mentés glTF vagy GLB formátumba
Használd GltfSaveOptions a kimeneti formátum vezérléséhez. Állítsd be binaryMode = true egy önálló .glb fájlt; hagyd false a JSON .gltf + .bin kísérő pár:
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');Add GltfFormat.getInstance() formátum argumentumként, hogy a könyvtár a megfelelő kódolót használja a fájlkiterjesztéstől függetlenül.
Tippek és bevált gyakorlatok
- Használd
createChildNode()ahelyett, hogy létrehoznádNodeközvetlenül:createChildNode()automatikusan összekapcsolja a szülő-gyermek kapcsolatot, és regisztrálja a csomópontot a fában. - Ellenőrizd
node.entitymielőtt hozzáférnél az entitás tulajdonságaihoz: sok csomópont (csoportcsomópontok, csontok, lokátorok) nem tartalmaz entitást. Mindig védd null-ellenőrzéssel vagyinstanceofteszt. - Beállítás
translationgyermekcsomópontokon, nem a háló csúcspontjain:módosítástransform.translationnem destruktív, és kombinálható a szülő transzformációkkal. - Előnyben részesítse
binaryMode = trueGLB-hez: egyetlen.glbfájl könnyebben terjeszthető, betölthető böngészőkben, és importálható játék motorokba, mint a szétválasztott.gltf+.binformátum. - Bejárás a
for...offölöttchildNodes: kerüld a numerikus indexelést; használd közvetlenül az iterálható elemet a jövőbeli kompatibilitás érdekében.
Gyakori problémák
| Tünet | Valószínű ok | Javítás |
|---|---|---|
child.entity = mesh nincs hatása az exportálásra | Entitás rossz csomópont szinthez van hozzárendelve | Rendeld entity a levélcsomóponthoz, nem a csoportcsomóponthoz |
node.entity mindig null | Csak ellenőrzés rootNode maga | Rekurzív bejárás node.childNodes; rootNode általában nincs entitása |
| A transzformáció nem jelenik meg a GLB megjelenítőben | globalTransform nem frissült | globalTransform a mentéskor számítódik; állítsa be transform.translation hívás előtt scene.save() |
A GLB egy külön .bin sidecar | binaryMode alapértelmezett false | Beállítás saveOpts.binaryMode = true |
Lásd még
- Jellemzők és funkciók: teljes API referencia minden funkcióterülethez.
- Formátumtámogatás: támogatott 3D formátumok, olvasási/írási képesség és formátum beállítások.
- Hogyan építsünk 3D Mesh-et programozottan.