BsSkeleton.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsSkeleton.h"
  4. #include "BsAnimationClip.h"
  5. #include "BsSkeletonRTTI.h"
  6. namespace BansheeEngine
  7. {
  8. SkeletonPose::SkeletonPose(UINT32 numBones)
  9. : numBones(numBones)
  10. {
  11. UINT32 elementSize = sizeof(Matrix4) + sizeof(Vector3) * 2 + sizeof(Quaternion);
  12. UINT8* buffer = (UINT8*)bs_alloc(elementSize * sizeof(numBones));
  13. bonePoses = (Matrix4*)buffer;
  14. buffer += sizeof(Matrix4) * numBones;
  15. positions = (Vector3*)buffer;
  16. buffer += sizeof(Vector3) * numBones;
  17. rotations = (Quaternion*)buffer;
  18. buffer += sizeof(Quaternion) * numBones;
  19. scales = (Vector3*)buffer;
  20. for (UINT32 i = 0; i < numBones; i++)
  21. {
  22. bonePoses[i] = Matrix4::IDENTITY;
  23. positions[i] = Vector3::ZERO;
  24. rotations[i] = Quaternion::IDENTITY;
  25. scales[i] = Vector3::ONE;
  26. }
  27. }
  28. SkeletonPose::~SkeletonPose()
  29. {
  30. bs_free(bonePoses);
  31. }
  32. Skeleton::Skeleton()
  33. :mInvBindPoses(nullptr), mBoneInfo(nullptr), mNumBones(0)
  34. { }
  35. Skeleton::Skeleton(BONE_DESC* bones, UINT32 numBones)
  36. :mInvBindPoses(bs_newN<Matrix4>(numBones)), mBoneInfo(bs_newN<SkeletonBoneInfo>(numBones)), mNumBones(numBones)
  37. {
  38. for(UINT32 i = 0; i < numBones; i++)
  39. {
  40. mInvBindPoses[i] = bones[i].invBindPose;
  41. mBoneInfo[i].name = bones[i].name;
  42. mBoneInfo[i].parent = bones[i].parent;
  43. }
  44. }
  45. Skeleton::~Skeleton()
  46. {
  47. if(mInvBindPoses != nullptr)
  48. bs_deleteN(mInvBindPoses, mNumBones);
  49. if (mBoneInfo != nullptr)
  50. bs_deleteN(mBoneInfo, mNumBones);
  51. }
  52. SPtr<Skeleton> Skeleton::create(BONE_DESC* bones, UINT32 numBones)
  53. {
  54. Skeleton* rawPtr = new (bs_alloc<Skeleton>()) Skeleton(bones, numBones);
  55. return bs_shared_ptr<Skeleton>(rawPtr);
  56. }
  57. void Skeleton::getPose(SkeletonPose& pose, const AnimationClip& clip, float time, bool loop)
  58. {
  59. AnimationState state;
  60. state.curves = clip.getCurves();
  61. state.loop = loop;
  62. state.weight = 1.0f;
  63. state.positionEval.time = time;
  64. state.rotationEval.time = time;
  65. state.scaleEval.time = time;
  66. AnimationStateLayer layer;
  67. layer.index = 0;
  68. layer.normalizeWeights = false;
  69. layer.states = &state;
  70. layer.numStates = 1;
  71. state.boneToCurveMapping.resize(mNumBones);
  72. clip.getBoneMapping(*this, state.boneToCurveMapping.data());
  73. getPose(pose, &layer, 1);
  74. }
  75. void Skeleton::getPose(SkeletonPose& pose, const AnimationStateLayer* layers, UINT32 numLayers)
  76. {
  77. assert(pose.numBones == mNumBones);
  78. for(UINT32 i = 0; i < mNumBones; i++)
  79. {
  80. pose.positions[i] = Vector3::ZERO;
  81. pose.rotations[i] = Quaternion::IDENTITY;
  82. pose.scales[i] = Vector3::ONE;
  83. }
  84. for(UINT32 i = 0; i < numLayers; i++)
  85. {
  86. const AnimationStateLayer& layer = layers[i];
  87. float invLayerWeight;
  88. if (layer.normalizeWeights)
  89. {
  90. float weightSum = 0.0f;
  91. for (UINT32 j = 0; j < layer.numStates; j++)
  92. weightSum += layer.normalizeWeights;
  93. invLayerWeight = 1.0f / weightSum;
  94. }
  95. else
  96. invLayerWeight = 1.0f;
  97. for (UINT32 j = 0; j < layer.numStates; j++)
  98. {
  99. const AnimationState& state = layer.states[i];
  100. float normWeight = state.weight * invLayerWeight;
  101. for (UINT32 k = 0; k < mNumBones; k++)
  102. {
  103. const AnimationCurveMapping& mapping = state.boneToCurveMapping[k];
  104. if (mapping.position != (UINT32)-1)
  105. {
  106. const TAnimationCurve<Vector3>& curve = state.curves->position[mapping.position].curve;
  107. pose.positions[k] += curve.evaluate(state.positionEval, state.loop) * normWeight;
  108. }
  109. if (mapping.rotation != (UINT32)-1)
  110. {
  111. const TAnimationCurve<Quaternion>& curve = state.curves->rotation[mapping.rotation].curve;
  112. pose.rotations[k] += curve.evaluate(state.rotationEval, state.loop) * normWeight;
  113. }
  114. if (mapping.scale != (UINT32)-1)
  115. {
  116. const TAnimationCurve<Vector3>& curve = state.curves->scale[mapping.scale].curve;
  117. pose.scales[k] += curve.evaluate(state.scaleEval, state.loop) * normWeight;
  118. }
  119. }
  120. }
  121. }
  122. // Calculate local pose matrices
  123. for(UINT32 i = 0; i < mNumBones; i++)
  124. {
  125. pose.rotations[i].normalize();
  126. pose.bonePoses[i] = Matrix4::TRS(pose.positions[i], pose.rotations[i], pose.scales[i]);
  127. pose.bonePoses[i] = pose.bonePoses[i] * mInvBindPoses[i];
  128. }
  129. // Calculate global poses
  130. UINT32 isGlobalBytes = sizeof(bool) * mNumBones;
  131. bool* isGlobal = (bool*)bs_stack_alloc(isGlobalBytes);
  132. memset(isGlobal, 0, isGlobalBytes);
  133. std::function<void(UINT32)> calcGlobal = [&](UINT32 boneIdx)
  134. {
  135. UINT32 parentBoneIdx = mBoneInfo[boneIdx].parent;
  136. if (parentBoneIdx == (UINT32)-1)
  137. {
  138. isGlobal[boneIdx] = true;
  139. return;
  140. }
  141. if (!isGlobal[parentBoneIdx])
  142. calcGlobal(parentBoneIdx);
  143. pose.bonePoses[boneIdx] = pose.bonePoses[parentBoneIdx] * pose.bonePoses[boneIdx];
  144. isGlobal[boneIdx] = true;
  145. };
  146. for (UINT32 i = 0; i < mNumBones; i++)
  147. {
  148. if (!isGlobal[i])
  149. calcGlobal(i);
  150. }
  151. bs_stack_free(isGlobal);
  152. }
  153. SPtr<Skeleton> Skeleton::createEmpty()
  154. {
  155. Skeleton* rawPtr = new (bs_alloc<Skeleton>()) Skeleton();
  156. SPtr<Skeleton> newSkeleton = bs_shared_ptr<Skeleton>(rawPtr);
  157. return newSkeleton;
  158. }
  159. RTTITypeBase* Skeleton::getRTTIStatic()
  160. {
  161. return SkeletonRTTI::instance();
  162. }
  163. RTTITypeBase* Skeleton::getRTTI() const
  164. {
  165. return getRTTIStatic();
  166. }
  167. }