كيفية تصدير المشاهد ثلاثية الأبعاد إلى glTF/GLB باستخدام TypeScript

كيفية تصدير المشاهد ثلاثية الأبعاد إلى glTF/GLB باستخدام TypeScript

يدعم Aspose.3D FOSS تنسيق glTF 2.0 كتنسيق استيراد وتصدير على حد سواء. يمكن تعبئة نفس كائن Scene من ملف OBJ أو FBX أو STL أو أي ملف مصدر آخر ثم كتابته إلى .gltf (JSON + ثنائي خارجي) أو .glb (حاوية ثنائية واحدة) عن طريق ضبط علم واحد على 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: بناء أو تحميل مشهد

الخيار أ: التحميل من ملف موجود (تحويل 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());

الخيار ب: بناء مشهد بسيط برمجياً:

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;

الخيارات الإضافية التي يمكنك تعيينها:

الخاصيةالنوعالافتراضيالتأثير
binaryModebooleanfalsetrue → GLB, false → glTF JSON
flipTexCoordVbooleantrueقلب محور 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')، يتم كتابة ملف مادة .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) يعبئ كل شيء في حاوية ثنائية واحدة. اضبط 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 والإصدارات الأقدم غير مدعومة.

انظر أيضًا

 العربية