KHR_draco_mesh_compression.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON.GLTF2.Extensions {
  3. const NAME = "KHR_draco_mesh_compression";
  4. interface IKHRDracoMeshCompression {
  5. bufferView: number;
  6. attributes: { [name: string]: number };
  7. }
  8. interface ILoaderBufferViewDraco extends ILoaderBufferView {
  9. _dracoBabylonGeometry?: Promise<Geometry>;
  10. }
  11. /**
  12. * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression)
  13. */
  14. export class KHR_draco_mesh_compression implements IGLTFLoaderExtension {
  15. /** The name of this extension. */
  16. public readonly name = NAME;
  17. /** Defines whether this extension is enabled. */
  18. public enabled = DracoCompression.DecoderAvailable;
  19. private _loader: GLTFLoader;
  20. private _dracoCompression?: DracoCompression;
  21. /** @hidden */
  22. constructor(loader: GLTFLoader) {
  23. this._loader = loader;
  24. }
  25. /** @hidden */
  26. public dispose(): void {
  27. if (this._dracoCompression) {
  28. this._dracoCompression.dispose();
  29. delete this._dracoCompression;
  30. }
  31. delete this._loader;
  32. }
  33. /** @hidden */
  34. public _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>> {
  35. return GLTFLoader.LoadExtensionAsync<IKHRDracoMeshCompression, Geometry>(context, primitive, this.name, (extensionContext, extension) => {
  36. if (primitive.mode != undefined) {
  37. if (primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP &&
  38. primitive.mode !== MeshPrimitiveMode.TRIANGLES) {
  39. throw new Error(`${context}: Unsupported mode ${primitive.mode}`);
  40. }
  41. // TODO: handle triangle strips
  42. if (primitive.mode === MeshPrimitiveMode.TRIANGLE_STRIP) {
  43. throw new Error(`${context}: Mode ${primitive.mode} is not currently supported`);
  44. }
  45. }
  46. const attributes: { [kind: string]: number } = {};
  47. const loadAttribute = (name: string, kind: string) => {
  48. const uniqueId = extension.attributes[name];
  49. if (uniqueId == undefined) {
  50. return;
  51. }
  52. babylonMesh._delayInfo = babylonMesh._delayInfo || [];
  53. if (babylonMesh._delayInfo.indexOf(kind) === -1) {
  54. babylonMesh._delayInfo.push(kind);
  55. }
  56. attributes[kind] = uniqueId;
  57. };
  58. loadAttribute("POSITION", VertexBuffer.PositionKind);
  59. loadAttribute("NORMAL", VertexBuffer.NormalKind);
  60. loadAttribute("TANGENT", VertexBuffer.TangentKind);
  61. loadAttribute("TEXCOORD_0", VertexBuffer.UVKind);
  62. loadAttribute("TEXCOORD_1", VertexBuffer.UV2Kind);
  63. loadAttribute("JOINTS_0", VertexBuffer.MatricesIndicesKind);
  64. loadAttribute("WEIGHTS_0", VertexBuffer.MatricesWeightsKind);
  65. loadAttribute("COLOR_0", VertexBuffer.ColorKind);
  66. var bufferView = ArrayItem.Get(extensionContext, this._loader.gltf.bufferViews, extension.bufferView) as ILoaderBufferViewDraco;
  67. if (!bufferView._dracoBabylonGeometry) {
  68. bufferView._dracoBabylonGeometry = this._loader.loadBufferViewAsync(`#/bufferViews/${bufferView.index}`, bufferView).then(data => {
  69. if (!this._dracoCompression) {
  70. this._dracoCompression = new DracoCompression();
  71. }
  72. return this._dracoCompression.decodeMeshAsync(data, attributes).then(babylonVertexData => {
  73. const babylonGeometry = new Geometry(babylonMesh.name, this._loader.babylonScene);
  74. babylonVertexData.applyToGeometry(babylonGeometry);
  75. return babylonGeometry;
  76. }).catch(error => {
  77. throw new Error(`${context}: ${error.message}`);
  78. });
  79. });
  80. }
  81. return bufferView._dracoBabylonGeometry;
  82. });
  83. }
  84. }
  85. GLTFLoader.RegisterExtension(NAME, loader => new KHR_draco_mesh_compression(loader));
  86. }