///////////////////////////////////////// public int GetCachedBoneIndex(Component_Skeleton skeleton) { //!!!!threading if (getCachedBoneIndex_Skeleton != skeleton) { getCachedBoneIndex_Skeleton = skeleton; getCachedBoneIndex_Index = Array.IndexOf(skeleton.GetBones(), this); } return(getCachedBoneIndex_Index); }
void Update(Component_Skeleton skeleton, Component_SkeletonAnimationTrack animationTrack, double time) { if (time != calculatedForTime) { //update general data calculatedForTime = time; bones = skeleton.GetBones(); //calculate bone transforms if (boneTransforms == null || boneTransforms.Length != bones.Length) { boneTransforms = new Component_SkeletonAnimationTrack.CalculateBoneTransformsItem[bones.Length]; } animationTrack?.CalculateBoneTransforms(time, boneTransforms); CalculateBoneTransforms?.Invoke(this, boneTransforms); //calculate transformMatrixRelativeToSkin, transformRelativeToSkin, boneGlobalTransforms, hasScale if (transformMatrixRelativeToSkin == null || transformMatrixRelativeToSkin.Length != bones.Length) { transformMatrixRelativeToSkin = new Matrix4F[bones.Length]; } if (transformRelativeToSkin == null || transformRelativeToSkin.Length != bones.Length) { transformRelativeToSkin = new Component_SkeletonAnimationTrack.CalculateBoneTransformsItem[bones.Length]; } if (boneGlobalTransforms == null || boneGlobalTransforms.Length != bones.Length) { boneGlobalTransforms = new BoneGlobalTransformItem[bones.Length]; } var matrixZero = Matrix4F.Zero; for (int i = 0; i < bones.Length; i++) { boneGlobalTransforms[i] = new BoneGlobalTransformItem(false, ref matrixZero); } foreach (var b in bones) { GetBoneGlobalTransformRecursive(skeleton, b); } hasScale = false; for (int i = 0; i < bones.Length; i++) { var bone = bones[i]; Matrix4F m; if (bone != null) { Matrix4F.Multiply(ref GetBoneGlobalTransformRecursive(skeleton, bone), ref bone.GetTransformMatrixInverse(), out m); } else { m = Matrix4F.Identity; } transformMatrixRelativeToSkin[i] = m; m.Decompose(out Vector3F t, out QuaternionF r, out Vector3F s); transformRelativeToSkin[i] = new Component_SkeletonAnimationTrack.CalculateBoneTransformsItem { Position = t, Rotation = r, Scale = s }; //if the scale differs from 1.0 more than this value, then the scaling is present and DualQuaternionSkinning can not be used. const float EpsilonForScale = 1e-3f; if (Math.Abs(1.0f - s.X) > EpsilonForScale || Math.Abs(1.0f - s.Y) > EpsilonForScale || Math.Abs(1.0f - s.Y) > EpsilonForScale) { hasScale = true; } } } }