Prace s grafickým zobrazením scén

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é hodnotyTřídaÚloha:
ScénaSceneKontejner nejvyšší úrovně. rootNode, animationClips,a) assetInfo.
Vstupní uzelNodeMůže mít dětské uzly, entitu, transformaci a materiály.
Účetní jednotkaMesh, 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. Node přímo: createChildNode() automaticky propojí vztah rodič-děť a zaregistruje uzel v stromu.
  • Ček. node.entity př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 nebo instanceof test.
  • Sestavení: translation na dětských uzlech, ne na vrcholy ok.: změna transform.translation je nedestruktivní a komposibilní s základními transformy.
  • Preferovat binaryMode = true pro GLB:Jednotná: .glb soubor je jednodušší distribuovat, naložit v prohlížečích a importovat do herních motorů než rozdělení. .gltf + .bin formát.
  • Procházet přes for...of Přesně. childNodes: vyhnout se číselnému indexování; pro budoucí kompatibilitu používat přímo iterovatelné.

Obvyklé problémy

Příznak:Pravděpodobná příčinaOpravy
child.entity = mesh nemá vliv na vývozEntita přiřazena na špatnou úroveň uzluPřidělit entity k uzlu listů, ne ke skupinovému uznu.
node.entity je vždy nullJenom kontroluji. rootNode sama o soběPřístup k node.childNodes; rootNode typicky nemá žádnou entitu.
Transformace není odrážena v zobrazovači GLBglobalTransform 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 falseSestavení: saveOpts.binaryMode = true

Viz také:

 Čeština