Kaip perkelti 3D sceno grafiją TypeScript

Kaip perkelti 3D sceno grafiją TypeScript

Sceno grafikas Aspose.3D FOSS TypeScript yra medžio Node Objektas, įsikūręs scene.rootNode.Kelionė yra pakartotinė: kiekvienas mazgas atskleidžia childNodes Neįtikėtina ir pasirinktinė entity Šis vadovas rodo, kaip vaikščioti visą medį, nustatyti subjektų tipus ir rinkti mesh statistiką.

Priešpriešiniai reikalavimai

  • Node.js 18 arba vėliau
  • TipScript 5.0 arba vėliau
  • @aspose/3d Įdiegta

Žingsnis po žingsnio vadovėlis

1 žingsnis: įdiegti ir importuoti

Įdiegti pakuotę:

npm install @aspose/3d

Įvesti klases, naudojamas šiame vadove:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { Mesh } from '@aspose/3d/entities';

Scene ir Mesh Tai pagrindinės klasės. ObjLoadOptions naudojamas įkrovimo pavyzdyje; pakeiskite atitikties parinkčių klasę kitomis formatais.


2 žingsnis: atsisiųskite sceną iš failo

sukurti a Scene ir paskambinti scene.open() Formato aptikimas yra automatiškai iš dvejetainių magiškų skaičių, todėl jums nereikia nurodyti formato GLB, STL ar 3MF failus:

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

const scene = new Scene();
scene.open('model.obj', new ObjLoadOptions());

console.log(`Root node: "${scene.rootNode.name}"`);
console.log(`Top-level children: ${scene.rootNode.childNodes.length}`);

Taip pat galite atsisiųsti iš A Buffer Atminties naudojimas scene.openFromBuffer(buffer, options);Naudinga be serverio vamzdžiuose, kuriuose disko I/O nėra.


3 žingsnis: rašykite atkūrimo kelionės funkciją

Rekursija per childNodes funkcija aplanko kiekvieną mazgą gylis pirmiausia:

function traverse(node: any, depth = 0): void {
    const indent = '  '.repeat(depth);
    const entityType = node.entity ? node.entity.constructor.name : '-';
    console.log(`${indent}[${entityType}] ${node.name}`);
    for (const child of node.childNodes) {
        traverse(child, depth + 1);
    }
}

traverse(scene.rootNode);

Vienas sceną su vienu meshu pavadintas Cube,Išmetimas atrodys taip:

[-] RootNode
  [Mesh] Cube

<button class=“hextra-code-copy-btn hx-group/copybtn hx-transition-all active:hx-opacity-50 hx-bg-primary-700/5 hx-border hx-border-black/5 hx-text-gray-600 hover:hx-text-gray-900 hx-rounded-md hx-p-1.5 dark:hx-bg-primary-300/10 dark:hx-border-white/10 dark:hx-text-gray-400 dark:hover:hx-text-gray-50” title=“Copy code”

<div class="copy-icon group-[.copied]/copybtn:hx-hidden hx-pointer-events-none hx-h-4 hx-w-4"></div>
<div class="success-icon hx-hidden group-[.copied]/copybtn:hx-block hx-pointer-events-none hx-h-4 hx-w-4"></div>

node.entity yra null grupės mazgų, kaulų ir lokatorių. constructor.name patikrinti bet kokio tipo subjektų darbus: Mesh, Camera, Light,ir tt.


4 žingsnis: prieiga prie subjekto tipo kiekviename mazgo

Norėdami imtis veiksmų pagal subjekto tipą, naudokite vieną instanceof Pasitikrinkite po nulinės apsaugos:

import { Mesh } from '@aspose/3d/entities';

function visitWithTypeCheck(node: any, depth = 0): void {
    const indent = '  '.repeat(depth);
    if (node.entity instanceof Mesh) {
        const mesh = node.entity as Mesh;
        console.log(`${indent}MESH "${node.name}": ${mesh.controlPoints.length} vertices`);
    } else if (node.entity) {
        console.log(`${indent}${node.entity.constructor.name} "${node.name}"`);
    } else {
        console.log(`${indent}GROUP "${node.name}"`);
    }
    for (const child of node.childNodes) {
        visitWithTypeCheck(child, depth + 1);
    }
}

visitWithTypeCheck(scene.rootNode);

instanceof Mesh yra saugiausias būdas patvirtinti, kad subjektas yra poligonų kaukė prieš prieinant controlPoints, polygonCount,arba vertikalių elementų.


5 žingsnis: Filtruokite sąnaudas pagal subjektų tipą

Norėdami surinkti tik mazgų dėžutes be pilno medžio spausdinimo, naudokite atsinaujinančią akumuliatorių:

import { Mesh } from '@aspose/3d/entities';

function collectMeshes(
    node: any,
    results: Array<{ name: string; mesh: Mesh }> = []
): Array<{ name: string; mesh: Mesh }> {
    if (node.entity instanceof Mesh) {
        results.push({ name: node.name, mesh: node.entity as Mesh });
    }
    for (const child of node.childNodes) {
        collectMeshes(child, results);
    }
    return results;
}

const meshNodes = collectMeshes(scene.rootNode);
console.log(`Found ${meshNodes.length} mesh node(s)`);

Funkcija priima pasirinktą results ratas, kad kvietėjai galėtų iš anksto populiuoti jį dėl rezultatų derinimo per kelias substramas.


6 žingsnis: surinkti visus sandėlius ir spausdinti vertikalų skaičių

