e7feb03da28f6b1d1dea98b00b59405528874fe632c687a1c6cf7a69e30eda22.json 81 KB

1
  1. {"ast":null,"code":"import { Bone } from \"./bone.js\";\nimport { Observable } from \"../Misc/observable.js\";\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector.js\";\nimport { RawTexture } from \"../Materials/Textures/rawTexture.js\";\nimport { Animation } from \"../Animations/animation.js\";\nimport { AnimationRange } from \"../Animations/animationRange.js\";\nimport { EngineStore } from \"../Engines/engineStore.js\";\nimport { Logger } from \"../Misc/logger.js\";\nimport { DeepCopier } from \"../Misc/deepCopier.js\";\n/**\n * Class used to handle skinning animations\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons\n */\nexport class Skeleton {\n /**\n * Gets or sets a boolean indicating that bone matrices should be stored as a texture instead of using shader uniforms (default is true).\n * Please note that this option is not available if the hardware does not support it\n */\n get useTextureToStoreBoneMatrices() {\n return this._useTextureToStoreBoneMatrices;\n }\n set useTextureToStoreBoneMatrices(value) {\n this._useTextureToStoreBoneMatrices = value;\n this._markAsDirty();\n }\n /**\n * Gets or sets the animation properties override\n */\n get animationPropertiesOverride() {\n if (!this._animationPropertiesOverride) {\n return this._scene.animationPropertiesOverride;\n }\n return this._animationPropertiesOverride;\n }\n set animationPropertiesOverride(value) {\n this._animationPropertiesOverride = value;\n }\n /**\n * Gets a boolean indicating that the skeleton effectively stores matrices into a texture\n */\n get isUsingTextureForMatrices() {\n return this.useTextureToStoreBoneMatrices && this._canUseTextureForBones;\n }\n /**\n * Gets the unique ID of this skeleton\n */\n get uniqueId() {\n return this._uniqueId;\n }\n /**\n * Creates a new skeleton\n * @param name defines the skeleton name\n * @param id defines the skeleton Id\n * @param scene defines the hosting scene\n */\n constructor( /** defines the skeleton name */\n name, /** defines the skeleton Id */\n id, scene) {\n this.name = name;\n this.id = id;\n /**\n * Defines the list of child bones\n */\n this.bones = [];\n /**\n * Defines a boolean indicating if the root matrix is provided by meshes or by the current skeleton (this is the default value)\n */\n this.needInitialSkinMatrix = false;\n this._isDirty = true;\n this._meshesWithPoseMatrix = new Array();\n this._identity = Matrix.Identity();\n this._currentRenderId = -1;\n this._ranges = {};\n this._absoluteTransformIsDirty = true;\n this._canUseTextureForBones = false;\n this._uniqueId = 0;\n /** @internal */\n this._numBonesWithLinkedTransformNode = 0;\n /** @internal */\n this._hasWaitingData = null;\n /** @internal */\n this._parentContainer = null;\n /**\n * Specifies if the skeleton should be serialized\n */\n this.doNotSerialize = false;\n this._useTextureToStoreBoneMatrices = true;\n this._animationPropertiesOverride = null;\n // Events\n /**\n * An observable triggered before computing the skeleton's matrices\n */\n this.onBeforeComputeObservable = new Observable();\n this.bones = [];\n this._scene = scene || EngineStore.LastCreatedScene;\n this._uniqueId = this._scene.getUniqueId();\n this._scene.addSkeleton(this);\n //make sure it will recalculate the matrix next time prepare is called.\n this._isDirty = true;\n const engineCaps = this._scene.getEngine().getCaps();\n this._canUseTextureForBones = engineCaps.textureFloat && engineCaps.maxVertexTextureImageUnits > 0;\n }\n /**\n * Gets the current object class name.\n * @returns the class name\n */\n getClassName() {\n return \"Skeleton\";\n }\n /**\n * Returns an array containing the root bones\n * @returns an array containing the root bones\n */\n getChildren() {\n return this.bones.filter(b => !b.getParent());\n }\n // Members\n /**\n * Gets the list of transform matrices to send to shaders (one matrix per bone)\n * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\n * @returns a Float32Array containing matrices data\n */\n getTransformMatrices(mesh) {\n if (this.needInitialSkinMatrix) {\n if (!mesh) {\n throw new Error(\"getTransformMatrices: When using the needInitialSkinMatrix flag, a mesh must be provided\");\n }\n if (!mesh._bonesTransformMatrices) {\n this.prepare(true);\n }\n return mesh._bonesTransformMatrices;\n }\n if (!this._transformMatrices || this._isDirty) {\n this.prepare(!this._transformMatrices);\n }\n return this._transformMatrices;\n }\n /**\n * Gets the list of transform matrices to send to shaders inside a texture (one matrix per bone)\n * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\n * @returns a raw texture containing the data\n */\n getTransformMatrixTexture(mesh) {\n if (this.needInitialSkinMatrix && mesh._transformMatrixTexture) {\n return mesh._transformMatrixTexture;\n }\n return this._transformMatrixTexture;\n }\n /**\n * Gets the current hosting scene\n * @returns a scene object\n */\n getScene() {\n return this._scene;\n }\n // Methods\n /**\n * Gets a string representing the current skeleton data\n * @param fullDetails defines a boolean indicating if we want a verbose version\n * @returns a string representing the current skeleton data\n */\n toString(fullDetails) {\n let ret = `Name: ${this.name}, nBones: ${this.bones.length}`;\n ret += `, nAnimationRanges: ${this._ranges ? Object.keys(this._ranges).length : \"none\"}`;\n if (fullDetails) {\n ret += \", Ranges: {\";\n let first = true;\n for (const name in this._ranges) {\n if (first) {\n ret += \", \";\n first = false;\n }\n ret += name;\n }\n ret += \"}\";\n }\n return ret;\n }\n /**\n * Get bone's index searching by name\n * @param name defines bone's name to search for\n * @returns the indice of the bone. Returns -1 if not found\n */\n getBoneIndexByName(name) {\n for (let boneIndex = 0, cache = this.bones.length; boneIndex < cache; boneIndex++) {\n if (this.bones[boneIndex].name === name) {\n return boneIndex;\n }\n }\n return -1;\n }\n /**\n * Create a new animation range\n * @param name defines the name of the range\n * @param from defines the start key\n * @param to defines the end key\n */\n createAnimationRange(name, from, to) {\n // check name not already in use\n if (!this._ranges[name]) {\n this._ranges[name] = new AnimationRange(name, from, to);\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\n if (this.bones[i].animations[0]) {\n this.bones[i].animations[0].createRange(name, from, to);\n }\n }\n }\n }\n /**\n * Delete a specific animation range\n * @param name defines the name of the range\n * @param deleteFrames defines if frames must be removed as well\n */\n deleteAnimationRange(name, deleteFrames = true) {\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\n if (this.bones[i].animations[0]) {\n this.bones[i].animations[0].deleteRange(name, deleteFrames);\n }\n }\n this._ranges[name] = null; // said much faster than 'delete this._range[name]'\n }\n /**\n * Gets a specific animation range\n * @param name defines the name of the range to look for\n * @returns the requested animation range or null if not found\n */\n getAnimationRange(name) {\n return this._ranges[name] || null;\n }\n /**\n * Gets the list of all animation ranges defined on this skeleton\n * @returns an array\n */\n getAnimationRanges() {\n const animationRanges = [];\n let name;\n for (name in this._ranges) {\n animationRanges.push(this._ranges[name]);\n }\n return animationRanges;\n }\n /**\n * Copy animation range from a source skeleton.\n * This is not for a complete retargeting, only between very similar skeleton's with only possible bone length differences\n * @param source defines the source skeleton\n * @param name defines the name of the range to copy\n * @param rescaleAsRequired defines if rescaling must be applied if required\n * @returns true if operation was successful\n */\n copyAnimationRange(source, name, rescaleAsRequired = false) {\n if (this._ranges[name] || !source.getAnimationRange(name)) {\n return false;\n }\n let ret = true;\n const frameOffset = this._getHighestAnimationFrame() + 1;\n // make a dictionary of source skeleton's bones, so exact same order or doubly nested loop is not required\n const boneDict = {};\n const sourceBones = source.bones;\n let nBones;\n let i;\n for (i = 0, nBones = sourceBones.length; i < nBones; i++) {\n boneDict[sourceBones[i].name] = sourceBones[i];\n }\n if (this.bones.length !== sourceBones.length) {\n Logger.Warn(`copyAnimationRange: this rig has ${this.bones.length} bones, while source as ${sourceBones.length}`);\n ret = false;\n }\n const skelDimensionsRatio = rescaleAsRequired && this.dimensionsAtRest && source.dimensionsAtRest ? this.dimensionsAtRest.divide(source.dimensionsAtRest) : null;\n for (i = 0, nBones = this.bones.length; i < nBones; i++) {\n const boneName = this.bones[i].name;\n const sourceBone = boneDict[boneName];\n if (sourceBone) {\n ret = ret && this.bones[i].copyAnimationRange(sourceBone, name, frameOffset, rescaleAsRequired, skelDimensionsRatio);\n } else {\n Logger.Warn(\"copyAnimationRange: not same rig, missing source bone \" + boneName);\n ret = false;\n }\n }\n // do not call createAnimationRange(), since it also is done to bones, which was already done\n const range = source.getAnimationRange(name);\n if (range) {\n this._ranges[name] = new AnimationRange(name, range.from + frameOffset, range.to + frameOffset);\n }\n return ret;\n }\n /**\n * Forces the skeleton to go to rest pose\n */\n returnToRest() {\n for (const bone of this.bones) {\n if (bone._index !== -1) {\n bone.returnToRest();\n }\n }\n }\n _getHighestAnimationFrame() {\n let ret = 0;\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\n if (this.bones[i].animations[0]) {\n const highest = this.bones[i].animations[0].getHighestFrame();\n if (ret < highest) {\n ret = highest;\n }\n }\n }\n return ret;\n }\n /**\n * Begin a specific animation range\n * @param name defines the name of the range to start\n * @param loop defines if looping must be turned on (false by default)\n * @param speedRatio defines the speed ratio to apply (1 by default)\n * @param onAnimationEnd defines a callback which will be called when animation will end\n * @returns a new animatable\n */\n beginAnimation(name, loop, speedRatio, onAnimationEnd) {\n const range = this.getAnimationRange(name);\n if (!range) {\n return null;\n }\n return this._scene.beginAnimation(this, range.from, range.to, loop, speedRatio, onAnimationEnd);\n }\n /**\n * Convert the keyframes for a range of animation on a skeleton to be relative to a given reference frame.\n * @param skeleton defines the Skeleton containing the animation range to convert\n * @param referenceFrame defines the frame that keyframes in the range will be relative to\n * @param range defines the name of the AnimationRange belonging to the Skeleton to convert\n * @returns the original skeleton\n */\n static MakeAnimationAdditive(skeleton, referenceFrame = 0, range) {\n const rangeValue = skeleton.getAnimationRange(range);\n // We can't make a range additive if it doesn't exist\n if (!rangeValue) {\n return null;\n }\n // Find any current scene-level animatable belonging to the target that matches the range\n const sceneAnimatables = skeleton._scene.getAllAnimatablesByTarget(skeleton);\n let rangeAnimatable = null;\n for (let index = 0; index < sceneAnimatables.length; index++) {\n const sceneAnimatable = sceneAnimatables[index];\n if (sceneAnimatable.fromFrame === (rangeValue === null || rangeValue === void 0 ? void 0 : rangeValue.from) && sceneAnimatable.toFrame === (rangeValue === null || rangeValue === void 0 ? void 0 : rangeValue.to)) {\n rangeAnimatable = sceneAnimatable;\n break;\n }\n }\n // Convert the animations belonging to the skeleton to additive keyframes\n const animatables = skeleton.getAnimatables();\n for (let index = 0; index < animatables.length; index++) {\n const animatable = animatables[index];\n const animations = animatable.animations;\n if (!animations) {\n continue;\n }\n for (let animIndex = 0; animIndex < animations.length; animIndex++) {\n Animation.MakeAnimationAdditive(animations[animIndex], referenceFrame, range);\n }\n }\n // Mark the scene-level animatable as additive\n if (rangeAnimatable) {\n rangeAnimatable.isAdditive = true;\n }\n return skeleton;\n }\n /** @internal */\n _markAsDirty() {\n this._isDirty = true;\n this._absoluteTransformIsDirty = true;\n }\n /**\n * @internal\n */\n _registerMeshWithPoseMatrix(mesh) {\n this._meshesWithPoseMatrix.push(mesh);\n }\n /**\n * @internal\n */\n _unregisterMeshWithPoseMatrix(mesh) {\n const index = this._meshesWithPoseMatrix.indexOf(mesh);\n if (index > -1) {\n this._meshesWithPoseMatrix.splice(index, 1);\n }\n }\n _computeTransformMatrices(targetMatrix, initialSkinMatrix) {\n this.onBeforeComputeObservable.notifyObservers(this);\n for (let index = 0; index < this.bones.length; index++) {\n const bone = this.bones[index];\n bone._childUpdateId++;\n const parentBone = bone.getParent();\n if (parentBone) {\n bone.getLocalMatrix().multiplyToRef(parentBone.getFinalMatrix(), bone.getFinalMatrix());\n } else {\n if (initialSkinMatrix) {\n bone.getLocalMatrix().multiplyToRef(initialSkinMatrix, bone.getFinalMatrix());\n } else {\n bone.getFinalMatrix().copyFrom(bone.getLocalMatrix());\n }\n }\n if (bone._index !== -1) {\n const mappedIndex = bone._index === null ? index : bone._index;\n bone.getAbsoluteInverseBindMatrix().multiplyToArray(bone.getFinalMatrix(), targetMatrix, mappedIndex * 16);\n }\n }\n this._identity.copyToArray(targetMatrix, this.bones.length * 16);\n }\n /**\n * Build all resources required to render a skeleton\n * @param dontCheckFrameId defines a boolean indicating if prepare should be run without checking first the current frame id (default: false)\n */\n prepare(dontCheckFrameId = false) {\n if (!dontCheckFrameId) {\n const currentRenderId = this.getScene().getRenderId();\n if (this._currentRenderId === currentRenderId) {\n return;\n }\n this._currentRenderId = currentRenderId;\n }\n // Update the local matrix of bones with linked transform nodes.\n if (this._numBonesWithLinkedTransformNode > 0) {\n for (const bone of this.bones) {\n if (bone._linkedTransformNode) {\n const node = bone._linkedTransformNode;\n bone.position = node.position;\n if (node.rotationQuaternion) {\n bone.rotationQuaternion = node.rotationQuaternion;\n } else {\n bone.rotation = node.rotation;\n }\n bone.scaling = node.scaling;\n }\n }\n }\n if (this.needInitialSkinMatrix) {\n for (const mesh of this._meshesWithPoseMatrix) {\n const poseMatrix = mesh.getPoseMatrix();\n let needsUpdate = this._isDirty;\n if (!mesh._bonesTransformMatrices || mesh._bonesTransformMatrices.length !== 16 * (this.bones.length + 1)) {\n mesh._bonesTransformMatrices = new Float32Array(16 * (this.bones.length + 1));\n needsUpdate = true;\n }\n if (!needsUpdate) {\n continue;\n }\n if (this._synchronizedWithMesh !== mesh) {\n this._synchronizedWithMesh = mesh;\n // Prepare bones\n for (const bone of this.bones) {\n if (!bone.getParent()) {\n const matrix = bone.getBindMatrix();\n matrix.multiplyToRef(poseMatrix, TmpVectors.Matrix[1]);\n bone._updateAbsoluteBindMatrices(TmpVectors.Matrix[1]);\n }\n }\n if (this.isUsingTextureForMatrices) {\n const textureWidth = (this.bones.length + 1) * 4;\n if (!mesh._transformMatrixTexture || mesh._transformMatrixTexture.getSize().width !== textureWidth) {\n if (mesh._transformMatrixTexture) {\n mesh._transformMatrixTexture.dispose();\n }\n mesh._transformMatrixTexture = RawTexture.CreateRGBATexture(mesh._bonesTransformMatrices, (this.bones.length + 1) * 4, 1, this._scene, false, false, 1, 1);\n }\n }\n }\n this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);\n if (this.isUsingTextureForMatrices && mesh._transformMatrixTexture) {\n mesh._transformMatrixTexture.update(mesh._bonesTransformMatrices);\n }\n }\n } else {\n if (!this._isDirty) {\n return;\n }\n if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {\n this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));\n if (this.isUsingTextureForMatrices) {\n if (this._transformMatrixTexture) {\n this._transformMatrixTexture.dispose();\n }\n this._transformMatrixTexture = RawTexture.CreateRGBATexture(this._transformMatrices, (this.bones.length + 1) * 4, 1, this._scene, false, false, 1, 1);\n }\n }\n this._computeTransformMatrices(this._transformMatrices, null);\n if (this.isUsingTextureForMatrices && this._transformMatrixTexture) {\n this._transformMatrixTexture.update(this._transformMatrices);\n }\n }\n this._isDirty = false;\n }\n /**\n * Gets the list of animatables currently running for this skeleton\n * @returns an array of animatables\n */\n getAnimatables() {\n if (!this._animatables || this._animatables.length !== this.bones.length) {\n this._animatables = [];\n for (let index = 0; index < this.bones.length; index++) {\n this._animatables.push(this.bones[index]);\n }\n }\n return this._animatables;\n }\n /**\n * Clone the current skeleton\n * @param name defines the name of the new skeleton\n * @param id defines the id of the new skeleton\n * @returns the new skeleton\n */\n clone(name, id) {\n const result = new Skeleton(name, id || name, this._scene);\n result.needInitialSkinMatrix = this.needInitialSkinMatrix;\n for (let index = 0; index < this.bones.length; index++) {\n const source = this.bones[index];\n let parentBone = null;\n const parent = source.getParent();\n if (parent) {\n const parentIndex = this.bones.indexOf(parent);\n parentBone = result.bones[parentIndex];\n }\n const bone = new Bone(source.name, result, parentBone, source.getBindMatrix().clone(), source.getRestMatrix().clone());\n bone._index = source._index;\n if (source._linkedTransformNode) {\n bone.linkTransformNode(source._linkedTransformNode);\n }\n DeepCopier.DeepCopy(source.animations, bone.animations);\n }\n if (this._ranges) {\n result._ranges = {};\n for (const rangeName in this._ranges) {\n const range = this._ranges[rangeName];\n if (range) {\n result._ranges[rangeName] = range.clone();\n }\n }\n }\n this._isDirty = true;\n result.prepare(true);\n return result;\n }\n /**\n * Enable animation blending for this skeleton\n * @param blendingSpeed defines the blending speed to apply\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-blending\n */\n enableBlending(blendingSpeed = 0.01) {\n this.bones.forEach(bone => {\n bone.animations.forEach(animation => {\n animation.enableBlending = true;\n animation.blendingSpeed = blendingSpeed;\n });\n });\n }\n /**\n * Releases all resources associated with the current skeleton\n */\n dispose() {\n this._meshesWithPoseMatrix.length = 0;\n // Animations\n this.getScene().stopAnimation(this);\n // Remove from scene\n this.getScene().removeSkeleton(this);\n if (this._parentContainer) {\n const index = this._parentContainer.skeletons.indexOf(this);\n if (index > -1) {\n this._parentContainer.skeletons.splice(index, 1);\n }\n this._parentContainer = null;\n }\n if (this._transformMatrixTexture) {\n this._transformMatrixTexture.dispose();\n this._transformMatrixTexture = null;\n }\n }\n /**\n * Serialize the skeleton in a JSON object\n * @returns a JSON object\n */\n serialize() {\n const serializationObject = {};\n serializationObject.name = this.name;\n serializationObject.id = this.id;\n if (this.dimensionsAtRest) {\n serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();\n }\n serializationObject.bones = [];\n serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;\n for (let index = 0; index < this.bones.length; index++) {\n var _bone$getTransformNod;\n const bone = this.bones[index];\n const parent = bone.getParent();\n const serializedBone = {\n parentBoneIndex: parent ? this.bones.indexOf(parent) : -1,\n index: bone.getIndex(),\n name: bone.name,\n id: bone.id,\n matrix: bone.getBindMatrix().asArray(),\n rest: bone.getRestMatrix().asArray(),\n linkedTransformNodeId: (_bone$getTransformNod = bone.getTransformNode()) === null || _bone$getTransformNod === void 0 ? void 0 : _bone$getTransformNod.id\n };\n serializationObject.bones.push(serializedBone);\n if (bone.length) {\n serializedBone.length = bone.length;\n }\n if (bone.metadata) {\n serializedBone.metadata = bone.metadata;\n }\n if (bone.animations && bone.animations.length > 0) {\n serializedBone.animation = bone.animations[0].serialize();\n }\n serializationObject.ranges = [];\n for (const name in this._ranges) {\n const source = this._ranges[name];\n if (!source) {\n continue;\n }\n const range = {};\n range.name = name;\n range.from = source.from;\n range.to = source.to;\n serializationObject.ranges.push(range);\n }\n }\n return serializationObject;\n }\n /**\n * Creates a new skeleton from serialized data\n * @param parsedSkeleton defines the serialized data\n * @param scene defines the hosting scene\n * @returns a new skeleton\n */\n static Parse(parsedSkeleton, scene) {\n const skeleton = new Skeleton(parsedSkeleton.name, parsedSkeleton.id, scene);\n if (parsedSkeleton.dimensionsAtRest) {\n skeleton.dimensionsAtRest = Vector3.FromArray(parsedSkeleton.dimensionsAtRest);\n }\n skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;\n let index;\n for (index = 0; index < parsedSkeleton.bones.length; index++) {\n const parsedBone = parsedSkeleton.bones[index];\n const parsedBoneIndex = parsedSkeleton.bones[index].index;\n let parentBone = null;\n if (parsedBone.parentBoneIndex > -1) {\n parentBone = skeleton.bones[parsedBone.parentBoneIndex];\n }\n const rest = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;\n const bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest, null, parsedBoneIndex);\n if (parsedBone.id !== undefined && parsedBone.id !== null) {\n bone.id = parsedBone.id;\n }\n if (parsedBone.length) {\n bone.length = parsedBone.length;\n }\n if (parsedBone.metadata) {\n bone.metadata = parsedBone.metadata;\n }\n if (parsedBone.animation) {\n bone.animations.push(Animation.Parse(parsedBone.animation));\n }\n if (parsedBone.linkedTransformNodeId !== undefined && parsedBone.linkedTransformNodeId !== null) {\n skeleton._hasWaitingData = true;\n bone._waitingTransformNodeId = parsedBone.linkedTransformNodeId;\n }\n }\n // placed after bones, so createAnimationRange can cascade down\n if (parsedSkeleton.ranges) {\n for (index = 0; index < parsedSkeleton.ranges.length; index++) {\n const data = parsedSkeleton.ranges[index];\n skeleton.createAnimationRange(data.name, data.from, data.to);\n }\n }\n return skeleton;\n }\n /**\n * Compute all node absolute matrices\n * @param forceUpdate defines if computation must be done even if cache is up to date\n */\n computeAbsoluteMatrices(forceUpdate = false) {\n if (this._absoluteTransformIsDirty || forceUpdate) {\n this.bones[0].computeAbsoluteMatrices();\n this._absoluteTransformIsDirty = false;\n }\n }\n /**\n * Compute all node absolute matrices\n * @param forceUpdate defines if computation must be done even if cache is up to date\n * @deprecated Please use computeAbsoluteMatrices instead\n */\n computeAbsoluteTransforms(forceUpdate = false) {\n this.computeAbsoluteMatrices(forceUpdate);\n }\n /**\n * Gets the root pose matrix\n * @returns a matrix\n */\n getPoseMatrix() {\n let poseMatrix = null;\n if (this._meshesWithPoseMatrix.length > 0) {\n poseMatrix = this._meshesWithPoseMatrix[0].getPoseMatrix();\n }\n return poseMatrix;\n }\n /**\n * Sorts bones per internal index\n */\n sortBones() {\n const bones = [];\n const visited = new Array(this.bones.length);\n for (let index = 0; index < this.bones.length; index++) {\n this._sortBones(index, bones, visited);\n }\n this.bones = bones;\n }\n _sortBones(index, bones, visited) {\n if (visited[index]) {\n return;\n }\n visited[index] = true;\n const bone = this.bones[index];\n if (!bone) return;\n if (bone._index === undefined) {\n bone._index = index;\n }\n const parentBone = bone.getParent();\n if (parentBone) {\n this._sortBones(this.bones.indexOf(parentBone), bones, visited);\n }\n bones.push(bone);\n }\n /**\n * Set the current local matrix as the restPose for all bones in the skeleton.\n */\n setCurrentPoseAsRest() {\n this.bones.forEach(b => {\n b.setCurrentPoseAsRest();\n });\n }\n}","map":{"version":3,"names":["Bone","Observable","Vector3","Matrix","TmpVectors","RawTexture","Animation","AnimationRange","EngineStore","Logger","DeepCopier","Skeleton","useTextureToStoreBoneMatrices","_useTextureToStoreBoneMatrices","value","_markAsDirty","animationPropertiesOverride","_animationPropertiesOverride","_scene","isUsingTextureForMatrices","_canUseTextureForBones","uniqueId","_uniqueId","constructor","name","id","scene","bones","needInitialSkinMatrix","_isDirty","_meshesWithPoseMatrix","Array","_identity","Identity","_currentRenderId","_ranges","_absoluteTransformIsDirty","_numBonesWithLinkedTransformNode","_hasWaitingData","_parentContainer","doNotSerialize","onBeforeComputeObservable","LastCreatedScene","getUniqueId","addSkeleton","engineCaps","getEngine","getCaps","textureFloat","maxVertexTextureImageUnits","getClassName","getChildren","filter","b","getParent","getTransformMatrices","mesh","Error","_bonesTransformMatrices","prepare","_transformMatrices","getTransformMatrixTexture","_transformMatrixTexture","getScene","toString","fullDetails","ret","length","Object","keys","first","getBoneIndexByName","boneIndex","cache","createAnimationRange","from","to","i","nBones","animations","createRange","deleteAnimationRange","deleteFrames","deleteRange","getAnimationRange","getAnimationRanges","animationRanges","push","copyAnimationRange","source","rescaleAsRequired","frameOffset","_getHighestAnimationFrame","boneDict","sourceBones","Warn","skelDimensionsRatio","dimensionsAtRest","divide","boneName","sourceBone","range","returnToRest","bone","_index","highest","getHighestFrame","beginAnimation","loop","speedRatio","onAnimationEnd","MakeAnimationAdditive","skeleton","referenceFrame","rangeValue","sceneAnimatables","getAllAnimatablesByTarget","rangeAnimatable","index","sceneAnimatable","fromFrame","toFrame","animatables","getAnimatables","animatable","animIndex","isAdditive","_registerMeshWithPoseMatrix","_unregisterMeshWithPoseMatrix","indexOf","splice","_computeTransformMatrices","targetMatrix","initialSkinMatrix","notifyObservers","_childUpdateId","parentBone","getLocalMatrix","multiplyToRef","getFinalMatrix","copyFrom","mappedIndex","getAbsoluteInverseBindMatrix","multiplyToArray","copyToArray","dontCheckFrameId","currentRenderId","getRenderId","_linkedTransformNode","node","position","rotationQuaternion","rotation","scaling","poseMatrix","getPoseMatrix","needsUpdate","Float32Array","_synchronizedWithMesh","matrix","getBindMatrix","_updateAbsoluteBindMatrices","textureWidth","getSize","width","dispose","CreateRGBATexture","update","_animatables","clone","result","parent","parentIndex","getRestMatrix","linkTransformNode","DeepCopy","rangeName","enableBlending","blendingSpeed","forEach","animation","stopAnimation","removeSkeleton","skeletons","serialize","serializationObject","asArray","_bone$getTransformNod","serializedBone","parentBoneIndex","getIndex","rest","linkedTransformNodeId","getTransformNode","metadata","ranges","Parse","parsedSkeleton","FromArray","parsedBone","parsedBoneIndex","undefined","_waitingTransformNodeId","data","computeAbsoluteMatrices","forceUpdate","computeAbsoluteTransforms","sortBones","visited","_sortBones","setCurrentPoseAsRest"],"sources":["F:/workspace/202226701027/huinongbao-app/node_modules/@babylonjs/core/Bones/skeleton.js"],"sourcesContent":["import { Bone } from \"./bone.js\";\nimport { Observable } from \"../Misc/observable.js\";\nimport { Vector3, Matrix, TmpVectors } from \"../Maths/math.vector.js\";\nimport { RawTexture } from \"../Materials/Textures/rawTexture.js\";\nimport { Animation } from \"../Animations/animation.js\";\nimport { AnimationRange } from \"../Animations/animationRange.js\";\nimport { EngineStore } from \"../Engines/engineStore.js\";\n\nimport { Logger } from \"../Misc/logger.js\";\nimport { DeepCopier } from \"../Misc/deepCopier.js\";\n/**\n * Class used to handle skinning animations\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons\n */\nexport class Skeleton {\n /**\n * Gets or sets a boolean indicating that bone matrices should be stored as a texture instead of using shader uniforms (default is true).\n * Please note that this option is not available if the hardware does not support it\n */\n get useTextureToStoreBoneMatrices() {\n return this._useTextureToStoreBoneMatrices;\n }\n set useTextureToStoreBoneMatrices(value) {\n this._useTextureToStoreBoneMatrices = value;\n this._markAsDirty();\n }\n /**\n * Gets or sets the animation properties override\n */\n get animationPropertiesOverride() {\n if (!this._animationPropertiesOverride) {\n return this._scene.animationPropertiesOverride;\n }\n return this._animationPropertiesOverride;\n }\n set animationPropertiesOverride(value) {\n this._animationPropertiesOverride = value;\n }\n /**\n * Gets a boolean indicating that the skeleton effectively stores matrices into a texture\n */\n get isUsingTextureForMatrices() {\n return this.useTextureToStoreBoneMatrices && this._canUseTextureForBones;\n }\n /**\n * Gets the unique ID of this skeleton\n */\n get uniqueId() {\n return this._uniqueId;\n }\n /**\n * Creates a new skeleton\n * @param name defines the skeleton name\n * @param id defines the skeleton Id\n * @param scene defines the hosting scene\n */\n constructor(\n /** defines the skeleton name */\n name, \n /** defines the skeleton Id */\n id, scene) {\n this.name = name;\n this.id = id;\n /**\n * Defines the list of child bones\n */\n this.bones = [];\n /**\n * Defines a boolean indicating if the root matrix is provided by meshes or by the current skeleton (this is the default value)\n */\n this.needInitialSkinMatrix = false;\n this._isDirty = true;\n this._meshesWithPoseMatrix = new Array();\n this._identity = Matrix.Identity();\n this._currentRenderId = -1;\n this._ranges = {};\n this._absoluteTransformIsDirty = true;\n this._canUseTextureForBones = false;\n this._uniqueId = 0;\n /** @internal */\n this._numBonesWithLinkedTransformNode = 0;\n /** @internal */\n this._hasWaitingData = null;\n /** @internal */\n this._parentContainer = null;\n /**\n * Specifies if the skeleton should be serialized\n */\n this.doNotSerialize = false;\n this._useTextureToStoreBoneMatrices = true;\n this._animationPropertiesOverride = null;\n // Events\n /**\n * An observable triggered before computing the skeleton's matrices\n */\n this.onBeforeComputeObservable = new Observable();\n this.bones = [];\n this._scene = scene || EngineStore.LastCreatedScene;\n this._uniqueId = this._scene.getUniqueId();\n this._scene.addSkeleton(this);\n //make sure it will recalculate the matrix next time prepare is called.\n this._isDirty = true;\n const engineCaps = this._scene.getEngine().getCaps();\n this._canUseTextureForBones = engineCaps.textureFloat && engineCaps.maxVertexTextureImageUnits > 0;\n }\n /**\n * Gets the current object class name.\n * @returns the class name\n */\n getClassName() {\n return \"Skeleton\";\n }\n /**\n * Returns an array containing the root bones\n * @returns an array containing the root bones\n */\n getChildren() {\n return this.bones.filter((b) => !b.getParent());\n }\n // Members\n /**\n * Gets the list of transform matrices to send to shaders (one matrix per bone)\n * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\n * @returns a Float32Array containing matrices data\n */\n getTransformMatrices(mesh) {\n if (this.needInitialSkinMatrix) {\n if (!mesh) {\n throw new Error(\"getTransformMatrices: When using the needInitialSkinMatrix flag, a mesh must be provided\");\n }\n if (!mesh._bonesTransformMatrices) {\n this.prepare(true);\n }\n return mesh._bonesTransformMatrices;\n }\n if (!this._transformMatrices || this._isDirty) {\n this.prepare(!this._transformMatrices);\n }\n return this._transformMatrices;\n }\n /**\n * Gets the list of transform matrices to send to shaders inside a texture (one matrix per bone)\n * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)\n * @returns a raw texture containing the data\n */\n getTransformMatrixTexture(mesh) {\n if (this.needInitialSkinMatrix && mesh._transformMatrixTexture) {\n return mesh._transformMatrixTexture;\n }\n return this._transformMatrixTexture;\n }\n /**\n * Gets the current hosting scene\n * @returns a scene object\n */\n getScene() {\n return this._scene;\n }\n // Methods\n /**\n * Gets a string representing the current skeleton data\n * @param fullDetails defines a boolean indicating if we want a verbose version\n * @returns a string representing the current skeleton data\n */\n toString(fullDetails) {\n let ret = `Name: ${this.name}, nBones: ${this.bones.length}`;\n ret += `, nAnimationRanges: ${this._ranges ? Object.keys(this._ranges).length : \"none\"}`;\n if (fullDetails) {\n ret += \", Ranges: {\";\n let first = true;\n for (const name in this._ranges) {\n if (first) {\n ret += \", \";\n first = false;\n }\n ret += name;\n }\n ret += \"}\";\n }\n return ret;\n }\n /**\n * Get bone's index searching by name\n * @param name defines bone's name to search for\n * @returns the indice of the bone. Returns -1 if not found\n */\n getBoneIndexByName(name) {\n for (let boneIndex = 0, cache = this.bones.length; boneIndex < cache; boneIndex++) {\n if (this.bones[boneIndex].name === name) {\n return boneIndex;\n }\n }\n return -1;\n }\n /**\n * Create a new animation range\n * @param name defines the name of the range\n * @param from defines the start key\n * @param to defines the end key\n */\n createAnimationRange(name, from, to) {\n // check name not already in use\n if (!this._ranges[name]) {\n this._ranges[name] = new AnimationRange(name, from, to);\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\n if (this.bones[i].animations[0]) {\n this.bones[i].animations[0].createRange(name, from, to);\n }\n }\n }\n }\n /**\n * Delete a specific animation range\n * @param name defines the name of the range\n * @param deleteFrames defines if frames must be removed as well\n */\n deleteAnimationRange(name, deleteFrames = true) {\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\n if (this.bones[i].animations[0]) {\n this.bones[i].animations[0].deleteRange(name, deleteFrames);\n }\n }\n this._ranges[name] = null; // said much faster than 'delete this._range[name]'\n }\n /**\n * Gets a specific animation range\n * @param name defines the name of the range to look for\n * @returns the requested animation range or null if not found\n */\n getAnimationRange(name) {\n return this._ranges[name] || null;\n }\n /**\n * Gets the list of all animation ranges defined on this skeleton\n * @returns an array\n */\n getAnimationRanges() {\n const animationRanges = [];\n let name;\n for (name in this._ranges) {\n animationRanges.push(this._ranges[name]);\n }\n return animationRanges;\n }\n /**\n * Copy animation range from a source skeleton.\n * This is not for a complete retargeting, only between very similar skeleton's with only possible bone length differences\n * @param source defines the source skeleton\n * @param name defines the name of the range to copy\n * @param rescaleAsRequired defines if rescaling must be applied if required\n * @returns true if operation was successful\n */\n copyAnimationRange(source, name, rescaleAsRequired = false) {\n if (this._ranges[name] || !source.getAnimationRange(name)) {\n return false;\n }\n let ret = true;\n const frameOffset = this._getHighestAnimationFrame() + 1;\n // make a dictionary of source skeleton's bones, so exact same order or doubly nested loop is not required\n const boneDict = {};\n const sourceBones = source.bones;\n let nBones;\n let i;\n for (i = 0, nBones = sourceBones.length; i < nBones; i++) {\n boneDict[sourceBones[i].name] = sourceBones[i];\n }\n if (this.bones.length !== sourceBones.length) {\n Logger.Warn(`copyAnimationRange: this rig has ${this.bones.length} bones, while source as ${sourceBones.length}`);\n ret = false;\n }\n const skelDimensionsRatio = rescaleAsRequired && this.dimensionsAtRest && source.dimensionsAtRest ? this.dimensionsAtRest.divide(source.dimensionsAtRest) : null;\n for (i = 0, nBones = this.bones.length; i < nBones; i++) {\n const boneName = this.bones[i].name;\n const sourceBone = boneDict[boneName];\n if (sourceBone) {\n ret = ret && this.bones[i].copyAnimationRange(sourceBone, name, frameOffset, rescaleAsRequired, skelDimensionsRatio);\n }\n else {\n Logger.Warn(\"copyAnimationRange: not same rig, missing source bone \" + boneName);\n ret = false;\n }\n }\n // do not call createAnimationRange(), since it also is done to bones, which was already done\n const range = source.getAnimationRange(name);\n if (range) {\n this._ranges[name] = new AnimationRange(name, range.from + frameOffset, range.to + frameOffset);\n }\n return ret;\n }\n /**\n * Forces the skeleton to go to rest pose\n */\n returnToRest() {\n for (const bone of this.bones) {\n if (bone._index !== -1) {\n bone.returnToRest();\n }\n }\n }\n _getHighestAnimationFrame() {\n let ret = 0;\n for (let i = 0, nBones = this.bones.length; i < nBones; i++) {\n if (this.bones[i].animations[0]) {\n const highest = this.bones[i].animations[0].getHighestFrame();\n if (ret < highest) {\n ret = highest;\n }\n }\n }\n return ret;\n }\n /**\n * Begin a specific animation range\n * @param name defines the name of the range to start\n * @param loop defines if looping must be turned on (false by default)\n * @param speedRatio defines the speed ratio to apply (1 by default)\n * @param onAnimationEnd defines a callback which will be called when animation will end\n * @returns a new animatable\n */\n beginAnimation(name, loop, speedRatio, onAnimationEnd) {\n const range = this.getAnimationRange(name);\n if (!range) {\n return null;\n }\n return this._scene.beginAnimation(this, range.from, range.to, loop, speedRatio, onAnimationEnd);\n }\n /**\n * Convert the keyframes for a range of animation on a skeleton to be relative to a given reference frame.\n * @param skeleton defines the Skeleton containing the animation range to convert\n * @param referenceFrame defines the frame that keyframes in the range will be relative to\n * @param range defines the name of the AnimationRange belonging to the Skeleton to convert\n * @returns the original skeleton\n */\n static MakeAnimationAdditive(skeleton, referenceFrame = 0, range) {\n const rangeValue = skeleton.getAnimationRange(range);\n // We can't make a range additive if it doesn't exist\n if (!rangeValue) {\n return null;\n }\n // Find any current scene-level animatable belonging to the target that matches the range\n const sceneAnimatables = skeleton._scene.getAllAnimatablesByTarget(skeleton);\n let rangeAnimatable = null;\n for (let index = 0; index < sceneAnimatables.length; index++) {\n const sceneAnimatable = sceneAnimatables[index];\n if (sceneAnimatable.fromFrame === rangeValue?.from && sceneAnimatable.toFrame === rangeValue?.to) {\n rangeAnimatable = sceneAnimatable;\n break;\n }\n }\n // Convert the animations belonging to the skeleton to additive keyframes\n const animatables = skeleton.getAnimatables();\n for (let index = 0; index < animatables.length; index++) {\n const animatable = animatables[index];\n const animations = animatable.animations;\n if (!animations) {\n continue;\n }\n for (let animIndex = 0; animIndex < animations.length; animIndex++) {\n Animation.MakeAnimationAdditive(animations[animIndex], referenceFrame, range);\n }\n }\n // Mark the scene-level animatable as additive\n if (rangeAnimatable) {\n rangeAnimatable.isAdditive = true;\n }\n return skeleton;\n }\n /** @internal */\n _markAsDirty() {\n this._isDirty = true;\n this._absoluteTransformIsDirty = true;\n }\n /**\n * @internal\n */\n _registerMeshWithPoseMatrix(mesh) {\n this._meshesWithPoseMatrix.push(mesh);\n }\n /**\n * @internal\n */\n _unregisterMeshWithPoseMatrix(mesh) {\n const index = this._meshesWithPoseMatrix.indexOf(mesh);\n if (index > -1) {\n this._meshesWithPoseMatrix.splice(index, 1);\n }\n }\n _computeTransformMatrices(targetMatrix, initialSkinMatrix) {\n this.onBeforeComputeObservable.notifyObservers(this);\n for (let index = 0; index < this.bones.length; index++) {\n const bone = this.bones[index];\n bone._childUpdateId++;\n const parentBone = bone.getParent();\n if (parentBone) {\n bone.getLocalMatrix().multiplyToRef(parentBone.getFinalMatrix(), bone.getFinalMatrix());\n }\n else {\n if (initialSkinMatrix) {\n bone.getLocalMatrix().multiplyToRef(initialSkinMatrix, bone.getFinalMatrix());\n }\n else {\n bone.getFinalMatrix().copyFrom(bone.getLocalMatrix());\n }\n }\n if (bone._index !== -1) {\n const mappedIndex = bone._index === null ? index : bone._index;\n bone.getAbsoluteInverseBindMatrix().multiplyToArray(bone.getFinalMatrix(), targetMatrix, mappedIndex * 16);\n }\n }\n this._identity.copyToArray(targetMatrix, this.bones.length * 16);\n }\n /**\n * Build all resources required to render a skeleton\n * @param dontCheckFrameId defines a boolean indicating if prepare should be run without checking first the current frame id (default: false)\n */\n prepare(dontCheckFrameId = false) {\n if (!dontCheckFrameId) {\n const currentRenderId = this.getScene().getRenderId();\n if (this._currentRenderId === currentRenderId) {\n return;\n }\n this._currentRenderId = currentRenderId;\n }\n // Update the local matrix of bones with linked transform nodes.\n if (this._numBonesWithLinkedTransformNode > 0) {\n for (const bone of this.bones) {\n if (bone._linkedTransformNode) {\n const node = bone._linkedTransformNode;\n bone.position = node.position;\n if (node.rotationQuaternion) {\n bone.rotationQuaternion = node.rotationQuaternion;\n }\n else {\n bone.rotation = node.rotation;\n }\n bone.scaling = node.scaling;\n }\n }\n }\n if (this.needInitialSkinMatrix) {\n for (const mesh of this._meshesWithPoseMatrix) {\n const poseMatrix = mesh.getPoseMatrix();\n let needsUpdate = this._isDirty;\n if (!mesh._bonesTransformMatrices || mesh._bonesTransformMatrices.length !== 16 * (this.bones.length + 1)) {\n mesh._bonesTransformMatrices = new Float32Array(16 * (this.bones.length + 1));\n needsUpdate = true;\n }\n if (!needsUpdate) {\n continue;\n }\n if (this._synchronizedWithMesh !== mesh) {\n this._synchronizedWithMesh = mesh;\n // Prepare bones\n for (const bone of this.bones) {\n if (!bone.getParent()) {\n const matrix = bone.getBindMatrix();\n matrix.multiplyToRef(poseMatrix, TmpVectors.Matrix[1]);\n bone._updateAbsoluteBindMatrices(TmpVectors.Matrix[1]);\n }\n }\n if (this.isUsingTextureForMatrices) {\n const textureWidth = (this.bones.length + 1) * 4;\n if (!mesh._transformMatrixTexture || mesh._transformMatrixTexture.getSize().width !== textureWidth) {\n if (mesh._transformMatrixTexture) {\n mesh._transformMatrixTexture.dispose();\n }\n mesh._transformMatrixTexture = RawTexture.CreateRGBATexture(mesh._bonesTransformMatrices, (this.bones.length + 1) * 4, 1, this._scene, false, false, 1, 1);\n }\n }\n }\n this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);\n if (this.isUsingTextureForMatrices && mesh._transformMatrixTexture) {\n mesh._transformMatrixTexture.update(mesh._bonesTransformMatrices);\n }\n }\n }\n else {\n if (!this._isDirty) {\n return;\n }\n if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {\n this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));\n if (this.isUsingTextureForMatrices) {\n if (this._transformMatrixTexture) {\n this._transformMatrixTexture.dispose();\n }\n this._transformMatrixTexture = RawTexture.CreateRGBATexture(this._transformMatrices, (this.bones.length + 1) * 4, 1, this._scene, false, false, 1, 1);\n }\n }\n this._computeTransformMatrices(this._transformMatrices, null);\n if (this.isUsingTextureForMatrices && this._transformMatrixTexture) {\n this._transformMatrixTexture.update(this._transformMatrices);\n }\n }\n this._isDirty = false;\n }\n /**\n * Gets the list of animatables currently running for this skeleton\n * @returns an array of animatables\n */\n getAnimatables() {\n if (!this._animatables || this._animatables.length !== this.bones.length) {\n this._animatables = [];\n for (let index = 0; index < this.bones.length; index++) {\n this._animatables.push(this.bones[index]);\n }\n }\n return this._animatables;\n }\n /**\n * Clone the current skeleton\n * @param name defines the name of the new skeleton\n * @param id defines the id of the new skeleton\n * @returns the new skeleton\n */\n clone(name, id) {\n const result = new Skeleton(name, id || name, this._scene);\n result.needInitialSkinMatrix = this.needInitialSkinMatrix;\n for (let index = 0; index < this.bones.length; index++) {\n const source = this.bones[index];\n let parentBone = null;\n const parent = source.getParent();\n if (parent) {\n const parentIndex = this.bones.indexOf(parent);\n parentBone = result.bones[parentIndex];\n }\n const bone = new Bone(source.name, result, parentBone, source.getBindMatrix().clone(), source.getRestMatrix().clone());\n bone._index = source._index;\n if (source._linkedTransformNode) {\n bone.linkTransformNode(source._linkedTransformNode);\n }\n DeepCopier.DeepCopy(source.animations, bone.animations);\n }\n if (this._ranges) {\n result._ranges = {};\n for (const rangeName in this._ranges) {\n const range = this._ranges[rangeName];\n if (range) {\n result._ranges[rangeName] = range.clone();\n }\n }\n }\n this._isDirty = true;\n result.prepare(true);\n return result;\n }\n /**\n * Enable animation blending for this skeleton\n * @param blendingSpeed defines the blending speed to apply\n * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#animation-blending\n */\n enableBlending(blendingSpeed = 0.01) {\n this.bones.forEach((bone) => {\n bone.animations.forEach((animation) => {\n animation.enableBlending = true;\n animation.blendingSpeed = blendingSpeed;\n });\n });\n }\n /**\n * Releases all resources associated with the current skeleton\n */\n dispose() {\n this._meshesWithPoseMatrix.length = 0;\n // Animations\n this.getScene().stopAnimation(this);\n // Remove from scene\n this.getScene().removeSkeleton(this);\n if (this._parentContainer) {\n const index = this._parentContainer.skeletons.indexOf(this);\n if (index > -1) {\n this._parentContainer.skeletons.splice(index, 1);\n }\n this._parentContainer = null;\n }\n if (this._transformMatrixTexture) {\n this._transformMatrixTexture.dispose();\n this._transformMatrixTexture = null;\n }\n }\n /**\n * Serialize the skeleton in a JSON object\n * @returns a JSON object\n */\n serialize() {\n const serializationObject = {};\n serializationObject.name = this.name;\n serializationObject.id = this.id;\n if (this.dimensionsAtRest) {\n serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();\n }\n serializationObject.bones = [];\n serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;\n for (let index = 0; index < this.bones.length; index++) {\n const bone = this.bones[index];\n const parent = bone.getParent();\n const serializedBone = {\n parentBoneIndex: parent ? this.bones.indexOf(parent) : -1,\n index: bone.getIndex(),\n name: bone.name,\n id: bone.id,\n matrix: bone.getBindMatrix().asArray(),\n rest: bone.getRestMatrix().asArray(),\n linkedTransformNodeId: bone.getTransformNode()?.id,\n };\n serializationObject.bones.push(serializedBone);\n if (bone.length) {\n serializedBone.length = bone.length;\n }\n if (bone.metadata) {\n serializedBone.metadata = bone.metadata;\n }\n if (bone.animations && bone.animations.length > 0) {\n serializedBone.animation = bone.animations[0].serialize();\n }\n serializationObject.ranges = [];\n for (const name in this._ranges) {\n const source = this._ranges[name];\n if (!source) {\n continue;\n }\n const range = {};\n range.name = name;\n range.from = source.from;\n range.to = source.to;\n serializationObject.ranges.push(range);\n }\n }\n return serializationObject;\n }\n /**\n * Creates a new skeleton from serialized data\n * @param parsedSkeleton defines the serialized data\n * @param scene defines the hosting scene\n * @returns a new skeleton\n */\n static Parse(parsedSkeleton, scene) {\n const skeleton = new Skeleton(parsedSkeleton.name, parsedSkeleton.id, scene);\n if (parsedSkeleton.dimensionsAtRest) {\n skeleton.dimensionsAtRest = Vector3.FromArray(parsedSkeleton.dimensionsAtRest);\n }\n skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;\n let index;\n for (index = 0; index < parsedSkeleton.bones.length; index++) {\n const parsedBone = parsedSkeleton.bones[index];\n const parsedBoneIndex = parsedSkeleton.bones[index].index;\n let parentBone = null;\n if (parsedBone.parentBoneIndex > -1) {\n parentBone = skeleton.bones[parsedBone.parentBoneIndex];\n }\n const rest = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;\n const bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest, null, parsedBoneIndex);\n if (parsedBone.id !== undefined && parsedBone.id !== null) {\n bone.id = parsedBone.id;\n }\n if (parsedBone.length) {\n bone.length = parsedBone.length;\n }\n if (parsedBone.metadata) {\n bone.metadata = parsedBone.metadata;\n }\n if (parsedBone.animation) {\n bone.animations.push(Animation.Parse(parsedBone.animation));\n }\n if (parsedBone.linkedTransformNodeId !== undefined && parsedBone.linkedTransformNodeId !== null) {\n skeleton._hasWaitingData = true;\n bone._waitingTransformNodeId = parsedBone.linkedTransformNodeId;\n }\n }\n // placed after bones, so createAnimationRange can cascade down\n if (parsedSkeleton.ranges) {\n for (index = 0; index < parsedSkeleton.ranges.length; index++) {\n const data = parsedSkeleton.ranges[index];\n skeleton.createAnimationRange(data.name, data.from, data.to);\n }\n }\n return skeleton;\n }\n /**\n * Compute all node absolute matrices\n * @param forceUpdate defines if computation must be done even if cache is up to date\n */\n computeAbsoluteMatrices(forceUpdate = false) {\n if (this._absoluteTransformIsDirty || forceUpdate) {\n this.bones[0].computeAbsoluteMatrices();\n this._absoluteTransformIsDirty = false;\n }\n }\n /**\n * Compute all node absolute matrices\n * @param forceUpdate defines if computation must be done even if cache is up to date\n * @deprecated Please use computeAbsoluteMatrices instead\n */\n computeAbsoluteTransforms(forceUpdate = false) {\n this.computeAbsoluteMatrices(forceUpdate);\n }\n /**\n * Gets the root pose matrix\n * @returns a matrix\n */\n getPoseMatrix() {\n let poseMatrix = null;\n if (this._meshesWithPoseMatrix.length > 0) {\n poseMatrix = this._meshesWithPoseMatrix[0].getPoseMatrix();\n }\n return poseMatrix;\n }\n /**\n * Sorts bones per internal index\n */\n sortBones() {\n const bones = [];\n const visited = new Array(this.bones.length);\n for (let index = 0; index < this.bones.length; index++) {\n this._sortBones(index, bones, visited);\n }\n this.bones = bones;\n }\n _sortBones(index, bones, visited) {\n if (visited[index]) {\n return;\n }\n visited[index] = true;\n const bone = this.bones[index];\n if (!bone)\n return;\n if (bone._index === undefined) {\n bone._index = index;\n }\n const parentBone = bone.getParent();\n if (parentBone) {\n this._sortBones(this.bones.indexOf(parentBone), bones, visited);\n }\n bones.push(bone);\n }\n /**\n * Set the current local matrix as the restPose for all bones in the skeleton.\n */\n setCurrentPoseAsRest() {\n this.bones.forEach((b) => {\n b.setCurrentPoseAsRest();\n });\n }\n}\n"],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}