/// module BABYLON.GLTF2 { /** * Abstract class that can be implemented to extend existing gltf loader behavior. */ export abstract class GLTFLoaderExtension implements IGLTFLoaderExtension, IDisposable { public enabled = true; public abstract readonly name: string; protected _loader: GLTFLoader; constructor(loader: GLTFLoader) { this._loader = loader; } public dispose(): void { delete this._loader; } // #region Overridable Methods /** Override this method to modify the default behavior for loading scenes. */ protected _loadSceneAsync(context: string, node: ILoaderScene): Nullable> { return null; } /** Override this method to modify the default behavior for loading nodes. */ protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable> { return null; } /** Override this method to modify the default behavior for loading mesh primitive vertex data. */ protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable> { return null; } /** Override this method to modify the default behavior for loading materials. */ protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable> { return null; } /** Override this method to modify the default behavior for loading uris. */ protected _loadUriAsync(context: string, uri: string): Nullable> { return null; } // #endregion /** Helper method called by a loader extension to load an glTF extension. */ protected _loadExtensionAsync(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise): Nullable> { if (!property.extensions) { return null; } const extensions = property.extensions; const extension = extensions[this.name] as TProperty; if (!extension) { return null; } // Clear out the extension before executing the action to avoid recursing into the same property. delete extensions[this.name]; try { return actionAsync(`${context}/extensions/${this.name}`, extension); } finally { // Restore the extension after executing the action. extensions[this.name] = extension; } } /** Helper method called by the loader to allow extensions to override loading scenes. */ public static _LoadSceneAsync(loader: GLTFLoader, context: string, scene: ILoaderScene): Nullable> { return loader._applyExtensions(extension => extension._loadSceneAsync(context, scene)); } /** Helper method called by the loader to allow extensions to override loading nodes. */ public static _LoadNodeAsync(loader: GLTFLoader, context: string, node: ILoaderNode): Nullable> { return loader._applyExtensions(extension => extension._loadNodeAsync(context, node)); } /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */ public static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable> { return loader._applyExtensions(extension => extension._loadVertexDataAsync(context, primitive, babylonMesh)); } /** Helper method called by the loader to allow extensions to override loading materials. */ public static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable> { return loader._applyExtensions(extension => extension._loadMaterialAsync(context, material, babylonMesh, babylonDrawMode, assign)); } /** Helper method called by the loader to allow extensions to override loading uris. */ public static _LoadUriAsync(loader: GLTFLoader, context: string, uri: string): Nullable> { return loader._applyExtensions(extension => extension._loadUriAsync(context, uri)); } } }