BsAnimationClip.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Animation/BsAnimationClip.h"
  4. #include "Resources/BsResources.h"
  5. #include "Animation/BsSkeleton.h"
  6. #include "Private/RTTI/BsAnimationClipRTTI.h"
  7. namespace bs
  8. {
  9. void AnimationCurves::addPositionCurve(const String& name, const TAnimationCurve<Vector3>& curve)
  10. {
  11. auto iterFind = std::find_if(position.begin(), position.end(), [&](auto x) { return x.name == name; });
  12. if (iterFind != position.end())
  13. iterFind->curve = curve;
  14. else
  15. position.push_back({ name, AnimationCurveFlags(), curve });
  16. }
  17. void AnimationCurves::addRotationCurve(const String& name, const TAnimationCurve<Quaternion>& curve)
  18. {
  19. auto iterFind = std::find_if(rotation.begin(), rotation.end(), [&](auto x) { return x.name == name; });
  20. if (iterFind != rotation.end())
  21. iterFind->curve = curve;
  22. else
  23. rotation.push_back({ name, AnimationCurveFlags(), curve });
  24. }
  25. void AnimationCurves::addScaleCurve(const String& name, const TAnimationCurve<Vector3>& curve)
  26. {
  27. auto iterFind = std::find_if(scale.begin(), scale.end(), [&](auto x) { return x.name == name; });
  28. if (iterFind != scale.end())
  29. iterFind->curve = curve;
  30. else
  31. scale.push_back({ name, AnimationCurveFlags(), curve });
  32. }
  33. void AnimationCurves::addGenericCurve(const String& name, const TAnimationCurve<float>& curve)
  34. {
  35. auto iterFind = std::find_if(generic.begin(), generic.end(), [&](auto x) { return x.name == name; });
  36. if (iterFind != generic.end())
  37. iterFind->curve = curve;
  38. else
  39. generic.push_back({ name, AnimationCurveFlags(), curve });
  40. }
  41. void AnimationCurves::removePositionCurve(const String& name)
  42. {
  43. auto iterFind = std::find_if(position.begin(), position.end(), [&](auto x) { return x.name == name; });
  44. if (iterFind != position.end())
  45. position.erase(iterFind);
  46. }
  47. void AnimationCurves::removeRotationCurve(const String& name)
  48. {
  49. auto iterFind = std::find_if(rotation.begin(), rotation.end(), [&](auto x) { return x.name == name; });
  50. if (iterFind != rotation.end())
  51. rotation.erase(iterFind);
  52. }
  53. void AnimationCurves::removeScaleCurve(const String& name)
  54. {
  55. auto iterFind = std::find_if(scale.begin(), scale.end(), [&](auto x) { return x.name == name; });
  56. if (iterFind != scale.end())
  57. scale.erase(iterFind);
  58. }
  59. void AnimationCurves::removeGenericCurve(const String& name)
  60. {
  61. auto iterFind = std::find_if(generic.begin(), generic.end(), [&](auto x) { return x.name == name; });
  62. if (iterFind != generic.end())
  63. generic.erase(iterFind);
  64. }
  65. AnimationClip::AnimationClip()
  66. : Resource(false), mVersion(0), mCurves(bs_shared_ptr_new<AnimationCurves>())
  67. , mRootMotion(bs_shared_ptr_new<RootMotion>()), mIsAdditive(false), mLength(0.0f), mSampleRate(1)
  68. {
  69. }
  70. AnimationClip::AnimationClip(const SPtr<AnimationCurves>& curves, bool isAdditive, UINT32 sampleRate,
  71. const SPtr<RootMotion>& rootMotion)
  72. : Resource(false), mVersion(0), mCurves(curves), mRootMotion(rootMotion), mIsAdditive(isAdditive), mLength(0.0f)
  73. , mSampleRate(sampleRate)
  74. {
  75. if (mCurves == nullptr)
  76. mCurves = bs_shared_ptr_new<AnimationCurves>();
  77. if (mRootMotion == nullptr)
  78. mRootMotion = bs_shared_ptr_new<RootMotion>();
  79. buildNameMapping();
  80. calculateLength();
  81. }
  82. HAnimationClip AnimationClip::create(bool isAdditive)
  83. {
  84. return static_resource_cast<AnimationClip>(gResources()._createResourceHandle(
  85. _createPtr(bs_shared_ptr_new<AnimationCurves>(), isAdditive)));
  86. }
  87. HAnimationClip AnimationClip::create(const SPtr<AnimationCurves>& curves, bool isAdditive, UINT32 sampleRate,
  88. const SPtr<RootMotion>& rootMotion)
  89. {
  90. return static_resource_cast<AnimationClip>(gResources()._createResourceHandle(
  91. _createPtr(curves, isAdditive, sampleRate, rootMotion)));
  92. }
  93. SPtr<AnimationClip> AnimationClip::createEmpty()
  94. {
  95. AnimationClip* rawPtr = new (bs_alloc<AnimationClip>()) AnimationClip();
  96. SPtr<AnimationClip> newClip = bs_core_ptr<AnimationClip>(rawPtr);
  97. newClip->_setThisPtr(newClip);
  98. return newClip;
  99. }
  100. SPtr<AnimationClip> AnimationClip::_createPtr(const SPtr<AnimationCurves>& curves, bool isAdditive, UINT32 sampleRate,
  101. const SPtr<RootMotion>& rootMotion)
  102. {
  103. AnimationClip* rawPtr = new (bs_alloc<AnimationClip>()) AnimationClip(curves, isAdditive, sampleRate, rootMotion);
  104. SPtr<AnimationClip> newClip = bs_core_ptr<AnimationClip>(rawPtr);
  105. newClip->_setThisPtr(newClip);
  106. newClip->initialize();
  107. return newClip;
  108. }
  109. void AnimationClip::setCurves(const AnimationCurves& curves)
  110. {
  111. *mCurves = curves;
  112. buildNameMapping();
  113. calculateLength();
  114. mVersion++;
  115. }
  116. bool AnimationClip::hasRootMotion() const
  117. {
  118. return mRootMotion != nullptr &&
  119. (mRootMotion->position.getNumKeyFrames() > 0 || mRootMotion->rotation.getNumKeyFrames() > 0);
  120. }
  121. void AnimationClip::calculateLength()
  122. {
  123. mLength = 0.0f;
  124. for (auto& entry : mCurves->position)
  125. mLength = std::max(mLength, entry.curve.getLength());
  126. for (auto& entry : mCurves->rotation)
  127. mLength = std::max(mLength, entry.curve.getLength());
  128. for (auto& entry : mCurves->scale)
  129. mLength = std::max(mLength, entry.curve.getLength());
  130. for (auto& entry : mCurves->generic)
  131. mLength = std::max(mLength, entry.curve.getLength());
  132. }
  133. void AnimationClip::buildNameMapping()
  134. {
  135. mNameMapping.clear();
  136. auto registerEntries = [&](auto& curve, CurveType type)
  137. {
  138. UINT32 typeIdx = (UINT32)type;
  139. for (UINT32 i = 0; i < (UINT32)curve.size(); i++)
  140. {
  141. auto& entry = curve[i];
  142. auto iterFind = mNameMapping.find(entry.name);
  143. if (iterFind == mNameMapping.end())
  144. {
  145. UINT32* indices = mNameMapping[entry.name];
  146. memset(indices, -1, sizeof(UINT32) * (int)CurveType::Count);
  147. indices[typeIdx] = i;
  148. }
  149. else
  150. mNameMapping[entry.name][typeIdx] = i;
  151. }
  152. };
  153. registerEntries(mCurves->position, CurveType::Position);
  154. registerEntries(mCurves->rotation, CurveType::Rotation);
  155. registerEntries(mCurves->scale, CurveType::Scale);
  156. // Generic and morph curves
  157. {
  158. Vector<TNamedAnimationCurve<float>>& curve = mCurves->generic;
  159. for (UINT32 i = 0; i < (UINT32)curve.size(); i++)
  160. {
  161. auto& entry = curve[i];
  162. UINT32 typeIdx;
  163. if (entry.flags.isSet(AnimationCurveFlag::MorphFrame))
  164. typeIdx = (UINT32)CurveType::MorphFrame;
  165. else if (entry.flags.isSet(AnimationCurveFlag::MorphWeight))
  166. typeIdx = (UINT32)CurveType::MorphWeight;
  167. else
  168. typeIdx = (UINT32)CurveType::Generic;
  169. auto iterFind = mNameMapping.find(entry.name);
  170. if (iterFind == mNameMapping.end())
  171. {
  172. UINT32* indices = mNameMapping[entry.name];
  173. memset(indices, -1, sizeof(UINT32) * (int)CurveType::Count);
  174. indices[typeIdx] = i;
  175. }
  176. else
  177. mNameMapping[entry.name][typeIdx] = i;
  178. }
  179. }
  180. }
  181. void AnimationClip::initialize()
  182. {
  183. buildNameMapping();
  184. Resource::initialize();
  185. }
  186. void AnimationClip::getBoneMapping(const Skeleton& skeleton, AnimationCurveMapping* mapping) const
  187. {
  188. UINT32 numBones = skeleton.getNumBones();
  189. for(UINT32 i = 0; i < numBones; i++)
  190. {
  191. const SkeletonBoneInfo& boneInfo = skeleton.getBoneInfo(i);
  192. getCurveMapping(boneInfo.name, mapping[i]);
  193. }
  194. }
  195. void AnimationClip::getCurveMapping(const String& name, AnimationCurveMapping& mapping) const
  196. {
  197. auto iterFind = mNameMapping.find(name);
  198. if (iterFind != mNameMapping.end())
  199. {
  200. const UINT32* indices = iterFind->second;
  201. mapping.position = indices[(UINT32)CurveType::Position];
  202. mapping.rotation = indices[(UINT32)CurveType::Rotation];
  203. mapping.scale = indices[(UINT32)CurveType::Scale];
  204. }
  205. else
  206. mapping = { (UINT32)-1, (UINT32)-1, (UINT32)-1 };
  207. }
  208. void AnimationClip::getMorphMapping(const String& name, UINT32& frameIdx, UINT32& weightIdx) const
  209. {
  210. auto iterFind = mNameMapping.find(name);
  211. if (iterFind != mNameMapping.end())
  212. {
  213. const UINT32* indices = iterFind->second;
  214. frameIdx = indices[(UINT32)CurveType::MorphFrame];
  215. weightIdx = indices[(UINT32)CurveType::MorphWeight];
  216. }
  217. else
  218. {
  219. frameIdx = (UINT32)-1;
  220. weightIdx = (UINT32)-1;
  221. }
  222. }
  223. RTTITypeBase* AnimationClip::getRTTIStatic()
  224. {
  225. return AnimationClipRTTI::instance();
  226. }
  227. RTTITypeBase* AnimationClip::getRTTI() const
  228. {
  229. return getRTTIStatic();
  230. }
  231. }