Darbs ar ainas grafiku

Visais 3D saturs Aspose.3D FOSS priekš TypeScript atrodas iekš a Scene objekts, kas organizēts kā koka struktūra no Node objektu. Šīs hierarhijas izpratne ir pamats jebkura 3D faila izveidei, ielādei un apstrādei.

Instalēšana

Instalējiet pakotni no npm pirms izpildīt jebkuru šīs rokasgrāmatas kodu:

npm install @aspose/3d

Pārliecinieties, ka jūsu tsconfig.json iekļauj "module": "commonjs" un "moduleResolution": "node" pareizai apakšceļu importēšanas izšķirtspējai.

Ainas grafika koncepcijas

Ainas grafikai ir trīs līmeņi:

LīmenisKlaseLoma
AinaSceneAugstākā līmeņa konteineris. Satur rootNode, animationClips, un assetInfo.
MezglsNodeNosaukts koka mezgls. Var saturēt bērna mezglus, entītiju, transformāciju un materiālus.
EntītijaMesh, Camera, Light, …Saturs, kas pievienots mezglam. Mezglam var būt ne vairāk kā viena vienība.

Mantošanas ķēde galvenajiem būvblokus ir:

A3DObject
  └─ SceneObject
       ├─ Node          (tree structure)
       └─ Entity
            └─ Geometry
                 └─ Mesh   (polygon geometry)

scene.rootNode tiek izveidots automātiski. Jūs to neveidojat manuāli; jūs izveidojat bērna mezglus zem tā.

1. solis: Izveidot ainu

import { Scene } from '@aspose/3d';

const scene = new Scene();
console.log(scene.rootNode.name); // '' (empty string — the root node is created with no name)

Jauns Scene sākas ar tukšu saknes mezglu un bez animācijas klipiem. Jūs veidojat saturu, pievienojot bērna mezglus.

2. solis: Pievienot bērna mezglus

Izmantojiet createChildNode() lai izaugtu koku. Metode atgriež jauno Node, tāpēc jūs varat ķēdēt papildu izsaukumus no jebkura līmeņa:

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)

Mezglu nosaukumi ir patvaļīgi virknes. Nosaukumiem nav jābūt unikāliem, bet nozīmīgu nosaukumu lietošana atvieglo pārvietošanas koda atkļūdošanu.

3. solis: Izveidot Mesh un iestatīt virsotnes

Mesh ir galvenā ģeometrijas klase. Pievienojiet virsotņu pozīcijas, ievietojot Vector4 vērtības mesh.controlPoints, tad izsauc createPolygon() lai definētu sejas pēc virsotnes indeksa:

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 izmanto homogēnas koordinātas: tas w komponents ir 1 pozīcijām un 0 virziena vektoriem.

4. solis: Iestatīt mezglu transformācijas

Katram mezglam ir transform īpašība ar translation, rotation, un scaling. Iestatīt translation lai pārvietotu mezglu attiecībā pret tā vecāku:

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 sniedz pasaules telpas transformācijas matricu (tikai lasāma), aprēķinātu, apvienojot visus priekšgājēju transformācijas.

5. solis: Pāriet cauri koka struktūrai

Uzrakstiet rekursīvu funkciju, lai apmeklētu katru mezglu. Pārbaudiet node.entity un node.childNodes katrā līmenī:

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);

Izveidotajai hierarhijai, kas izveidota iepriekš, izvadījums būs:

 [none]
  parent [none]
    child [Mesh]

Saknes mezgla nosaukums ir tukša virkne, jo Scene izveido to bez nosaukuma argumenta.

Vienmēr aizsargājiet piekļuvi entītijai ar null pārbaudi pirms pārvēršanas uz konkrētu tipu. Ne katrs mezgls nes entītiju.

6. solis: Saglabāt kā glTF vai GLB

Izmantojiet GltfSaveOptions lai kontrolētu izvades formātu. Iestatiet binaryMode = true lai izveidotu vienu pašpietiekamu .glb failu; atstājiet to false JSON .gltf + .bin piederošo pāri:

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');

Pārsūtiet GltfFormat.getInstance() kā formāta argumentu, lai bibliotēka izmantotu pareizo kodētāju neatkarīgi no faila paplašinājuma.

Padomi un labākā prakse

  • Izmantojiet createChildNode() nevis konstruējot Node tieši: createChildNode() automātiski savieno vecāka-bērna attiecību un reģistrē mezglu koks.
  • Pārbaudiet node.entity pirms piekļūt vienības īpašībām: daudzi mezgli (grupas mezgli, kauli, lokatori) nēsā neviens entītiju. Vienmēr aizsargājiet ar null pārbaudi vai instanceof tests.
  • Iestatīt translation uz bērnu mezgliem, nevis uz režģa virsotnēm:modificēšana transform.translation ir neiznīcinošs un savienojams ar vecāku transformācijām.
  • Izvēlieties binaryMode = true GLB formātam: viens .glb fails ir vieglāk izplatāms, ielādējams pārlūkprogrammās un importējams spēļu dzinējos nekā sadalīts .gltf + .bin formāts.
  • Pārejiet caur for...of pāri childNodes: izvairieties no skaitliskās indeksācijas; izmantojiet iterējamo tieši, lai nodrošinātu nākotnes saderību.

Biežāk sastopamās problēmas

SimptomsIespējams cēlonisLabojums
child.entity = mesh nekādā veidā neietekmē eksportuEntītija piešķirta nepareizam mezgla līmenimPiešķirt entity uz lapas mezglu, nevis uz grupas mezglu
node.entity vienmēr ir nullTikai pārbauda rootNode pašamRekursīvi iekļaut node.childNodes; rootNode parasti nav vienības
Transformācija nav atspoguļota GLB skatītājāglobalTransform nav atjauninātsglobalTransform tiek aprēķināts saglabājot; iestatīt transform.translation pirms izsaukšanas scene.save()
GLB izveido atsevišķu .bin palīgfailsbinaryMode noklusējuma vērtība ir falseIestatīt saveOpts.binaryMode = true

Skatīt arī

 Latviešu