EXT_meshopt_compression.ts 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { Nullable } from "babylonjs/types";
  2. import { Tools } from "babylonjs/Misc/tools";
  3. import { IGLTFLoaderExtension } from "../glTFLoaderExtension";
  4. import { GLTFLoader } from "../glTFLoader";
  5. import { IBufferView } from "../glTFLoaderInterfaces";
  6. const NAME = "EXT_meshopt_compression";
  7. /**
  8. * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression)
  9. *
  10. * This extension uses a WebAssembly decoder module from https://github.com/zeux/meshoptimizer/tree/master/js
  11. */
  12. export class EXT_meshopt_compression implements IGLTFLoaderExtension {
  13. /**
  14. * The name of this extension.
  15. */
  16. public readonly name = NAME;
  17. /**
  18. * Defines whether this extension is enabled.
  19. */
  20. public enabled: boolean;
  21. /**
  22. * Path to decoder module; defaults to https://preview.babylonjs.com/meshopt_decoder.module.js
  23. */
  24. public static DecoderPath: string = "https://preview.babylonjs.com/meshopt_decoder.module.js";
  25. private _loader: GLTFLoader;
  26. private _decoder: Promise<any>;
  27. /** @hidden */
  28. constructor(loader: GLTFLoader) {
  29. this.enabled = loader.isExtensionUsed(NAME);
  30. this._loader = loader;
  31. if (this.enabled) {
  32. var url = Tools.GetAbsoluteUrl(EXT_meshopt_compression.DecoderPath);
  33. this._decoder = import(/* webpackIgnore: true */ url).then(function (result) {
  34. // Wait for WebAssembly compilation before resolving promise
  35. var MeshoptDecoder = result.MeshoptDecoder;
  36. return MeshoptDecoder.ready.then(() => MeshoptDecoder);
  37. });
  38. }
  39. }
  40. /** @hidden */
  41. public dispose() {
  42. }
  43. /** @hidden */
  44. public loadBufferViewAsync(context: string, bufferView: IBufferView): Nullable<Promise<ArrayBufferView>> {
  45. if (bufferView.extensions && bufferView.extensions[this.name]) {
  46. var extensionDef = bufferView.extensions[this.name];
  47. if (extensionDef._decoded) {
  48. return extensionDef._decoded;
  49. }
  50. var view = this._loader.loadBufferViewAsync(context, extensionDef);
  51. extensionDef._decoded = Promise.all([view, this._decoder]).then(function (res) {
  52. var source = res[0] as Uint8Array;
  53. var decoder = res[1];
  54. var count = extensionDef.count;
  55. var stride = extensionDef.byteStride;
  56. var result = new Uint8Array(new ArrayBuffer(count * stride));
  57. decoder.decodeGltfBuffer(result, count, stride, source, extensionDef.mode, extensionDef.filter);
  58. return Promise.resolve(result);
  59. });
  60. return extensionDef._decoded;
  61. } else {
  62. return null;
  63. }
  64. }
  65. }
  66. GLTFLoader.RegisterExtension(NAME, (loader) => new EXT_meshopt_compression(loader));