BsAnimationClip.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsAnimationClip.h"
  4. #include "BsResources.h"
  5. #include "BsSkeleton.h"
  6. #include "BsAnimationClipRTTI.h"
  7. namespace BansheeEngine
  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>()), mIsAdditive(false), mLength(0.0f)
  67. , mSampleRate(1)
  68. {
  69. }
  70. AnimationClip::AnimationClip(const SPtr<AnimationCurves>& curves, bool isAdditive, UINT32 sampleRate)
  71. : Resource(false), mVersion(0), mCurves(curves), mIsAdditive(isAdditive), mLength(0.0f), mSampleRate(sampleRate)
  72. {
  73. buildNameMapping();
  74. calculateLength();
  75. }
  76. HAnimationClip AnimationClip::create(bool isAdditive)
  77. {
  78. return static_resource_cast<AnimationClip>(gResources()._createResourceHandle(_createPtr(bs_shared_ptr_new<AnimationCurves>(), isAdditive)));
  79. }
  80. HAnimationClip AnimationClip::create(const SPtr<AnimationCurves>& curves, bool isAdditive, UINT32 sampleRate)
  81. {
  82. return static_resource_cast<AnimationClip>(gResources()._createResourceHandle(_createPtr(curves, isAdditive, sampleRate)));
  83. }
  84. SPtr<AnimationClip> AnimationClip::createEmpty()
  85. {
  86. AnimationClip* rawPtr = new (bs_alloc<AnimationClip>()) AnimationClip();
  87. SPtr<AnimationClip> newClip = bs_core_ptr<AnimationClip>(rawPtr);
  88. newClip->_setThisPtr(newClip);
  89. return newClip;
  90. }
  91. SPtr<AnimationClip> AnimationClip::_createPtr(const SPtr<AnimationCurves>& curves, bool isAdditive, UINT32 sampleRate)
  92. {
  93. AnimationClip* rawPtr = new (bs_alloc<AnimationClip>()) AnimationClip(curves, isAdditive, sampleRate);
  94. SPtr<AnimationClip> newClip = bs_core_ptr<AnimationClip>(rawPtr);
  95. newClip->_setThisPtr(newClip);
  96. newClip->initialize();
  97. return newClip;
  98. }
  99. void AnimationClip::setCurves(const AnimationCurves& curves)
  100. {
  101. *mCurves = curves;
  102. buildNameMapping();
  103. calculateLength();
  104. mVersion++;
  105. }
  106. void AnimationClip::calculateLength()
  107. {
  108. mLength = 0.0f;
  109. for (auto& entry : mCurves->position)
  110. mLength = std::max(mLength, entry.curve.getLength());
  111. for (auto& entry : mCurves->rotation)
  112. mLength = std::max(mLength, entry.curve.getLength());
  113. for (auto& entry : mCurves->scale)
  114. mLength = std::max(mLength, entry.curve.getLength());
  115. for (auto& entry : mCurves->generic)
  116. mLength = std::max(mLength, entry.curve.getLength());
  117. }
  118. void AnimationClip::buildNameMapping()
  119. {
  120. mNameMapping.clear();
  121. auto registerEntries = [&](auto& curve, CurveType type)
  122. {
  123. UINT32 typeIdx = (UINT32)type;
  124. for (UINT32 i = 0; i < (UINT32)curve.size(); i++)
  125. {
  126. auto& entry = curve[i];
  127. auto iterFind = mNameMapping.find(entry.name);
  128. if (iterFind == mNameMapping.end())
  129. {
  130. UINT32* indices = mNameMapping[entry.name];
  131. memset(indices, -1, sizeof(UINT32) * 4);
  132. indices[typeIdx] = i;
  133. }
  134. else
  135. mNameMapping[entry.name][typeIdx] = i;
  136. }
  137. };
  138. registerEntries(mCurves->position, CurveType::Position);
  139. registerEntries(mCurves->rotation, CurveType::Rotation);
  140. registerEntries(mCurves->scale, CurveType::Scale);
  141. registerEntries(mCurves->generic, CurveType::Generic);
  142. }
  143. void AnimationClip::initialize()
  144. {
  145. buildNameMapping();
  146. Resource::initialize();
  147. }
  148. void AnimationClip::getBoneMapping(const Skeleton& skeleton, AnimationCurveMapping* mapping) const
  149. {
  150. UINT32 numBones = skeleton.getNumBones();
  151. for(UINT32 i = 0; i < numBones; i++)
  152. {
  153. const SkeletonBoneInfo& boneInfo = skeleton.getBoneInfo(i);
  154. getCurveMapping(boneInfo.name, mapping[i]);
  155. }
  156. }
  157. void AnimationClip::getCurveMapping(const String& name, AnimationCurveMapping& mapping) const
  158. {
  159. auto iterFind = mNameMapping.find(name);
  160. if (iterFind != mNameMapping.end())
  161. {
  162. const UINT32* indices = iterFind->second;
  163. mapping.position = indices[(UINT32)CurveType::Position];
  164. mapping.rotation = indices[(UINT32)CurveType::Rotation];
  165. mapping.scale = indices[(UINT32)CurveType::Scale];
  166. }
  167. else
  168. mapping = { (UINT32)-1, (UINT32)-1, (UINT32)-1 };
  169. }
  170. RTTITypeBase* AnimationClip::getRTTIStatic()
  171. {
  172. return AnimationClipRTTI::instance();
  173. }
  174. RTTITypeBase* AnimationClip::getRTTI() const
  175. {
  176. return getRTTIStatic();
  177. }
  178. }