public void Update(float elapsed) { foreach (AnimationState state in animationStates) { if (!state.IsActive()) { continue; } Animation animation = state.GetAnimation(); state.Update(elapsed); float timePosition = state.GetTimePosition(); for (int i = 0; i < animation.GetTrackCount(); i++) { AnimationTrack track = animation.GetTrack(i); AnimationKeyFrame keyframe = track.GetInterpolatedKeyFrame(timePosition); int boneIndex = skeleton.GetBoneIndexByName(track.GetName()); keyframe.GetMatrix(out animationTransforms[boneIndex]); } } // convert animation transforms from local to world coordinates for (int i = 0; i < animationTransforms.Length; i++) { int parent = skeleton.GetParentBoneIndexByIndex(i); if (parent == -1) { continue; } Matrix.Multiply(ref animationTransforms[i], ref animationTransforms[parent], out animationTransforms[i]); } // create the skinning matrix // the skinning matrix takes world space vertices to joint space and then back // to world space using the animation transform for (int i = 0; i < animationTransforms.Length; i++) { Matrix invWorldBoneMatrix; AnimationBone bone = skeleton.GetBoneByIndex(i); bone.GetInvWorldTransform(out invWorldBoneMatrix); Matrix.Multiply(ref invWorldBoneMatrix, ref animationTransforms[i], out animationTransforms[i]); } effect.SetBoneTransforms(animationTransforms); effect.World = world; }