KHR_animation_pointer.js 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { GLTFLoader } from "../glTFLoader.js";
  2. import { Logger } from "@babylonjs/core/Misc/logger.js";
  3. import { animationPointerTree } from "./KHR_animation_pointer.data.js";
  4. import { GLTFPathToObjectConverter } from "./gltfPathToObjectConverter.js";
  5. const NAME = "KHR_animation_pointer";
  6. /**
  7. * Class to convert an animation pointer path to a smart object that
  8. * gets data from the animation buffer and creates animations.
  9. */
  10. class AnimationPointerPathToObjectConverter extends GLTFPathToObjectConverter {
  11. constructor(gltf) {
  12. super(gltf, animationPointerTree);
  13. }
  14. }
  15. /**
  16. * [Specification PR](https://github.com/KhronosGroup/glTF/pull/2147)
  17. * !!! Experimental Extension Subject to Changes !!!
  18. */
  19. // eslint-disable-next-line @typescript-eslint/naming-convention
  20. export class KHR_animation_pointer {
  21. /**
  22. * @internal
  23. */
  24. constructor(loader) {
  25. /**
  26. * The name of this extension.
  27. */
  28. this.name = NAME;
  29. this._loader = loader;
  30. this._pathToObjectConverter = new AnimationPointerPathToObjectConverter(this._loader.gltf);
  31. }
  32. /**
  33. * Defines whether this extension is enabled.
  34. */
  35. get enabled() {
  36. return this._loader.isExtensionUsed(NAME);
  37. }
  38. /** @internal */
  39. dispose() {
  40. this._loader = null;
  41. delete this._pathToObjectConverter; // GC
  42. }
  43. /**
  44. * Loads a glTF animation channel.
  45. * @param context The context when loading the asset
  46. * @param animationContext The context of the animation when loading the asset
  47. * @param animation The glTF animation property
  48. * @param channel The glTF animation channel property
  49. * @param onLoad Called for each animation loaded
  50. * @returns A void promise that resolves when the load is complete or null if not handled
  51. */
  52. _loadAnimationChannelAsync(context, animationContext, animation, channel, onLoad) {
  53. const extension = channel.target.extensions?.KHR_animation_pointer;
  54. if (!extension || !this._pathToObjectConverter) {
  55. return null;
  56. }
  57. if (channel.target.path !== "pointer" /* AnimationChannelTargetPath.POINTER */) {
  58. Logger.Warn(`${context}/target/path: Value (${channel.target.path}) must be (${"pointer" /* AnimationChannelTargetPath.POINTER */}) when using the ${this.name} extension`);
  59. }
  60. if (channel.target.node != undefined) {
  61. Logger.Warn(`${context}/target/node: Value (${channel.target.node}) must not be present when using the ${this.name} extension`);
  62. }
  63. const extensionContext = `${context}/extensions/${this.name}`;
  64. const pointer = extension.pointer;
  65. if (!pointer) {
  66. throw new Error(`${extensionContext}: Pointer is missing`);
  67. }
  68. try {
  69. const targetInfo = this._pathToObjectConverter.convert(pointer);
  70. return this._loader._loadAnimationChannelFromTargetInfoAsync(context, animationContext, animation, channel, targetInfo, onLoad);
  71. }
  72. catch (e) {
  73. Logger.Warn(`${extensionContext}/pointer: Invalid pointer (${pointer}) skipped`);
  74. return null;
  75. }
  76. }
  77. }
  78. GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_animation_pointer(loader));
  79. //# sourceMappingURL=KHR_animation_pointer.js.map