Cara Mengekspor Adegan 3D ke glTF/GLB dalam TypeScript

Cara Mengekspor Adegan 3D ke glTF/GLB dalam TypeScript

Aspose.3D FOSS mendukung glTF 2.0 sebagai format impor dan ekspor. Objek Scene yang sama dapat diisi dari file OBJ, FBX, STL, atau file sumber lainnya dan kemudian ditulis ke .gltf (JSON + binary eksternal) atau .glb (kontainer biner tunggal) dengan mengatur satu flag pada GltfSaveOptions.

Panduan Langkah-demi-Langkah

Langkah 1: Instal @aspose/3d

npm install @aspose/3d

Pastikan Node.js 18 atau yang lebih baru aktif:

node --version   # must be >= 16.0.0

Langkah 2: Impor Scene, GltfSaveOptions, dan GltfFormat

import { Scene } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

GltfFormat adalah deskripsi format yang diteruskan ke scene.save(). GltfSaveOptions membawa semua konfigurasi ekspor.

Jika Anda juga memuat file sumber (mis., OBJ), impor opsi pemuatan yang cocok:

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

Langkah 3: Bangun atau muat adegan

Opsi A: Muat dari file yang ada (konversi OBJ → GLB):

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

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

Opsi B: Bangun adegan minimal secara programatis:

import { Scene, Node, Mesh } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
const childNode = new Node('cube');
scene.rootNode.addChildNode(childNode);
// Attach geometry to childNode as needed

Langkah 4: Konfigurasikan GltfSaveOptions

GltfSaveOptions mengontrol format output dan detail pengkodean.

const saveOpts = new GltfSaveOptions();

// Set to true for a single binary .glb file
// Set to false (default) for JSON .gltf + separate .bin
saveOpts.binaryMode = true;

Opsi tambahan yang dapat Anda atur:

PropertiTipeBawaanEfek
binaryModebooleanfalsetrue → GLB, false → glTF JSON
flipTexCoordVbooleantrueBalik sumbu UV vertikal untuk kompatibilitas mesin

Langkah 5: Simpan menggunakan scene.save()

Berikan jalur output, deskriptor GltfFormat, dan opsi yang dikonfigurasi:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

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

const saveOpts = new GltfSaveOptions();
saveOpts.binaryMode = true;   // produce .glb

scene.save('output.glb', GltfFormat.getInstance(), saveOpts);
console.log('Converted to GLB successfully');

Untuk menghasilkan file JSON .gltf sebagai gantinya:

saveOpts.binaryMode = false;
scene.save('output.gltf', GltfFormat.getInstance(), saveOpts);
console.log('Exported to glTF JSON successfully');

Langkah 6: Verifikasi file output

Periksa bahwa file output ada dan memiliki ukuran tidak nol:

import * as fs from 'fs';

const outputPath = 'output.glb';
const stats = fs.statSync(outputPath);
console.log(`Output file size: ${stats.size} bytes`);

if (stats.size === 0) {
    throw new Error('Export produced an empty file: check scene content');
}

Untuk verifikasi putar‑balik, muat ulang GLB dan periksa jumlah node:

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

const verify = new Scene();
verify.open('output.glb', new GltfLoadOptions());

let nodeCount = 0;
function countNodes(node: any): void {
    nodeCount++;
    for (const child of node.childNodes) countNodes(child);
}
countNodes(verify.rootNode);

console.log(`Round-trip verification: ${nodeCount} node(s) in output`);

Masalah Umum dan Solusi

File material OBJ tidak ditemukan setelah ekspor
Saat menyimpan ke OBJ melalui scene.save('output.obj'), file material .mtl ditulis berdampingan dengan file .obj secara otomatis. Pastikan direktori output dapat ditulisi dan kedua file disimpan bersama.

Output .glb lebih kecil dari yang diharapkan / mesh hilang
Jika adegan yang dimuat memiliki node tanpa entitas (misalnya, grup kosong dari OBJ), GLB tidak akan berisi geometri node tersebut. Pastikan file input Anda memiliki data poligon sebenarnya menggunakan mesh.controlPoints.length > 0 sebelum menyimpan.

Tidak dapat menemukan modul ‘@aspose/3d/formats/gltf’ Pastikan Anda menggunakan Node.js 18+ dan bahwa @aspose/3d terpasang di node_modules yang sama dengan titik masuk Anda. Jalankan npm ls @aspose/3d untuk mengonfirmasi versi 24.12.0 atau lebih baru.

GltfFormat.getInstance() returns undefined
Ini menunjukkan adanya ketidaksesuaian versi antara paket utama @aspose/3d dan versi lama yang di-cache. Hapus node_modules dan package-lock.json, lalu jalankan npm install lagi.

Textures are missing in the output GLB
Pastikan binaryMode = true diatur untuk menghasilkan GLB yang mandiri. Untuk output JSON glTF, file gambar tekstur harus ada di samping file output karena mereka direferensikan dengan jalur relatif.

Kesalahan tipe: Argumen bertipe ‘GltfSaveOptions’ tidak dapat ditetapkan
Pastikan kedua Scene dan GltfSaveOptions diimpor dari instansi paket yang terpasang sama. Instalasi campuran (global + lokal) dapat menyebabkan ketidakcocokan antarmuka.

Pertanyaan yang Sering Diajukan (FAQ)

Apa perbedaan antara glTF dan GLB?
glTF 2.0 JSON (.gltf) menyimpan grafik adegan sebagai file JSON yang dapat dibaca manusia dengan buffer .bin dan file gambar terpisah. GLB (.glb) mengemas semuanya ke dalam satu kontainer biner. Atur binaryMode = true untuk GLB, false untuk JSON glTF.

Bisakah saya mengekspor sebuah scene yang dibangun sepenuhnya dengan kode (tanpa file sumber)?
Ya. Buat sebuah Scene, tambahkan objek Node, lampirkan Mesh atau entitas lain, kemudian panggil scene.save(). Scene tidak perlu berasal dari file yang dimuat.

Apakah ekspor glTF lossless?
Untuk geometri dan transformasi, ya. Material dipetakan ke properti material glTF PBR bila memungkinkan. Ekstensi material FBX proprietari mungkin tidak dapat melakukan round‑trip dengan sempurna.

Bisakah saya mengekspor ke STL atau 3MF sebagai gantinya? Ya. Polanya identik; impor *SaveOptions dan *Format.getInstance() dari format yang bersangkutan:

import { StlSaveOptions, StlFormat } from '@aspose/3d/formats/stl';
const opts = new StlSaveOptions();
scene.save('output.stl', StlFormat.getInstance(), opts);

Apakah scene.save() berjalan secara asynchronous?
Tidak. scene.save() bersifat synchronous. Bungkus dalam worker thread jika Anda perlu menghindari pemblokiran event loop selama ekspor besar.

Versi Node.js apa yang didukung?
Node.js 18, 20, dan 22+. Node.js 16 dan sebelumnya tidak didukung.

Lihat Juga

 Bahasa Indonesia