|
@@ -1,4 +1,4 @@
|
|
|
-import { AccessorType, IBufferView, IAccessor, INode, IScene, IMesh, IMaterial, ITexture, IImage, ISampler, IAnimation, ImageMimeType, IMeshPrimitive, IBuffer, IGLTF, MeshPrimitiveMode, AccessorComponentType } from "babylonjs-gltf2interface";
|
|
|
+import { AccessorType, IBufferView, IAccessor, INode, IScene, IMesh, IMaterial, ITexture, IImage, ISampler, IAnimation, ImageMimeType, IMeshPrimitive, IBuffer, IGLTF, MeshPrimitiveMode, AccessorComponentType, ITextureInfo } from "babylonjs-gltf2interface";
|
|
|
|
|
|
import { FloatArray, Nullable, IndicesArray } from "babylonjs/types";
|
|
|
import { Viewport, Color3, Vector2, Vector3, Vector4, Quaternion } from "babylonjs/Maths/math";
|
|
@@ -142,43 +142,68 @@ export class _Exporter {
|
|
|
private static _ExtensionNames = new Array<string>();
|
|
|
private static _ExtensionFactories: { [name: string]: (exporter: _Exporter) => IGLTFExporterExtensionV2 } = {};
|
|
|
|
|
|
- private _applyExtensions<T>(property: any, actionAsync: (extension: IGLTFExporterExtensionV2) => Nullable<T> | undefined): Nullable<T> {
|
|
|
+ private _applyExtension<T>(node: T, extensions: IGLTFExporterExtensionV2[], index: number, actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined): Promise<Nullable<T>> {
|
|
|
+ if (index >= extensions.length) {
|
|
|
+ return Promise.resolve(node);
|
|
|
+ }
|
|
|
+
|
|
|
+ let currentPromise = actionAsync(extensions[index], node);
|
|
|
+
|
|
|
+ if (!currentPromise) {
|
|
|
+ return this._applyExtension(node, extensions, index + 1, actionAsync)
|
|
|
+ }
|
|
|
+
|
|
|
+ return currentPromise.then(newNode => this._applyExtension(newNode || node, extensions, index + 1, actionAsync));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private _applyExtensions<T>(node: T, actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined): Promise<Nullable<T>> {
|
|
|
+ var extensions: IGLTFExporterExtensionV2[] = [];
|
|
|
for (const name of _Exporter._ExtensionNames) {
|
|
|
- const extension = this._extensions[name];
|
|
|
- if (extension.enabled) {
|
|
|
- const exporterProperty = property as any;
|
|
|
- exporterProperty._activeLoaderExtensions = exporterProperty._activeLoaderExtensions || {};
|
|
|
- const activeLoaderExtensions = exporterProperty._activeLoaderExtensions;
|
|
|
- if (!activeLoaderExtensions[name]) {
|
|
|
- activeLoaderExtensions[name] = true;
|
|
|
-
|
|
|
- try {
|
|
|
- const result = actionAsync(extension);
|
|
|
- if (result) {
|
|
|
- return result;
|
|
|
- }
|
|
|
- }
|
|
|
- finally {
|
|
|
- delete activeLoaderExtensions[name];
|
|
|
- delete exporterProperty._activeLoaderExtensions;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ extensions.push(this._extensions[name]);
|
|
|
}
|
|
|
+
|
|
|
+ return this._applyExtension(node, extensions, 0, actionAsync);
|
|
|
+ }
|
|
|
|
|
|
- return null;
|
|
|
+ public _extensionsPreExportTextureAsync(context: string, babylonTexture: Texture, mimeType: ImageMimeType): Promise<Nullable<BaseTexture>> {
|
|
|
+ return this._applyExtensions(babylonTexture, (extension, node) => extension.preExportTextureAsync && extension.preExportTextureAsync(context, node, mimeType));
|
|
|
}
|
|
|
|
|
|
- public _extensionsPreExportTextureAsync(context: string, babylonTexture: Texture, mimeType: ImageMimeType): Nullable<Promise<BaseTexture>> {
|
|
|
- return this._applyExtensions(babylonTexture, (extension) => extension.preExportTextureAsync && extension.preExportTextureAsync(context, babylonTexture, mimeType));
|
|
|
+ public _extensionsPostExportMeshPrimitiveAsync(context: string, meshPrimitive: IMeshPrimitive, babylonSubMesh: SubMesh, binaryWriter: _BinaryWriter): Promise<Nullable<IMeshPrimitive>> {
|
|
|
+ return this._applyExtensions(meshPrimitive, (extension, node) => extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, node, babylonSubMesh, binaryWriter));
|
|
|
}
|
|
|
|
|
|
- public _extensionsPostExportMeshPrimitiveAsync(context: string, meshPrimitive: IMeshPrimitive, babylonSubMesh: SubMesh, binaryWriter: _BinaryWriter): Nullable<Promise<IMeshPrimitive>> {
|
|
|
- return this._applyExtensions(meshPrimitive, (extension) => extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, meshPrimitive, babylonSubMesh, binaryWriter));
|
|
|
+ public _extensionsPostExportNodeAsync(context: string, node: INode, babylonNode: Node): Promise<Nullable<INode>> {
|
|
|
+ return this._applyExtensions(node, (extension, node) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode));
|
|
|
}
|
|
|
|
|
|
- public _extensionsPostExportNodeAsync(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>> {
|
|
|
- return this._applyExtensions(node, (extension) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode));
|
|
|
+ public _extensionsPostExportMaterialAsync(context: string, material: IMaterial, babylonMaterial: Material): Promise<Nullable<IMaterial>> {
|
|
|
+ return this._applyExtensions(material, (extension, node) => extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial));
|
|
|
+ }
|
|
|
+
|
|
|
+ public _extensionsPostExportMaterialAdditionalTextures(context: string, material: IMaterial, babylonMaterial: Material): BaseTexture[] {
|
|
|
+ let output: BaseTexture[] = [];
|
|
|
+
|
|
|
+ for (const name of _Exporter._ExtensionNames) {
|
|
|
+ var extension = this._extensions[name];
|
|
|
+
|
|
|
+ if (extension.postExportMaterialAdditionalTextures) {
|
|
|
+ output.push(...extension.postExportMaterialAdditionalTextures(context, material, babylonMaterial))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return output;
|
|
|
+ }
|
|
|
+
|
|
|
+ public _extensionsPostExportTextures(context: string, textureInfo: ITextureInfo, babylonTexture: BaseTexture): void {
|
|
|
+ for (const name of _Exporter._ExtensionNames) {
|
|
|
+ var extension = this._extensions[name];
|
|
|
+
|
|
|
+ if (extension.postExportTexture) {
|
|
|
+ extension.postExportTexture(context, textureInfo, babylonTexture);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private _forEachExtensions(action: (extension: IGLTFExporterExtensionV2) => void): void {
|
|
@@ -233,6 +258,14 @@ export class _Exporter {
|
|
|
this._glTFMaterialExporter = new _GLTFMaterialExporter(this);
|
|
|
this._loadExtensions();
|
|
|
}
|
|
|
+
|
|
|
+ public dispose() {
|
|
|
+ for (var extensionKey in this._extensions) {
|
|
|
+ const extension = this._extensions[extensionKey];
|
|
|
+
|
|
|
+ extension.dispose();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* Registers a glTF exporter extension
|
|
@@ -749,9 +782,10 @@ export class _Exporter {
|
|
|
/**
|
|
|
* Generates data for .gltf and .bin files based on the glTF prefix string
|
|
|
* @param glTFPrefix Text to use when prefixing a glTF file
|
|
|
+ * @param dispose Dispose the exporter
|
|
|
* @returns GLTFData with glTF file data
|
|
|
*/
|
|
|
- public _generateGLTFAsync(glTFPrefix: string): Promise<GLTFData> {
|
|
|
+ public _generateGLTFAsync(glTFPrefix: string, dispose = true): Promise<GLTFData> {
|
|
|
return this._generateBinaryAsync().then((binaryBuffer) => {
|
|
|
this._extensionsOnExporting();
|
|
|
const jsonText = this.generateJSON(false, glTFPrefix, true);
|
|
@@ -771,6 +805,10 @@ export class _Exporter {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (dispose) {
|
|
|
+ this.dispose();
|
|
|
+ }
|
|
|
+
|
|
|
return container;
|
|
|
});
|
|
|
|
|
@@ -803,12 +841,9 @@ export class _Exporter {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Generates a glb file from the json and binary data
|
|
|
- * Returns an object with the glb file name as the key and data as the value
|
|
|
- * @param glTFPrefix
|
|
|
- * @returns object with glb filename as key and data as value
|
|
|
+ * @hidden
|
|
|
*/
|
|
|
- public _generateGLBAsync(glTFPrefix: string): Promise<GLTFData> {
|
|
|
+ public _generateGLBAsync(glTFPrefix: string, dispose = true): Promise<GLTFData> {
|
|
|
return this._generateBinaryAsync().then((binaryBuffer) => {
|
|
|
this._extensionsOnExporting();
|
|
|
const jsonText = this.generateJSON(true);
|
|
@@ -890,6 +925,10 @@ export class _Exporter {
|
|
|
this._localEngine.dispose();
|
|
|
}
|
|
|
|
|
|
+ if (dispose) {
|
|
|
+ this.dispose();
|
|
|
+ }
|
|
|
+
|
|
|
return container;
|
|
|
});
|
|
|
}
|
|
@@ -1331,6 +1370,9 @@ export class _Exporter {
|
|
|
}
|
|
|
else {
|
|
|
return promise.then((node) => {
|
|
|
+ if (!node) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
this._nodes.push(node);
|
|
|
nodeIndex = this._nodes.length - 1;
|
|
|
nodeMap[babylonNode.uniqueId] = nodeIndex;
|