Як експортувати 3D-сцени у glTF/GLB за допомогою TypeScript
Aspose.3D FOSS підтримує glTF 2.0 як формат імпорту, так і експорту. Та ж Scene об’єкт може бути заповнений з OBJ, FBX, STL або іншого вихідного файлу, а потім записаний у .gltf (JSON + external binary) або .glb (single binary container) шляхом встановлення одного прапорця на GltfSaveOptions.
Покроковий посібник
Крок 1: Встановіть @aspose/3d
npm install @aspose/3dПереконайтеся, що активний Node.js 18 або новіший:
node --version # must be >= 16.0.0Крок 2: Імпорт Scene, GltfSaveOptions та GltfFormat
import { Scene } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';GltfFormat є дескриптором формату, який передається scene.save(). GltfSaveOptions містить усі налаштування експорту.
Якщо ви також завантажуєте вихідний файл (наприклад, OBJ), імпортуйте відповідні параметри завантаження:
import { ObjLoadOptions } from '@aspose/3d/formats/obj';Крок 3: Створити або завантажити сцену
Варіант A: Завантажити з існуючого файлу (конвертація 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());Варіант B: Програмно створити мінімальну сцену:
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
Крок 4: Налаштувати GltfSaveOptions
GltfSaveOptions керує форматом виводу та деталями кодування.
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;Додаткові параметри, які ви можете встановити:
| Властивість | Тип | За замовчуванням | Ефект |
|---|---|---|---|
binaryMode | boolean | false | true → GLB, false → glTF JSON |
flipTexCoordV | boolean | true | Перевернути вертикальну вісь UV для сумісності з рушієм |
Крок 5: Зберегти за допомогою scene.save()
Передайте шлях виводу, GltfFormat дескриптор, і налаштовані параметри:
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');Для створення JSON .gltf файл замість:
saveOpts.binaryMode = false;
scene.save('output.gltf', GltfFormat.getInstance(), saveOpts);
console.log('Exported to glTF JSON successfully');Крок 6: Перевірте вихідний файл
Перевірте, чи існує вихідний файл і чи має він ненульовий розмір:
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');
}Для двосторонньої перевірки перезавантажте GLB і перевірте кількість вузлів:
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`);Типові проблеми та їх виправлення
Файл матеріалів OBJ не знайдено після експорту При збереженні у формат OBJ через scene.save('output.obj'), the .mtl файл матеріалу записується поруч із .obj файл автоматично. Переконайтеся, що вихідний каталог доступний для запису і що обидва файли зберігаються разом.
Вихідний .glb менший, ніж очікувалося / сітки відсутні Якщо завантажена сцена має вузли без сутностей (наприклад, порожні групи з OBJ), GLB не міститиме геометрії цих вузлів. Переконайтеся, що ваш вхідний файл містить фактичні дані полігонів, використовуючи mesh.controlPoints.length > 0 перед збереженням.
Не вдалося знайти модуль ‘@aspose/3d/formats/gltf’ Переконайтеся, що ви використовуєте Node.js 18+ і що @aspose/3d встановлено в тому ж node_modules як вашу точку входу. Запустіть npm ls @aspose/3d щоб підтвердити, що версія 24.12.0 або новіша.
GltfFormat.getInstance() повертає undefined Це вказує на невідповідність версій між основним @aspose/3d пакет і кешовану старішу версію. Видаліть node_modules і package-lock.json, потім запустіть npm install знову.
Текстури відсутні у вихідному GLB Переконайтеся binaryMode = true встановлено для створення самодостатнього GLB. Для виводу glTF JSON файли зображень текстур мають бути присутні поруч з вихідним файлом, оскільки вони посилаються за відносним шляхом.
Помилка типу: аргумент типу ‘GltfSaveOptions’ не можна призначити Переконайтеся, що обидва Scene і GltfSaveOptions імпортуються з одного й того ж встановленого екземпляра пакету. Змішані інсталяції (глобальні + локальні) можуть спричиняти невідповідності інтерфейсів.
Поширені запитання (FAQ)
У чому різниця між glTF і GLB? glTF 2.0 JSON (.gltf) зберігає граф сцени у читабельному JSON‑файлі з окремими .bin буферами та файлами зображень. GLB (.glb) упакує все в один бінарний контейнер. Set binaryMode = true для GLB, false для JSON glTF.
Чи можу я експортувати сцену, яка була створена повністю в коді (без вихідного файлу)? Так. Створіть Scene, додати Node об’єкти, прикріпити Mesh або інші сутності, потім викликати scene.save(). Сцена не обов’язково має походити з завантаженого файлу.
Чи є експорт glTF без втрат? Для геометрії та трансформацій — так. Матеріали, де можливо, відображаються у властивості матеріалів glTF PBR. Пропрієтарні розширення матеріалів FBX можуть не проходити повний круговий процес без втрат.
Чи можу я експортувати у STL або 3MF замість цього? Так. Шаблон ідентичний; імпортуйте відповідний формат. *SaveOptions і *Format.getInstance():
import { StlSaveOptions, StlFormat } from '@aspose/3d/formats/stl';
const opts = new StlSaveOptions();
scene.save('output.stl', StlFormat.getInstance(), opts);Чи виконується scene.save() асинхронно? Ні. scene.save() є синхронним. Обгорніть його у робочий потік, якщо потрібно уникнути блокування циклу подій під час великих експортів.
Які версії Node.js підтримуються? Node.js 18, 20 і 22+. Node.js 16 та раніше не підтримуються.