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/3d

Győ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:

SzintOsztálySzerep
JelenetSceneLegfelső szintű tároló. Tartalmaz rootNode, animationClips, és assetInfo.
CsomópontNodeNevet kapott fa csomópont. Lehetnek benne gyermekcsomópontok, egy entitás, egy transzformáció és anyagok.
EntitásMesh, 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ád Node közvetlenül: createChildNode() automatikusan összekapcsolja a szülő-gyermek kapcsolatot, és regisztrálja a csomópontot a fában.
  • Ellenőrizd node.entity mielő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 vagy instanceof teszt.
  • Beállítás translation gyermekcsomópontokon, nem a háló csúcspontjain:módosítás transform.translation nem destruktív, és kombinálható a szülő transzformációkkal.
  • Előnyben részesítse binaryMode = true GLB-hez: egyetlen .glb fájl könnyebben terjeszthető, betölthető böngészőkben, és importálható játék motorokba, mint a szétválasztott .gltf + .bin formátum.
  • Bejárás a for...of fölött childNodes: 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ünetValószínű okJavítás
child.entity = mesh nincs hatása az exportálásraEntitás rossz csomópont szinthez van hozzárendelveRendeld entity a levélcsomóponthoz, nem a csoportcsomóponthoz
node.entity mindig nullCsak ellenőrzés rootNode magaRekurzív bejárás node.childNodes; rootNode általában nincs entitása
A transzformáció nem jelenik meg a GLB megjelenítőbenglobalTransform nem frissültglobalTransform 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 sidecarbinaryMode alapértelmezett falseBeállítás saveOpts.binaryMode = true

Lásd még

 Magyar