@babylonjs/core 6.17.0 → 6.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/Audio/audioEngine.d.ts +1 -1
  2. package/Audio/audioEngine.js +24 -13
  3. package/Audio/audioEngine.js.map +1 -1
  4. package/Bones/skeleton.d.ts +3 -1
  5. package/Bones/skeleton.js +11 -2
  6. package/Bones/skeleton.js.map +1 -1
  7. package/DeviceInput/webDeviceInputSystem.js +26 -1
  8. package/DeviceInput/webDeviceInputSystem.js.map +1 -1
  9. package/Engines/thinEngine.js +2 -2
  10. package/Engines/thinEngine.js.map +1 -1
  11. package/Materials/Node/Blocks/Teleport/teleportInBlock.js +1 -0
  12. package/Materials/Node/Blocks/Teleport/teleportInBlock.js.map +1 -1
  13. package/Materials/greasedLinePluginMaterial.d.ts +7 -2
  14. package/Materials/greasedLinePluginMaterial.js +46 -21
  15. package/Materials/greasedLinePluginMaterial.js.map +1 -1
  16. package/Meshes/Node/Blocks/Instances/instantiateBlock.d.ts +77 -0
  17. package/Meshes/Node/Blocks/Instances/instantiateBlock.js +169 -0
  18. package/Meshes/Node/Blocks/Instances/instantiateBlock.js.map +1 -0
  19. package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.d.ts +6 -0
  20. package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.js +74 -68
  21. package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.js.map +1 -1
  22. package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.d.ts +11 -0
  23. package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.js +94 -66
  24. package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.js.map +1 -1
  25. package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.d.ts +6 -0
  26. package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.js +68 -62
  27. package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.js.map +1 -1
  28. package/Meshes/Node/Blocks/Set/setColorsBlock.d.ts +5 -0
  29. package/Meshes/Node/Blocks/Set/setColorsBlock.js +7 -0
  30. package/Meshes/Node/Blocks/Set/setColorsBlock.js.map +1 -1
  31. package/Meshes/Node/Blocks/Set/setNormalsBlock.d.ts +5 -0
  32. package/Meshes/Node/Blocks/Set/setNormalsBlock.js +7 -0
  33. package/Meshes/Node/Blocks/Set/setNormalsBlock.js.map +1 -1
  34. package/Meshes/Node/Blocks/Set/setPositionsBlock.d.ts +5 -0
  35. package/Meshes/Node/Blocks/Set/setPositionsBlock.js +7 -0
  36. package/Meshes/Node/Blocks/Set/setPositionsBlock.js.map +1 -1
  37. package/Meshes/Node/Blocks/Set/setTangentsBlock.d.ts +5 -0
  38. package/Meshes/Node/Blocks/Set/setTangentsBlock.js +7 -0
  39. package/Meshes/Node/Blocks/Set/setTangentsBlock.js.map +1 -1
  40. package/Meshes/Node/Blocks/Set/setUVsBlock.d.ts +5 -0
  41. package/Meshes/Node/Blocks/Set/setUVsBlock.js +7 -0
  42. package/Meshes/Node/Blocks/Set/setUVsBlock.js.map +1 -1
  43. package/Meshes/Node/Blocks/Sources/meshBlock.d.ts +4 -0
  44. package/Meshes/Node/Blocks/Sources/meshBlock.js +6 -0
  45. package/Meshes/Node/Blocks/Sources/meshBlock.js.map +1 -1
  46. package/Meshes/Node/Blocks/Teleport/teleportInBlock.js +1 -0
  47. package/Meshes/Node/Blocks/Teleport/teleportInBlock.js.map +1 -1
  48. package/Meshes/Node/Blocks/computeNormalsBlock.js +3 -0
  49. package/Meshes/Node/Blocks/computeNormalsBlock.js.map +1 -1
  50. package/Meshes/Node/Blocks/geometryCollectionBlock.d.ts +76 -0
  51. package/Meshes/Node/Blocks/geometryCollectionBlock.js +163 -0
  52. package/Meshes/Node/Blocks/geometryCollectionBlock.js.map +1 -0
  53. package/Meshes/Node/Blocks/geometryInfoBlock.d.ts +43 -0
  54. package/Meshes/Node/Blocks/geometryInfoBlock.js +100 -0
  55. package/Meshes/Node/Blocks/geometryInfoBlock.js.map +1 -0
  56. package/Meshes/Node/Blocks/geometryInputBlock.js +2 -0
  57. package/Meshes/Node/Blocks/geometryInputBlock.js.map +1 -1
  58. package/Meshes/Node/Enums/nodeGeometryContextualSources.d.ts +5 -1
  59. package/Meshes/Node/Enums/nodeGeometryContextualSources.js +4 -0
  60. package/Meshes/Node/Enums/nodeGeometryContextualSources.js.map +1 -1
  61. package/Meshes/Node/Interfaces/nodeGeometryExecutionContext.d.ts +5 -0
  62. package/Meshes/Node/Interfaces/nodeGeometryExecutionContext.js.map +1 -1
  63. package/Meshes/Node/index.d.ts +3 -0
  64. package/Meshes/Node/index.js +3 -0
  65. package/Meshes/Node/index.js.map +1 -1
  66. package/Meshes/Node/nodeGeometry.d.ts +7 -0
  67. package/Meshes/Node/nodeGeometry.js +17 -0
  68. package/Meshes/Node/nodeGeometry.js.map +1 -1
  69. package/Meshes/Node/nodeGeometryBlock.d.ts +8 -3
  70. package/Meshes/Node/nodeGeometryBlock.js +24 -5
  71. package/Meshes/Node/nodeGeometryBlock.js.map +1 -1
  72. package/Meshes/Node/nodeGeometryBuildState.d.ts +3 -1
  73. package/Meshes/Node/nodeGeometryBuildState.js +34 -12
  74. package/Meshes/Node/nodeGeometryBuildState.js.map +1 -1
  75. package/Meshes/mesh.vertexData.d.ts +4 -0
  76. package/Meshes/mesh.vertexData.js +4 -0
  77. package/Meshes/mesh.vertexData.js.map +1 -1
  78. package/Meshes/transformNode.js +7 -3
  79. package/Meshes/transformNode.js.map +1 -1
  80. package/Shaders/gpuRenderParticles.vertex.js +5 -5
  81. package/Shaders/gpuRenderParticles.vertex.js.map +1 -1
  82. package/Shaders/particles.vertex.js +5 -5
  83. package/Shaders/particles.vertex.js.map +1 -1
  84. package/Sprites/sprite.js +4 -4
  85. package/Sprites/sprite.js.map +1 -1
  86. package/package.json +1 -1
