/// module BABYLON.GLTF2.Extensions { const NAME = "KHR_draco_mesh_compression"; interface IKHRDracoMeshCompression { bufferView: number; attributes: { [name: string]: number }; } interface ILoaderBufferViewDraco extends ILoaderBufferView { _dracoBabylonGeometry?: Promise; } /** * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression) */ export class KHR_draco_mesh_compression implements IGLTFLoaderExtension { /** The name of this extension. */ public readonly name = NAME; /** Defines whether this extension is enabled. */ public enabled = DracoCompression.DecoderAvailable; private _loader: GLTFLoader; private _dracoCompression?: DracoCompression; /** @hidden */ constructor(loader: GLTFLoader) { this._loader = loader; } /** @hidden */ public dispose(): void { if (this._dracoCompression) { this._dracoCompression.dispose(); delete this._dracoCompression; } delete this._loader; } /** @hidden */ public _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable> { return GLTFLoader.LoadExtensionAsync(context, primitive, this.name, (extensionContext, extension) => { if (primitive.mode != undefined) { if (primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP && primitive.mode !== MeshPrimitiveMode.TRIANGLES) { throw new Error(`${context}: Unsupported mode ${primitive.mode}`); } // TODO: handle triangle strips if (primitive.mode === MeshPrimitiveMode.TRIANGLE_STRIP) { throw new Error(`${context}: Mode ${primitive.mode} is not currently supported`); } } const attributes: { [kind: string]: number } = {}; const loadAttribute = (name: string, kind: string) => { const uniqueId = extension.attributes[name]; if (uniqueId == undefined) { return; } babylonMesh._delayInfo = babylonMesh._delayInfo || []; if (babylonMesh._delayInfo.indexOf(kind) === -1) { babylonMesh._delayInfo.push(kind); } attributes[kind] = uniqueId; }; loadAttribute("POSITION", VertexBuffer.PositionKind); loadAttribute("NORMAL", VertexBuffer.NormalKind); loadAttribute("TANGENT", VertexBuffer.TangentKind); loadAttribute("TEXCOORD_0", VertexBuffer.UVKind); loadAttribute("TEXCOORD_1", VertexBuffer.UV2Kind); loadAttribute("JOINTS_0", VertexBuffer.MatricesIndicesKind); loadAttribute("WEIGHTS_0", VertexBuffer.MatricesWeightsKind); loadAttribute("COLOR_0", VertexBuffer.ColorKind); var bufferView = ArrayItem.Get(extensionContext, this._loader.gltf.bufferViews, extension.bufferView) as ILoaderBufferViewDraco; if (!bufferView._dracoBabylonGeometry) { bufferView._dracoBabylonGeometry = this._loader.loadBufferViewAsync(`#/bufferViews/${bufferView.index}`, bufferView).then(data => { if (!this._dracoCompression) { this._dracoCompression = new DracoCompression(); } return this._dracoCompression.decodeMeshAsync(data, attributes).then(babylonVertexData => { const babylonGeometry = new Geometry(babylonMesh.name, this._loader.babylonScene); babylonVertexData.applyToGeometry(babylonGeometry); return babylonGeometry; }).catch(error => { throw new Error(`${context}: ${error.message}`); }); }); } return bufferView._dracoBabylonGeometry; }); } } GLTFLoader.RegisterExtension(NAME, loader => new KHR_draco_mesh_compression(loader)); }