BsCAnimation.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsCAnimation.h"
  4. #include "BsSceneObject.h"
  5. #include "BsCRenderable.h"
  6. #include "BsCBone.h"
  7. #include "BsCAnimationRTTI.h"
  8. using namespace std::placeholders;
  9. namespace bs
  10. {
  11. CAnimation::CAnimation()
  12. :mWrapMode(AnimWrapMode::Loop), mSpeed(1.0f), mEnableCull(true), mUseBounds(false)
  13. { }
  14. CAnimation::CAnimation(const HSceneObject& parent)
  15. : Component(parent), mWrapMode(AnimWrapMode::Loop), mSpeed(1.0f), mEnableCull(true), mUseBounds(false)
  16. {
  17. mNotifyFlags = TCF_Transform;
  18. setName("Animation");
  19. }
  20. void CAnimation::setDefaultClip(const HAnimationClip& clip)
  21. {
  22. mDefaultClip = clip;
  23. if(clip.isLoaded() && mInternal != nullptr)
  24. {
  25. mInternal->play(clip);
  26. }
  27. }
  28. void CAnimation::setWrapMode(AnimWrapMode wrapMode)
  29. {
  30. mWrapMode = wrapMode;
  31. if (mInternal != nullptr)
  32. mInternal->setWrapMode(wrapMode);
  33. }
  34. void CAnimation::setSpeed(float speed)
  35. {
  36. mSpeed = speed;
  37. if (mInternal != nullptr)
  38. mInternal->setSpeed(speed);
  39. }
  40. void CAnimation::play(const HAnimationClip& clip)
  41. {
  42. if (mInternal != nullptr)
  43. mInternal->play(clip);
  44. }
  45. void CAnimation::blendAdditive(const HAnimationClip& clip, float weight, float fadeLength, UINT32 layer)
  46. {
  47. if (mInternal != nullptr)
  48. mInternal->play(clip);
  49. }
  50. void CAnimation::blend1D(const Blend1DInfo& info, float t)
  51. {
  52. if (mInternal != nullptr)
  53. mInternal->blend1D(info, t);
  54. }
  55. void CAnimation::blend2D(const Blend2DInfo& info, const Vector2& t)
  56. {
  57. if (mInternal != nullptr)
  58. mInternal->blend2D(info, t);
  59. }
  60. void CAnimation::crossFade(const HAnimationClip& clip, float fadeLength)
  61. {
  62. if (mInternal != nullptr)
  63. mInternal->crossFade(clip, fadeLength);
  64. }
  65. void CAnimation::sample(const HAnimationClip& clip, float time)
  66. {
  67. if (mInternal != nullptr)
  68. mInternal->sample(clip, time);
  69. }
  70. void CAnimation::stop(UINT32 layer)
  71. {
  72. if (mInternal != nullptr)
  73. mInternal->stop(layer);
  74. }
  75. void CAnimation::stopAll()
  76. {
  77. if (mInternal != nullptr)
  78. mInternal->stopAll();
  79. }
  80. bool CAnimation::isPlaying() const
  81. {
  82. if (mInternal != nullptr)
  83. return mInternal->isPlaying();
  84. return false;
  85. }
  86. bool CAnimation::getState(const HAnimationClip& clip, AnimationClipState& state)
  87. {
  88. if (mInternal != nullptr)
  89. return mInternal->getState(clip, state);
  90. return false;
  91. }
  92. void CAnimation::setState(const HAnimationClip& clip, AnimationClipState state)
  93. {
  94. if (mInternal != nullptr)
  95. return mInternal->setState(clip, state);
  96. }
  97. void CAnimation::setMorphChannelWeight(UINT32 idx, float weight)
  98. {
  99. if (mInternal != nullptr)
  100. return mInternal->setMorphChannelWeight(idx, weight);
  101. }
  102. void CAnimation::setBounds(const AABox& bounds)
  103. {
  104. mBounds = bounds;
  105. if(mUseBounds)
  106. {
  107. if(mAnimatedRenderable != nullptr)
  108. {
  109. SPtr<Renderable> renderable = mAnimatedRenderable->_getRenderable();
  110. if (renderable != nullptr)
  111. renderable->setOverrideBounds(bounds);
  112. if(mInternal != nullptr)
  113. {
  114. AABox bounds = mBounds;
  115. bounds.transformAffine(SO()->getWorldTfrm());
  116. mInternal->setBounds(bounds);
  117. }
  118. }
  119. }
  120. }
  121. void CAnimation::setUseBounds(bool enable)
  122. {
  123. mUseBounds = enable;
  124. _updateBounds();
  125. }
  126. void CAnimation::setEnableCull(bool enable)
  127. {
  128. mEnableCull = enable;
  129. if (mInternal != nullptr)
  130. mInternal->setCulling(enable);
  131. }
  132. void CAnimation::onInitialized()
  133. {
  134. }
  135. void CAnimation::onDestroyed()
  136. {
  137. destroyInternal();
  138. }
  139. void CAnimation::onDisabled()
  140. {
  141. destroyInternal();
  142. }
  143. void CAnimation::onEnabled()
  144. {
  145. restoreInternal();
  146. }
  147. void CAnimation::onTransformChanged(TransformChangedFlags flags)
  148. {
  149. if (!SO()->getActive())
  150. return;
  151. if ((flags & (TCF_Transform)) != 0)
  152. _updateBounds(false);
  153. }
  154. void CAnimation::restoreInternal()
  155. {
  156. if (mInternal == nullptr)
  157. {
  158. mInternal = Animation::create();
  159. mInternal->onEventTriggered.connect(std::bind(&CAnimation::eventTriggered, this, _1, _2));
  160. }
  161. mAnimatedRenderable = SO()->getComponent<CRenderable>();
  162. mInternal->setWrapMode(mWrapMode);
  163. mInternal->setSpeed(mSpeed);
  164. mInternal->setCulling(mEnableCull);
  165. _updateBounds();
  166. if (mDefaultClip.isLoaded())
  167. mInternal->play(mDefaultClip);
  168. setBoneMappings();
  169. if (mAnimatedRenderable != nullptr)
  170. mAnimatedRenderable->_registerAnimation(mThisHandle);
  171. }
  172. void CAnimation::destroyInternal()
  173. {
  174. if (mAnimatedRenderable != nullptr)
  175. mAnimatedRenderable->_unregisterAnimation();
  176. // This should release the last reference and destroy the internal listener
  177. mInternal = nullptr;
  178. }
  179. void CAnimation::_addBone(const HBone& bone)
  180. {
  181. if (mInternal == nullptr)
  182. return;
  183. HSceneObject currentSO = bone->SO();
  184. SceneObjectMappingInfo newMapping;
  185. newMapping.sceneObject = currentSO;
  186. newMapping.isMappedToBone = true;
  187. newMapping.bone = bone;
  188. mMappingInfos.push_back(newMapping);
  189. mInternal->mapCurveToSceneObject(bone->getName(), newMapping.sceneObject);
  190. }
  191. void CAnimation::_removeBone(const HBone& bone)
  192. {
  193. if (mInternal == nullptr)
  194. return;
  195. HSceneObject newSO;
  196. for (UINT32 i = 0; i < (UINT32)mMappingInfos.size(); i++)
  197. {
  198. if (mMappingInfos[i].bone == bone)
  199. {
  200. mMappingInfos.erase(mMappingInfos.begin() + i);
  201. mInternal->unmapSceneObject(mMappingInfos[i].sceneObject);
  202. i--;
  203. }
  204. }
  205. }
  206. void CAnimation::_notifyBoneChanged(const HBone& bone)
  207. {
  208. if (mInternal == nullptr)
  209. return;
  210. for (UINT32 i = 0; i < (UINT32)mMappingInfos.size(); i++)
  211. {
  212. if (mMappingInfos[i].bone == bone)
  213. {
  214. mInternal->unmapSceneObject(mMappingInfos[i].sceneObject);
  215. mInternal->mapCurveToSceneObject(bone->getName(), mMappingInfos[i].sceneObject);
  216. break;
  217. }
  218. }
  219. }
  220. void CAnimation::_registerRenderable(const HRenderable& renderable)
  221. {
  222. mAnimatedRenderable = renderable;
  223. _updateBounds();
  224. }
  225. void CAnimation::_unregisterRenderable()
  226. {
  227. mAnimatedRenderable = nullptr;
  228. }
  229. void CAnimation::_updateBounds(bool updateRenderable)
  230. {
  231. SPtr<Renderable> renderable;
  232. if (updateRenderable && mAnimatedRenderable != nullptr)
  233. renderable = mAnimatedRenderable->_getRenderable();
  234. if (mUseBounds)
  235. {
  236. if (renderable != nullptr)
  237. {
  238. renderable->setUseOverrideBounds(true);
  239. renderable->setOverrideBounds(mBounds);
  240. }
  241. if (mInternal != nullptr)
  242. {
  243. AABox bounds = mBounds;
  244. bounds.transformAffine(SO()->getWorldTfrm());
  245. mInternal->setBounds(bounds);
  246. }
  247. }
  248. else
  249. {
  250. if (renderable != nullptr)
  251. renderable->setUseOverrideBounds(false);
  252. if (mInternal != nullptr)
  253. {
  254. AABox bounds;
  255. if (mAnimatedRenderable != nullptr)
  256. bounds = mAnimatedRenderable->getBounds().getBox();
  257. mInternal->setBounds(bounds);
  258. }
  259. }
  260. }
  261. void CAnimation::setBoneMappings()
  262. {
  263. mMappingInfos.clear();
  264. SceneObjectMappingInfo rootMapping;
  265. rootMapping.sceneObject = SO();
  266. rootMapping.isMappedToBone = true;
  267. mMappingInfos.push_back(rootMapping);
  268. mInternal->mapCurveToSceneObject("", rootMapping.sceneObject);
  269. Vector<HBone> childBones = findChildBones();
  270. for (auto& entry : childBones)
  271. _addBone(entry);
  272. }
  273. Vector<HBone> CAnimation::findChildBones()
  274. {
  275. Stack<HSceneObject> todo;
  276. todo.push(SO());
  277. Vector<HBone> bones;
  278. while (todo.size() > 0)
  279. {
  280. HSceneObject currentSO = todo.top();
  281. todo.pop();
  282. HBone bone = currentSO->getComponent<CBone>();
  283. if (bone != nullptr)
  284. {
  285. bone->_setParent(getHandle(), true);
  286. bones.push_back(bone);
  287. }
  288. int childCount = currentSO->getNumChildren();
  289. for (int i = 0; i < childCount; i++)
  290. {
  291. HSceneObject child = currentSO->getChild(i);
  292. if (child->getComponent<CAnimation>() != nullptr)
  293. continue;
  294. todo.push(child);
  295. }
  296. }
  297. return bones;
  298. }
  299. void CAnimation::eventTriggered(const HAnimationClip& clip, const String& name)
  300. {
  301. onEventTriggered(clip, name);
  302. }
  303. RTTITypeBase* CAnimation::getRTTIStatic()
  304. {
  305. return CAnimationRTTI::instance();
  306. }
  307. RTTITypeBase* CAnimation::getRTTI() const
  308. {
  309. return CAnimation::getRTTIStatic();
  310. }
  311. }