///
module BABYLON.GLTF2.Extensions {
// https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression
const NAME = "KHR_draco_mesh_compression";
interface IKHRDracoMeshCompression {
bufferView: number;
attributes: { [name: string]: number };
}
export class KHR_draco_mesh_compression extends GLTFLoaderExtension {
public readonly name = NAME;
private _dracoCompression: Nullable = null;
constructor(loader: GLTFLoader) {
super(loader);
// Disable extension if decoder is not available.
if (!DracoCompression.DecoderUrl) {
this.enabled = false;
}
}
public dispose(): void {
if (this._dracoCompression) {
this._dracoCompression.dispose();
}
super.dispose();
}
protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable> {
return this._loadExtensionAsync(context, primitive, (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 = GLTFLoader._GetProperty(extensionContext, this._loader._gltf.bufferViews, extension.bufferView);
return this._loader._loadBufferViewAsync(`#/bufferViews/${bufferView._index}`, bufferView).then(data => {
try {
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 (e) {
throw new Error(`${context}: ${e.message}`);
}
});
});
}
}
GLTFLoader._Register(NAME, loader => new KHR_draco_mesh_compression(loader));
}