SkinNode.cpp 6.9 KB

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