SkinnedAnimationPlayer.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // SkinnedAnimationPlayer.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. using System;
  10. using System.Collections.Generic;
  11. using Microsoft.Xna.Framework;
  12. namespace CustomModelAnimation
  13. {
  14. /// <summary>
  15. /// The animation player manipulates a skinned model
  16. /// </summary>
  17. public class SkinnedAnimationPlayer : ModelAnimationPlayerBase
  18. {
  19. // Current animation transform matrices.
  20. Matrix[] boneTransforms;
  21. Matrix[] worldTransforms;
  22. Matrix[] skinTransforms;
  23. List<Matrix> bindPose;
  24. List<Matrix> inverseBindPose;
  25. List<int> skeletonHierarchy;
  26. /// <summary>
  27. /// Constructs a new animation player.
  28. /// </summary>
  29. public SkinnedAnimationPlayer(List<Matrix> bindPose, List<Matrix> inverseBindPose, List<int> skeletonHierarchy)
  30. {
  31. if (bindPose == null || bindPose.Count == 0)
  32. throw new Exception("Bad arguments to model animation player");
  33. boneTransforms = new Matrix[bindPose.Count];
  34. worldTransforms = new Matrix[bindPose.Count];
  35. skinTransforms = new Matrix[bindPose.Count];
  36. this.bindPose = bindPose;
  37. this.inverseBindPose = inverseBindPose;
  38. this.skeletonHierarchy = skeletonHierarchy;
  39. }
  40. /// <summary>
  41. /// Initializes the animation clip
  42. /// </summary>
  43. protected override void InitClip()
  44. {
  45. bindPose.CopyTo(boneTransforms);
  46. }
  47. /// <summary>
  48. /// Sets the key frame for the passed in frame
  49. /// </summary>
  50. /// <param name="keyframe"></param>
  51. protected override void SetKeyframe(ModelKeyframe keyframe)
  52. {
  53. boneTransforms[keyframe.Bone] = keyframe.Transform;
  54. }
  55. /// <summary>
  56. /// Updates the transformations ultimately needed for rendering
  57. /// </summary>
  58. protected override void OnUpdate()
  59. {
  60. if (CurrentClip != null)
  61. {
  62. // Root bone.
  63. worldTransforms[0] = boneTransforms[0];
  64. skinTransforms[0] = inverseBindPose[0] * worldTransforms[0];
  65. // Child bones.
  66. for (int bone = 1; bone < worldTransforms.Length; bone++)
  67. {
  68. int parentBone = skeletonHierarchy[bone];
  69. worldTransforms[bone] = boneTransforms[bone] * worldTransforms[parentBone];
  70. skinTransforms[bone] = inverseBindPose[bone] * worldTransforms[bone];
  71. }
  72. }
  73. }
  74. /// <summary>
  75. /// Gets the current bone transform matrices, relative to their parent bones.
  76. /// </summary>
  77. private Matrix[] GetBoneTransforms()
  78. {
  79. return boneTransforms;
  80. }
  81. /// <summary>
  82. /// Gets the current bone transform matrices, in absolute format.
  83. /// </summary>
  84. private Matrix[] GetWorldTransforms()
  85. {
  86. return worldTransforms;
  87. }
  88. /// <summary>
  89. /// Gets the current bone transform matrices, relative to the skinning bind pose.
  90. /// </summary>
  91. public Matrix[] GetSkinTransforms()
  92. {
  93. return skinTransforms;
  94. }
  95. }
  96. }