BsSkeleton.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  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. LocalSkeletonPose::LocalSkeletonPose()
  9. : positions(nullptr), rotations(nullptr), scales(nullptr), numBones(0)
  10. { }
  11. LocalSkeletonPose::LocalSkeletonPose(UINT32 numBones)
  12. : numBones(numBones)
  13. {
  14. UINT32 elementSize = sizeof(Vector3) * 2 + sizeof(Quaternion);
  15. UINT8* buffer = (UINT8*)bs_alloc(elementSize * sizeof(numBones));
  16. positions = (Vector3*)buffer;
  17. buffer += sizeof(Vector3) * numBones;
  18. rotations = (Quaternion*)buffer;
  19. buffer += sizeof(Quaternion) * numBones;
  20. scales = (Vector3*)buffer;
  21. }
  22. LocalSkeletonPose::LocalSkeletonPose(UINT32 numPos, UINT32 numRot, UINT32 numScale)
  23. : numBones(0)
  24. {
  25. UINT32 bufferSize = sizeof(Vector3) * numPos + sizeof(Quaternion) * numRot + sizeof(Vector3) * numScale;
  26. UINT8* buffer = (UINT8*)bs_alloc(bufferSize);
  27. positions = (Vector3*)buffer;
  28. buffer += sizeof(Vector3) * numPos;
  29. rotations = (Quaternion*)buffer;
  30. buffer += sizeof(Quaternion) * numRot;
  31. scales = (Vector3*)buffer;
  32. }
  33. LocalSkeletonPose::~LocalSkeletonPose()
  34. {
  35. if (positions != nullptr)
  36. bs_free(positions);
  37. }
  38. Skeleton::Skeleton()
  39. :mInvBindPoses(nullptr), mBoneInfo(nullptr), mNumBones(0)
  40. { }
  41. Skeleton::Skeleton(BONE_DESC* bones, UINT32 numBones)
  42. :mInvBindPoses(bs_newN<Matrix4>(numBones)), mBoneInfo(bs_newN<SkeletonBoneInfo>(numBones)), mNumBones(numBones)
  43. {
  44. for(UINT32 i = 0; i < numBones; i++)
  45. {
  46. mInvBindPoses[i] = bones[i].invBindPose;
  47. mBoneInfo[i].name = bones[i].name;
  48. mBoneInfo[i].parent = bones[i].parent;
  49. }
  50. }
  51. Skeleton::~Skeleton()
  52. {
  53. if(mInvBindPoses != nullptr)
  54. bs_deleteN(mInvBindPoses, mNumBones);
  55. if (mBoneInfo != nullptr)
  56. bs_deleteN(mBoneInfo, mNumBones);
  57. }
  58. SPtr<Skeleton> Skeleton::create(BONE_DESC* bones, UINT32 numBones)
  59. {
  60. Skeleton* rawPtr = new (bs_alloc<Skeleton>()) Skeleton(bones, numBones);
  61. return bs_shared_ptr<Skeleton>(rawPtr);
  62. }
  63. void Skeleton::getPose(Matrix4* pose, LocalSkeletonPose& localPose, const AnimationClip& clip, float time,
  64. bool loop)
  65. {
  66. bs_frame_mark();
  67. {
  68. FrameVector<AnimationCurveMapping> boneToCurveMapping(mNumBones);
  69. AnimationState state;
  70. state.curves = clip.getCurves();
  71. state.boneToCurveMapping = boneToCurveMapping.data();
  72. state.loop = loop;
  73. state.weight = 1.0f;
  74. state.time = time;
  75. FrameVector<TCurveCache<Vector3>> positionCache(state.curves->position.size());
  76. FrameVector<TCurveCache<Quaternion>> rotationCache(state.curves->rotation.size());
  77. FrameVector<TCurveCache<Vector3>> scaleCache(state.curves->scale.size());
  78. state.positionCaches = positionCache.data();
  79. state.rotationCaches = rotationCache.data();
  80. state.scaleCaches = scaleCache.data();
  81. state.genericCaches = nullptr;
  82. AnimationStateLayer layer;
  83. layer.index = 0;
  84. layer.additive = false;
  85. layer.states = &state;
  86. layer.numStates = 1;
  87. clip.getBoneMapping(*this, state.boneToCurveMapping);
  88. getPose(pose, localPose, &layer, 1);
  89. }
  90. bs_frame_clear();
  91. }
  92. void Skeleton::getPose(Matrix4* pose, LocalSkeletonPose& localPose, const AnimationStateLayer* layers,
  93. UINT32 numLayers)
  94. {
  95. // Note: If more performance is required this method could be optimized with vector instructions
  96. assert(localPose.numBones == mNumBones);
  97. for(UINT32 i = 0; i < mNumBones; i++)
  98. {
  99. localPose.positions[i] = Vector3::ZERO;
  100. localPose.rotations[i] = Quaternion::IDENTITY;
  101. localPose.scales[i] = Vector3::ONE;
  102. }
  103. for(UINT32 i = 0; i < numLayers; i++)
  104. {
  105. const AnimationStateLayer& layer = layers[i];
  106. float invLayerWeight;
  107. if (layer.additive)
  108. {
  109. float weightSum = 0.0f;
  110. for (UINT32 j = 0; j < layer.numStates; j++)
  111. weightSum += layer.states[j].weight;
  112. invLayerWeight = 1.0f / weightSum;
  113. }
  114. else
  115. invLayerWeight = 1.0f;
  116. for (UINT32 j = 0; j < layer.numStates; j++)
  117. {
  118. const AnimationState& state = layer.states[j];
  119. float normWeight = state.weight * invLayerWeight;
  120. // Early exit for clips that don't contribute (which there could be plenty especially for sequential blends)
  121. if (Math::approxEquals(normWeight, 0.0f))
  122. continue;
  123. for (UINT32 k = 0; k < mNumBones; k++)
  124. {
  125. const AnimationCurveMapping& mapping = state.boneToCurveMapping[k];
  126. if (mapping.position != (UINT32)-1)
  127. {
  128. const TAnimationCurve<Vector3>& curve = state.curves->position[mapping.position].curve;
  129. localPose.positions[k] += curve.evaluate(state.time, state.positionCaches[k], state.loop) * normWeight;
  130. }
  131. }
  132. for (UINT32 k = 0; k < mNumBones; k++)
  133. {
  134. const AnimationCurveMapping& mapping = state.boneToCurveMapping[k];
  135. if (mapping.scale != (UINT32)-1)
  136. {
  137. const TAnimationCurve<Vector3>& curve = state.curves->scale[mapping.scale].curve;
  138. localPose.scales[k] += curve.evaluate(state.time, state.scaleCaches[k], state.loop) * normWeight;
  139. }
  140. }
  141. if(layer.additive)
  142. {
  143. for (UINT32 k = 0; k < mNumBones; k++)
  144. {
  145. const AnimationCurveMapping& mapping = state.boneToCurveMapping[k];
  146. if (mapping.rotation != (UINT32)-1)
  147. {
  148. const TAnimationCurve<Quaternion>& curve = state.curves->rotation[mapping.rotation].curve;
  149. Quaternion value = curve.evaluate(state.time, state.rotationCaches[k], state.loop);
  150. value = Quaternion::lerp(normWeight, Quaternion::IDENTITY, value);
  151. localPose.rotations[k] *= value;
  152. }
  153. }
  154. }
  155. else
  156. {
  157. for (UINT32 k = 0; k < mNumBones; k++)
  158. {
  159. const AnimationCurveMapping& mapping = state.boneToCurveMapping[k];
  160. if (mapping.rotation != (UINT32)-1)
  161. {
  162. const TAnimationCurve<Quaternion>& curve = state.curves->rotation[mapping.rotation].curve;
  163. localPose.rotations[k] += curve.evaluate(state.time, state.rotationCaches[k], state.loop) * normWeight;
  164. }
  165. }
  166. }
  167. }
  168. }
  169. // Calculate local pose matrices
  170. for(UINT32 i = 0; i < mNumBones; i++)
  171. {
  172. localPose.rotations[i].normalize();
  173. pose[i] = Matrix4::TRS(localPose.positions[i], localPose.rotations[i], localPose.scales[i]);
  174. pose[i] = pose[i] * mInvBindPoses[i];
  175. }
  176. // Calculate global poses
  177. UINT32 isGlobalBytes = sizeof(bool) * mNumBones;
  178. bool* isGlobal = (bool*)bs_stack_alloc(isGlobalBytes);
  179. memset(isGlobal, 0, isGlobalBytes);
  180. std::function<void(UINT32)> calcGlobal = [&](UINT32 boneIdx)
  181. {
  182. UINT32 parentBoneIdx = mBoneInfo[boneIdx].parent;
  183. if (parentBoneIdx == (UINT32)-1)
  184. {
  185. isGlobal[boneIdx] = true;
  186. return;
  187. }
  188. if (!isGlobal[parentBoneIdx])
  189. calcGlobal(parentBoneIdx);
  190. pose[boneIdx] = pose[parentBoneIdx] * pose[boneIdx];
  191. isGlobal[boneIdx] = true;
  192. };
  193. for (UINT32 i = 0; i < mNumBones; i++)
  194. {
  195. if (!isGlobal[i])
  196. calcGlobal(i);
  197. }
  198. bs_stack_free(isGlobal);
  199. }
  200. SPtr<Skeleton> Skeleton::createEmpty()
  201. {
  202. Skeleton* rawPtr = new (bs_alloc<Skeleton>()) Skeleton();
  203. SPtr<Skeleton> newSkeleton = bs_shared_ptr<Skeleton>(rawPtr);
  204. return newSkeleton;
  205. }
  206. RTTITypeBase* Skeleton::getRTTIStatic()
  207. {
  208. return SkeletonRTTI::instance();
  209. }
  210. RTTITypeBase* Skeleton::getRTTI() const
  211. {
  212. return getRTTIStatic();
  213. }
  214. }