SkelAnimModelNodeCtrl.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "SkelAnimModelNodeCtrl.h"
  2. #include "SkelAnim.h"
  3. #include "Skeleton.h"
  4. #include "SkinNode.h"
  5. #include "Model.h"
  6. #include "MainRenderer.h"
  7. #include "Skin.h"
  8. //======================================================================================================================
  9. // SkelAnimModelNodeCtrl =
  10. //======================================================================================================================
  11. SkelAnimModelNodeCtrl::SkelAnimModelNodeCtrl(SkinNode& skinNode_):
  12. Controller(CT_SKEL_ANIM_SKIN_NODE, skinNode_),
  13. frame(0.0),
  14. skinNode(skinNode_)
  15. {}
  16. //======================================================================================================================
  17. // interpolate =
  18. //======================================================================================================================
  19. void SkelAnimModelNodeCtrl::interpolate(const SkelAnim& animation, float frame,
  20. Vec<Vec3>& boneTranslations, Vec<Mat3>& boneRotations)
  21. {
  22. ASSERT(frame < animation.framesNum);
  23. // calculate the t (used in slerp and lerp) using the keyframs and the frame and
  24. // calc the lPose and rPose witch indicate the pose IDs in witch the frame lies between
  25. const Vec<uint>& keyframes = animation.keyframes;
  26. float t = 0.0;
  27. uint lPose = 0, rPose = 0;
  28. for(uint j=0; j<keyframes.size(); j++)
  29. {
  30. if((float)keyframes[j] == frame)
  31. {
  32. lPose = rPose = j;
  33. t = 0.0;
  34. break;
  35. }
  36. else if((float)keyframes[j] > frame)
  37. {
  38. lPose = j-1;
  39. rPose = j;
  40. t = (frame - (float)keyframes[lPose]) / float(keyframes[rPose] - keyframes[lPose]);
  41. break;
  42. }
  43. }
  44. // now for all bones update bone's poses
  45. ASSERT(boneRotations.size() >= 1);
  46. for(uint i=0; i<boneRotations.size(); i++)
  47. {
  48. const SkelAnim::BoneAnim& banim = animation.bones[i];
  49. Mat3& localRot = boneRotations[i];
  50. Vec3& localTransl = boneTranslations[i];
  51. // if the bone has animations then slerp and lerp to find the rotation and translation
  52. if(banim.keyframes.size() != 0)
  53. {
  54. const SkelAnim::BonePose& lBpose = banim.keyframes[lPose];
  55. const SkelAnim::BonePose& rBpose = banim.keyframes[rPose];
  56. // rotation
  57. const Quat& q0 = lBpose.rotation;
  58. const Quat& q1 = rBpose.rotation;
  59. localRot = Mat3(q0.slerp(q1, t));
  60. // translation
  61. const Vec3& v0 = lBpose.translation;
  62. const Vec3& v1 = rBpose.translation;
  63. localTransl = v0.lerp(v1, t);
  64. }
  65. // else put the idents
  66. else
  67. {
  68. localRot = Mat3::getIdentity();
  69. localTransl = Vec3(0.0, 0.0, 0.0);
  70. }
  71. }
  72. }
  73. //======================================================================================================================
  74. // updateBoneTransforms =
  75. //======================================================================================================================
  76. void SkelAnimModelNodeCtrl::updateBoneTransforms(const Skeleton& skeleton,
  77. Vec<Vec3>& boneTranslations, Vec<Mat3>& boneRotations)
  78. {
  79. uint queue[128];
  80. uint head = 0, tail = 0;
  81. // put the roots
  82. for(uint i=0; i<skeleton.bones.size(); i++)
  83. {
  84. if(skeleton.bones[i].parent == NULL)
  85. {
  86. queue[tail++] = i; // queue push
  87. }
  88. }
  89. // loop
  90. while(head != tail) // while queue not empty
  91. {
  92. uint boneId = queue[head++]; // queue pop
  93. const Skeleton::Bone& boned = skeleton.bones[boneId];
  94. // bone.final_transform = MA * ANIM * MAi
  95. // where MA is bone matrix at armature space and ANIM the interpolated transformation.
  96. combineTransformations(boneTranslations[boneId], boneRotations[boneId],
  97. boned.tslSkelSpaceInv, boned.rotSkelSpaceInv,
  98. boneTranslations[boneId], boneRotations[boneId]);
  99. combineTransformations(boned.tslSkelSpace, boned.rotSkelSpace,
  100. boneTranslations[boneId], boneRotations[boneId],
  101. boneTranslations[boneId], boneRotations[boneId]);
  102. // and finaly add the parent's transform
  103. if(boned.parent)
  104. {
  105. // bone.final_final_transform = parent.transf * bone.final_transform
  106. combineTransformations(boneTranslations[boned.parent->getPos()], boneRotations[boned.parent->getPos()],
  107. boneTranslations[boneId], boneRotations[boneId],
  108. boneTranslations[boneId], boneRotations[boneId]);
  109. }
  110. // now add the bone's childes
  111. for(uint i=0; i<boned.childsNum; i++)
  112. {
  113. queue[tail++] = boned.childs[i]->getPos();
  114. }
  115. }
  116. }
  117. //======================================================================================================================
  118. // deform =
  119. //======================================================================================================================
  120. void SkelAnimModelNodeCtrl::deform(const Skeleton& skeleton, const Vec<Vec3>& boneTranslations,
  121. const Vec<Mat3>& boneRotations, Vec<Vec3>& heads, Vec<Vec3>& tails)
  122. {
  123. for(uint i=0; i<skeleton.bones.size(); i++)
  124. {
  125. const Mat3& rot = boneRotations[i];
  126. const Vec3& transl = boneTranslations[i];
  127. heads[i] = skeleton.bones[i].getHead().getTransformed(transl, rot);
  128. tails[i] = skeleton.bones[i].getTail().getTransformed(transl, rot);
  129. }
  130. }
  131. //======================================================================================================================
  132. // update =
  133. //======================================================================================================================
  134. void SkelAnimModelNodeCtrl::update(float)
  135. {
  136. frame += step;
  137. if(frame > skelAnim->framesNum) // if the crnt is finished then play the next or loop the crnt
  138. {
  139. frame = 0.0;
  140. }
  141. if(!controlledNode.isVisible())
  142. {
  143. return;
  144. }
  145. interpolate(*skelAnim, frame, skinNode.getBoneTranslations(), skinNode.getBoneRotations());
  146. updateBoneTransforms(skinNode.getSkin().getSkeleton(), skinNode.getBoneTranslations(), skinNode.getBoneRotations());
  147. if(MainRendererSingleton::getInstance().getDbg().isEnabled() &&
  148. MainRendererSingleton::getInstance().getDbg().isShowSkeletonsEnabled())
  149. {
  150. deform(skinNode.getSkin().getSkeleton(), skinNode.getBoneTranslations(), skinNode.getBoneRotations(),
  151. skinNode.getHeads(), skinNode.getTails());
  152. }
  153. }