KHR_draco_mesh_compression.ts 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON.GLTF2.Extensions {
  3. // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression
  4. const NAME = "KHR_draco_mesh_compression";
  5. interface IKHRDracoMeshCompression {
  6. bufferView: number;
  7. attributes: { [name: string]: number };
  8. }
  9. export class KHR_draco_mesh_compression extends GLTFLoaderExtension {
  10. public readonly name = NAME;
  11. private _dracoCompression: Nullable<DracoCompression> = null;
  12. constructor(loader: GLTFLoader) {
  13. super(loader);
  14. // Disable extension if decoder is not available.
  15. if (!DracoCompression.DecoderUrl) {
  16. this.enabled = false;
  17. }
  18. }
  19. public dispose(): void {
  20. if (this._dracoCompression) {
  21. this._dracoCompression.dispose();
  22. }
  23. super.dispose();
  24. }
  25. protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>> {
  26. return this._loadExtensionAsync<IKHRDracoMeshCompression, Geometry>(context, primitive, (extensionContext, extension) => {
  27. if (primitive.mode != undefined) {
  28. if (primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP &&
  29. primitive.mode !== MeshPrimitiveMode.TRIANGLES) {
  30. throw new Error(`${context}: Unsupported mode ${primitive.mode}`);
  31. }
  32. // TODO: handle triangle strips
  33. if (primitive.mode === MeshPrimitiveMode.TRIANGLE_STRIP) {
  34. throw new Error(`${context}: Mode ${primitive.mode} is not currently supported`);
  35. }
  36. }
  37. const attributes: { [kind: string]: number } = {};
  38. const loadAttribute = (name: string, kind: string) => {
  39. const uniqueId = extension.attributes[name];
  40. if (uniqueId == undefined) {
  41. return;
  42. }
  43. babylonMesh._delayInfo = babylonMesh._delayInfo || [];
  44. if (babylonMesh._delayInfo.indexOf(kind) === -1) {
  45. babylonMesh._delayInfo.push(kind);
  46. }
  47. attributes[kind] = uniqueId;
  48. };
  49. loadAttribute("POSITION", VertexBuffer.PositionKind);
  50. loadAttribute("NORMAL", VertexBuffer.NormalKind);
  51. loadAttribute("TANGENT", VertexBuffer.TangentKind);
  52. loadAttribute("TEXCOORD_0", VertexBuffer.UVKind);
  53. loadAttribute("TEXCOORD_1", VertexBuffer.UV2Kind);
  54. loadAttribute("JOINTS_0", VertexBuffer.MatricesIndicesKind);
  55. loadAttribute("WEIGHTS_0", VertexBuffer.MatricesWeightsKind);
  56. loadAttribute("COLOR_0", VertexBuffer.ColorKind);
  57. var bufferView = GLTFLoader._GetProperty(extensionContext, this._loader._gltf.bufferViews, extension.bufferView);
  58. return this._loader._loadBufferViewAsync(`#/bufferViews/${bufferView._index}`, bufferView).then(data => {
  59. try {
  60. if (!this._dracoCompression) {
  61. this._dracoCompression = new DracoCompression();
  62. }
  63. return this._dracoCompression.decodeMeshAsync(data, attributes).then(babylonVertexData => {
  64. const babylonGeometry = new Geometry(babylonMesh.name, this._loader._babylonScene);
  65. babylonVertexData.applyToGeometry(babylonGeometry);
  66. return babylonGeometry;
  67. });
  68. }
  69. catch (e) {
  70. throw new Error(`${context}: ${e.message}`);
  71. }
  72. });
  73. });
  74. }
  75. }
  76. GLTFLoader._Register(NAME, loader => new KHR_draco_mesh_compression(loader));
  77. }