BsSkeleton.cpp 8.8 KB

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