} // Update #region Interpolate Animation /// <summary> /// Retrieves and interpolates two pose. /// </summary> private static ModelAnimationPlayer.BoneTransformationData InterpolatePose(ModelAnimationPlayer.BoneTransformationData transformationData1, ModelAnimationPlayer.BoneTransformationData transformationData2, float amount) { Vector3 translation = Vector3.SmoothStep(transformationData1.position, transformationData2.position, amount); Quaternion rotation = Quaternion.Slerp(transformationData1.rotation, transformationData2.rotation, amount); float scale = transformationData1.scale * (1 - amount) + transformationData2.scale * amount; return(new ModelAnimationPlayer.BoneTransformationData { position = translation, rotation = rotation, scale = scale }); } // InterpolatePose
} // Stop #endregion #region Update /// <summary> /// Update. /// </summary> internal void Update() { if (!(cachedModel is FileModel)) { return; } if (activeAnimations.Count == 0) { return; } // Update cross fade elapsed time. for (int i = 0; i < activeAnimations.Count; i++) { if (activeAnimations[i].FadeLenght != 0) { activeAnimations[i].ElapsedTime += Time.GameDeltaTime; } } bool stopAnimations = false; for (int i = activeAnimations.Count - 1; i >= 0; i--) { if (stopAnimations) { activeAnimations[i].ModelAnimationPlayer.Stop(); } else // If cross fade is completed the rest of the animations are removed. if (activeAnimations[activeAnimations.Count - 1].ElapsedTime > activeAnimations[activeAnimations.Count - 1].FadeLenght) { stopAnimations = true; } } FileModel fileModel = (FileModel)cachedModel; if (activeAnimations.Count >= 2) { // Update bone transform for (int bone = 0; bone < fileModel.BoneCount; bone++) { float amout = activeAnimations[activeAnimations.Count - 1].ElapsedTime / activeAnimations[activeAnimations.Count - 1].FadeLenght; ModelAnimationPlayer.BoneTransformationData blendedPose = InterpolatePose(activeAnimations[activeAnimations.Count - 2].ModelAnimationPlayer.BoneTransforms[bone], activeAnimations[activeAnimations.Count - 1].ModelAnimationPlayer.BoneTransforms[bone], amout); localBoneTransform[bone] = Matrix.CreateScale(blendedPose.scale) * Matrix.CreateFromQuaternion(blendedPose.rotation) * Matrix.CreateTranslation(blendedPose.position); } } else { // Update bone transform for (int bone = 0; bone < fileModel.BoneCount; bone++) { localBoneTransform[bone] = Matrix.CreateScale(activeAnimations[0].ModelAnimationPlayer.BoneTransforms[bone].scale) * Matrix.CreateFromQuaternion(activeAnimations[0].ModelAnimationPlayer.BoneTransforms[bone].rotation) * Matrix.CreateTranslation(activeAnimations[0].ModelAnimationPlayer.BoneTransforms[bone].position); } } // When the local bone transforms change the world bone transforms are updated. UpdateLocalBoneTransforms(); // Remove finished animations from the active animations (Change the list to array TODO) for (int i = 0; i < activeAnimations.Count; i++) { if (activeAnimations[i].ModelAnimationPlayer.State == MediaState.Stopped) { activeAnimations.Remove(activeAnimations[i]); i--; } } } // Update