SkelAnimModelNodeCtrl.cpp 6.2 KB

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