Išplėsti kolektorių spausdinimo per-mesh statistiką:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { Mesh } from '@aspose/3d/entities';

function collectMeshes(node: any, results: Array<{name: string, mesh: Mesh}> = []) {
    if (node.entity instanceof Mesh) {
        results.push({ name: node.name, mesh: node.entity as Mesh });
    }
    for (const child of node.childNodes) {
        collectMeshes(child, results);
    }
    return results;
}

const scene = new Scene();
scene.open('model.obj', new ObjLoadOptions());

const meshes = collectMeshes(scene.rootNode);
for (const { name, mesh } of meshes) {
    console.log(`${name}: ${mesh.controlPoints.length} vertices, ${mesh.polygonCount} polygons`);
}

Pavyzdžiui, išleidimas dviejų mėnesių scenoje:

Cube: 8 vertices, 6 polygons
Sphere: 482 vertices, 480 polygons

<button class=“hextra-code-copy-btn hx-group/copybtn hx-transition-all active:hx-opacity-50 hx-bg-primary-700/5 hx-border hx-border-black/5 hx-text-gray-600 hover:hx-text-gray-900 hx-rounded-md hx-p-1.5 dark:hx-bg-primary-300/10 dark:hx-border-white/10 dark:hx-text-gray-400 dark:hover:hx-text-gray-50” title=“Copy code”

<div class="copy-icon group-[.copied]/copybtn:hx-hidden hx-pointer-events-none hx-h-4 hx-w-4"></div>
<div class="success-icon hx-hidden group-[.copied]/copybtn:hx-block hx-pointer-events-none hx-h-4 hx-w-4"></div>

Patarimai ir geriausios praktikos

  • Visada nulinis tikrinimas node.entity daugelis mazgų yra grynos grupės mazgai, kurie nešioja jokią subjektą.
  • Naudojimas instanceof per viršų constructor.name Įrodymai, kaip tikrinti loginius kelius. instanceof yra refaktorius-saugus; srauto palyginimas constructor.name Sumažėja su miniatiūriniais.
  • Perėjimas per for...of per viršų childNodes: neterabilus tvarko visus grandinės dydžius saugiai. vengti numerinio indeksavimo, kad būtų galima suderinti priekinį ryšį.
  • Venkite medžio perėjimo metu:• Nenaudokite arba nepašalinkite mazgų per atkūrimo skambučius. pirmiausia surinkti rezultatus, tada keisti.
  • Paspauskite rezultatus kaip parametrą:Tai vengia kiekvieno atkuriamojo skambučio naujo rato paskirstymo ir palengvina substrato rezultatų derinimą.

Bendros problemos

SimptomaiPriežastisFixas
childNodes Nuliui ilgai rootNodeModelis nepakrautasĮsitikinti scene.open() Pasibaigė be klaidų prieš perėjimo
node.entity instanceof Mesh Niekada tikraKlaidingas Mesh Importo keliasImporto Mesh@aspose/3d/entities,Ne iš @aspose/3d Šaknis
Keliautojai praleidžia nušluostytas kauliukasNeatsisakyti visų vaikųĮsitikinkite, kad atkuriamasis skambutis apima kiekvieną elementą node.childNodes
mesh.controlPoints.length 0 yraMesh įkrautas, bet neturi geometrijosPatikrinkite OBJ šaltinį tuščioms grupėms; naudokite mesh.polygonCount Kaip antrinis patikrinimas
Sunkiai įtempta ant gilių hierarchijųLabai gilios scenos medžiai (šimtus lygių)Pakeiskite atgalį aiškiai naudojant stack Array.push / Array.pop

Dažnai užduodami klausimai

Arba scene.rootNode Ar pati turi subjektą? Ne. Šaknis yra konteineris, kurį automatiškai sukūrė biblioteka. neturi subjekto. Jūsų geometrija ir kiti scenos objektai gyvena ant vaiko mazgų viename ar daugiau lygių žemiau rootNode.

Koks skirtumas tarp node.entity ir node.entities? node.entity kai kurie vyresni FBX ir COLLADA failai gali gaminti mazgas su keliomis prijungtomis subjektais; šiuo atveju node.entities (Plural) pateikia visą sąrašą.

Ar galiu peržengti plačiajuosčio pirmuoju tvarka, o ne giliuojuosius? Naudokite švirkštą vietoj atnaujinimo skambučio: spauskite scene.rootNode į eilę, tada perkelti ir apdoroti mazgas, o kiekvieno mazgo slėpimas childNodes Į kišenę į kištuką.

yra scene.open() Ar tai sinchroninė? Taip ir. scene.open() ir scene.openFromBuffer() Abu blokuoja skambučių juostą, kol failas yra visiškai išdžiovintas. Įpilkite juos į darbininkų juostoje, jei reikia palaikyti renginio ratas atsiliepimą.

Kaip aš gaunu pasaulinės erdvės pozicijas iš mazgo? Skaityti → node.globalTransform;Jis grąžina tik skaitymo GlobalTransform su pasaulio-templiu matrizu, sudaryta iš visų protėvių transformacijų. node.evaluateGlobalTransform(false).

Kokios rūšies subjektai yra įmanomi be Mesh? Camera, Light, ir pritaikytos skeletonų / kaulų subjektų. patikrinti node.entity.constructor.name arba naudojimas instanceof Į importuojamą klasę įtraukiama specialios klasės. @aspose/3d.

Taip pat žiūrėkite

 Lietuvių