@@ -36,7 +36,7 @@ export declare class AudioEngine implements IAudioEngine {
36
36
  isOGGsupported: boolean;
37
37
  /**
38
38
  * Gets whether audio has been unlocked on the device.
39
- * Some Browsers have strong restrictions about Audio and won t autoplay unless
39
+ * Some Browsers have strong restrictions about Audio and won't autoplay unless
40
40
  * a user interaction has happened.
41
41
  */
42
42
  unlocked: boolean;
@@ -19,11 +19,6 @@ export class AudioEngine {
19
19
  if (!this._audioContextInitialized) {
20
20
  this._initializeAudioContext();
21
21
  }
22
- else {
23
- if (!this.unlocked && !this._muteButton) {
24
- this._displayMuteButton();
25
- }
26
- }
27
22
  return this._audioContext;
28
23
  }
29
24
  /**
@@ -60,10 +55,10 @@ export class AudioEngine {
60
55
  this.isOGGsupported = false;
61
56
  /**
62
57
  * Gets whether audio has been unlocked on the device.
63
- * Some Browsers have strong restrictions about Audio and won t autoplay unless
58
+ * Some Browsers have strong restrictions about Audio and won't autoplay unless
64
59
  * a user interaction has happened.
65
60
  */
66
- this.unlocked = true;
61
+ this.unlocked = false;
67
62
  /**
68
63
  * Defines if the audio engine relies on a custom unlocked button.
69
64
  * In this case, the embedded button will not be displayed.
@@ -122,14 +117,30 @@ export class AudioEngine {
122
117
  * This is helpful to resume play once browser policies have been satisfied.
123
118
  */
124
119
  unlock() {
125
- this._triggerRunningState();
120
+ var _a, _b;
121
+ if (((_a = this._audioContext) === null || _a === void 0 ? void 0 : _a.state) === "running") {
122
+ this._hideMuteButton();
123
+ return;
124
+ }
125
+ // On iOS, if the audio context resume request was sent from an event other than a `click` event, then
126
+ // the resume promise will never resolve and the only way to get the audio context unstuck is to
127
+ // suspend it and make another resume request.
128
+ if (this._tryToRun) {
129
+ (_b = this._audioContext) === null || _b === void 0 ? void 0 : _b.suspend().then(() => {
130
+ this._tryToRun = false;
131
+ this._triggerRunningState();
132
+ });
133
+ }
134
+ else {
135
+ this._triggerRunningState();
136
+ }
126
137
  }
127
138
  _resumeAudioContext() {
128
- let result;
129
- if (this._audioContext.resume !== undefined) {
130
- result = this._audioContext.resume();
139
+ var _a;
140
+ if ((_a = this._audioContext) === null || _a === void 0 ? void 0 : _a.resume) {
141
+ return this._audioContext.resume();
131
142
  }
132
- return result || Promise.resolve();
143
+ return Promise.resolve();
133
144
  }
134
145
  _initializeAudioContext() {
135
146
  try {
@@ -204,7 +215,7 @@ export class AudioEngine {
204
215
  this._triggerRunningState();
205
216
  }, true);
206
217
  this._muteButton.addEventListener("click", () => {
207
- this._triggerRunningState();
218
+ this.unlock();
208
219
  }, true);
209
220
  window.addEventListener("resize", this._onResize);
210
221
  }
@@ -1 +1 @@
1
- {"version":3,"file":"audioEngine.js","sourceRoot":"","sources":["../../../../dev/core/src/Audio/audioEngine.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Analyser } from \"./analyser\";\r\n\r\nimport type { Nullable } from \"../types\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Engine } from \"../Engines/engine\";\r\nimport type { IAudioEngine } from \"./Interfaces/IAudioEngine\";\r\nimport { IsWindowObjectExist } from \"../Misc/domManagement\";\r\n\r\n// Sets the default audio engine to Babylon.js\r\nEngine.AudioEngineFactory = (\r\n hostElement: Nullable<HTMLElement>,\r\n audioContext: Nullable<AudioContext>,\r\n audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode>\r\n) => {\r\n return new AudioEngine(hostElement, audioContext, audioDestination);\r\n};\r\n\r\n/**\r\n * This represents the default audio engine used in babylon.\r\n * It is responsible to play, synchronize and analyse sounds throughout the application.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic\r\n */\r\nexport class AudioEngine implements IAudioEngine {\r\n private _audioContext: Nullable<AudioContext> = null;\r\n private _audioContextInitialized = false;\r\n private _muteButton: Nullable<HTMLButtonElement> = null;\r\n private _hostElement: Nullable<HTMLElement>;\r\n private _audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode> = null;\r\n\r\n /**\r\n * Gets whether the current host supports Web Audio and thus could create AudioContexts.\r\n */\r\n public canUseWebAudio: boolean = false;\r\n\r\n /**\r\n * The master gain node defines the global audio volume of your audio engine.\r\n */\r\n public masterGain: GainNode;\r\n\r\n /**\r\n * Defines if Babylon should emit a warning if WebAudio is not supported.\r\n * @ignoreNaming\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public WarnedWebAudioUnsupported: boolean = false;\r\n\r\n /**\r\n * Gets whether or not mp3 are supported by your browser.\r\n */\r\n public isMP3supported: boolean = false;\r\n\r\n /**\r\n * Gets whether or not ogg are supported by your browser.\r\n */\r\n public isOGGsupported: boolean = false;\r\n\r\n /**\r\n * Gets whether audio has been unlocked on the device.\r\n * Some Browsers have strong restrictions about Audio and won t autoplay unless\r\n * a user interaction has happened.\r\n */\r\n public unlocked: boolean = true;\r\n\r\n /**\r\n * Defines if the audio engine relies on a custom unlocked button.\r\n * In this case, the embedded button will not be displayed.\r\n */\r\n public useCustomUnlockedButton: boolean = false;\r\n\r\n /**\r\n * Event raised when audio has been unlocked on the browser.\r\n */\r\n public onAudioUnlockedObservable = new Observable<IAudioEngine>();\r\n\r\n /**\r\n * Event raised when audio has been locked on the browser.\r\n */\r\n public onAudioLockedObservable = new Observable<IAudioEngine>();\r\n\r\n /**\r\n * Gets the current AudioContext if available.\r\n */\r\n public get audioContext(): Nullable<AudioContext> {\r\n if (!this._audioContextInitialized) {\r\n this._initializeAudioContext();\r\n } else {\r\n if (!this.unlocked && !this._muteButton) {\r\n this._displayMuteButton();\r\n }\r\n }\r\n return this._audioContext;\r\n }\r\n\r\n private _connectedAnalyser: Nullable<Analyser>;\r\n\r\n /**\r\n * Instantiates a new audio engine.\r\n *\r\n * There should be only one per page as some browsers restrict the number\r\n * of audio contexts you can create.\r\n * @param hostElement defines the host element where to display the mute icon if necessary\r\n * @param audioContext defines the audio context to be used by the audio engine\r\n * @param audioDestination defines the audio destination node to be used by audio engine\r\n */\r\n constructor(\r\n hostElement: Nullable<HTMLElement> = null,\r\n audioContext: Nullable<AudioContext> = null,\r\n audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode> = null\r\n ) {\r\n if (!IsWindowObjectExist()) {\r\n return;\r\n }\r\n if (typeof window.AudioContext !== \"undefined\") {\r\n this.canUseWebAudio = true;\r\n }\r\n\r\n const audioElem = document.createElement(\"audio\");\r\n this._hostElement = hostElement;\r\n this._audioContext = audioContext;\r\n this._audioDestination = audioDestination;\r\n\r\n try {\r\n if (\r\n audioElem &&\r\n !!audioElem.canPlayType &&\r\n (audioElem.canPlayType('audio/mpeg; codecs=\"mp3\"').replace(/^no$/, \"\") || audioElem.canPlayType(\"audio/mp3\").replace(/^no$/, \"\"))\r\n ) {\r\n this.isMP3supported = true;\r\n }\r\n } catch (e) {\r\n // protect error during capability check.\r\n }\r\n\r\n try {\r\n if (audioElem && !!audioElem.canPlayType && audioElem.canPlayType('audio/ogg; codecs=\"vorbis\"').replace(/^no$/, \"\")) {\r\n this.isOGGsupported = true;\r\n }\r\n } catch (e) {\r\n // protect error during capability check.\r\n }\r\n }\r\n\r\n /**\r\n * Flags the audio engine in Locked state.\r\n * This happens due to new browser policies preventing audio to autoplay.\r\n */\r\n public lock() {\r\n this._triggerSuspendedState();\r\n }\r\n\r\n /**\r\n * Unlocks the audio engine once a user action has been done on the dom.\r\n * This is helpful to resume play once browser policies have been satisfied.\r\n */\r\n public unlock() {\r\n this._triggerRunningState();\r\n }\r\n\r\n private _resumeAudioContext(): Promise<void> {\r\n let result: Promise<void>;\r\n if (this._audioContext!.resume !== undefined) {\r\n result = this._audioContext!.resume();\r\n }\r\n return result! || Promise.resolve();\r\n }\r\n\r\n private _initializeAudioContext() {\r\n try {\r\n if (this.canUseWebAudio) {\r\n if (!this._audioContext) {\r\n this._audioContext = new AudioContext();\r\n }\r\n // create a global volume gain node\r\n this.masterGain = this._audioContext.createGain();\r\n this.masterGain.gain.value = 1;\r\n if (!this._audioDestination) {\r\n this._audioDestination = this._audioContext.destination;\r\n }\r\n this.masterGain.connect(this._audioDestination);\r\n this._audioContextInitialized = true;\r\n if (this._audioContext.state === \"running\") {\r\n // Do not wait for the promise to unlock.\r\n this._triggerRunningState();\r\n }\r\n }\r\n } catch (e) {\r\n this.canUseWebAudio = false;\r\n Logger.Error(\"Web Audio: \" + e.message);\r\n }\r\n }\r\n\r\n private _tryToRun = false;\r\n private _triggerRunningState() {\r\n if (this._tryToRun) {\r\n return;\r\n }\r\n this._tryToRun = true;\r\n\r\n this._resumeAudioContext()\r\n .then(() => {\r\n this._tryToRun = false;\r\n if (this._muteButton) {\r\n this._hideMuteButton();\r\n }\r\n // Notify users that the audio stack is unlocked/unmuted\r\n this.unlocked = true;\r\n this.onAudioUnlockedObservable.notifyObservers(this);\r\n })\r\n .catch(() => {\r\n this._tryToRun = false;\r\n this.unlocked = false;\r\n });\r\n }\r\n\r\n private _triggerSuspendedState() {\r\n this.unlocked = false;\r\n this.onAudioLockedObservable.notifyObservers(this);\r\n this._displayMuteButton();\r\n }\r\n\r\n private _displayMuteButton() {\r\n if (this.useCustomUnlockedButton || this._muteButton) {\r\n return;\r\n }\r\n\r\n this._muteButton = <HTMLButtonElement>document.createElement(\"BUTTON\");\r\n this._muteButton.className = \"babylonUnmuteIcon\";\r\n this._muteButton.id = \"babylonUnmuteIconBtn\";\r\n this._muteButton.title = \"Unmute\";\r\n const imageUrl = !window.SVGSVGElement\r\n ? \"https://cdn.babylonjs.com/Assets/audio.png\"\r\n : \"data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2239%22%20height%3D%2232%22%20viewBox%3D%220%200%2039%2032%22%3E%3Cpath%20fill%3D%22white%22%20d%3D%22M9.625%2018.938l-0.031%200.016h-4.953q-0.016%200-0.031-0.016v-12.453q0-0.016%200.031-0.016h4.953q0.031%200%200.031%200.016v12.453zM12.125%207.688l8.719-8.703v27.453l-8.719-8.719-0.016-0.047v-9.938zM23.359%207.875l1.406-1.406%204.219%204.203%204.203-4.203%201.422%201.406-4.219%204.219%204.219%204.203-1.484%201.359-4.141-4.156-4.219%204.219-1.406-1.422%204.219-4.203z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E\";\r\n\r\n const css =\r\n \".babylonUnmuteIcon { position: absolute; left: 20px; top: 20px; height: 40px; width: 60px; background-color: rgba(51,51,51,0.7); background-image: url(\" +\r\n imageUrl +\r\n \"); background-size: 80%; background-repeat:no-repeat; background-position: center; background-position-y: 4px; border: none; outline: none; transition: transform 0.125s ease-out; cursor: pointer; z-index: 9999; } .babylonUnmuteIcon:hover { transform: scale(1.05) } .babylonUnmuteIcon:active { background-color: rgba(51,51,51,1) }\";\r\n\r\n const style = document.createElement(\"style\");\r\n style.appendChild(document.createTextNode(css));\r\n document.getElementsByTagName(\"head\")[0].appendChild(style);\r\n\r\n document.body.appendChild(this._muteButton);\r\n\r\n this._moveButtonToTopLeft();\r\n\r\n this._muteButton.addEventListener(\r\n \"touchend\",\r\n () => {\r\n this._triggerRunningState();\r\n },\r\n true\r\n );\r\n this._muteButton.addEventListener(\r\n \"click\",\r\n () => {\r\n this._triggerRunningState();\r\n },\r\n true\r\n );\r\n\r\n window.addEventListener(\"resize\", this._onResize);\r\n }\r\n\r\n private _moveButtonToTopLeft() {\r\n if (this._hostElement && this._muteButton) {\r\n this._muteButton.style.top = this._hostElement.offsetTop + 20 + \"px\";\r\n this._muteButton.style.left = this._hostElement.offsetLeft + 20 + \"px\";\r\n }\r\n }\r\n\r\n private _onResize = () => {\r\n this._moveButtonToTopLeft();\r\n };\r\n\r\n private _hideMuteButton() {\r\n if (this._muteButton) {\r\n document.body.removeChild(this._muteButton);\r\n this._muteButton = null;\r\n }\r\n }\r\n\r\n /**\r\n * Destroy and release the resources associated with the audio context.\r\n */\r\n public dispose(): void {\r\n if (this.canUseWebAudio && this._audioContextInitialized) {\r\n if (this._connectedAnalyser && this._audioContext) {\r\n this._connectedAnalyser.stopDebugCanvas();\r\n this._connectedAnalyser.dispose();\r\n this.masterGain.disconnect();\r\n this.masterGain.connect(this._audioContext.destination);\r\n this._connectedAnalyser = null;\r\n }\r\n this.masterGain.gain.value = 1;\r\n }\r\n this.WarnedWebAudioUnsupported = false;\r\n this._hideMuteButton();\r\n window.removeEventListener(\"resize\", this._onResize);\r\n\r\n this.onAudioUnlockedObservable.clear();\r\n this.onAudioLockedObservable.clear();\r\n }\r\n\r\n /**\r\n * Gets the global volume sets on the master gain.\r\n * @returns the global volume if set or -1 otherwise\r\n */\r\n public getGlobalVolume(): number {\r\n if (this.canUseWebAudio && this._audioContextInitialized) {\r\n return this.masterGain.gain.value;\r\n } else {\r\n return -1;\r\n }\r\n }\r\n\r\n /**\r\n * Sets the global volume of your experience (sets on the master gain).\r\n * @param newVolume Defines the new global volume of the application\r\n */\r\n public setGlobalVolume(newVolume: number): void {\r\n if (this.canUseWebAudio && this._audioContextInitialized) {\r\n this.masterGain.gain.value = newVolume;\r\n }\r\n }\r\n\r\n /**\r\n * Connect the audio engine to an audio analyser allowing some amazing\r\n * synchronization between the sounds/music and your visualization (VuMeter for instance).\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic#using-the-analyser\r\n * @param analyser The analyser to connect to the engine\r\n */\r\n public connectToAnalyser(analyser: Analyser): void {\r\n if (this._connectedAnalyser) {\r\n this._connectedAnalyser.stopDebugCanvas();\r\n }\r\n if (this.canUseWebAudio && this._audioContextInitialized && this._audioContext) {\r\n this._connectedAnalyser = analyser;\r\n this.masterGain.disconnect();\r\n this._connectedAnalyser.connectAudioNodes(this.masterGain, this._audioContext.destination);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"audioEngine.js","sourceRoot":"","sources":["../../../../dev/core/src/Audio/audioEngine.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Analyser } from \"./analyser\";\r\n\r\nimport type { Nullable } from \"../types\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { Engine } from \"../Engines/engine\";\r\nimport type { IAudioEngine } from \"./Interfaces/IAudioEngine\";\r\nimport { IsWindowObjectExist } from \"../Misc/domManagement\";\r\n\r\n// Sets the default audio engine to Babylon.js\r\nEngine.AudioEngineFactory = (\r\n hostElement: Nullable<HTMLElement>,\r\n audioContext: Nullable<AudioContext>,\r\n audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode>\r\n) => {\r\n return new AudioEngine(hostElement, audioContext, audioDestination);\r\n};\r\n\r\n/**\r\n * This represents the default audio engine used in babylon.\r\n * It is responsible to play, synchronize and analyse sounds throughout the application.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic\r\n */\r\nexport class AudioEngine implements IAudioEngine {\r\n private _audioContext: Nullable<AudioContext> = null;\r\n private _audioContextInitialized = false;\r\n private _muteButton: Nullable<HTMLButtonElement> = null;\r\n private _hostElement: Nullable<HTMLElement>;\r\n private _audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode> = null;\r\n\r\n /**\r\n * Gets whether the current host supports Web Audio and thus could create AudioContexts.\r\n */\r\n public canUseWebAudio: boolean = false;\r\n\r\n /**\r\n * The master gain node defines the global audio volume of your audio engine.\r\n */\r\n public masterGain: GainNode;\r\n\r\n /**\r\n * Defines if Babylon should emit a warning if WebAudio is not supported.\r\n * @ignoreNaming\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public WarnedWebAudioUnsupported: boolean = false;\r\n\r\n /**\r\n * Gets whether or not mp3 are supported by your browser.\r\n */\r\n public isMP3supported: boolean = false;\r\n\r\n /**\r\n * Gets whether or not ogg are supported by your browser.\r\n */\r\n public isOGGsupported: boolean = false;\r\n\r\n /**\r\n * Gets whether audio has been unlocked on the device.\r\n * Some Browsers have strong restrictions about Audio and won't autoplay unless\r\n * a user interaction has happened.\r\n */\r\n public unlocked: boolean = false;\r\n\r\n /**\r\n * Defines if the audio engine relies on a custom unlocked button.\r\n * In this case, the embedded button will not be displayed.\r\n */\r\n public useCustomUnlockedButton: boolean = false;\r\n\r\n /**\r\n * Event raised when audio has been unlocked on the browser.\r\n */\r\n public onAudioUnlockedObservable = new Observable<IAudioEngine>();\r\n\r\n /**\r\n * Event raised when audio has been locked on the browser.\r\n */\r\n public onAudioLockedObservable = new Observable<IAudioEngine>();\r\n\r\n /**\r\n * Gets the current AudioContext if available.\r\n */\r\n public get audioContext(): Nullable<AudioContext> {\r\n if (!this._audioContextInitialized) {\r\n this._initializeAudioContext();\r\n }\r\n return this._audioContext;\r\n }\r\n\r\n private _connectedAnalyser: Nullable<Analyser>;\r\n\r\n /**\r\n * Instantiates a new audio engine.\r\n *\r\n * There should be only one per page as some browsers restrict the number\r\n * of audio contexts you can create.\r\n * @param hostElement defines the host element where to display the mute icon if necessary\r\n * @param audioContext defines the audio context to be used by the audio engine\r\n * @param audioDestination defines the audio destination node to be used by audio engine\r\n */\r\n constructor(\r\n hostElement: Nullable<HTMLElement> = null,\r\n audioContext: Nullable<AudioContext> = null,\r\n audioDestination: Nullable<AudioDestinationNode | MediaStreamAudioDestinationNode> = null\r\n ) {\r\n if (!IsWindowObjectExist()) {\r\n return;\r\n }\r\n if (typeof window.AudioContext !== \"undefined\") {\r\n this.canUseWebAudio = true;\r\n }\r\n\r\n const audioElem = document.createElement(\"audio\");\r\n this._hostElement = hostElement;\r\n this._audioContext = audioContext;\r\n this._audioDestination = audioDestination;\r\n\r\n try {\r\n if (\r\n audioElem &&\r\n !!audioElem.canPlayType &&\r\n (audioElem.canPlayType('audio/mpeg; codecs=\"mp3\"').replace(/^no$/, \"\") || audioElem.canPlayType(\"audio/mp3\").replace(/^no$/, \"\"))\r\n ) {\r\n this.isMP3supported = true;\r\n }\r\n } catch (e) {\r\n // protect error during capability check.\r\n }\r\n\r\n try {\r\n if (audioElem && !!audioElem.canPlayType && audioElem.canPlayType('audio/ogg; codecs=\"vorbis\"').replace(/^no$/, \"\")) {\r\n this.isOGGsupported = true;\r\n }\r\n } catch (e) {\r\n // protect error during capability check.\r\n }\r\n }\r\n\r\n /**\r\n * Flags the audio engine in Locked state.\r\n * This happens due to new browser policies preventing audio to autoplay.\r\n */\r\n public lock() {\r\n this._triggerSuspendedState();\r\n }\r\n\r\n /**\r\n * Unlocks the audio engine once a user action has been done on the dom.\r\n * This is helpful to resume play once browser policies have been satisfied.\r\n */\r\n public unlock() {\r\n if (this._audioContext?.state === \"running\") {\r\n this._hideMuteButton();\r\n return;\r\n }\r\n\r\n // On iOS, if the audio context resume request was sent from an event other than a `click` event, then\r\n // the resume promise will never resolve and the only way to get the audio context unstuck is to\r\n // suspend it and make another resume request.\r\n if (this._tryToRun) {\r\n this._audioContext?.suspend().then(() => {\r\n this._tryToRun = false;\r\n this._triggerRunningState();\r\n });\r\n } else {\r\n this._triggerRunningState();\r\n }\r\n }\r\n\r\n private _resumeAudioContext(): Promise<void> {\r\n if (this._audioContext?.resume) {\r\n return this._audioContext.resume();\r\n }\r\n return Promise.resolve();\r\n }\r\n\r\n private _initializeAudioContext() {\r\n try {\r\n if (this.canUseWebAudio) {\r\n if (!this._audioContext) {\r\n this._audioContext = new AudioContext();\r\n }\r\n // create a global volume gain node\r\n this.masterGain = this._audioContext.createGain();\r\n this.masterGain.gain.value = 1;\r\n if (!this._audioDestination) {\r\n this._audioDestination = this._audioContext.destination;\r\n }\r\n this.masterGain.connect(this._audioDestination);\r\n this._audioContextInitialized = true;\r\n if (this._audioContext.state === \"running\") {\r\n // Do not wait for the promise to unlock.\r\n this._triggerRunningState();\r\n }\r\n }\r\n } catch (e) {\r\n this.canUseWebAudio = false;\r\n Logger.Error(\"Web Audio: \" + e.message);\r\n }\r\n }\r\n\r\n private _tryToRun = false;\r\n private _triggerRunningState() {\r\n if (this._tryToRun) {\r\n return;\r\n }\r\n this._tryToRun = true;\r\n\r\n this._resumeAudioContext()\r\n .then(() => {\r\n this._tryToRun = false;\r\n if (this._muteButton) {\r\n this._hideMuteButton();\r\n }\r\n // Notify users that the audio stack is unlocked/unmuted\r\n this.unlocked = true;\r\n this.onAudioUnlockedObservable.notifyObservers(this);\r\n })\r\n .catch(() => {\r\n this._tryToRun = false;\r\n this.unlocked = false;\r\n });\r\n }\r\n\r\n private _triggerSuspendedState() {\r\n this.unlocked = false;\r\n this.onAudioLockedObservable.notifyObservers(this);\r\n this._displayMuteButton();\r\n }\r\n\r\n private _displayMuteButton() {\r\n if (this.useCustomUnlockedButton || this._muteButton) {\r\n return;\r\n }\r\n\r\n this._muteButton = <HTMLButtonElement>document.createElement(\"BUTTON\");\r\n this._muteButton.className = \"babylonUnmuteIcon\";\r\n this._muteButton.id = \"babylonUnmuteIconBtn\";\r\n this._muteButton.title = \"Unmute\";\r\n const imageUrl = !window.SVGSVGElement\r\n ? \"https://cdn.babylonjs.com/Assets/audio.png\"\r\n : \"data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2239%22%20height%3D%2232%22%20viewBox%3D%220%200%2039%2032%22%3E%3Cpath%20fill%3D%22white%22%20d%3D%22M9.625%2018.938l-0.031%200.016h-4.953q-0.016%200-0.031-0.016v-12.453q0-0.016%200.031-0.016h4.953q0.031%200%200.031%200.016v12.453zM12.125%207.688l8.719-8.703v27.453l-8.719-8.719-0.016-0.047v-9.938zM23.359%207.875l1.406-1.406%204.219%204.203%204.203-4.203%201.422%201.406-4.219%204.219%204.219%204.203-1.484%201.359-4.141-4.156-4.219%204.219-1.406-1.422%204.219-4.203z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E\";\r\n\r\n const css =\r\n \".babylonUnmuteIcon { position: absolute; left: 20px; top: 20px; height: 40px; width: 60px; background-color: rgba(51,51,51,0.7); background-image: url(\" +\r\n imageUrl +\r\n \"); background-size: 80%; background-repeat:no-repeat; background-position: center; background-position-y: 4px; border: none; outline: none; transition: transform 0.125s ease-out; cursor: pointer; z-index: 9999; } .babylonUnmuteIcon:hover { transform: scale(1.05) } .babylonUnmuteIcon:active { background-color: rgba(51,51,51,1) }\";\r\n\r\n const style = document.createElement(\"style\");\r\n style.appendChild(document.createTextNode(css));\r\n document.getElementsByTagName(\"head\")[0].appendChild(style);\r\n\r\n document.body.appendChild(this._muteButton);\r\n\r\n this._moveButtonToTopLeft();\r\n\r\n this._muteButton.addEventListener(\r\n \"touchend\",\r\n () => {\r\n this._triggerRunningState();\r\n },\r\n true\r\n );\r\n this._muteButton.addEventListener(\r\n \"click\",\r\n () => {\r\n this.unlock();\r\n },\r\n true\r\n );\r\n\r\n window.addEventListener(\"resize\", this._onResize);\r\n }\r\n\r\n private _moveButtonToTopLeft() {\r\n if (this._hostElement && this._muteButton) {\r\n this._muteButton.style.top = this._hostElement.offsetTop + 20 + \"px\";\r\n this._muteButton.style.left = this._hostElement.offsetLeft + 20 + \"px\";\r\n }\r\n }\r\n\r\n private _onResize = () => {\r\n this._moveButtonToTopLeft();\r\n };\r\n\r\n private _hideMuteButton() {\r\n if (this._muteButton) {\r\n document.body.removeChild(this._muteButton);\r\n this._muteButton = null;\r\n }\r\n }\r\n\r\n /**\r\n * Destroy and release the resources associated with the audio context.\r\n */\r\n public dispose(): void {\r\n if (this.canUseWebAudio && this._audioContextInitialized) {\r\n if (this._connectedAnalyser && this._audioContext) {\r\n this._connectedAnalyser.stopDebugCanvas();\r\n this._connectedAnalyser.dispose();\r\n this.masterGain.disconnect();\r\n this.masterGain.connect(this._audioContext.destination);\r\n this._connectedAnalyser = null;\r\n }\r\n this.masterGain.gain.value = 1;\r\n }\r\n this.WarnedWebAudioUnsupported = false;\r\n this._hideMuteButton();\r\n window.removeEventListener(\"resize\", this._onResize);\r\n\r\n this.onAudioUnlockedObservable.clear();\r\n this.onAudioLockedObservable.clear();\r\n }\r\n\r\n /**\r\n * Gets the global volume sets on the master gain.\r\n * @returns the global volume if set or -1 otherwise\r\n */\r\n public getGlobalVolume(): number {\r\n if (this.canUseWebAudio && this._audioContextInitialized) {\r\n return this.masterGain.gain.value;\r\n } else {\r\n return -1;\r\n }\r\n }\r\n\r\n /**\r\n * Sets the global volume of your experience (sets on the master gain).\r\n * @param newVolume Defines the new global volume of the application\r\n */\r\n public setGlobalVolume(newVolume: number): void {\r\n if (this.canUseWebAudio && this._audioContextInitialized) {\r\n this.masterGain.gain.value = newVolume;\r\n }\r\n }\r\n\r\n /**\r\n * Connect the audio engine to an audio analyser allowing some amazing\r\n * synchronization between the sounds/music and your visualization (VuMeter for instance).\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic#using-the-analyser\r\n * @param analyser The analyser to connect to the engine\r\n */\r\n public connectToAnalyser(analyser: Analyser): void {\r\n if (this._connectedAnalyser) {\r\n this._connectedAnalyser.stopDebugCanvas();\r\n }\r\n if (this.canUseWebAudio && this._audioContextInitialized && this._audioContext) {\r\n this._connectedAnalyser = analyser;\r\n this.masterGain.disconnect();\r\n this._connectedAnalyser.connectAudioNodes(this.masterGain, this._audioContext.destination);\r\n }\r\n }\r\n}\r\n"]}
@@ -45,6 +45,7 @@ export declare class Skeleton implements IAnimatable {
45
45
  private _animatables;
46
46
  private _identity;
47
47
  private _synchronizedWithMesh;
48
+ private _currentRenderId;
48
49
  private _ranges;
49
50
  private _absoluteTransformIsDirty;
50
51
  private _canUseTextureForBones;
@@ -207,8 +208,9 @@ export declare class Skeleton implements IAnimatable {
207
208
  private _computeTransformMatrices;
208
209
  /**
209
210
  * Build all resources required to render a skeleton
211
+ * @param dontCheckFrameId defines a boolean indicating if prepare should be run without checking first the current frame id (default: false)
210
212
  */
211
- prepare(): void;
213
+ prepare(dontCheckFrameId?: boolean): void;
212
214
  /**
213
215
  * Gets the list of animatables currently running for this skeleton
214
216
  * @returns an array of animatables
package/Bones/skeleton.js CHANGED
@@ -72,6 +72,7 @@ export class Skeleton {
72
72
  this._isDirty = true;
73
73
  this._meshesWithPoseMatrix = new Array();
74
74
  this._identity = Matrix.Identity();
75
+ this._currentRenderId = -1;
75
76
  this._ranges = {};
76
77
  this._absoluteTransformIsDirty = true;
77
78
  this._canUseTextureForBones = false;
@@ -407,8 +408,16 @@ export class Skeleton {
407
408
  }
408
409
  /**
409
410
  * Build all resources required to render a skeleton
411
+ * @param dontCheckFrameId defines a boolean indicating if prepare should be run without checking first the current frame id (default: false)
410
412
  */
411
- prepare() {
413
+ prepare(dontCheckFrameId = false) {
414
+ if (!dontCheckFrameId) {
415
+ const currentRenderId = this.getScene().getRenderId();
416
+ if (this._currentRenderId === currentRenderId) {
417
+ return;
418
+ }
419
+ this._currentRenderId = currentRenderId;
420
+ }
412
421
  // Update the local matrix of bones with linked transform nodes.
413
422
  if (this._numBonesWithLinkedTransformNode > 0) {
414
423
  for (const bone of this.bones) {
@@ -529,7 +538,7 @@ export class Skeleton {
529
538
  }
530
539
  }
531
540
  this._isDirty = true;
532
- result.prepare();
541
+ result.prepare(true);
533
542
  return result;
534
543
  }
535
544
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.js","sourceRoot":"","sources":["../../../../dev/core/src/Bones/skeleton.ts"],"names":[],"mappings":"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","sourcesContent":["import { Bone } from \"./bone\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector\";\r\nimport type { Scene } from \"../scene\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport type { Animatable } from \"../Animations/animatable\";\r\nimport type { AnimationPropertiesOverride } from \"../Animations/animationPropertiesOverride\";\r\nimport { Animation } from \"../Animations/animation\";\r\nimport { AnimationRange } from \"../Animations/animationRange\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { DeepCopier } from \"../Misc/deepCopier\";\r\nimport type { IInspectable } from \"../Misc/iInspectable\";\r\nimport type { IAnimatable } from \"../Animations/animatable.interface\";\r\nimport type { AbstractScene } from \"../abstractScene\";\r\n\r\n/**\r\n * Class used to handle skinning animations\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons\r\n */\r\nexport class Skeleton implements IAnimatable {\r\n /**\r\n * Defines the list of child bones\r\n */\r\n public bones = new Array<Bone>();\r\n /**\r\n * Defines an estimate of the dimension of the skeleton at rest\r\n */\r\n public dimensionsAtRest: Vector3;\r\n /**\r\n * Defines a boolean indicating if the root matrix is provided by meshes or by the current skeleton (this is the default value)\r\n */\r\n public needInitialSkinMatrix = false;\r\n\r\n /**\r\n * Gets the list of animations attached to this skeleton\r\n */\r\n public animations: Array<Animation>;\r\n\r\n private _scene: Scene;\r\n private _isDirty = true;\r\n private _transformMatrices: Float32Array;\r\n private _transformMatrixTexture: Nullable<RawTexture>;\r\n private _meshesWithPoseMatrix = new Array<AbstractMesh>();\r\n private _animatables: IAnimatable[];\r\n private _identity = Matrix.Identity();\r\n private _synchronizedWithMesh: AbstractMesh;\r\n\r\n private _ranges: { [name: string]: Nullable<AnimationRange> } = {};\r\n\r\n private _absoluteTransformIsDirty = true;\r\n\r\n private _canUseTextureForBones = false;\r\n private _uniqueId = 0;\r\n\r\n /** @internal */\r\n public _numBonesWithLinkedTransformNode = 0;\r\n\r\n /** @internal */\r\n public _hasWaitingData: Nullable<boolean> = null;\r\n\r\n /** @internal */\r\n public _parentContainer: Nullable<AbstractScene> = null;\r\n\r\n /**\r\n * Specifies if the skeleton should be serialized\r\n */\r\n public doNotSerialize = false;\r\n\r\n private _useTextureToStoreBoneMatrices = true;\r\n /**\r\n * Gets or sets a boolean indicating that bone matrices should be stored as a texture instead of using shader uniforms (default is true).\r\n * Please note that this option is not available if the hardware does not support it\r\n */\r\n public get useTextureToStoreBoneMatrices(): boolean {\r\n return this._useTextureToStoreBoneMatrices;\r\n }\r\n\r\n public set useTextureToStoreBoneMatrices(value: boolean) {\r\n this._useTextureToStoreBoneMatrices = value;\r\n this._markAsDirty();\r\n }\r\n\r\n private _animationPropertiesOverride: Nullable<AnimationPropertiesOverride> = null;\r\n\r\n /**\r\n * Gets or sets the animation properties override\r\n */\r\n public get animationPropertiesOverride(): Nullable<AnimationPropertiesOverride> {\r\n if (!this._animationPropertiesOverride) {\r\n return this._scene.animationPropertiesOverride;\r\n }\r\n return this._animationPropertiesOverride;\r\n }\r\n\r\n public set animationPropertiesOverride(value: Nullable<AnimationPropertiesOverride>) {\r\n this._animationPropertiesOverride = value;\r\n }\r\n\r\n /**\r\n * List of inspectable custom properties (used by the Inspector)\r\n * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n */\r\n public inspectableCustomProperties: IInspectable[];\r\n\r\n // Events\r\n\r\n /**\r\n * An observable triggered before computing the skeleton's matrices\r\n */\r\n public onBeforeComputeObservable = new Observable<Skeleton>();\r\n\r\n /**\r\n * Gets a boolean indicating that the skeleton effectively stores matrices into a texture\r\n */\r\n public get isUsingTextureForMatrices() {\r\n return this.useTextureToStoreBoneMatrices && this._canUseTextureForBones;\r\n }\r\n\r\n /**\r\n * Gets the unique ID of this skeleton\r\n */\r\n public get uniqueId(): number {\r\n return this._uniqueId;\r\n }\r\n\r\n /**\r\n * Creates a new skeleton\r\n * @param name defines the skeleton name\r\n * @param id defines the skeleton Id\r\n * @param scene defines the hosting scene\r\n */\r\n constructor(\r\n /** defines the skeleton name */\r\n public name: string,\r\n /** defines the skeleton Id */\r\n public id: string,\r\n scene: Scene\r\n ) {\r\n this.bones = [];\r\n\r\n this._scene = scene || EngineStore.LastCreatedScene;\r\n this._uniqueId = this._scene.getUniqueId();\r\n\r\n this._scene.addSkeleton(this);\r\n\r\n //make sure it will recalculate the matrix next time prepare is called.\r\n this._isDirty = true;\r\n\r\n const engineCaps = this._scene.getEngine().getCaps();\r\n this._canUseTextureForBones = engineCaps.textureFloat && engineCaps.maxVertexTextureImageUnits > 0;\r\n }\r\n\r\n /**\r\n * Gets the current object class name.\r\n * @returns the class name\r\n */\r\n public getClassName(): string {\r\n return \"Skeleton\";\r\n }\r\n\r\n /**\r\n * Returns an array containing the root bones\r\n * @returns an array containing the root bones\r\n */\r\n public getChildren(): Array<Bone> {\r\n return this.bones.filter((b) => !b.getParent());\r\n }\r\n\r\n // Members\r\n /**\r\n * Gets the list of transform matrices to send to shaders (one matrix per bone)\r\n * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\r\n * @returns a Float32Array containing matrices data\r\n */\r\n public getTransformMatrices(mesh: AbstractMesh): Float32Array {\r\n if (this.needInitialSkinMatrix) {\r\n if (!mesh._bonesTransformMatrices) {\r\n this.prepare();\r\n }\r\n\r\n return mesh._bonesTransformMatrices!;\r\n }\r\n\r\n if (!this._transformMatrices || this._isDirty) {\r\n this.prepare();\r\n }\r\n\r\n return this._transformMatrices;\r\n }\r\n\r\n /**\r\n * Gets the list of transform matrices to send to shaders inside a texture (one matrix per bone)\r\n * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\r\n * @returns a raw texture containing the data\r\n */\r\n public getTransformMatrixTexture(mesh: AbstractMesh): Nullable<RawTexture> {\r\n if (this.needInitialSkinMatrix && mesh._transformMatrixTexture) {\r\n return mesh._transformMatrixTexture;\r\n }\r\n\r\n return this._transformMatrixTexture;\r\n }\r\n\r\n /**\r\n * Gets the current hosting scene\r\n * @returns a scene object\r\n */\r\n public getScene(): Scene {\r\n return this._scene;\r\n }\r\n\r\n // Methods\r\n\r\n /**\r\n * Gets a string representing the current skeleton data\r\n * @param fullDetails defines a boolean indicating if we want a verbose version\r\n * @returns a string representing the current skeleton data\r\n */\r\n public toString(fullDetails?: boolean): string {\r\n let ret = `Name: ${this.name}, nBones: ${this.bones.length}`;\r\n ret += `, nAnimationRanges: ${this._ranges ? Object.keys(this._ranges).length : \"none\"}`;\r\n if (fullDetails) {\r\n ret += \", Ranges: {\";\r\n let first = true;\r\n for (const name in this._ranges) {\r\n if (first) {\r\n ret += \", \";\r\n first = false;\r\n }\r\n ret += name;\r\n }\r\n ret += \"}\";\r\n }\r\n return ret;\r\n }\r\n\r\n /**\r\n * Get bone's index searching by name\r\n * @param name defines bone's name to search for\r\n * @returns the indice of the bone. Returns -1 if not found\r\n */\r\n public getBoneIndexByName(name: string): number {\r\n for (let boneIndex = 0, cache = this.bones.length; boneIndex < cache; boneIndex++) {\r\n if (this.bones[boneIndex].name === name) {\r\n return boneIndex;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n /**\r\n * Create a new animation range\r\n * @param name defines the name of the range\r\n * @param from defines the start key\r\n * @param to defines the end key\r\n */\r\n public createAnimationRange(name: string, from: number, to: number): void {\r\n // check name not already in use\r\n if (!this._ranges[name]) {\r\n this._ranges[name] = new AnimationRange(name, from, to);\r\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n if (this.bones[i].animations[0]) {\r\n this.bones[i].animations[0].createRange(name, from, to);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Delete a specific animation range\r\n * @param name defines the name of the range\r\n * @param deleteFrames defines if frames must be removed as well\r\n */\r\n public deleteAnimationRange(name: string, deleteFrames = true): void {\r\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n if (this.bones[i].animations[0]) {\r\n this.bones[i].animations[0].deleteRange(name, deleteFrames);\r\n }\r\n }\r\n this._ranges[name] = null; // said much faster than 'delete this._range[name]'\r\n }\r\n\r\n /**\r\n * Gets a specific animation range\r\n * @param name defines the name of the range to look for\r\n * @returns the requested animation range or null if not found\r\n */\r\n public getAnimationRange(name: string): Nullable<AnimationRange> {\r\n return this._ranges[name] || null;\r\n }\r\n\r\n /**\r\n * Gets the list of all animation ranges defined on this skeleton\r\n * @returns an array\r\n */\r\n public getAnimationRanges(): Nullable<AnimationRange>[] {\r\n const animationRanges: Nullable<AnimationRange>[] = [];\r\n let name: string;\r\n for (name in this._ranges) {\r\n animationRanges.push(this._ranges[name]);\r\n }\r\n return animationRanges;\r\n }\r\n\r\n /**\r\n * Copy animation range from a source skeleton.\r\n * This is not for a complete retargeting, only between very similar skeleton's with only possible bone length differences\r\n * @param source defines the source skeleton\r\n * @param name defines the name of the range to copy\r\n * @param rescaleAsRequired defines if rescaling must be applied if required\r\n * @returns true if operation was successful\r\n */\r\n public copyAnimationRange(source: Skeleton, name: string, rescaleAsRequired = false): boolean {\r\n if (this._ranges[name] || !source.getAnimationRange(name)) {\r\n return false;\r\n }\r\n let ret = true;\r\n const frameOffset = this._getHighestAnimationFrame() + 1;\r\n\r\n // make a dictionary of source skeleton's bones, so exact same order or doubly nested loop is not required\r\n const boneDict: { [key: string]: Bone } = {};\r\n const sourceBones = source.bones;\r\n let nBones: number;\r\n let i: number;\r\n for (i = 0, nBones = sourceBones.length; i < nBones; i++) {\r\n boneDict[sourceBones[i].name] = sourceBones[i];\r\n }\r\n\r\n if (this.bones.length !== sourceBones.length) {\r\n Logger.Warn(`copyAnimationRange: this rig has ${this.bones.length} bones, while source as ${sourceBones.length}`);\r\n ret = false;\r\n }\r\n\r\n const skelDimensionsRatio = rescaleAsRequired && this.dimensionsAtRest && source.dimensionsAtRest ? this.dimensionsAtRest.divide(source.dimensionsAtRest) : null;\r\n\r\n for (i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n const boneName = this.bones[i].name;\r\n const sourceBone = boneDict[boneName];\r\n if (sourceBone) {\r\n ret = ret && this.bones[i].copyAnimationRange(sourceBone, name, frameOffset, rescaleAsRequired, skelDimensionsRatio);\r\n } else {\r\n Logger.Warn(\"copyAnimationRange: not same rig, missing source bone \" + boneName);\r\n ret = false;\r\n }\r\n }\r\n // do not call createAnimationRange(), since it also is done to bones, which was already done\r\n const range = source.getAnimationRange(name);\r\n if (range) {\r\n this._ranges[name] = new AnimationRange(name, range.from + frameOffset, range.to + frameOffset);\r\n }\r\n return ret;\r\n }\r\n\r\n /**\r\n * Forces the skeleton to go to rest pose\r\n */\r\n public returnToRest(): void {\r\n for (const bone of this.bones) {\r\n if (bone._index !== -1) {\r\n bone.returnToRest();\r\n }\r\n }\r\n }\r\n\r\n private _getHighestAnimationFrame(): number {\r\n let ret = 0;\r\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n if (this.bones[i].animations[0]) {\r\n const highest = this.bones[i].animations[0].getHighestFrame();\r\n if (ret < highest) {\r\n ret = highest;\r\n }\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n /**\r\n * Begin a specific animation range\r\n * @param name defines the name of the range to start\r\n * @param loop defines if looping must be turned on (false by default)\r\n * @param speedRatio defines the speed ratio to apply (1 by default)\r\n * @param onAnimationEnd defines a callback which will be called when animation will end\r\n * @returns a new animatable\r\n */\r\n public beginAnimation(name: string, loop?: boolean, speedRatio?: number, onAnimationEnd?: () => void): Nullable<Animatable> {\r\n const range = this.getAnimationRange(name);\r\n\r\n if (!range) {\r\n return null;\r\n }\r\n\r\n return this._scene.beginAnimation(this, range.from, range.to, loop, speedRatio, onAnimationEnd);\r\n }\r\n\r\n /**\r\n * Convert the keyframes for a range of animation on a skeleton to be relative to a given reference frame.\r\n * @param skeleton defines the Skeleton containing the animation range to convert\r\n * @param referenceFrame defines the frame that keyframes in the range will be relative to\r\n * @param range defines the name of the AnimationRange belonging to the Skeleton to convert\r\n * @returns the original skeleton\r\n */\r\n public static MakeAnimationAdditive(skeleton: Skeleton, referenceFrame = 0, range: string): Nullable<Skeleton> {\r\n const rangeValue = skeleton.getAnimationRange(range);\r\n\r\n // We can't make a range additive if it doesn't exist\r\n if (!rangeValue) {\r\n return null;\r\n }\r\n\r\n // Find any current scene-level animatable belonging to the target that matches the range\r\n const sceneAnimatables = skeleton._scene.getAllAnimatablesByTarget(skeleton);\r\n let rangeAnimatable: Nullable<Animatable> = null;\r\n\r\n for (let index = 0; index < sceneAnimatables.length; index++) {\r\n const sceneAnimatable = sceneAnimatables[index];\r\n\r\n if (sceneAnimatable.fromFrame === rangeValue?.from && sceneAnimatable.toFrame === rangeValue?.to) {\r\n rangeAnimatable = sceneAnimatable;\r\n break;\r\n }\r\n }\r\n\r\n // Convert the animations belonging to the skeleton to additive keyframes\r\n const animatables = skeleton.getAnimatables();\r\n\r\n for (let index = 0; index < animatables.length; index++) {\r\n const animatable = animatables[index];\r\n const animations = animatable.animations;\r\n\r\n if (!animations) {\r\n continue;\r\n }\r\n\r\n for (let animIndex = 0; animIndex < animations.length; animIndex++) {\r\n Animation.MakeAnimationAdditive(animations[animIndex], referenceFrame, range);\r\n }\r\n }\r\n\r\n // Mark the scene-level animatable as additive\r\n if (rangeAnimatable) {\r\n rangeAnimatable.isAdditive = true;\r\n }\r\n\r\n return skeleton;\r\n }\r\n\r\n /** @internal */\r\n public _markAsDirty(): void {\r\n this._isDirty = true;\r\n this._absoluteTransformIsDirty = true;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _registerMeshWithPoseMatrix(mesh: AbstractMesh): void {\r\n this._meshesWithPoseMatrix.push(mesh);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _unregisterMeshWithPoseMatrix(mesh: AbstractMesh): void {\r\n const index = this._meshesWithPoseMatrix.indexOf(mesh);\r\n\r\n if (index > -1) {\r\n this._meshesWithPoseMatrix.splice(index, 1);\r\n }\r\n }\r\n\r\n private _computeTransformMatrices(targetMatrix: Float32Array, initialSkinMatrix: Nullable<Matrix>): void {\r\n this.onBeforeComputeObservable.notifyObservers(this);\r\n\r\n for (let index = 0; index < this.bones.length; index++) {\r\n const bone = this.bones[index];\r\n bone._childUpdateId++;\r\n const parentBone = bone.getParent();\r\n\r\n if (parentBone) {\r\n bone.getLocalMatrix().multiplyToRef(parentBone.getFinalMatrix(), bone.getFinalMatrix());\r\n } else {\r\n if (initialSkinMatrix) {\r\n bone.getLocalMatrix().multiplyToRef(initialSkinMatrix, bone.getFinalMatrix());\r\n } else {\r\n bone.getFinalMatrix().copyFrom(bone.getLocalMatrix());\r\n }\r\n }\r\n\r\n if (bone._index !== -1) {\r\n const mappedIndex = bone._index === null ? index : bone._index;\r\n bone.getAbsoluteInverseBindMatrix().multiplyToArray(bone.getFinalMatrix(), targetMatrix, mappedIndex * 16);\r\n }\r\n }\r\n\r\n this._identity.copyToArray(targetMatrix, this.bones.length * 16);\r\n }\r\n\r\n /**\r\n * Build all resources required to render a skeleton\r\n */\r\n public prepare(): void {\r\n // Update the local matrix of bones with linked transform nodes.\r\n if (this._numBonesWithLinkedTransformNode > 0) {\r\n for (const bone of this.bones) {\r\n if (bone._linkedTransformNode) {\r\n const node = bone._linkedTransformNode;\r\n bone.position = node.position;\r\n if (node.rotationQuaternion) {\r\n bone.rotationQuaternion = node.rotationQuaternion;\r\n } else {\r\n bone.rotation = node.rotation;\r\n }\r\n bone.scaling = node.scaling;\r\n }\r\n }\r\n }\r\n\r\n if (this.needInitialSkinMatrix) {\r\n for (const mesh of this._meshesWithPoseMatrix) {\r\n const poseMatrix = mesh.getPoseMatrix();\r\n\r\n let needsUpdate = this._isDirty;\r\n if (!mesh._bonesTransformMatrices || mesh._bonesTransformMatrices.length !== 16 * (this.bones.length + 1)) {\r\n mesh._bonesTransformMatrices = new Float32Array(16 * (this.bones.length + 1));\r\n needsUpdate = true;\r\n }\r\n\r\n if (!needsUpdate) {\r\n continue;\r\n }\r\n\r\n if (this._synchronizedWithMesh !== mesh) {\r\n this._synchronizedWithMesh = mesh;\r\n\r\n // Prepare bones\r\n for (const bone of this.bones) {\r\n if (!bone.getParent()) {\r\n const matrix = bone.getBindMatrix();\r\n matrix.multiplyToRef(poseMatrix, TmpVectors.Matrix[1]);\r\n bone._updateAbsoluteBindMatrices(TmpVectors.Matrix[1]);\r\n }\r\n }\r\n\r\n if (this.isUsingTextureForMatrices) {\r\n const textureWidth = (this.bones.length + 1) * 4;\r\n if (!mesh._transformMatrixTexture || mesh._transformMatrixTexture.getSize().width !== textureWidth) {\r\n if (mesh._transformMatrixTexture) {\r\n mesh._transformMatrixTexture.dispose();\r\n }\r\n\r\n mesh._transformMatrixTexture = RawTexture.CreateRGBATexture(\r\n mesh._bonesTransformMatrices,\r\n (this.bones.length + 1) * 4,\r\n 1,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_FLOAT\r\n );\r\n }\r\n }\r\n }\r\n\r\n this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);\r\n\r\n if (this.isUsingTextureForMatrices && mesh._transformMatrixTexture) {\r\n mesh._transformMatrixTexture.update(mesh._bonesTransformMatrices);\r\n }\r\n }\r\n } else {\r\n if (!this._isDirty) {\r\n return;\r\n }\r\n\r\n if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {\r\n this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));\r\n\r\n if (this.isUsingTextureForMatrices) {\r\n if (this._transformMatrixTexture) {\r\n this._transformMatrixTexture.dispose();\r\n }\r\n\r\n this._transformMatrixTexture = RawTexture.CreateRGBATexture(\r\n this._transformMatrices,\r\n (this.bones.length + 1) * 4,\r\n 1,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_FLOAT\r\n );\r\n }\r\n }\r\n\r\n this._computeTransformMatrices(this._transformMatrices, null);\r\n\r\n if (this.isUsingTextureForMatrices && this._transformMatrixTexture) {\r\n this._transformMatrixTexture.update(this._transformMatrices);\r\n }\r\n }\r\n\r\n this._isDirty = false;\r\n }\r\n\r\n /**\r\n * Gets the list of animatables currently running for this skeleton\r\n * @returns an array of animatables\r\n */\r\n public getAnimatables(): IAnimatable[] {\r\n if (!this._animatables || this._animatables.length !== this.bones.length) {\r\n this._animatables = [];\r\n\r\n for (let index = 0; index < this.bones.length; index++) {\r\n this._animatables.push(this.bones[index]);\r\n }\r\n }\r\n\r\n return this._animatables;\r\n }\r\n\r\n /**\r\n * Clone the current skeleton\r\n * @param name defines the name of the new skeleton\r\n * @param id defines the id of the new skeleton\r\n * @returns the new skeleton\r\n */\r\n public clone(name: string, id?: string): Skeleton {\r\n const result = new Skeleton(name, id || name, this._scene);\r\n\r\n result.needInitialSkinMatrix = this.needInitialSkinMatrix;\r\n\r\n for (let index = 0; index < this.bones.length; index++) {\r\n const source = this.bones[index];\r\n let parentBone = null;\r\n\r\n const parent = source.getParent();\r\n if (parent) {\r\n const parentIndex = this.bones.indexOf(parent);\r\n parentBone = result.bones[parentIndex];\r\n }\r\n\r\n const bone = new Bone(source.name, result, parentBone, source.getBindMatrix().clone(), source.getRestMatrix().clone());\r\n bone._index = source._index;\r\n\r\n if (source._linkedTransformNode) {\r\n bone.linkTransformNode(source._linkedTransformNode);\r\n }\r\n\r\n DeepCopier.DeepCopy(source.animations, bone.animations);\r\n }\r\n\r\n if (this._ranges) {\r\n result._ranges = {};\r\n for (const rangeName in this._ranges) {\r\n const range = this._ranges[rangeName];\r\n\r\n if (range) {\r\n result._ranges[rangeName] = range.clone();\r\n }\r\n }\r\n }\r\n\r\n this._isDirty = true;\r\n\r\n result.prepare();\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Enable animation blending for this skeleton\r\n * @param blendingSpeed defines the blending speed to apply\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-blending\r\n */\r\n public enableBlending(blendingSpeed = 0.01) {\r\n this.bones.forEach((bone) => {\r\n bone.animations.forEach((animation: Animation) => {\r\n animation.enableBlending = true;\r\n animation.blendingSpeed = blendingSpeed;\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Releases all resources associated with the current skeleton\r\n */\r\n public dispose() {\r\n this._meshesWithPoseMatrix.length = 0;\r\n\r\n // Animations\r\n this.getScene().stopAnimation(this);\r\n\r\n // Remove from scene\r\n this.getScene().removeSkeleton(this);\r\n\r\n if (this._parentContainer) {\r\n const index = this._parentContainer.skeletons.indexOf(this);\r\n if (index > -1) {\r\n this._parentContainer.skeletons.splice(index, 1);\r\n }\r\n this._parentContainer = null;\r\n }\r\n\r\n if (this._transformMatrixTexture) {\r\n this._transformMatrixTexture.dispose();\r\n this._transformMatrixTexture = null;\r\n }\r\n }\r\n\r\n /**\r\n * Serialize the skeleton in a JSON object\r\n * @returns a JSON object\r\n */\r\n public serialize(): any {\r\n const serializationObject: any = {};\r\n\r\n serializationObject.name = this.name;\r\n serializationObject.id = this.id;\r\n\r\n if (this.dimensionsAtRest) {\r\n serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();\r\n }\r\n\r\n serializationObject.bones = [];\r\n\r\n serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;\r\n\r\n for (let index = 0; index < this.bones.length; index++) {\r\n const bone = this.bones[index];\r\n const parent = bone.getParent();\r\n\r\n const serializedBone: any = {\r\n parentBoneIndex: parent ? this.bones.indexOf(parent) : -1,\r\n index: bone.getIndex(),\r\n name: bone.name,\r\n id: bone.id,\r\n matrix: bone.getBindMatrix().toArray(),\r\n rest: bone.getRestMatrix().toArray(),\r\n linkedTransformNodeId: bone.getTransformNode()?.id,\r\n };\r\n\r\n serializationObject.bones.push(serializedBone);\r\n\r\n if (bone.length) {\r\n serializedBone.length = bone.length;\r\n }\r\n\r\n if (bone.metadata) {\r\n serializedBone.metadata = bone.metadata;\r\n }\r\n\r\n if (bone.animations && bone.animations.length > 0) {\r\n serializedBone.animation = bone.animations[0].serialize();\r\n }\r\n\r\n serializationObject.ranges = [];\r\n for (const name in this._ranges) {\r\n const source = this._ranges[name];\r\n\r\n if (!source) {\r\n continue;\r\n }\r\n\r\n const range: any = {};\r\n range.name = name;\r\n range.from = source.from;\r\n range.to = source.to;\r\n serializationObject.ranges.push(range);\r\n }\r\n }\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Creates a new skeleton from serialized data\r\n * @param parsedSkeleton defines the serialized data\r\n * @param scene defines the hosting scene\r\n * @returns a new skeleton\r\n */\r\n public static Parse(parsedSkeleton: any, scene: Scene): Skeleton {\r\n const skeleton = new Skeleton(parsedSkeleton.name, parsedSkeleton.id, scene);\r\n if (parsedSkeleton.dimensionsAtRest) {\r\n skeleton.dimensionsAtRest = Vector3.FromArray(parsedSkeleton.dimensionsAtRest);\r\n }\r\n\r\n skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;\r\n\r\n let index: number;\r\n for (index = 0; index < parsedSkeleton.bones.length; index++) {\r\n const parsedBone = parsedSkeleton.bones[index];\r\n const parsedBoneIndex = parsedSkeleton.bones[index].index;\r\n let parentBone = null;\r\n if (parsedBone.parentBoneIndex > -1) {\r\n parentBone = skeleton.bones[parsedBone.parentBoneIndex];\r\n }\r\n\r\n const rest: Nullable<Matrix> = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;\r\n const bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest, null, parsedBoneIndex);\r\n\r\n if (parsedBone.id !== undefined && parsedBone.id !== null) {\r\n bone.id = parsedBone.id;\r\n }\r\n\r\n if (parsedBone.length) {\r\n bone.length = parsedBone.length;\r\n }\r\n\r\n if (parsedBone.metadata) {\r\n bone.metadata = parsedBone.metadata;\r\n }\r\n\r\n if (parsedBone.animation) {\r\n bone.animations.push(Animation.Parse(parsedBone.animation));\r\n }\r\n\r\n if (parsedBone.linkedTransformNodeId !== undefined && parsedBone.linkedTransformNodeId !== null) {\r\n skeleton._hasWaitingData = true;\r\n bone._waitingTransformNodeId = parsedBone.linkedTransformNodeId;\r\n }\r\n }\r\n\r\n // placed after bones, so createAnimationRange can cascade down\r\n if (parsedSkeleton.ranges) {\r\n for (index = 0; index < parsedSkeleton.ranges.length; index++) {\r\n const data = parsedSkeleton.ranges[index];\r\n skeleton.createAnimationRange(data.name, data.from, data.to);\r\n }\r\n }\r\n return skeleton;\r\n }\r\n\r\n /**\r\n * Compute all node absolute matrices\r\n * @param forceUpdate defines if computation must be done even if cache is up to date\r\n */\r\n public computeAbsoluteMatrices(forceUpdate = false): void {\r\n if (this._absoluteTransformIsDirty || forceUpdate) {\r\n this.bones[0].computeAbsoluteMatrices();\r\n this._absoluteTransformIsDirty = false;\r\n }\r\n }\r\n\r\n /**\r\n * Compute all node absolute matrices\r\n * @param forceUpdate defines if computation must be done even if cache is up to date\r\n * @deprecated Please use computeAbsoluteMatrices instead\r\n */\r\n public computeAbsoluteTransforms(forceUpdate = false): void {\r\n this.computeAbsoluteMatrices(forceUpdate);\r\n }\r\n\r\n /**\r\n * Gets the root pose matrix\r\n * @returns a matrix\r\n */\r\n public getPoseMatrix(): Nullable<Matrix> {\r\n let poseMatrix: Nullable<Matrix> = null;\r\n\r\n if (this._meshesWithPoseMatrix.length > 0) {\r\n poseMatrix = this._meshesWithPoseMatrix[0].getPoseMatrix();\r\n }\r\n\r\n return poseMatrix;\r\n }\r\n\r\n /**\r\n * Sorts bones per internal index\r\n */\r\n public sortBones(): void {\r\n const bones = new Array<Bone>();\r\n const visited = new Array<boolean>(this.bones.length);\r\n for (let index = 0; index < this.bones.length; index++) {\r\n this._sortBones(index, bones, visited);\r\n }\r\n\r\n this.bones = bones;\r\n }\r\n\r\n private _sortBones(index: number, bones: Bone[], visited: boolean[]): void {\r\n if (visited[index]) {\r\n return;\r\n }\r\n\r\n visited[index] = true;\r\n\r\n const bone = this.bones[index];\r\n if (!bone) return;\r\n\r\n if (bone._index === undefined) {\r\n bone._index = index;\r\n }\r\n\r\n const parentBone = bone.getParent();\r\n if (parentBone) {\r\n this._sortBones(this.bones.indexOf(parentBone), bones, visited);\r\n }\r\n\r\n bones.push(bone);\r\n }\r\n\r\n /**\r\n * Set the current local matrix as the restPose for all bones in the skeleton.\r\n */\r\n public setCurrentPoseAsRest(): void {\r\n this.bones.forEach((b) => {\r\n b.setCurrentPoseAsRest();\r\n });\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"skeleton.js","sourceRoot":"","sources":["../../../../dev/core/src/Bones/skeleton.ts"],"names":[],"mappings":"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","sourcesContent":["import { Bone } from \"./bone\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector\";\r\nimport type { Scene } from \"../scene\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { RawTexture } from \"../Materials/Textures/rawTexture\";\r\nimport type { Animatable } from \"../Animations/animatable\";\r\nimport type { AnimationPropertiesOverride } from \"../Animations/animationPropertiesOverride\";\r\nimport { Animation } from \"../Animations/animation\";\r\nimport { AnimationRange } from \"../Animations/animationRange\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { DeepCopier } from \"../Misc/deepCopier\";\r\nimport type { IInspectable } from \"../Misc/iInspectable\";\r\nimport type { IAnimatable } from \"../Animations/animatable.interface\";\r\nimport type { AbstractScene } from \"../abstractScene\";\r\n\r\n/**\r\n * Class used to handle skinning animations\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons\r\n */\r\nexport class Skeleton implements IAnimatable {\r\n /**\r\n * Defines the list of child bones\r\n */\r\n public bones = new Array<Bone>();\r\n /**\r\n * Defines an estimate of the dimension of the skeleton at rest\r\n */\r\n public dimensionsAtRest: Vector3;\r\n /**\r\n * Defines a boolean indicating if the root matrix is provided by meshes or by the current skeleton (this is the default value)\r\n */\r\n public needInitialSkinMatrix = false;\r\n\r\n /**\r\n * Gets the list of animations attached to this skeleton\r\n */\r\n public animations: Array<Animation>;\r\n\r\n private _scene: Scene;\r\n private _isDirty = true;\r\n private _transformMatrices: Float32Array;\r\n private _transformMatrixTexture: Nullable<RawTexture>;\r\n private _meshesWithPoseMatrix = new Array<AbstractMesh>();\r\n private _animatables: IAnimatable[];\r\n private _identity = Matrix.Identity();\r\n private _synchronizedWithMesh: AbstractMesh;\r\n private _currentRenderId = -1;\r\n\r\n private _ranges: { [name: string]: Nullable<AnimationRange> } = {};\r\n\r\n private _absoluteTransformIsDirty = true;\r\n\r\n private _canUseTextureForBones = false;\r\n private _uniqueId = 0;\r\n\r\n /** @internal */\r\n public _numBonesWithLinkedTransformNode = 0;\r\n\r\n /** @internal */\r\n public _hasWaitingData: Nullable<boolean> = null;\r\n\r\n /** @internal */\r\n public _parentContainer: Nullable<AbstractScene> = null;\r\n\r\n /**\r\n * Specifies if the skeleton should be serialized\r\n */\r\n public doNotSerialize = false;\r\n\r\n private _useTextureToStoreBoneMatrices = true;\r\n /**\r\n * Gets or sets a boolean indicating that bone matrices should be stored as a texture instead of using shader uniforms (default is true).\r\n * Please note that this option is not available if the hardware does not support it\r\n */\r\n public get useTextureToStoreBoneMatrices(): boolean {\r\n return this._useTextureToStoreBoneMatrices;\r\n }\r\n\r\n public set useTextureToStoreBoneMatrices(value: boolean) {\r\n this._useTextureToStoreBoneMatrices = value;\r\n this._markAsDirty();\r\n }\r\n\r\n private _animationPropertiesOverride: Nullable<AnimationPropertiesOverride> = null;\r\n\r\n /**\r\n * Gets or sets the animation properties override\r\n */\r\n public get animationPropertiesOverride(): Nullable<AnimationPropertiesOverride> {\r\n if (!this._animationPropertiesOverride) {\r\n return this._scene.animationPropertiesOverride;\r\n }\r\n return this._animationPropertiesOverride;\r\n }\r\n\r\n public set animationPropertiesOverride(value: Nullable<AnimationPropertiesOverride>) {\r\n this._animationPropertiesOverride = value;\r\n }\r\n\r\n /**\r\n * List of inspectable custom properties (used by the Inspector)\r\n * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n */\r\n public inspectableCustomProperties: IInspectable[];\r\n\r\n // Events\r\n\r\n /**\r\n * An observable triggered before computing the skeleton's matrices\r\n */\r\n public onBeforeComputeObservable = new Observable<Skeleton>();\r\n\r\n /**\r\n * Gets a boolean indicating that the skeleton effectively stores matrices into a texture\r\n */\r\n public get isUsingTextureForMatrices() {\r\n return this.useTextureToStoreBoneMatrices && this._canUseTextureForBones;\r\n }\r\n\r\n /**\r\n * Gets the unique ID of this skeleton\r\n */\r\n public get uniqueId(): number {\r\n return this._uniqueId;\r\n }\r\n\r\n /**\r\n * Creates a new skeleton\r\n * @param name defines the skeleton name\r\n * @param id defines the skeleton Id\r\n * @param scene defines the hosting scene\r\n */\r\n constructor(\r\n /** defines the skeleton name */\r\n public name: string,\r\n /** defines the skeleton Id */\r\n public id: string,\r\n scene: Scene\r\n ) {\r\n this.bones = [];\r\n\r\n this._scene = scene || EngineStore.LastCreatedScene;\r\n this._uniqueId = this._scene.getUniqueId();\r\n\r\n this._scene.addSkeleton(this);\r\n\r\n //make sure it will recalculate the matrix next time prepare is called.\r\n this._isDirty = true;\r\n\r\n const engineCaps = this._scene.getEngine().getCaps();\r\n this._canUseTextureForBones = engineCaps.textureFloat && engineCaps.maxVertexTextureImageUnits > 0;\r\n }\r\n\r\n /**\r\n * Gets the current object class name.\r\n * @returns the class name\r\n */\r\n public getClassName(): string {\r\n return \"Skeleton\";\r\n }\r\n\r\n /**\r\n * Returns an array containing the root bones\r\n * @returns an array containing the root bones\r\n */\r\n public getChildren(): Array<Bone> {\r\n return this.bones.filter((b) => !b.getParent());\r\n }\r\n\r\n // Members\r\n /**\r\n * Gets the list of transform matrices to send to shaders (one matrix per bone)\r\n * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\r\n * @returns a Float32Array containing matrices data\r\n */\r\n public getTransformMatrices(mesh: AbstractMesh): Float32Array {\r\n if (this.needInitialSkinMatrix) {\r\n if (!mesh._bonesTransformMatrices) {\r\n this.prepare();\r\n }\r\n\r\n return mesh._bonesTransformMatrices!;\r\n }\r\n\r\n if (!this._transformMatrices || this._isDirty) {\r\n this.prepare();\r\n }\r\n\r\n return this._transformMatrices;\r\n }\r\n\r\n /**\r\n * Gets the list of transform matrices to send to shaders inside a texture (one matrix per bone)\r\n * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\r\n * @returns a raw texture containing the data\r\n */\r\n public getTransformMatrixTexture(mesh: AbstractMesh): Nullable<RawTexture> {\r\n if (this.needInitialSkinMatrix && mesh._transformMatrixTexture) {\r\n return mesh._transformMatrixTexture;\r\n }\r\n\r\n return this._transformMatrixTexture;\r\n }\r\n\r\n /**\r\n * Gets the current hosting scene\r\n * @returns a scene object\r\n */\r\n public getScene(): Scene {\r\n return this._scene;\r\n }\r\n\r\n // Methods\r\n\r\n /**\r\n * Gets a string representing the current skeleton data\r\n * @param fullDetails defines a boolean indicating if we want a verbose version\r\n * @returns a string representing the current skeleton data\r\n */\r\n public toString(fullDetails?: boolean): string {\r\n let ret = `Name: ${this.name}, nBones: ${this.bones.length}`;\r\n ret += `, nAnimationRanges: ${this._ranges ? Object.keys(this._ranges).length : \"none\"}`;\r\n if (fullDetails) {\r\n ret += \", Ranges: {\";\r\n let first = true;\r\n for (const name in this._ranges) {\r\n if (first) {\r\n ret += \", \";\r\n first = false;\r\n }\r\n ret += name;\r\n }\r\n ret += \"}\";\r\n }\r\n return ret;\r\n }\r\n\r\n /**\r\n * Get bone's index searching by name\r\n * @param name defines bone's name to search for\r\n * @returns the indice of the bone. Returns -1 if not found\r\n */\r\n public getBoneIndexByName(name: string): number {\r\n for (let boneIndex = 0, cache = this.bones.length; boneIndex < cache; boneIndex++) {\r\n if (this.bones[boneIndex].name === name) {\r\n return boneIndex;\r\n }\r\n }\r\n return -1;\r\n }\r\n\r\n /**\r\n * Create a new animation range\r\n * @param name defines the name of the range\r\n * @param from defines the start key\r\n * @param to defines the end key\r\n */\r\n public createAnimationRange(name: string, from: number, to: number): void {\r\n // check name not already in use\r\n if (!this._ranges[name]) {\r\n this._ranges[name] = new AnimationRange(name, from, to);\r\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n if (this.bones[i].animations[0]) {\r\n this.bones[i].animations[0].createRange(name, from, to);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Delete a specific animation range\r\n * @param name defines the name of the range\r\n * @param deleteFrames defines if frames must be removed as well\r\n */\r\n public deleteAnimationRange(name: string, deleteFrames = true): void {\r\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n if (this.bones[i].animations[0]) {\r\n this.bones[i].animations[0].deleteRange(name, deleteFrames);\r\n }\r\n }\r\n this._ranges[name] = null; // said much faster than 'delete this._range[name]'\r\n }\r\n\r\n /**\r\n * Gets a specific animation range\r\n * @param name defines the name of the range to look for\r\n * @returns the requested animation range or null if not found\r\n */\r\n public getAnimationRange(name: string): Nullable<AnimationRange> {\r\n return this._ranges[name] || null;\r\n }\r\n\r\n /**\r\n * Gets the list of all animation ranges defined on this skeleton\r\n * @returns an array\r\n */\r\n public getAnimationRanges(): Nullable<AnimationRange>[] {\r\n const animationRanges: Nullable<AnimationRange>[] = [];\r\n let name: string;\r\n for (name in this._ranges) {\r\n animationRanges.push(this._ranges[name]);\r\n }\r\n return animationRanges;\r\n }\r\n\r\n /**\r\n * Copy animation range from a source skeleton.\r\n * This is not for a complete retargeting, only between very similar skeleton's with only possible bone length differences\r\n * @param source defines the source skeleton\r\n * @param name defines the name of the range to copy\r\n * @param rescaleAsRequired defines if rescaling must be applied if required\r\n * @returns true if operation was successful\r\n */\r\n public copyAnimationRange(source: Skeleton, name: string, rescaleAsRequired = false): boolean {\r\n if (this._ranges[name] || !source.getAnimationRange(name)) {\r\n return false;\r\n }\r\n let ret = true;\r\n const frameOffset = this._getHighestAnimationFrame() + 1;\r\n\r\n // make a dictionary of source skeleton's bones, so exact same order or doubly nested loop is not required\r\n const boneDict: { [key: string]: Bone } = {};\r\n const sourceBones = source.bones;\r\n let nBones: number;\r\n let i: number;\r\n for (i = 0, nBones = sourceBones.length; i < nBones; i++) {\r\n boneDict[sourceBones[i].name] = sourceBones[i];\r\n }\r\n\r\n if (this.bones.length !== sourceBones.length) {\r\n Logger.Warn(`copyAnimationRange: this rig has ${this.bones.length} bones, while source as ${sourceBones.length}`);\r\n ret = false;\r\n }\r\n\r\n const skelDimensionsRatio = rescaleAsRequired && this.dimensionsAtRest && source.dimensionsAtRest ? this.dimensionsAtRest.divide(source.dimensionsAtRest) : null;\r\n\r\n for (i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n const boneName = this.bones[i].name;\r\n const sourceBone = boneDict[boneName];\r\n if (sourceBone) {\r\n ret = ret && this.bones[i].copyAnimationRange(sourceBone, name, frameOffset, rescaleAsRequired, skelDimensionsRatio);\r\n } else {\r\n Logger.Warn(\"copyAnimationRange: not same rig, missing source bone \" + boneName);\r\n ret = false;\r\n }\r\n }\r\n // do not call createAnimationRange(), since it also is done to bones, which was already done\r\n const range = source.getAnimationRange(name);\r\n if (range) {\r\n this._ranges[name] = new AnimationRange(name, range.from + frameOffset, range.to + frameOffset);\r\n }\r\n return ret;\r\n }\r\n\r\n /**\r\n * Forces the skeleton to go to rest pose\r\n */\r\n public returnToRest(): void {\r\n for (const bone of this.bones) {\r\n if (bone._index !== -1) {\r\n bone.returnToRest();\r\n }\r\n }\r\n }\r\n\r\n private _getHighestAnimationFrame(): number {\r\n let ret = 0;\r\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\r\n if (this.bones[i].animations[0]) {\r\n const highest = this.bones[i].animations[0].getHighestFrame();\r\n if (ret < highest) {\r\n ret = highest;\r\n }\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n /**\r\n * Begin a specific animation range\r\n * @param name defines the name of the range to start\r\n * @param loop defines if looping must be turned on (false by default)\r\n * @param speedRatio defines the speed ratio to apply (1 by default)\r\n * @param onAnimationEnd defines a callback which will be called when animation will end\r\n * @returns a new animatable\r\n */\r\n public beginAnimation(name: string, loop?: boolean, speedRatio?: number, onAnimationEnd?: () => void): Nullable<Animatable> {\r\n const range = this.getAnimationRange(name);\r\n\r\n if (!range) {\r\n return null;\r\n }\r\n\r\n return this._scene.beginAnimation(this, range.from, range.to, loop, speedRatio, onAnimationEnd);\r\n }\r\n\r\n /**\r\n * Convert the keyframes for a range of animation on a skeleton to be relative to a given reference frame.\r\n * @param skeleton defines the Skeleton containing the animation range to convert\r\n * @param referenceFrame defines the frame that keyframes in the range will be relative to\r\n * @param range defines the name of the AnimationRange belonging to the Skeleton to convert\r\n * @returns the original skeleton\r\n */\r\n public static MakeAnimationAdditive(skeleton: Skeleton, referenceFrame = 0, range: string): Nullable<Skeleton> {\r\n const rangeValue = skeleton.getAnimationRange(range);\r\n\r\n // We can't make a range additive if it doesn't exist\r\n if (!rangeValue) {\r\n return null;\r\n }\r\n\r\n // Find any current scene-level animatable belonging to the target that matches the range\r\n const sceneAnimatables = skeleton._scene.getAllAnimatablesByTarget(skeleton);\r\n let rangeAnimatable: Nullable<Animatable> = null;\r\n\r\n for (let index = 0; index < sceneAnimatables.length; index++) {\r\n const sceneAnimatable = sceneAnimatables[index];\r\n\r\n if (sceneAnimatable.fromFrame === rangeValue?.from && sceneAnimatable.toFrame === rangeValue?.to) {\r\n rangeAnimatable = sceneAnimatable;\r\n break;\r\n }\r\n }\r\n\r\n // Convert the animations belonging to the skeleton to additive keyframes\r\n const animatables = skeleton.getAnimatables();\r\n\r\n for (let index = 0; index < animatables.length; index++) {\r\n const animatable = animatables[index];\r\n const animations = animatable.animations;\r\n\r\n if (!animations) {\r\n continue;\r\n }\r\n\r\n for (let animIndex = 0; animIndex < animations.length; animIndex++) {\r\n Animation.MakeAnimationAdditive(animations[animIndex], referenceFrame, range);\r\n }\r\n }\r\n\r\n // Mark the scene-level animatable as additive\r\n if (rangeAnimatable) {\r\n rangeAnimatable.isAdditive = true;\r\n }\r\n\r\n return skeleton;\r\n }\r\n\r\n /** @internal */\r\n public _markAsDirty(): void {\r\n this._isDirty = true;\r\n this._absoluteTransformIsDirty = true;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _registerMeshWithPoseMatrix(mesh: AbstractMesh): void {\r\n this._meshesWithPoseMatrix.push(mesh);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _unregisterMeshWithPoseMatrix(mesh: AbstractMesh): void {\r\n const index = this._meshesWithPoseMatrix.indexOf(mesh);\r\n\r\n if (index > -1) {\r\n this._meshesWithPoseMatrix.splice(index, 1);\r\n }\r\n }\r\n\r\n private _computeTransformMatrices(targetMatrix: Float32Array, initialSkinMatrix: Nullable<Matrix>): void {\r\n this.onBeforeComputeObservable.notifyObservers(this);\r\n\r\n for (let index = 0; index < this.bones.length; index++) {\r\n const bone = this.bones[index];\r\n bone._childUpdateId++;\r\n const parentBone = bone.getParent();\r\n\r\n if (parentBone) {\r\n bone.getLocalMatrix().multiplyToRef(parentBone.getFinalMatrix(), bone.getFinalMatrix());\r\n } else {\r\n if (initialSkinMatrix) {\r\n bone.getLocalMatrix().multiplyToRef(initialSkinMatrix, bone.getFinalMatrix());\r\n } else {\r\n bone.getFinalMatrix().copyFrom(bone.getLocalMatrix());\r\n }\r\n }\r\n\r\n if (bone._index !== -1) {\r\n const mappedIndex = bone._index === null ? index : bone._index;\r\n bone.getAbsoluteInverseBindMatrix().multiplyToArray(bone.getFinalMatrix(), targetMatrix, mappedIndex * 16);\r\n }\r\n }\r\n\r\n this._identity.copyToArray(targetMatrix, this.bones.length * 16);\r\n }\r\n\r\n /**\r\n * Build all resources required to render a skeleton\r\n * @param dontCheckFrameId defines a boolean indicating if prepare should be run without checking first the current frame id (default: false)\r\n */\r\n public prepare(dontCheckFrameId = false): void {\r\n if (!dontCheckFrameId) {\r\n const currentRenderId = this.getScene().getRenderId();\r\n if (this._currentRenderId === currentRenderId) {\r\n return;\r\n }\r\n this._currentRenderId = currentRenderId;\r\n }\r\n\r\n // Update the local matrix of bones with linked transform nodes.\r\n if (this._numBonesWithLinkedTransformNode > 0) {\r\n for (const bone of this.bones) {\r\n if (bone._linkedTransformNode) {\r\n const node = bone._linkedTransformNode;\r\n bone.position = node.position;\r\n if (node.rotationQuaternion) {\r\n bone.rotationQuaternion = node.rotationQuaternion;\r\n } else {\r\n bone.rotation = node.rotation;\r\n }\r\n bone.scaling = node.scaling;\r\n }\r\n }\r\n }\r\n\r\n if (this.needInitialSkinMatrix) {\r\n for (const mesh of this._meshesWithPoseMatrix) {\r\n const poseMatrix = mesh.getPoseMatrix();\r\n\r\n let needsUpdate = this._isDirty;\r\n if (!mesh._bonesTransformMatrices || mesh._bonesTransformMatrices.length !== 16 * (this.bones.length + 1)) {\r\n mesh._bonesTransformMatrices = new Float32Array(16 * (this.bones.length + 1));\r\n needsUpdate = true;\r\n }\r\n\r\n if (!needsUpdate) {\r\n continue;\r\n }\r\n\r\n if (this._synchronizedWithMesh !== mesh) {\r\n this._synchronizedWithMesh = mesh;\r\n\r\n // Prepare bones\r\n for (const bone of this.bones) {\r\n if (!bone.getParent()) {\r\n const matrix = bone.getBindMatrix();\r\n matrix.multiplyToRef(poseMatrix, TmpVectors.Matrix[1]);\r\n bone._updateAbsoluteBindMatrices(TmpVectors.Matrix[1]);\r\n }\r\n }\r\n\r\n if (this.isUsingTextureForMatrices) {\r\n const textureWidth = (this.bones.length + 1) * 4;\r\n if (!mesh._transformMatrixTexture || mesh._transformMatrixTexture.getSize().width !== textureWidth) {\r\n if (mesh._transformMatrixTexture) {\r\n mesh._transformMatrixTexture.dispose();\r\n }\r\n\r\n mesh._transformMatrixTexture = RawTexture.CreateRGBATexture(\r\n mesh._bonesTransformMatrices,\r\n (this.bones.length + 1) * 4,\r\n 1,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_FLOAT\r\n );\r\n }\r\n }\r\n }\r\n\r\n this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);\r\n\r\n if (this.isUsingTextureForMatrices && mesh._transformMatrixTexture) {\r\n mesh._transformMatrixTexture.update(mesh._bonesTransformMatrices);\r\n }\r\n }\r\n } else {\r\n if (!this._isDirty) {\r\n return;\r\n }\r\n\r\n if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {\r\n this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));\r\n\r\n if (this.isUsingTextureForMatrices) {\r\n if (this._transformMatrixTexture) {\r\n this._transformMatrixTexture.dispose();\r\n }\r\n\r\n this._transformMatrixTexture = RawTexture.CreateRGBATexture(\r\n this._transformMatrices,\r\n (this.bones.length + 1) * 4,\r\n 1,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_FLOAT\r\n );\r\n }\r\n }\r\n\r\n this._computeTransformMatrices(this._transformMatrices, null);\r\n\r\n if (this.isUsingTextureForMatrices && this._transformMatrixTexture) {\r\n this._transformMatrixTexture.update(this._transformMatrices);\r\n }\r\n }\r\n\r\n this._isDirty = false;\r\n }\r\n\r\n /**\r\n * Gets the list of animatables currently running for this skeleton\r\n * @returns an array of animatables\r\n */\r\n public getAnimatables(): IAnimatable[] {\r\n if (!this._animatables || this._animatables.length !== this.bones.length) {\r\n this._animatables = [];\r\n\r\n for (let index = 0; index < this.bones.length; index++) {\r\n this._animatables.push(this.bones[index]);\r\n }\r\n }\r\n\r\n return this._animatables;\r\n }\r\n\r\n /**\r\n * Clone the current skeleton\r\n * @param name defines the name of the new skeleton\r\n * @param id defines the id of the new skeleton\r\n * @returns the new skeleton\r\n */\r\n public clone(name: string, id?: string): Skeleton {\r\n const result = new Skeleton(name, id || name, this._scene);\r\n\r\n result.needInitialSkinMatrix = this.needInitialSkinMatrix;\r\n\r\n for (let index = 0; index < this.bones.length; index++) {\r\n const source = this.bones[index];\r\n let parentBone = null;\r\n\r\n const parent = source.getParent();\r\n if (parent) {\r\n const parentIndex = this.bones.indexOf(parent);\r\n parentBone = result.bones[parentIndex];\r\n }\r\n\r\n const bone = new Bone(source.name, result, parentBone, source.getBindMatrix().clone(), source.getRestMatrix().clone());\r\n bone._index = source._index;\r\n\r\n if (source._linkedTransformNode) {\r\n bone.linkTransformNode(source._linkedTransformNode);\r\n }\r\n\r\n DeepCopier.DeepCopy(source.animations, bone.animations);\r\n }\r\n\r\n if (this._ranges) {\r\n result._ranges = {};\r\n for (const rangeName in this._ranges) {\r\n const range = this._ranges[rangeName];\r\n\r\n if (range) {\r\n result._ranges[rangeName] = range.clone();\r\n }\r\n }\r\n }\r\n\r\n this._isDirty = true;\r\n\r\n result.prepare(true);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Enable animation blending for this skeleton\r\n * @param blendingSpeed defines the blending speed to apply\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-blending\r\n */\r\n public enableBlending(blendingSpeed = 0.01) {\r\n this.bones.forEach((bone) => {\r\n bone.animations.forEach((animation: Animation) => {\r\n animation.enableBlending = true;\r\n animation.blendingSpeed = blendingSpeed;\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Releases all resources associated with the current skeleton\r\n */\r\n public dispose() {\r\n this._meshesWithPoseMatrix.length = 0;\r\n\r\n // Animations\r\n this.getScene().stopAnimation(this);\r\n\r\n // Remove from scene\r\n this.getScene().removeSkeleton(this);\r\n\r\n if (this._parentContainer) {\r\n const index = this._parentContainer.skeletons.indexOf(this);\r\n if (index > -1) {\r\n this._parentContainer.skeletons.splice(index, 1);\r\n }\r\n this._parentContainer = null;\r\n }\r\n\r\n if (this._transformMatrixTexture) {\r\n this._transformMatrixTexture.dispose();\r\n this._transformMatrixTexture = null;\r\n }\r\n }\r\n\r\n /**\r\n * Serialize the skeleton in a JSON object\r\n * @returns a JSON object\r\n */\r\n public serialize(): any {\r\n const serializationObject: any = {};\r\n\r\n serializationObject.name = this.name;\r\n serializationObject.id = this.id;\r\n\r\n if (this.dimensionsAtRest) {\r\n serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();\r\n }\r\n\r\n serializationObject.bones = [];\r\n\r\n serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;\r\n\r\n for (let index = 0; index < this.bones.length; index++) {\r\n const bone = this.bones[index];\r\n const parent = bone.getParent();\r\n\r\n const serializedBone: any = {\r\n parentBoneIndex: parent ? this.bones.indexOf(parent) : -1,\r\n index: bone.getIndex(),\r\n name: bone.name,\r\n id: bone.id,\r\n matrix: bone.getBindMatrix().toArray(),\r\n rest: bone.getRestMatrix().toArray(),\r\n linkedTransformNodeId: bone.getTransformNode()?.id,\r\n };\r\n\r\n serializationObject.bones.push(serializedBone);\r\n\r\n if (bone.length) {\r\n serializedBone.length = bone.length;\r\n }\r\n\r\n if (bone.metadata) {\r\n serializedBone.metadata = bone.metadata;\r\n }\r\n\r\n if (bone.animations && bone.animations.length > 0) {\r\n serializedBone.animation = bone.animations[0].serialize();\r\n }\r\n\r\n serializationObject.ranges = [];\r\n for (const name in this._ranges) {\r\n const source = this._ranges[name];\r\n\r\n if (!source) {\r\n continue;\r\n }\r\n\r\n const range: any = {};\r\n range.name = name;\r\n range.from = source.from;\r\n range.to = source.to;\r\n serializationObject.ranges.push(range);\r\n }\r\n }\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Creates a new skeleton from serialized data\r\n * @param parsedSkeleton defines the serialized data\r\n * @param scene defines the hosting scene\r\n * @returns a new skeleton\r\n */\r\n public static Parse(parsedSkeleton: any, scene: Scene): Skeleton {\r\n const skeleton = new Skeleton(parsedSkeleton.name, parsedSkeleton.id, scene);\r\n if (parsedSkeleton.dimensionsAtRest) {\r\n skeleton.dimensionsAtRest = Vector3.FromArray(parsedSkeleton.dimensionsAtRest);\r\n }\r\n\r\n skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;\r\n\r\n let index: number;\r\n for (index = 0; index < parsedSkeleton.bones.length; index++) {\r\n const parsedBone = parsedSkeleton.bones[index];\r\n const parsedBoneIndex = parsedSkeleton.bones[index].index;\r\n let parentBone = null;\r\n if (parsedBone.parentBoneIndex > -1) {\r\n parentBone = skeleton.bones[parsedBone.parentBoneIndex];\r\n }\r\n\r\n const rest: Nullable<Matrix> = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;\r\n const bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest, null, parsedBoneIndex);\r\n\r\n if (parsedBone.id !== undefined && parsedBone.id !== null) {\r\n bone.id = parsedBone.id;\r\n }\r\n\r\n if (parsedBone.length) {\r\n bone.length = parsedBone.length;\r\n }\r\n\r\n if (parsedBone.metadata) {\r\n bone.metadata = parsedBone.metadata;\r\n }\r\n\r\n if (parsedBone.animation) {\r\n bone.animations.push(Animation.Parse(parsedBone.animation));\r\n }\r\n\r\n if (parsedBone.linkedTransformNodeId !== undefined && parsedBone.linkedTransformNodeId !== null) {\r\n skeleton._hasWaitingData = true;\r\n bone._waitingTransformNodeId = parsedBone.linkedTransformNodeId;\r\n }\r\n }\r\n\r\n // placed after bones, so createAnimationRange can cascade down\r\n if (parsedSkeleton.ranges) {\r\n for (index = 0; index < parsedSkeleton.ranges.length; index++) {\r\n const data = parsedSkeleton.ranges[index];\r\n skeleton.createAnimationRange(data.name, data.from, data.to);\r\n }\r\n }\r\n return skeleton;\r\n }\r\n\r\n /**\r\n * Compute all node absolute matrices\r\n * @param forceUpdate defines if computation must be done even if cache is up to date\r\n */\r\n public computeAbsoluteMatrices(forceUpdate = false): void {\r\n if (this._absoluteTransformIsDirty || forceUpdate) {\r\n this.bones[0].computeAbsoluteMatrices();\r\n this._absoluteTransformIsDirty = false;\r\n }\r\n }\r\n\r\n /**\r\n * Compute all node absolute matrices\r\n * @param forceUpdate defines if computation must be done even if cache is up to date\r\n * @deprecated Please use computeAbsoluteMatrices instead\r\n */\r\n public computeAbsoluteTransforms(forceUpdate = false): void {\r\n this.computeAbsoluteMatrices(forceUpdate);\r\n }\r\n\r\n /**\r\n * Gets the root pose matrix\r\n * @returns a matrix\r\n */\r\n public getPoseMatrix(): Nullable<Matrix> {\r\n let poseMatrix: Nullable<Matrix> = null;\r\n\r\n if (this._meshesWithPoseMatrix.length > 0) {\r\n poseMatrix = this._meshesWithPoseMatrix[0].getPoseMatrix();\r\n }\r\n\r\n return poseMatrix;\r\n }\r\n\r\n /**\r\n * Sorts bones per internal index\r\n */\r\n public sortBones(): void {\r\n const bones = new Array<Bone>();\r\n const visited = new Array<boolean>(this.bones.length);\r\n for (let index = 0; index < this.bones.length; index++) {\r\n this._sortBones(index, bones, visited);\r\n }\r\n\r\n this.bones = bones;\r\n }\r\n\r\n private _sortBones(index: number, bones: Bone[], visited: boolean[]): void {\r\n if (visited[index]) {\r\n return;\r\n }\r\n\r\n visited[index] = true;\r\n\r\n const bone = this.bones[index];\r\n if (!bone) return;\r\n\r\n if (bone._index === undefined) {\r\n bone._index = index;\r\n }\r\n\r\n const parentBone = bone.getParent();\r\n if (parentBone) {\r\n this._sortBones(this.bones.indexOf(parentBone), bones, visited);\r\n }\r\n\r\n bones.push(bone);\r\n }\r\n\r\n /**\r\n * Set the current local matrix as the restPose for all bones in the skeleton.\r\n */\r\n public setCurrentPoseAsRest(): void {\r\n this.bones.forEach((b) => {\r\n b.setCurrentPoseAsRest();\r\n });\r\n }\r\n}\r\n"]}
@@ -324,7 +324,23 @@ export class WebDeviceInputSystem {
324
324
  }
325
325
  this._pointerMoveEvent = (evt) => {
326
326
  const deviceType = this._getPointerType(evt);
327
- const deviceSlot = deviceType === DeviceType.Mouse ? 0 : this._activeTouchIds.indexOf(evt.pointerId);
327
+ let deviceSlot = deviceType === DeviceType.Mouse ? 0 : this._activeTouchIds.indexOf(evt.pointerId);
328
+ // In the event that we're gettting pointermove events from touch inputs that we aren't tracking,
329
+ // look for an available slot and retroactively connect it.
330
+ if (deviceType === DeviceType.Touch && deviceSlot === -1) {
331
+ const idx = this._activeTouchIds.indexOf(-1);
332
+ if (idx >= 0) {
333
+ deviceSlot = idx;
334
+ this._activeTouchIds[idx] = evt.pointerId;
335
+ // Because this is a "new" input, inform the connected callback
336
+ this._onDeviceConnected(deviceType, deviceSlot);
337
+ }
338
+ else {
339
+ // We can't find an open slot to store new pointer so just return (can only support max number of touches)
340
+ Tools.Warn(`Max number of touches exceeded. Ignoring touches in excess of ${this._maxTouchPoints}`);
341
+ return;
342
+ }
343
+ }
328
344
  if (!this._inputs[deviceType]) {
329
345
  this._inputs[deviceType] = {};
330
346
  }
@@ -337,6 +353,10 @@ export class WebDeviceInputSystem {
337
353
  deviceEvent.inputIndex = PointerInput.Move;
338
354
  pointer[PointerInput.Horizontal] = evt.clientX;
339
355
  pointer[PointerInput.Vertical] = evt.clientY;
356
+ // For touches that aren't started with a down, we need to set the button state to 1
357
+ if (deviceType === DeviceType.Touch && pointer[PointerInput.LeftClick] === 0) {
358
+ pointer[PointerInput.LeftClick] = 1;
359
+ }
340
360
  if (evt.pointerId === undefined) {
341
361
  evt.pointerId = this._mouseId;
342
362
  }
@@ -422,6 +442,7 @@ export class WebDeviceInputSystem {
422
442
  const deviceType = this._getPointerType(evt);
423
443
  const deviceSlot = deviceType === DeviceType.Mouse ? 0 : this._activeTouchIds.indexOf(evt.pointerId);
424
444
  if (deviceType === DeviceType.Touch) {
445
+ // If we're getting a pointerup event for a touch that isn't active, just return.
425
446
  if (deviceSlot === -1) {
426
447
  return;
427
448
  }
@@ -477,6 +498,10 @@ export class WebDeviceInputSystem {
477
498
  }
478
499
  else {
479
500
  const deviceSlot = this._activeTouchIds.indexOf(evt.pointerId);
501
+ // If we're getting a pointercancel event for a touch that isn't active, just return
502
+ if (deviceSlot === -1) {
503
+ return;
504
+ }
480
505
  if ((_d = (_c = this._elementToAttachTo).hasPointerCapture) === null || _d === void 0 ? void 0 : _d.call(_c, evt.pointerId)) {
481
506
  this._elementToAttachTo.releasePointerCapture(evt.pointerId);
482
507
  }