1 |
- {"ast":null,"code":"import { Animation } from \"./animation.js\";\nimport { Observable } from \"../Misc/observable.js\";\nimport { EngineStore } from \"../Engines/engineStore.js\";\nimport { Tags } from \"../Misc/tags.js\";\nimport \"./animatable.js\";\n/**\n * This class defines the direct association between an animation and a target\n */\nexport class TargetedAnimation {\n /**\n * Returns the string \"TargetedAnimation\"\n * @returns \"TargetedAnimation\"\n */\n getClassName() {\n return \"TargetedAnimation\";\n }\n /**\n * Serialize the object\n * @returns the JSON object representing the current entity\n */\n serialize() {\n const serializationObject = {};\n serializationObject.animation = this.animation.serialize();\n serializationObject.targetId = this.target.id;\n return serializationObject;\n }\n}\n/**\n * Use this class to create coordinated animations on multiple targets\n */\nexport class AnimationGroup {\n /**\n * Gets or sets the mask associated with this animation group. This mask is used to filter which objects should be animated.\n */\n get mask() {\n return this._mask;\n }\n set mask(value) {\n if (this._mask === value) {\n return;\n }\n this._mask = value;\n this.syncWithMask(true);\n }\n /**\n * Makes sure that the animations are either played or stopped according to the animation group mask.\n * Note however that the call won't have any effect if the animation group has not been started yet.\n * @param forceUpdate If true, forces to loop over the animatables even if no mask is defined (used internally, you shouldn't need to use it). Default: false.\n */\n syncWithMask(forceUpdate = false) {\n if (!this.mask && !forceUpdate) {\n this._numActiveAnimatables = this._targetedAnimations.length;\n return;\n }\n this._numActiveAnimatables = 0;\n for (let i = 0; i < this._animatables.length; ++i) {\n const animatable = this._animatables[i];\n if (!this.mask || this.mask.disabled || this.mask.retainsTarget(animatable.target.name)) {\n this._numActiveAnimatables++;\n if (animatable.paused) {\n animatable.restart();\n }\n } else {\n if (!animatable.paused) {\n animatable.pause();\n }\n }\n }\n }\n /**\n * Removes all animations for the targets not retained by the animation group mask.\n * Use this function if you know you won't need those animations anymore and if you want to free memory.\n */\n removeUnmaskedAnimations() {\n if (!this.mask || this.mask.disabled) {\n return;\n }\n // Removes all animatables (in case the animation group has already been started)\n for (let i = 0; i < this._animatables.length; ++i) {\n const animatable = this._animatables[i];\n if (!this.mask.retainsTarget(animatable.target.name)) {\n animatable.stop();\n this._animatables.splice(i, 1);\n --i;\n }\n }\n // Removes the targeted animations\n for (let index = 0; index < this._targetedAnimations.length; index++) {\n const targetedAnimation = this._targetedAnimations[index];\n if (!this.mask.retainsTarget(targetedAnimation.target.name)) {\n this._targetedAnimations.splice(index, 1);\n --index;\n }\n }\n }\n /**\n * Gets or sets the first frame\n */\n get from() {\n return this._from;\n }\n set from(value) {\n if (this._from === value) {\n return;\n }\n this._from = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.fromFrame = this._from;\n }\n }\n /**\n * Gets or sets the last frame\n */\n get to() {\n return this._to;\n }\n set to(value) {\n if (this._to === value) {\n return;\n }\n this._to = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.toFrame = this._to;\n }\n }\n /**\n * Define if the animations are started\n */\n get isStarted() {\n return this._isStarted;\n }\n /**\n * Gets a value indicating that the current group is playing\n */\n get isPlaying() {\n return this._isStarted && !this._isPaused;\n }\n /**\n * Gets or sets the speed ratio to use for all animations\n */\n get speedRatio() {\n return this._speedRatio;\n }\n /**\n * Gets or sets the speed ratio to use for all animations\n */\n set speedRatio(value) {\n if (this._speedRatio === value) {\n return;\n }\n this._speedRatio = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.speedRatio = this._speedRatio;\n }\n }\n /**\n * Gets or sets if all animations should loop or not\n */\n get loopAnimation() {\n return this._loopAnimation;\n }\n set loopAnimation(value) {\n if (this._loopAnimation === value) {\n return;\n }\n this._loopAnimation = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.loopAnimation = this._loopAnimation;\n }\n }\n /**\n * Gets or sets if all animations should be evaluated additively\n */\n get isAdditive() {\n return this._isAdditive;\n }\n set isAdditive(value) {\n if (this._isAdditive === value) {\n return;\n }\n this._isAdditive = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.isAdditive = this._isAdditive;\n }\n }\n /**\n * Gets or sets the weight to apply to all animations of the group\n */\n get weight() {\n return this._weight;\n }\n set weight(value) {\n if (this._weight === value) {\n return;\n }\n this._weight = value;\n this.setWeightForAllAnimatables(this._weight);\n }\n /**\n * Gets the targeted animations for this animation group\n */\n get targetedAnimations() {\n return this._targetedAnimations;\n }\n /**\n * returning the list of animatables controlled by this animation group.\n */\n get animatables() {\n return this._animatables;\n }\n /**\n * Gets the list of target animations\n */\n get children() {\n return this._targetedAnimations;\n }\n /**\n * Gets or sets the order of play of the animation group (default: 0)\n */\n get playOrder() {\n return this._playOrder;\n }\n set playOrder(value) {\n if (this._playOrder === value) {\n return;\n }\n this._playOrder = value;\n if (this._animatables.length > 0) {\n for (let i = 0; i < this._animatables.length; i++) {\n this._animatables[i].playOrder = this._playOrder;\n }\n this._scene.sortActiveAnimatables();\n }\n }\n /**\n * Allows the animations of the animation group to blend with current running animations\n * Note that a null value means that each animation will use their own existing blending configuration (Animation.enableBlending)\n */\n get enableBlending() {\n return this._enableBlending;\n }\n set enableBlending(value) {\n if (this._enableBlending === value) {\n return;\n }\n this._enableBlending = value;\n if (value !== null) {\n for (let i = 0; i < this._targetedAnimations.length; ++i) {\n this._targetedAnimations[i].animation.enableBlending = value;\n }\n }\n }\n /**\n * Gets or sets the animation blending speed\n * Note that a null value means that each animation will use their own existing blending configuration (Animation.blendingSpeed)\n */\n get blendingSpeed() {\n return this._blendingSpeed;\n }\n set blendingSpeed(value) {\n if (this._blendingSpeed === value) {\n return;\n }\n this._blendingSpeed = value;\n if (value !== null) {\n for (let i = 0; i < this._targetedAnimations.length; ++i) {\n this._targetedAnimations[i].animation.blendingSpeed = value;\n }\n }\n }\n /**\n * Gets the length (in seconds) of the animation group\n * This function assumes that all animations are played at the same framePerSecond speed!\n * Note: you can only call this method after you've added at least one targeted animation!\n * @param from Starting frame range (default is AnimationGroup.from)\n * @param to Ending frame range (default is AnimationGroup.to)\n * @returns The length in seconds\n */\n getLength(from, to) {\n var _from, _to;\n from = (_from = from) !== null && _from !== void 0 ? _from : this._from;\n to = (_to = to) !== null && _to !== void 0 ? _to : this._to;\n const fps = this.targetedAnimations[0].animation.framePerSecond * this._speedRatio;\n return (to - from) / fps;\n }\n /**\n * Merge the array of animation groups into a new animation group\n * @param animationGroups List of animation groups to merge\n * @param disposeSource If true, animation groups will be disposed after being merged (default: true)\n * @param normalize If true, animation groups will be normalized before being merged, so that all animations have the same \"from\" and \"to\" frame (default: false)\n * @param weight Weight for the new animation group. If not provided, it will inherit the weight from the first animation group of the array\n * @returns The new animation group or null if no animation groups were passed\n */\n static MergeAnimationGroups(animationGroups, disposeSource = true, normalize = false, weight) {\n var _weight;\n if (animationGroups.length === 0) {\n return null;\n }\n weight = (_weight = weight) !== null && _weight !== void 0 ? _weight : animationGroups[0].weight;\n let beginFrame = Number.MAX_VALUE;\n let endFrame = -Number.MAX_VALUE;\n if (normalize) {\n for (const animationGroup of animationGroups) {\n if (animationGroup.from < beginFrame) {\n beginFrame = animationGroup.from;\n }\n if (animationGroup.to > endFrame) {\n endFrame = animationGroup.to;\n }\n }\n }\n const mergedAnimationGroup = new AnimationGroup(animationGroups[0].name + \"_merged\", animationGroups[0]._scene, weight);\n for (const animationGroup of animationGroups) {\n if (normalize) {\n animationGroup.normalize(beginFrame, endFrame);\n }\n for (const targetedAnimation of animationGroup.targetedAnimations) {\n mergedAnimationGroup.addTargetedAnimation(targetedAnimation.animation, targetedAnimation.target);\n }\n if (disposeSource) {\n animationGroup.dispose();\n }\n }\n return mergedAnimationGroup;\n }\n /**\n * Instantiates a new Animation Group.\n * This helps managing several animations at once.\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/groupAnimations\n * @param name Defines the name of the group\n * @param scene Defines the scene the group belongs to\n * @param weight Defines the weight to use for animations in the group (-1.0 by default, meaning \"no weight\")\n * @param playOrder Defines the order of play of the animation group (default is 0)\n */\n constructor( /** The name of the animation group */\n name, scene = null, weight = -1, playOrder = 0) {\n this.name = name;\n this._targetedAnimations = new Array();\n this._animatables = new Array();\n this._from = Number.MAX_VALUE;\n this._to = -Number.MAX_VALUE;\n this._speedRatio = 1;\n this._loopAnimation = false;\n this._isAdditive = false;\n this._weight = -1;\n this._playOrder = 0;\n this._enableBlending = null;\n this._blendingSpeed = null;\n this._numActiveAnimatables = 0;\n this._shouldStart = true;\n /** @internal */\n this._parentContainer = null;\n /**\n * This observable will notify when one animation have ended\n */\n this.onAnimationEndObservable = new Observable();\n /**\n * Observer raised when one animation loops\n */\n this.onAnimationLoopObservable = new Observable();\n /**\n * Observer raised when all animations have looped\n */\n this.onAnimationGroupLoopObservable = new Observable();\n /**\n * This observable will notify when all animations have ended.\n */\n this.onAnimationGroupEndObservable = new Observable();\n /**\n * This observable will notify when all animations have paused.\n */\n this.onAnimationGroupPauseObservable = new Observable();\n /**\n * This observable will notify when all animations are playing.\n */\n this.onAnimationGroupPlayObservable = new Observable();\n /**\n * Gets or sets an object used to store user defined information for the node\n */\n this.metadata = null;\n this._mask = null;\n this._animationLoopFlags = [];\n this._scene = scene || EngineStore.LastCreatedScene;\n this._weight = weight;\n this._playOrder = playOrder;\n this.uniqueId = this._scene.getUniqueId();\n this._scene.addAnimationGroup(this);\n }\n /**\n * Add an animation (with its target) in the group\n * @param animation defines the animation we want to add\n * @param target defines the target of the animation\n * @returns the TargetedAnimation object\n */\n addTargetedAnimation(animation, target) {\n const targetedAnimation = new TargetedAnimation();\n targetedAnimation.animation = animation;\n targetedAnimation.target = target;\n const keys = animation.getKeys();\n if (this._from > keys[0].frame) {\n this._from = keys[0].frame;\n }\n if (this._to < keys[keys.length - 1].frame) {\n this._to = keys[keys.length - 1].frame;\n }\n if (this._enableBlending !== null) {\n animation.enableBlending = this._enableBlending;\n }\n if (this._blendingSpeed !== null) {\n animation.blendingSpeed = this._blendingSpeed;\n }\n this._targetedAnimations.push(targetedAnimation);\n this._shouldStart = true;\n return targetedAnimation;\n }\n /**\n * Remove an animation from the group\n * @param animation defines the animation we want to remove\n */\n removeTargetedAnimation(animation) {\n for (let index = this._targetedAnimations.length - 1; index > -1; index--) {\n const targetedAnimation = this._targetedAnimations[index];\n if (targetedAnimation.animation === animation) {\n this._targetedAnimations.splice(index, 1);\n }\n }\n }\n /**\n * This function will normalize every animation in the group to make sure they all go from beginFrame to endFrame\n * It can add constant keys at begin or end\n * @param beginFrame defines the new begin frame for all animations or the smallest begin frame of all animations if null (defaults to null)\n * @param endFrame defines the new end frame for all animations or the largest end frame of all animations if null (defaults to null)\n * @returns the animation group\n */\n normalize(beginFrame = null, endFrame = null) {\n if (beginFrame == null) {\n beginFrame = this._from;\n }\n if (endFrame == null) {\n endFrame = this._to;\n }\n for (let index = 0; index < this._targetedAnimations.length; index++) {\n const targetedAnimation = this._targetedAnimations[index];\n const keys = targetedAnimation.animation.getKeys();\n const startKey = keys[0];\n const endKey = keys[keys.length - 1];\n if (startKey.frame > beginFrame) {\n const newKey = {\n frame: beginFrame,\n value: startKey.value,\n inTangent: startKey.inTangent,\n outTangent: startKey.outTangent,\n interpolation: startKey.interpolation\n };\n keys.splice(0, 0, newKey);\n }\n if (endKey.frame < endFrame) {\n const newKey = {\n frame: endFrame,\n value: endKey.value,\n inTangent: endKey.inTangent,\n outTangent: endKey.outTangent,\n interpolation: endKey.interpolation\n };\n keys.push(newKey);\n }\n }\n this._from = beginFrame;\n this._to = endFrame;\n return this;\n }\n _processLoop(animatable, targetedAnimation, index) {\n animatable.onAnimationLoop = () => {\n this.onAnimationLoopObservable.notifyObservers(targetedAnimation);\n if (this._animationLoopFlags[index]) {\n return;\n }\n this._animationLoopFlags[index] = true;\n this._animationLoopCount++;\n if (this._animationLoopCount === this._numActiveAnimatables) {\n this.onAnimationGroupLoopObservable.notifyObservers(this);\n this._animationLoopCount = 0;\n this._animationLoopFlags.length = 0;\n }\n };\n }\n /**\n * Start all animations on given targets\n * @param loop defines if animations must loop\n * @param speedRatio defines the ratio to apply to animation speed (1 by default)\n * @param from defines the from key (optional)\n * @param to defines the to key (optional)\n * @param isAdditive defines the additive state for the resulting animatables (optional)\n * @returns the current animation group\n */\n start(loop = false, speedRatio = 1, from, to, isAdditive) {\n if (this._isStarted || this._targetedAnimations.length === 0) {\n return this;\n }\n this._loopAnimation = loop;\n this._shouldStart = false;\n this._animationLoopCount = 0;\n this._animationLoopFlags.length = 0;\n for (let index = 0; index < this._targetedAnimations.length; index++) {\n const targetedAnimation = this._targetedAnimations[index];\n const animatable = this._scene.beginDirectAnimation(targetedAnimation.target, [targetedAnimation.animation], from !== undefined ? from : this._from, to !== undefined ? to : this._to, loop, speedRatio, undefined, undefined, isAdditive !== undefined ? isAdditive : this._isAdditive);\n animatable.weight = this._weight;\n animatable.playOrder = this._playOrder;\n animatable.onAnimationEnd = () => {\n this.onAnimationEndObservable.notifyObservers(targetedAnimation);\n this._checkAnimationGroupEnded(animatable);\n };\n this._processLoop(animatable, targetedAnimation, index);\n this._animatables.push(animatable);\n }\n this.syncWithMask();\n this._scene.sortActiveAnimatables();\n this._speedRatio = speedRatio;\n this._isStarted = true;\n this._isPaused = false;\n this.onAnimationGroupPlayObservable.notifyObservers(this);\n return this;\n }\n /**\n * Pause all animations\n * @returns the animation group\n */\n pause() {\n if (!this._isStarted) {\n return this;\n }\n this._isPaused = true;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.pause();\n }\n this.onAnimationGroupPauseObservable.notifyObservers(this);\n return this;\n }\n /**\n * Play all animations to initial state\n * This function will start() the animations if they were not started or will restart() them if they were paused\n * @param loop defines if animations must loop\n * @returns the animation group\n */\n play(loop) {\n // only if there are animatable available\n if (this.isStarted && this._animatables.length && !this._shouldStart) {\n if (loop !== undefined) {\n this.loopAnimation = loop;\n }\n this.restart();\n } else {\n this.stop();\n this.start(loop, this._speedRatio);\n }\n return this;\n }\n /**\n * Reset all animations to initial state\n * @returns the animation group\n */\n reset() {\n if (!this._isStarted) {\n this.play();\n this.goToFrame(0);\n this.stop(true);\n return this;\n }\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.reset();\n }\n return this;\n }\n /**\n * Restart animations from after pausing it\n * @returns the animation group\n */\n restart() {\n if (!this._isStarted) {\n return this;\n }\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.restart();\n }\n this.syncWithMask();\n this._isPaused = false;\n this.onAnimationGroupPlayObservable.notifyObservers(this);\n return this;\n }\n /**\n * Stop all animations\n * @param skipOnAnimationEnd defines if the system should not raise onAnimationEnd. Default is false\n * @returns the animation group\n */\n stop(skipOnAnimationEnd = false) {\n if (!this._isStarted) {\n return this;\n }\n const list = this._animatables.slice();\n for (let index = 0; index < list.length; index++) {\n list[index].stop(undefined, undefined, true, skipOnAnimationEnd);\n }\n // We will take care of removing all stopped animatables\n let curIndex = 0;\n for (let index = 0; index < this._scene._activeAnimatables.length; index++) {\n const animatable = this._scene._activeAnimatables[index];\n if (animatable._runtimeAnimations.length > 0) {\n this._scene._activeAnimatables[curIndex++] = animatable;\n } else if (skipOnAnimationEnd) {\n // We normally rely on the onAnimationEnd callback (assigned in the start function) to be notified when an animatable\n // ends and should be removed from the active animatables array. However, if the animatable is stopped with the skipOnAnimationEnd\n // flag set to true, then we need to explicitly remove it from the active animatables array.\n this._checkAnimationGroupEnded(animatable, skipOnAnimationEnd);\n }\n }\n this._scene._activeAnimatables.length = curIndex;\n this._isStarted = false;\n return this;\n }\n /**\n * Set animation weight for all animatables\n *\n * @since 6.12.4\n * You can pass the weight to the AnimationGroup constructor, or use the weight property to set it after the group has been created,\n * making it easier to define the overall animation weight than calling setWeightForAllAnimatables() after the animation group has been started\n * @param weight defines the weight to use\n * @returns the animationGroup\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-weights\n */\n setWeightForAllAnimatables(weight) {\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.weight = weight;\n }\n return this;\n }\n /**\n * Synchronize and normalize all animatables with a source animatable\n * @param root defines the root animatable to synchronize with (null to stop synchronizing)\n * @returns the animationGroup\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-weights\n */\n syncAllAnimationsWith(root) {\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.syncWith(root);\n }\n return this;\n }\n /**\n * Goes to a specific frame in this animation group. Note that the animation group must be in playing or paused status\n * @param frame the frame number to go to\n * @param useWeight defines whether the animation weight should be applied to the image to be jumped to (false by default)\n * @returns the animationGroup\n */\n goToFrame(frame, useWeight = false) {\n if (!this._isStarted) {\n return this;\n }\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.goToFrame(frame, useWeight);\n }\n return this;\n }\n /**\n * Helper to get the current frame. This will return 0 if the AnimationGroup is not running, and it might return wrong results if multiple animations are running in different frames.\n * @returns current animation frame.\n */\n getCurrentFrame() {\n var _this$animatables$;\n return ((_this$animatables$ = this.animatables[0]) === null || _this$animatables$ === void 0 ? void 0 : _this$animatables$.masterFrame) || 0;\n }\n /**\n * Dispose all associated resources\n */\n dispose() {\n if (this.isStarted) {\n this.stop();\n }\n this._targetedAnimations.length = 0;\n this._animatables.length = 0;\n // Remove from scene\n const index = this._scene.animationGroups.indexOf(this);\n if (index > -1) {\n this._scene.animationGroups.splice(index, 1);\n }\n if (this._parentContainer) {\n const index = this._parentContainer.animationGroups.indexOf(this);\n if (index > -1) {\n this._parentContainer.animationGroups.splice(index, 1);\n }\n this._parentContainer = null;\n }\n this.onAnimationEndObservable.clear();\n this.onAnimationGroupEndObservable.clear();\n this.onAnimationGroupPauseObservable.clear();\n this.onAnimationGroupPlayObservable.clear();\n this.onAnimationLoopObservable.clear();\n this.onAnimationGroupLoopObservable.clear();\n }\n _checkAnimationGroupEnded(animatable, skipOnAnimationEnd = false) {\n // animatable should be taken out of the array\n const idx = this._animatables.indexOf(animatable);\n if (idx > -1) {\n this._animatables.splice(idx, 1);\n }\n // all animatables were removed? animation group ended!\n if (this._animatables.length === this._targetedAnimations.length - this._numActiveAnimatables) {\n this._isStarted = false;\n if (!skipOnAnimationEnd) {\n this.onAnimationGroupEndObservable.notifyObservers(this);\n }\n this._animatables.length = 0;\n }\n }\n /**\n * Clone the current animation group and returns a copy\n * @param newName defines the name of the new group\n * @param targetConverter defines an optional function used to convert current animation targets to new ones\n * @param cloneAnimations defines if the animations should be cloned or referenced\n * @returns the new animation group\n */\n clone(newName, targetConverter, cloneAnimations = false) {\n const newGroup = new AnimationGroup(newName || this.name, this._scene, this._weight, this._playOrder);\n newGroup._from = this.from;\n newGroup._to = this.to;\n newGroup._speedRatio = this.speedRatio;\n newGroup._loopAnimation = this.loopAnimation;\n newGroup._isAdditive = this.isAdditive;\n newGroup._enableBlending = this.enableBlending;\n newGroup._blendingSpeed = this.blendingSpeed;\n newGroup.metadata = this.metadata;\n newGroup.mask = this.mask;\n for (const targetAnimation of this._targetedAnimations) {\n newGroup.addTargetedAnimation(cloneAnimations ? targetAnimation.animation.clone() : targetAnimation.animation, targetConverter ? targetConverter(targetAnimation.target) : targetAnimation.target);\n }\n return newGroup;\n }\n /**\n * Serializes the animationGroup to an object\n * @returns Serialized object\n */\n serialize() {\n const serializationObject = {};\n serializationObject.name = this.name;\n serializationObject.from = this.from;\n serializationObject.to = this.to;\n serializationObject.speedRatio = this.speedRatio;\n serializationObject.loopAnimation = this.loopAnimation;\n serializationObject.isAdditive = this.isAdditive;\n serializationObject.weight = this.weight;\n serializationObject.playOrder = this.playOrder;\n serializationObject.enableBlending = this.enableBlending;\n serializationObject.blendingSpeed = this.blendingSpeed;\n serializationObject.targetedAnimations = [];\n for (let targetedAnimationIndex = 0; targetedAnimationIndex < this.targetedAnimations.length; targetedAnimationIndex++) {\n const targetedAnimation = this.targetedAnimations[targetedAnimationIndex];\n serializationObject.targetedAnimations[targetedAnimationIndex] = targetedAnimation.serialize();\n }\n if (Tags && Tags.HasTags(this)) {\n serializationObject.tags = Tags.GetTags(this);\n }\n // Metadata\n if (this.metadata) {\n serializationObject.metadata = this.metadata;\n }\n return serializationObject;\n }\n // Statics\n /**\n * Returns a new AnimationGroup object parsed from the source provided.\n * @param parsedAnimationGroup defines the source\n * @param scene defines the scene that will receive the animationGroup\n * @returns a new AnimationGroup\n */\n static Parse(parsedAnimationGroup, scene) {\n const animationGroup = new AnimationGroup(parsedAnimationGroup.name, scene, parsedAnimationGroup.weight, parsedAnimationGroup.playOrder);\n for (let i = 0; i < parsedAnimationGroup.targetedAnimations.length; i++) {\n const targetedAnimation = parsedAnimationGroup.targetedAnimations[i];\n const animation = Animation.Parse(targetedAnimation.animation);\n const id = targetedAnimation.targetId;\n if (targetedAnimation.animation.property === \"influence\") {\n // morph target animation\n const morphTarget = scene.getMorphTargetById(id);\n if (morphTarget) {\n animationGroup.addTargetedAnimation(animation, morphTarget);\n }\n } else {\n const targetNode = scene.getNodeById(id);\n if (targetNode != null) {\n animationGroup.addTargetedAnimation(animation, targetNode);\n }\n }\n }\n if (Tags) {\n Tags.AddTagsTo(animationGroup, parsedAnimationGroup.tags);\n }\n if (parsedAnimationGroup.from !== null && parsedAnimationGroup.to !== null) {\n animationGroup.normalize(parsedAnimationGroup.from, parsedAnimationGroup.to);\n }\n if (parsedAnimationGroup.speedRatio !== undefined) {\n animationGroup._speedRatio = parsedAnimationGroup.speedRatio;\n }\n if (parsedAnimationGroup.loopAnimation !== undefined) {\n animationGroup._loopAnimation = parsedAnimationGroup.loopAnimation;\n }\n if (parsedAnimationGroup.isAdditive !== undefined) {\n animationGroup._isAdditive = parsedAnimationGroup.isAdditive;\n }\n if (parsedAnimationGroup.weight !== undefined) {\n animationGroup._weight = parsedAnimationGroup.weight;\n }\n if (parsedAnimationGroup.playOrder !== undefined) {\n animationGroup._playOrder = parsedAnimationGroup.playOrder;\n }\n if (parsedAnimationGroup.enableBlending !== undefined) {\n animationGroup._enableBlending = parsedAnimationGroup.enableBlending;\n }\n if (parsedAnimationGroup.blendingSpeed !== undefined) {\n animationGroup._blendingSpeed = parsedAnimationGroup.blendingSpeed;\n }\n if (parsedAnimationGroup.metadata !== undefined) {\n animationGroup.metadata = parsedAnimationGroup.metadata;\n }\n return animationGroup;\n }\n /** @internal */\n static MakeAnimationAdditive(sourceAnimationGroup, referenceFrameOrOptions, range, cloneOriginal = false, clonedName) {\n let options;\n if (typeof referenceFrameOrOptions === \"object\") {\n options = referenceFrameOrOptions;\n } else {\n options = {\n referenceFrame: referenceFrameOrOptions,\n range: range,\n cloneOriginalAnimationGroup: cloneOriginal,\n clonedAnimationName: clonedName\n };\n }\n let animationGroup = sourceAnimationGroup;\n if (options.cloneOriginalAnimationGroup) {\n animationGroup = sourceAnimationGroup.clone(options.clonedAnimationGroupName || animationGroup.name);\n }\n const targetedAnimations = animationGroup.targetedAnimations;\n for (let index = 0; index < targetedAnimations.length; index++) {\n const targetedAnimation = targetedAnimations[index];\n targetedAnimation.animation = Animation.MakeAnimationAdditive(targetedAnimation.animation, options);\n }\n animationGroup.isAdditive = true;\n if (options.clipKeys) {\n // We need to recalculate the from/to frames for the animation group because some keys may have been removed\n let from = Number.MAX_VALUE;\n let to = -Number.MAX_VALUE;\n const targetedAnimations = animationGroup.targetedAnimations;\n for (let index = 0; index < targetedAnimations.length; index++) {\n const targetedAnimation = targetedAnimations[index];\n const animation = targetedAnimation.animation;\n const keys = animation.getKeys();\n if (from > keys[0].frame) {\n from = keys[0].frame;\n }\n if (to < keys[keys.length - 1].frame) {\n to = keys[keys.length - 1].frame;\n }\n }\n animationGroup._from = from;\n animationGroup._to = to;\n }\n return animationGroup;\n }\n /**\n * Creates a new animation, keeping only the keys that are inside a given key range\n * @param sourceAnimationGroup defines the animation group on which to operate\n * @param fromKey defines the lower bound of the range\n * @param toKey defines the upper bound of the range\n * @param name defines the name of the new animation group. If not provided, use the same name as animationGroup\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the keys. Default is false, so animations will be cloned\n * @returns a new animation group stripped from all the keys outside the given range\n */\n static ClipKeys(sourceAnimationGroup, fromKey, toKey, name, dontCloneAnimations) {\n const animationGroup = sourceAnimationGroup.clone(name || sourceAnimationGroup.name);\n return AnimationGroup.ClipKeysInPlace(animationGroup, fromKey, toKey, dontCloneAnimations);\n }\n /**\n * Updates an existing animation, keeping only the keys that are inside a given key range\n * @param animationGroup defines the animation group on which to operate\n * @param fromKey defines the lower bound of the range\n * @param toKey defines the upper bound of the range\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the keys. Default is false, so animations will be cloned\n * @returns the animationGroup stripped from all the keys outside the given range\n */\n static ClipKeysInPlace(animationGroup, fromKey, toKey, dontCloneAnimations) {\n return AnimationGroup.ClipInPlace(animationGroup, fromKey, toKey, dontCloneAnimations, false);\n }\n /**\n * Creates a new animation, keeping only the frames that are inside a given frame range\n * @param sourceAnimationGroup defines the animation group on which to operate\n * @param fromFrame defines the lower bound of the range\n * @param toFrame defines the upper bound of the range\n * @param name defines the name of the new animation group. If not provided, use the same name as animationGroup\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the frames. Default is false, so animations will be cloned\n * @returns a new animation group stripped from all the frames outside the given range\n */\n static ClipFrames(sourceAnimationGroup, fromFrame, toFrame, name, dontCloneAnimations) {\n const animationGroup = sourceAnimationGroup.clone(name || sourceAnimationGroup.name);\n return AnimationGroup.ClipFramesInPlace(animationGroup, fromFrame, toFrame, dontCloneAnimations);\n }\n /**\n * Updates an existing animation, keeping only the frames that are inside a given frame range\n * @param animationGroup defines the animation group on which to operate\n * @param fromFrame defines the lower bound of the range\n * @param toFrame defines the upper bound of the range\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the frames. Default is false, so animations will be cloned\n * @returns the animationGroup stripped from all the frames outside the given range\n */\n static ClipFramesInPlace(animationGroup, fromFrame, toFrame, dontCloneAnimations) {\n return AnimationGroup.ClipInPlace(animationGroup, fromFrame, toFrame, dontCloneAnimations, true);\n }\n /**\n * Updates an existing animation, keeping only the keys that are inside a given key or frame range\n * @param animationGroup defines the animation group on which to operate\n * @param start defines the lower bound of the range\n * @param end defines the upper bound of the range\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the keys. Default is false, so animations will be cloned\n * @param useFrame defines if the range is defined by frame numbers or key indices (default is false which means use key indices)\n * @returns the animationGroup stripped from all the keys outside the given range\n */\n static ClipInPlace(animationGroup, start, end, dontCloneAnimations, useFrame = false) {\n let from = Number.MAX_VALUE;\n let to = -Number.MAX_VALUE;\n const targetedAnimations = animationGroup.targetedAnimations;\n for (let index = 0; index < targetedAnimations.length; index++) {\n const targetedAnimation = targetedAnimations[index];\n const animation = dontCloneAnimations ? targetedAnimation.animation : targetedAnimation.animation.clone();\n if (useFrame) {\n // Make sure we have keys corresponding to the bounds of the frame range\n animation.createKeyForFrame(start);\n animation.createKeyForFrame(end);\n }\n const keys = animation.getKeys();\n const newKeys = [];\n let startFrame = Number.MAX_VALUE;\n for (let k = 0; k < keys.length; k++) {\n const key = keys[k];\n if (!useFrame && k >= start && k <= end || useFrame && key.frame >= start && key.frame <= end) {\n const newKey = {\n frame: key.frame,\n value: key.value.clone ? key.value.clone() : key.value,\n inTangent: key.inTangent,\n outTangent: key.outTangent,\n interpolation: key.interpolation,\n lockedTangent: key.lockedTangent\n };\n if (startFrame === Number.MAX_VALUE) {\n startFrame = newKey.frame;\n }\n newKey.frame -= startFrame;\n newKeys.push(newKey);\n }\n }\n if (newKeys.length === 0) {\n targetedAnimations.splice(index, 1);\n index--;\n continue;\n }\n if (from > newKeys[0].frame) {\n from = newKeys[0].frame;\n }\n if (to < newKeys[newKeys.length - 1].frame) {\n to = newKeys[newKeys.length - 1].frame;\n }\n animation.setKeys(newKeys, true);\n targetedAnimation.animation = animation; // in case the animation has been cloned\n }\n animationGroup._from = from;\n animationGroup._to = to;\n return animationGroup;\n }\n /**\n * Returns the string \"AnimationGroup\"\n * @returns \"AnimationGroup\"\n */\n getClassName() {\n return \"AnimationGroup\";\n }\n /**\n * Creates a detailed string about the object\n * @param fullDetails defines if the output string will support multiple levels of logging within scene loading\n * @returns a string representing the object\n */\n toString(fullDetails) {\n let ret = \"Name: \" + this.name;\n ret += \", type: \" + this.getClassName();\n if (fullDetails) {\n ret += \", from: \" + this._from;\n ret += \", to: \" + this._to;\n ret += \", isStarted: \" + this._isStarted;\n ret += \", speedRatio: \" + this._speedRatio;\n ret += \", targetedAnimations length: \" + this._targetedAnimations.length;\n ret += \", animatables length: \" + this._animatables;\n }\n return ret;\n }\n}","map":{"version":3,"names":["Animation","Observable","EngineStore","Tags","TargetedAnimation","getClassName","serialize","serializationObject","animation","targetId","target","id","AnimationGroup","mask","_mask","value","syncWithMask","forceUpdate","_numActiveAnimatables","_targetedAnimations","length","i","_animatables","animatable","disabled","retainsTarget","name","paused","restart","pause","removeUnmaskedAnimations","stop","splice","index","targetedAnimation","from","_from","fromFrame","to","_to","toFrame","isStarted","_isStarted","isPlaying","_isPaused","speedRatio","_speedRatio","loopAnimation","_loopAnimation","isAdditive","_isAdditive","weight","_weight","setWeightForAllAnimatables","targetedAnimations","animatables","children","playOrder","_playOrder","_scene","sortActiveAnimatables","enableBlending","_enableBlending","blendingSpeed","_blendingSpeed","getLength","fps","framePerSecond","MergeAnimationGroups","animationGroups","disposeSource","normalize","beginFrame","Number","MAX_VALUE","endFrame","animationGroup","mergedAnimationGroup","addTargetedAnimation","dispose","constructor","scene","Array","_shouldStart","_parentContainer","onAnimationEndObservable","onAnimationLoopObservable","onAnimationGroupLoopObservable","onAnimationGroupEndObservable","onAnimationGroupPauseObservable","onAnimationGroupPlayObservable","metadata","_animationLoopFlags","LastCreatedScene","uniqueId","getUniqueId","addAnimationGroup","keys","getKeys","frame","push","removeTargetedAnimation","startKey","endKey","newKey","inTangent","outTangent","interpolation","_processLoop","onAnimationLoop","notifyObservers","_animationLoopCount","start","loop","beginDirectAnimation","undefined","onAnimationEnd","_checkAnimationGroupEnded","play","reset","goToFrame","skipOnAnimationEnd","list","slice","curIndex","_activeAnimatables","_runtimeAnimations","syncAllAnimationsWith","root","syncWith","useWeight","getCurrentFrame","_this$animatables$","masterFrame","indexOf","clear","idx","clone","newName","targetConverter","cloneAnimations","newGroup","targetAnimation","targetedAnimationIndex","HasTags","tags","GetTags","Parse","parsedAnimationGroup","property","morphTarget","getMorphTargetById","targetNode","getNodeById","AddTagsTo","MakeAnimationAdditive","sourceAnimationGroup","referenceFrameOrOptions","range","cloneOriginal","clonedName","options","referenceFrame","cloneOriginalAnimationGroup","clonedAnimationName","clonedAnimationGroupName","clipKeys","ClipKeys","fromKey","toKey","dontCloneAnimations","ClipKeysInPlace","ClipInPlace","ClipFrames","ClipFramesInPlace","end","useFrame","createKeyForFrame","newKeys","startFrame","k","key","lockedTangent","setKeys","toString","fullDetails","ret"],"sources":["F:/workspace/202226701027/huinongbao-app/node_modules/@babylonjs/core/Animations/animationGroup.js"],"sourcesContent":["import { Animation } from \"./animation.js\";\nimport { Observable } from \"../Misc/observable.js\";\nimport { EngineStore } from \"../Engines/engineStore.js\";\nimport { Tags } from \"../Misc/tags.js\";\nimport \"./animatable.js\";\n/**\n * This class defines the direct association between an animation and a target\n */\nexport class TargetedAnimation {\n /**\n * Returns the string \"TargetedAnimation\"\n * @returns \"TargetedAnimation\"\n */\n getClassName() {\n return \"TargetedAnimation\";\n }\n /**\n * Serialize the object\n * @returns the JSON object representing the current entity\n */\n serialize() {\n const serializationObject = {};\n serializationObject.animation = this.animation.serialize();\n serializationObject.targetId = this.target.id;\n return serializationObject;\n }\n}\n/**\n * Use this class to create coordinated animations on multiple targets\n */\nexport class AnimationGroup {\n /**\n * Gets or sets the mask associated with this animation group. This mask is used to filter which objects should be animated.\n */\n get mask() {\n return this._mask;\n }\n set mask(value) {\n if (this._mask === value) {\n return;\n }\n this._mask = value;\n this.syncWithMask(true);\n }\n /**\n * Makes sure that the animations are either played or stopped according to the animation group mask.\n * Note however that the call won't have any effect if the animation group has not been started yet.\n * @param forceUpdate If true, forces to loop over the animatables even if no mask is defined (used internally, you shouldn't need to use it). Default: false.\n */\n syncWithMask(forceUpdate = false) {\n if (!this.mask && !forceUpdate) {\n this._numActiveAnimatables = this._targetedAnimations.length;\n return;\n }\n this._numActiveAnimatables = 0;\n for (let i = 0; i < this._animatables.length; ++i) {\n const animatable = this._animatables[i];\n if (!this.mask || this.mask.disabled || this.mask.retainsTarget(animatable.target.name)) {\n this._numActiveAnimatables++;\n if (animatable.paused) {\n animatable.restart();\n }\n }\n else {\n if (!animatable.paused) {\n animatable.pause();\n }\n }\n }\n }\n /**\n * Removes all animations for the targets not retained by the animation group mask.\n * Use this function if you know you won't need those animations anymore and if you want to free memory.\n */\n removeUnmaskedAnimations() {\n if (!this.mask || this.mask.disabled) {\n return;\n }\n // Removes all animatables (in case the animation group has already been started)\n for (let i = 0; i < this._animatables.length; ++i) {\n const animatable = this._animatables[i];\n if (!this.mask.retainsTarget(animatable.target.name)) {\n animatable.stop();\n this._animatables.splice(i, 1);\n --i;\n }\n }\n // Removes the targeted animations\n for (let index = 0; index < this._targetedAnimations.length; index++) {\n const targetedAnimation = this._targetedAnimations[index];\n if (!this.mask.retainsTarget(targetedAnimation.target.name)) {\n this._targetedAnimations.splice(index, 1);\n --index;\n }\n }\n }\n /**\n * Gets or sets the first frame\n */\n get from() {\n return this._from;\n }\n set from(value) {\n if (this._from === value) {\n return;\n }\n this._from = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.fromFrame = this._from;\n }\n }\n /**\n * Gets or sets the last frame\n */\n get to() {\n return this._to;\n }\n set to(value) {\n if (this._to === value) {\n return;\n }\n this._to = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.toFrame = this._to;\n }\n }\n /**\n * Define if the animations are started\n */\n get isStarted() {\n return this._isStarted;\n }\n /**\n * Gets a value indicating that the current group is playing\n */\n get isPlaying() {\n return this._isStarted && !this._isPaused;\n }\n /**\n * Gets or sets the speed ratio to use for all animations\n */\n get speedRatio() {\n return this._speedRatio;\n }\n /**\n * Gets or sets the speed ratio to use for all animations\n */\n set speedRatio(value) {\n if (this._speedRatio === value) {\n return;\n }\n this._speedRatio = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.speedRatio = this._speedRatio;\n }\n }\n /**\n * Gets or sets if all animations should loop or not\n */\n get loopAnimation() {\n return this._loopAnimation;\n }\n set loopAnimation(value) {\n if (this._loopAnimation === value) {\n return;\n }\n this._loopAnimation = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.loopAnimation = this._loopAnimation;\n }\n }\n /**\n * Gets or sets if all animations should be evaluated additively\n */\n get isAdditive() {\n return this._isAdditive;\n }\n set isAdditive(value) {\n if (this._isAdditive === value) {\n return;\n }\n this._isAdditive = value;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.isAdditive = this._isAdditive;\n }\n }\n /**\n * Gets or sets the weight to apply to all animations of the group\n */\n get weight() {\n return this._weight;\n }\n set weight(value) {\n if (this._weight === value) {\n return;\n }\n this._weight = value;\n this.setWeightForAllAnimatables(this._weight);\n }\n /**\n * Gets the targeted animations for this animation group\n */\n get targetedAnimations() {\n return this._targetedAnimations;\n }\n /**\n * returning the list of animatables controlled by this animation group.\n */\n get animatables() {\n return this._animatables;\n }\n /**\n * Gets the list of target animations\n */\n get children() {\n return this._targetedAnimations;\n }\n /**\n * Gets or sets the order of play of the animation group (default: 0)\n */\n get playOrder() {\n return this._playOrder;\n }\n set playOrder(value) {\n if (this._playOrder === value) {\n return;\n }\n this._playOrder = value;\n if (this._animatables.length > 0) {\n for (let i = 0; i < this._animatables.length; i++) {\n this._animatables[i].playOrder = this._playOrder;\n }\n this._scene.sortActiveAnimatables();\n }\n }\n /**\n * Allows the animations of the animation group to blend with current running animations\n * Note that a null value means that each animation will use their own existing blending configuration (Animation.enableBlending)\n */\n get enableBlending() {\n return this._enableBlending;\n }\n set enableBlending(value) {\n if (this._enableBlending === value) {\n return;\n }\n this._enableBlending = value;\n if (value !== null) {\n for (let i = 0; i < this._targetedAnimations.length; ++i) {\n this._targetedAnimations[i].animation.enableBlending = value;\n }\n }\n }\n /**\n * Gets or sets the animation blending speed\n * Note that a null value means that each animation will use their own existing blending configuration (Animation.blendingSpeed)\n */\n get blendingSpeed() {\n return this._blendingSpeed;\n }\n set blendingSpeed(value) {\n if (this._blendingSpeed === value) {\n return;\n }\n this._blendingSpeed = value;\n if (value !== null) {\n for (let i = 0; i < this._targetedAnimations.length; ++i) {\n this._targetedAnimations[i].animation.blendingSpeed = value;\n }\n }\n }\n /**\n * Gets the length (in seconds) of the animation group\n * This function assumes that all animations are played at the same framePerSecond speed!\n * Note: you can only call this method after you've added at least one targeted animation!\n * @param from Starting frame range (default is AnimationGroup.from)\n * @param to Ending frame range (default is AnimationGroup.to)\n * @returns The length in seconds\n */\n getLength(from, to) {\n from = from ?? this._from;\n to = to ?? this._to;\n const fps = this.targetedAnimations[0].animation.framePerSecond * this._speedRatio;\n return (to - from) / fps;\n }\n /**\n * Merge the array of animation groups into a new animation group\n * @param animationGroups List of animation groups to merge\n * @param disposeSource If true, animation groups will be disposed after being merged (default: true)\n * @param normalize If true, animation groups will be normalized before being merged, so that all animations have the same \"from\" and \"to\" frame (default: false)\n * @param weight Weight for the new animation group. If not provided, it will inherit the weight from the first animation group of the array\n * @returns The new animation group or null if no animation groups were passed\n */\n static MergeAnimationGroups(animationGroups, disposeSource = true, normalize = false, weight) {\n if (animationGroups.length === 0) {\n return null;\n }\n weight = weight ?? animationGroups[0].weight;\n let beginFrame = Number.MAX_VALUE;\n let endFrame = -Number.MAX_VALUE;\n if (normalize) {\n for (const animationGroup of animationGroups) {\n if (animationGroup.from < beginFrame) {\n beginFrame = animationGroup.from;\n }\n if (animationGroup.to > endFrame) {\n endFrame = animationGroup.to;\n }\n }\n }\n const mergedAnimationGroup = new AnimationGroup(animationGroups[0].name + \"_merged\", animationGroups[0]._scene, weight);\n for (const animationGroup of animationGroups) {\n if (normalize) {\n animationGroup.normalize(beginFrame, endFrame);\n }\n for (const targetedAnimation of animationGroup.targetedAnimations) {\n mergedAnimationGroup.addTargetedAnimation(targetedAnimation.animation, targetedAnimation.target);\n }\n if (disposeSource) {\n animationGroup.dispose();\n }\n }\n return mergedAnimationGroup;\n }\n /**\n * Instantiates a new Animation Group.\n * This helps managing several animations at once.\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/groupAnimations\n * @param name Defines the name of the group\n * @param scene Defines the scene the group belongs to\n * @param weight Defines the weight to use for animations in the group (-1.0 by default, meaning \"no weight\")\n * @param playOrder Defines the order of play of the animation group (default is 0)\n */\n constructor(\n /** The name of the animation group */\n name, scene = null, weight = -1, playOrder = 0) {\n this.name = name;\n this._targetedAnimations = new Array();\n this._animatables = new Array();\n this._from = Number.MAX_VALUE;\n this._to = -Number.MAX_VALUE;\n this._speedRatio = 1;\n this._loopAnimation = false;\n this._isAdditive = false;\n this._weight = -1;\n this._playOrder = 0;\n this._enableBlending = null;\n this._blendingSpeed = null;\n this._numActiveAnimatables = 0;\n this._shouldStart = true;\n /** @internal */\n this._parentContainer = null;\n /**\n * This observable will notify when one animation have ended\n */\n this.onAnimationEndObservable = new Observable();\n /**\n * Observer raised when one animation loops\n */\n this.onAnimationLoopObservable = new Observable();\n /**\n * Observer raised when all animations have looped\n */\n this.onAnimationGroupLoopObservable = new Observable();\n /**\n * This observable will notify when all animations have ended.\n */\n this.onAnimationGroupEndObservable = new Observable();\n /**\n * This observable will notify when all animations have paused.\n */\n this.onAnimationGroupPauseObservable = new Observable();\n /**\n * This observable will notify when all animations are playing.\n */\n this.onAnimationGroupPlayObservable = new Observable();\n /**\n * Gets or sets an object used to store user defined information for the node\n */\n this.metadata = null;\n this._mask = null;\n this._animationLoopFlags = [];\n this._scene = scene || EngineStore.LastCreatedScene;\n this._weight = weight;\n this._playOrder = playOrder;\n this.uniqueId = this._scene.getUniqueId();\n this._scene.addAnimationGroup(this);\n }\n /**\n * Add an animation (with its target) in the group\n * @param animation defines the animation we want to add\n * @param target defines the target of the animation\n * @returns the TargetedAnimation object\n */\n addTargetedAnimation(animation, target) {\n const targetedAnimation = new TargetedAnimation();\n targetedAnimation.animation = animation;\n targetedAnimation.target = target;\n const keys = animation.getKeys();\n if (this._from > keys[0].frame) {\n this._from = keys[0].frame;\n }\n if (this._to < keys[keys.length - 1].frame) {\n this._to = keys[keys.length - 1].frame;\n }\n if (this._enableBlending !== null) {\n animation.enableBlending = this._enableBlending;\n }\n if (this._blendingSpeed !== null) {\n animation.blendingSpeed = this._blendingSpeed;\n }\n this._targetedAnimations.push(targetedAnimation);\n this._shouldStart = true;\n return targetedAnimation;\n }\n /**\n * Remove an animation from the group\n * @param animation defines the animation we want to remove\n */\n removeTargetedAnimation(animation) {\n for (let index = this._targetedAnimations.length - 1; index > -1; index--) {\n const targetedAnimation = this._targetedAnimations[index];\n if (targetedAnimation.animation === animation) {\n this._targetedAnimations.splice(index, 1);\n }\n }\n }\n /**\n * This function will normalize every animation in the group to make sure they all go from beginFrame to endFrame\n * It can add constant keys at begin or end\n * @param beginFrame defines the new begin frame for all animations or the smallest begin frame of all animations if null (defaults to null)\n * @param endFrame defines the new end frame for all animations or the largest end frame of all animations if null (defaults to null)\n * @returns the animation group\n */\n normalize(beginFrame = null, endFrame = null) {\n if (beginFrame == null) {\n beginFrame = this._from;\n }\n if (endFrame == null) {\n endFrame = this._to;\n }\n for (let index = 0; index < this._targetedAnimations.length; index++) {\n const targetedAnimation = this._targetedAnimations[index];\n const keys = targetedAnimation.animation.getKeys();\n const startKey = keys[0];\n const endKey = keys[keys.length - 1];\n if (startKey.frame > beginFrame) {\n const newKey = {\n frame: beginFrame,\n value: startKey.value,\n inTangent: startKey.inTangent,\n outTangent: startKey.outTangent,\n interpolation: startKey.interpolation,\n };\n keys.splice(0, 0, newKey);\n }\n if (endKey.frame < endFrame) {\n const newKey = {\n frame: endFrame,\n value: endKey.value,\n inTangent: endKey.inTangent,\n outTangent: endKey.outTangent,\n interpolation: endKey.interpolation,\n };\n keys.push(newKey);\n }\n }\n this._from = beginFrame;\n this._to = endFrame;\n return this;\n }\n _processLoop(animatable, targetedAnimation, index) {\n animatable.onAnimationLoop = () => {\n this.onAnimationLoopObservable.notifyObservers(targetedAnimation);\n if (this._animationLoopFlags[index]) {\n return;\n }\n this._animationLoopFlags[index] = true;\n this._animationLoopCount++;\n if (this._animationLoopCount === this._numActiveAnimatables) {\n this.onAnimationGroupLoopObservable.notifyObservers(this);\n this._animationLoopCount = 0;\n this._animationLoopFlags.length = 0;\n }\n };\n }\n /**\n * Start all animations on given targets\n * @param loop defines if animations must loop\n * @param speedRatio defines the ratio to apply to animation speed (1 by default)\n * @param from defines the from key (optional)\n * @param to defines the to key (optional)\n * @param isAdditive defines the additive state for the resulting animatables (optional)\n * @returns the current animation group\n */\n start(loop = false, speedRatio = 1, from, to, isAdditive) {\n if (this._isStarted || this._targetedAnimations.length === 0) {\n return this;\n }\n this._loopAnimation = loop;\n this._shouldStart = false;\n this._animationLoopCount = 0;\n this._animationLoopFlags.length = 0;\n for (let index = 0; index < this._targetedAnimations.length; index++) {\n const targetedAnimation = this._targetedAnimations[index];\n const animatable = this._scene.beginDirectAnimation(targetedAnimation.target, [targetedAnimation.animation], from !== undefined ? from : this._from, to !== undefined ? to : this._to, loop, speedRatio, undefined, undefined, isAdditive !== undefined ? isAdditive : this._isAdditive);\n animatable.weight = this._weight;\n animatable.playOrder = this._playOrder;\n animatable.onAnimationEnd = () => {\n this.onAnimationEndObservable.notifyObservers(targetedAnimation);\n this._checkAnimationGroupEnded(animatable);\n };\n this._processLoop(animatable, targetedAnimation, index);\n this._animatables.push(animatable);\n }\n this.syncWithMask();\n this._scene.sortActiveAnimatables();\n this._speedRatio = speedRatio;\n this._isStarted = true;\n this._isPaused = false;\n this.onAnimationGroupPlayObservable.notifyObservers(this);\n return this;\n }\n /**\n * Pause all animations\n * @returns the animation group\n */\n pause() {\n if (!this._isStarted) {\n return this;\n }\n this._isPaused = true;\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.pause();\n }\n this.onAnimationGroupPauseObservable.notifyObservers(this);\n return this;\n }\n /**\n * Play all animations to initial state\n * This function will start() the animations if they were not started or will restart() them if they were paused\n * @param loop defines if animations must loop\n * @returns the animation group\n */\n play(loop) {\n // only if there are animatable available\n if (this.isStarted && this._animatables.length && !this._shouldStart) {\n if (loop !== undefined) {\n this.loopAnimation = loop;\n }\n this.restart();\n }\n else {\n this.stop();\n this.start(loop, this._speedRatio);\n }\n return this;\n }\n /**\n * Reset all animations to initial state\n * @returns the animation group\n */\n reset() {\n if (!this._isStarted) {\n this.play();\n this.goToFrame(0);\n this.stop(true);\n return this;\n }\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.reset();\n }\n return this;\n }\n /**\n * Restart animations from after pausing it\n * @returns the animation group\n */\n restart() {\n if (!this._isStarted) {\n return this;\n }\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.restart();\n }\n this.syncWithMask();\n this._isPaused = false;\n this.onAnimationGroupPlayObservable.notifyObservers(this);\n return this;\n }\n /**\n * Stop all animations\n * @param skipOnAnimationEnd defines if the system should not raise onAnimationEnd. Default is false\n * @returns the animation group\n */\n stop(skipOnAnimationEnd = false) {\n if (!this._isStarted) {\n return this;\n }\n const list = this._animatables.slice();\n for (let index = 0; index < list.length; index++) {\n list[index].stop(undefined, undefined, true, skipOnAnimationEnd);\n }\n // We will take care of removing all stopped animatables\n let curIndex = 0;\n for (let index = 0; index < this._scene._activeAnimatables.length; index++) {\n const animatable = this._scene._activeAnimatables[index];\n if (animatable._runtimeAnimations.length > 0) {\n this._scene._activeAnimatables[curIndex++] = animatable;\n }\n else if (skipOnAnimationEnd) {\n // We normally rely on the onAnimationEnd callback (assigned in the start function) to be notified when an animatable\n // ends and should be removed from the active animatables array. However, if the animatable is stopped with the skipOnAnimationEnd\n // flag set to true, then we need to explicitly remove it from the active animatables array.\n this._checkAnimationGroupEnded(animatable, skipOnAnimationEnd);\n }\n }\n this._scene._activeAnimatables.length = curIndex;\n this._isStarted = false;\n return this;\n }\n /**\n * Set animation weight for all animatables\n *\n * @since 6.12.4\n * You can pass the weight to the AnimationGroup constructor, or use the weight property to set it after the group has been created,\n * making it easier to define the overall animation weight than calling setWeightForAllAnimatables() after the animation group has been started\n * @param weight defines the weight to use\n * @returns the animationGroup\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-weights\n */\n setWeightForAllAnimatables(weight) {\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.weight = weight;\n }\n return this;\n }\n /**\n * Synchronize and normalize all animatables with a source animatable\n * @param root defines the root animatable to synchronize with (null to stop synchronizing)\n * @returns the animationGroup\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-weights\n */\n syncAllAnimationsWith(root) {\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.syncWith(root);\n }\n return this;\n }\n /**\n * Goes to a specific frame in this animation group. Note that the animation group must be in playing or paused status\n * @param frame the frame number to go to\n * @param useWeight defines whether the animation weight should be applied to the image to be jumped to (false by default)\n * @returns the animationGroup\n */\n goToFrame(frame, useWeight = false) {\n if (!this._isStarted) {\n return this;\n }\n for (let index = 0; index < this._animatables.length; index++) {\n const animatable = this._animatables[index];\n animatable.goToFrame(frame, useWeight);\n }\n return this;\n }\n /**\n * Helper to get the current frame. This will return 0 if the AnimationGroup is not running, and it might return wrong results if multiple animations are running in different frames.\n * @returns current animation frame.\n */\n getCurrentFrame() {\n return this.animatables[0]?.masterFrame || 0;\n }\n /**\n * Dispose all associated resources\n */\n dispose() {\n if (this.isStarted) {\n this.stop();\n }\n this._targetedAnimations.length = 0;\n this._animatables.length = 0;\n // Remove from scene\n const index = this._scene.animationGroups.indexOf(this);\n if (index > -1) {\n this._scene.animationGroups.splice(index, 1);\n }\n if (this._parentContainer) {\n const index = this._parentContainer.animationGroups.indexOf(this);\n if (index > -1) {\n this._parentContainer.animationGroups.splice(index, 1);\n }\n this._parentContainer = null;\n }\n this.onAnimationEndObservable.clear();\n this.onAnimationGroupEndObservable.clear();\n this.onAnimationGroupPauseObservable.clear();\n this.onAnimationGroupPlayObservable.clear();\n this.onAnimationLoopObservable.clear();\n this.onAnimationGroupLoopObservable.clear();\n }\n _checkAnimationGroupEnded(animatable, skipOnAnimationEnd = false) {\n // animatable should be taken out of the array\n const idx = this._animatables.indexOf(animatable);\n if (idx > -1) {\n this._animatables.splice(idx, 1);\n }\n // all animatables were removed? animation group ended!\n if (this._animatables.length === this._targetedAnimations.length - this._numActiveAnimatables) {\n this._isStarted = false;\n if (!skipOnAnimationEnd) {\n this.onAnimationGroupEndObservable.notifyObservers(this);\n }\n this._animatables.length = 0;\n }\n }\n /**\n * Clone the current animation group and returns a copy\n * @param newName defines the name of the new group\n * @param targetConverter defines an optional function used to convert current animation targets to new ones\n * @param cloneAnimations defines if the animations should be cloned or referenced\n * @returns the new animation group\n */\n clone(newName, targetConverter, cloneAnimations = false) {\n const newGroup = new AnimationGroup(newName || this.name, this._scene, this._weight, this._playOrder);\n newGroup._from = this.from;\n newGroup._to = this.to;\n newGroup._speedRatio = this.speedRatio;\n newGroup._loopAnimation = this.loopAnimation;\n newGroup._isAdditive = this.isAdditive;\n newGroup._enableBlending = this.enableBlending;\n newGroup._blendingSpeed = this.blendingSpeed;\n newGroup.metadata = this.metadata;\n newGroup.mask = this.mask;\n for (const targetAnimation of this._targetedAnimations) {\n newGroup.addTargetedAnimation(cloneAnimations ? targetAnimation.animation.clone() : targetAnimation.animation, targetConverter ? targetConverter(targetAnimation.target) : targetAnimation.target);\n }\n return newGroup;\n }\n /**\n * Serializes the animationGroup to an object\n * @returns Serialized object\n */\n serialize() {\n const serializationObject = {};\n serializationObject.name = this.name;\n serializationObject.from = this.from;\n serializationObject.to = this.to;\n serializationObject.speedRatio = this.speedRatio;\n serializationObject.loopAnimation = this.loopAnimation;\n serializationObject.isAdditive = this.isAdditive;\n serializationObject.weight = this.weight;\n serializationObject.playOrder = this.playOrder;\n serializationObject.enableBlending = this.enableBlending;\n serializationObject.blendingSpeed = this.blendingSpeed;\n serializationObject.targetedAnimations = [];\n for (let targetedAnimationIndex = 0; targetedAnimationIndex < this.targetedAnimations.length; targetedAnimationIndex++) {\n const targetedAnimation = this.targetedAnimations[targetedAnimationIndex];\n serializationObject.targetedAnimations[targetedAnimationIndex] = targetedAnimation.serialize();\n }\n if (Tags && Tags.HasTags(this)) {\n serializationObject.tags = Tags.GetTags(this);\n }\n // Metadata\n if (this.metadata) {\n serializationObject.metadata = this.metadata;\n }\n return serializationObject;\n }\n // Statics\n /**\n * Returns a new AnimationGroup object parsed from the source provided.\n * @param parsedAnimationGroup defines the source\n * @param scene defines the scene that will receive the animationGroup\n * @returns a new AnimationGroup\n */\n static Parse(parsedAnimationGroup, scene) {\n const animationGroup = new AnimationGroup(parsedAnimationGroup.name, scene, parsedAnimationGroup.weight, parsedAnimationGroup.playOrder);\n for (let i = 0; i < parsedAnimationGroup.targetedAnimations.length; i++) {\n const targetedAnimation = parsedAnimationGroup.targetedAnimations[i];\n const animation = Animation.Parse(targetedAnimation.animation);\n const id = targetedAnimation.targetId;\n if (targetedAnimation.animation.property === \"influence\") {\n // morph target animation\n const morphTarget = scene.getMorphTargetById(id);\n if (morphTarget) {\n animationGroup.addTargetedAnimation(animation, morphTarget);\n }\n }\n else {\n const targetNode = scene.getNodeById(id);\n if (targetNode != null) {\n animationGroup.addTargetedAnimation(animation, targetNode);\n }\n }\n }\n if (Tags) {\n Tags.AddTagsTo(animationGroup, parsedAnimationGroup.tags);\n }\n if (parsedAnimationGroup.from !== null && parsedAnimationGroup.to !== null) {\n animationGroup.normalize(parsedAnimationGroup.from, parsedAnimationGroup.to);\n }\n if (parsedAnimationGroup.speedRatio !== undefined) {\n animationGroup._speedRatio = parsedAnimationGroup.speedRatio;\n }\n if (parsedAnimationGroup.loopAnimation !== undefined) {\n animationGroup._loopAnimation = parsedAnimationGroup.loopAnimation;\n }\n if (parsedAnimationGroup.isAdditive !== undefined) {\n animationGroup._isAdditive = parsedAnimationGroup.isAdditive;\n }\n if (parsedAnimationGroup.weight !== undefined) {\n animationGroup._weight = parsedAnimationGroup.weight;\n }\n if (parsedAnimationGroup.playOrder !== undefined) {\n animationGroup._playOrder = parsedAnimationGroup.playOrder;\n }\n if (parsedAnimationGroup.enableBlending !== undefined) {\n animationGroup._enableBlending = parsedAnimationGroup.enableBlending;\n }\n if (parsedAnimationGroup.blendingSpeed !== undefined) {\n animationGroup._blendingSpeed = parsedAnimationGroup.blendingSpeed;\n }\n if (parsedAnimationGroup.metadata !== undefined) {\n animationGroup.metadata = parsedAnimationGroup.metadata;\n }\n return animationGroup;\n }\n /** @internal */\n static MakeAnimationAdditive(sourceAnimationGroup, referenceFrameOrOptions, range, cloneOriginal = false, clonedName) {\n let options;\n if (typeof referenceFrameOrOptions === \"object\") {\n options = referenceFrameOrOptions;\n }\n else {\n options = {\n referenceFrame: referenceFrameOrOptions,\n range: range,\n cloneOriginalAnimationGroup: cloneOriginal,\n clonedAnimationName: clonedName,\n };\n }\n let animationGroup = sourceAnimationGroup;\n if (options.cloneOriginalAnimationGroup) {\n animationGroup = sourceAnimationGroup.clone(options.clonedAnimationGroupName || animationGroup.name);\n }\n const targetedAnimations = animationGroup.targetedAnimations;\n for (let index = 0; index < targetedAnimations.length; index++) {\n const targetedAnimation = targetedAnimations[index];\n targetedAnimation.animation = Animation.MakeAnimationAdditive(targetedAnimation.animation, options);\n }\n animationGroup.isAdditive = true;\n if (options.clipKeys) {\n // We need to recalculate the from/to frames for the animation group because some keys may have been removed\n let from = Number.MAX_VALUE;\n let to = -Number.MAX_VALUE;\n const targetedAnimations = animationGroup.targetedAnimations;\n for (let index = 0; index < targetedAnimations.length; index++) {\n const targetedAnimation = targetedAnimations[index];\n const animation = targetedAnimation.animation;\n const keys = animation.getKeys();\n if (from > keys[0].frame) {\n from = keys[0].frame;\n }\n if (to < keys[keys.length - 1].frame) {\n to = keys[keys.length - 1].frame;\n }\n }\n animationGroup._from = from;\n animationGroup._to = to;\n }\n return animationGroup;\n }\n /**\n * Creates a new animation, keeping only the keys that are inside a given key range\n * @param sourceAnimationGroup defines the animation group on which to operate\n * @param fromKey defines the lower bound of the range\n * @param toKey defines the upper bound of the range\n * @param name defines the name of the new animation group. If not provided, use the same name as animationGroup\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the keys. Default is false, so animations will be cloned\n * @returns a new animation group stripped from all the keys outside the given range\n */\n static ClipKeys(sourceAnimationGroup, fromKey, toKey, name, dontCloneAnimations) {\n const animationGroup = sourceAnimationGroup.clone(name || sourceAnimationGroup.name);\n return AnimationGroup.ClipKeysInPlace(animationGroup, fromKey, toKey, dontCloneAnimations);\n }\n /**\n * Updates an existing animation, keeping only the keys that are inside a given key range\n * @param animationGroup defines the animation group on which to operate\n * @param fromKey defines the lower bound of the range\n * @param toKey defines the upper bound of the range\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the keys. Default is false, so animations will be cloned\n * @returns the animationGroup stripped from all the keys outside the given range\n */\n static ClipKeysInPlace(animationGroup, fromKey, toKey, dontCloneAnimations) {\n return AnimationGroup.ClipInPlace(animationGroup, fromKey, toKey, dontCloneAnimations, false);\n }\n /**\n * Creates a new animation, keeping only the frames that are inside a given frame range\n * @param sourceAnimationGroup defines the animation group on which to operate\n * @param fromFrame defines the lower bound of the range\n * @param toFrame defines the upper bound of the range\n * @param name defines the name of the new animation group. If not provided, use the same name as animationGroup\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the frames. Default is false, so animations will be cloned\n * @returns a new animation group stripped from all the frames outside the given range\n */\n static ClipFrames(sourceAnimationGroup, fromFrame, toFrame, name, dontCloneAnimations) {\n const animationGroup = sourceAnimationGroup.clone(name || sourceAnimationGroup.name);\n return AnimationGroup.ClipFramesInPlace(animationGroup, fromFrame, toFrame, dontCloneAnimations);\n }\n /**\n * Updates an existing animation, keeping only the frames that are inside a given frame range\n * @param animationGroup defines the animation group on which to operate\n * @param fromFrame defines the lower bound of the range\n * @param toFrame defines the upper bound of the range\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the frames. Default is false, so animations will be cloned\n * @returns the animationGroup stripped from all the frames outside the given range\n */\n static ClipFramesInPlace(animationGroup, fromFrame, toFrame, dontCloneAnimations) {\n return AnimationGroup.ClipInPlace(animationGroup, fromFrame, toFrame, dontCloneAnimations, true);\n }\n /**\n * Updates an existing animation, keeping only the keys that are inside a given key or frame range\n * @param animationGroup defines the animation group on which to operate\n * @param start defines the lower bound of the range\n * @param end defines the upper bound of the range\n * @param dontCloneAnimations defines whether or not the animations should be cloned before clipping the keys. Default is false, so animations will be cloned\n * @param useFrame defines if the range is defined by frame numbers or key indices (default is false which means use key indices)\n * @returns the animationGroup stripped from all the keys outside the given range\n */\n static ClipInPlace(animationGroup, start, end, dontCloneAnimations, useFrame = false) {\n let from = Number.MAX_VALUE;\n let to = -Number.MAX_VALUE;\n const targetedAnimations = animationGroup.targetedAnimations;\n for (let index = 0; index < targetedAnimations.length; index++) {\n const targetedAnimation = targetedAnimations[index];\n const animation = dontCloneAnimations ? targetedAnimation.animation : targetedAnimation.animation.clone();\n if (useFrame) {\n // Make sure we have keys corresponding to the bounds of the frame range\n animation.createKeyForFrame(start);\n animation.createKeyForFrame(end);\n }\n const keys = animation.getKeys();\n const newKeys = [];\n let startFrame = Number.MAX_VALUE;\n for (let k = 0; k < keys.length; k++) {\n const key = keys[k];\n if ((!useFrame && k >= start && k <= end) || (useFrame && key.frame >= start && key.frame <= end)) {\n const newKey = {\n frame: key.frame,\n value: key.value.clone ? key.value.clone() : key.value,\n inTangent: key.inTangent,\n outTangent: key.outTangent,\n interpolation: key.interpolation,\n lockedTangent: key.lockedTangent,\n };\n if (startFrame === Number.MAX_VALUE) {\n startFrame = newKey.frame;\n }\n newKey.frame -= startFrame;\n newKeys.push(newKey);\n }\n }\n if (newKeys.length === 0) {\n targetedAnimations.splice(index, 1);\n index--;\n continue;\n }\n if (from > newKeys[0].frame) {\n from = newKeys[0].frame;\n }\n if (to < newKeys[newKeys.length - 1].frame) {\n to = newKeys[newKeys.length - 1].frame;\n }\n animation.setKeys(newKeys, true);\n targetedAnimation.animation = animation; // in case the animation has been cloned\n }\n animationGroup._from = from;\n animationGroup._to = to;\n return animationGroup;\n }\n /**\n * Returns the string \"AnimationGroup\"\n * @returns \"AnimationGroup\"\n */\n getClassName() {\n return \"AnimationGroup\";\n }\n /**\n * Creates a detailed string about the object\n * @param fullDetails defines if the output string will support multiple levels of logging within scene loading\n * @returns a string representing the object\n */\n toString(fullDetails) {\n let ret = \"Name: \" + this.name;\n ret += \", type: \" + this.getClassName();\n if (fullDetails) {\n ret += \", from: \" + this._from;\n ret += \", to: \" + this._to;\n ret += \", isStarted: \" + this._isStarted;\n ret += \", speedRatio: \" + this._speedRatio;\n ret += \", targetedAnimations length: \" + this._targetedAnimations.length;\n ret += \", animatables length: \" + this._animatables;\n }\n return ret;\n }\n}\n"],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}
|