Cara Memuat Model 3D di TypeScript

Cara Memuat Model 3D di TypeScript

Paket @aspose/3d memberikan aplikasi TypeScript dan Node.js API yang sederhana untuk membuka file adegan 3D. Scene adalah objek akar: panggil scene.open() dengan jalur file dan opsi pemuatan khusus format yang opsional, kemudian telusuri scene.rootNode untuk mengakses geometri, material, dan transformasi.

Panduan Langkah-demi-Langkah

Langkah 1: Instal @aspose/3d via npm

Tambahkan paket ke proyek Anda. Tidak diperlukan binari native atau alat build khusus platform; hanya Node.js 18 atau yang lebih baru.

npm install @aspose/3d

Untuk proyek TypeScript, definisi tipe disertakan dalam paket:

##tsconfig.json: minimum required settings
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true
  }
}

Langkah 2: Impor Adegan dan opsi khusus format

Setiap format mengekspos kelas pemuat dan objek opsi masing‑masing di bawah sub‑path. Impor hanya apa yang Anda butuhkan:

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

Untuk format lain pola tersebut identik:

import { GltfLoadOptions } from '@aspose/3d/formats/gltf';
import { FbxLoadOptions } from '@aspose/3d/formats/fbx';
import { StlLoadOptions } from '@aspose/3d/formats/stl';

Langkah 3: Buka file 3D menggunakan scene.open()

Buat sebuah instance Scene, lalu panggil scene.open() dengan jalur file dan objek opsi‑muat opsional. Panggilan tersebut bersifat sinkron.

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

const scene = new Scene();
const options = new ObjLoadOptions();
options.enableMaterials = true;

scene.open('model.obj', options);
console.log('Scene loaded successfully');

Untuk memuat dari Buffer yang sudah ada di memori (berguna dalam konteks serverless atau streaming):

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

const buffer = fs.readFileSync('model.obj');
const scene = new Scene();
scene.openFromBuffer(buffer, new ObjLoadOptions());

Langkah 4: Iterasi node adegan

Grafik adegan adalah sebuah pohon yang berakar di scene.rootNode. Setiap Node dapat berisi node anak dan opsional entity (mesh, kamera, cahaya, dll.).

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

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

function visitNode(node: any, depth: number = 0): void {
    const indent = '  '.repeat(depth);
    console.log(`${indent}Node: ${node.name}`);
    if (node.entity) {
        console.log(`${indent}  Entity type: ${node.entity.constructor.name}`);
    }
    for (const child of node.childNodes) {
        visitNode(child, depth + 1);
    }
}

visitNode(scene.rootNode);

Langkah 5: Akses data vertex mesh melalui controlPoints

Ketika entitas node adalah Mesh, Anda dapat membaca titik kontrol mentah (vertices) dari array controlPoints. Setiap entri adalah Vector4 dengan komponen x, y, z, dan w.

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

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

for (const node of scene.rootNode.childNodes) {
    if (!node.entity) continue;
    const entity = node.entity;
    // Check if the entity is a Mesh by duck-typing controlPoints
    if ('controlPoints' in entity) {
        const mesh = entity as any;
        console.log(`Mesh "${node.name}": ${mesh.controlPoints.length} vertices`);
        // Print first three vertices
        for (let i = 0; i < Math.min(3, mesh.controlPoints.length); i++) {
            const v = mesh.controlPoints[i];
            console.log(`  v[${i}]: x=${v.x.toFixed(4)}, y=${v.y.toFixed(4)}, z=${v.z.toFixed(4)}`);
        }
    }
}

Langkah 6: Konfigurasikan ObjLoadOptions untuk pemuatan material

ObjLoadOptions mengekspos properti untuk mengontrol bagaimana file material .mtl yang menyertainya dan tekstur diselesaikan.

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

const options = new ObjLoadOptions();
options.enableMaterials = true;   // parse .mtl file if present

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

// Inspect materials attached to nodes
for (const node of scene.rootNode.childNodes) {
    if (node.material) {
        console.log(`Material on "${node.name}": ${node.material.constructor.name}`);
    }
}

Masalah Umum dan Solusi

Error: Tidak dapat menemukan modul ‘@aspose/3d/formats/obj’ Sub‑path format memerlukan ekspor paket Node.js 12.7+. Pastikan Anda menggunakan Node.js 18 atau yang lebih baru. Jika menggunakan TypeScript, atur "moduleResolution": "node16" atau "bundler" di tsconfig.json.

scene.rootNode.childNodes is empty after open()
Beberapa file OBJ menggunakan akhir baris non‑standar atau tidak memiliki newline di akhir. Verifikasi bahwa file tersebut adalah OBJ yang valid dengan membukanya di editor teks. Juga pastikan Anda mengirim ObjLoadOptions dan bukan LoadOptions generik: opsi khusus format diperlukan untuk penyaluran yang tepat.

array controlPoints memiliki panjang nol
Mesh mungkin telah dimuat tetapi tidak berisi geometri (mis., grup kosong dalam OBJ). Gunakan mesh.polygonCount untuk memeriksa sebelum mengiterasi vertex.

Penggunaan memori tinggi untuk file besar
Load-from-buffer dengan scene.openFromBuffer() tidak mengurangi memori puncak: seluruh file harus diparsing. Untuk file besar (> 100 MB), pastikan proses Node.js Anda memiliki heap yang cukup: node --max-old-space-size=4096 yourScript.js.

Kesalahan tipe: ’entity’ berjenis ‘unknown’
Properti entity memiliki tipe yang luas. Lakukan cast ke any atau ke kelas spesifik (Mesh, Camera, dll.) tergantung apa yang Anda harapkan dalam adegan Anda.

Pertanyaan yang Sering Diajukan (FAQ)

Format apa yang dapat dimuat dengan scene.open()? OBJ, glTF 2.0 (.gltf + .bin), GLB, STL, 3MF, FBX, dan COLLADA (.dae) semuanya didukung untuk impor. Gunakan kelas *LoadOptions yang sesuai untuk setiap format.

Bisakah saya memuat file tanpa menentukan opsi?
Ya. scene.open('model.glb') berfungsi tanpa opsi untuk format yang tidak memerlukan konfigurasi khusus. Disarankan untuk memberikan opsi pada OBJ karena resolusi material bergantung pada enableMaterials.

Apakah pemuatan berjalan secara asinkron?
Tidak. scene.open() dan scene.openFromBuffer() bersifat sinkron. Bungkus mereka dalam thread pekerja atau setImmediate jika Anda perlu menjaga loop peristiwa tetap responsif.

Apakah ekspor OBJ didukung?
Ya. Ekspor OBJ didukung melalui scene.save('output.obj'). File material .mtl ditulis secara otomatis bersamaan dengan file .obj.

Where is the .mtl file expected when loading OBJ? Secara default, parser mencari file .mtl yang direferensikan di dalam OBJ (direktif mtllib) relatif terhadap direktori file OBJ. Pastikan kedua file berada di folder yang sama.

Lihat Juga

 Bahasa Indonesia