BsAnimationClip.cpp 6.1 KB

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