BsCAnimation.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Components/BsCAnimation.h"
  4. #include "Scene/BsSceneObject.h"
  5. #include "Components/BsCRenderable.h"
  6. #include "Components/BsCBone.h"
  7. #include "Mesh/BsMesh.h"
  8. #include "Animation/BsMorphShapes.h"
  9. #include "Animation/BsAnimationClip.h"
  10. #include "RTTI/BsCAnimationRTTI.h"
  11. #include "Scene/BsSceneManager.h"
  12. using namespace std::placeholders;
  13. namespace bs
  14. {
  15. CAnimation::CAnimation()
  16. :mWrapMode(AnimWrapMode::Loop), mSpeed(1.0f), mEnableCull(true), mUseBounds(false), mPreviewMode(false)
  17. {
  18. mNotifyFlags = TCF_Transform;
  19. setFlag(ComponentFlag::AlwaysRun, true);
  20. setName("Animation");
  21. }
  22. CAnimation::CAnimation(const HSceneObject& parent)
  23. : Component(parent), mWrapMode(AnimWrapMode::Loop), mSpeed(1.0f), mEnableCull(true), mUseBounds(false), mPreviewMode(false)
  24. {
  25. mNotifyFlags = TCF_Transform;
  26. setFlag(ComponentFlag::AlwaysRun, true);
  27. setName("Animation");
  28. }
  29. void CAnimation::setDefaultClip(const HAnimationClip& clip)
  30. {
  31. mDefaultClip = clip;
  32. if(clip.isLoaded() && mInternal != nullptr && !mPreviewMode)
  33. mInternal->play(clip);
  34. }
  35. void CAnimation::setWrapMode(AnimWrapMode wrapMode)
  36. {
  37. mWrapMode = wrapMode;
  38. if (mInternal != nullptr && !mPreviewMode)
  39. mInternal->setWrapMode(wrapMode);
  40. }
  41. void CAnimation::setSpeed(float speed)
  42. {
  43. mSpeed = speed;
  44. if (mInternal != nullptr && !mPreviewMode)
  45. mInternal->setSpeed(speed);
  46. }
  47. void CAnimation::play(const HAnimationClip& clip)
  48. {
  49. if (mInternal != nullptr && !mPreviewMode)
  50. mInternal->play(clip);
  51. }
  52. void CAnimation::blendAdditive(const HAnimationClip& clip, float weight, float fadeLength, UINT32 layer)
  53. {
  54. if (mInternal != nullptr && !mPreviewMode)
  55. mInternal->play(clip);
  56. }
  57. void CAnimation::blend1D(const Blend1DInfo& info, float t)
  58. {
  59. if (mInternal != nullptr && !mPreviewMode)
  60. mInternal->blend1D(info, t);
  61. }
  62. void CAnimation::blend2D(const Blend2DInfo& info, const Vector2& t)
  63. {
  64. if (mInternal != nullptr && !mPreviewMode)
  65. mInternal->blend2D(info, t);
  66. }
  67. void CAnimation::crossFade(const HAnimationClip& clip, float fadeLength)
  68. {
  69. if (mInternal != nullptr && !mPreviewMode)
  70. mInternal->crossFade(clip, fadeLength);
  71. }
  72. void CAnimation::sample(const HAnimationClip& clip, float time)
  73. {
  74. if (mInternal != nullptr)
  75. mInternal->sample(clip, time);
  76. }
  77. void CAnimation::stop(UINT32 layer)
  78. {
  79. if (mInternal != nullptr && !mPreviewMode)
  80. mInternal->stop(layer);
  81. }
  82. void CAnimation::stopAll()
  83. {
  84. if (mInternal != nullptr && !mPreviewMode)
  85. mInternal->stopAll();
  86. }
  87. bool CAnimation::isPlaying() const
  88. {
  89. if (mInternal != nullptr)
  90. return mInternal->isPlaying();
  91. return false;
  92. }
  93. bool CAnimation::getState(const HAnimationClip& clip, AnimationClipState& state)
  94. {
  95. if (mInternal != nullptr)
  96. return mInternal->getState(clip, state);
  97. return false;
  98. }
  99. void CAnimation::setState(const HAnimationClip& clip, AnimationClipState state)
  100. {
  101. if (mInternal != nullptr)
  102. return mInternal->setState(clip, state);
  103. }
  104. void CAnimation::setMorphChannelWeight(const String& name, float weight)
  105. {
  106. if (mInternal == nullptr)
  107. return;
  108. if (mAnimatedRenderable == nullptr)
  109. return;
  110. HMesh mesh = mAnimatedRenderable->getMesh();
  111. if (!mesh.isLoaded())
  112. return;
  113. SPtr<MorphShapes> morphShapes = mesh->getMorphShapes();
  114. if (morphShapes == nullptr)
  115. return;
  116. const Vector<SPtr<MorphChannel>>& channels = morphShapes->getChannels();
  117. for (UINT32 i = 0; i < (UINT32)channels.size(); i++)
  118. {
  119. if (channels[i]->getName() == name)
  120. {
  121. mInternal->setMorphChannelWeight(i, weight);
  122. break;
  123. }
  124. }
  125. }
  126. void CAnimation::setBounds(const AABox& bounds)
  127. {
  128. mBounds = bounds;
  129. if(mUseBounds)
  130. {
  131. if(mAnimatedRenderable != nullptr)
  132. {
  133. SPtr<Renderable> renderable = mAnimatedRenderable->_getRenderable();
  134. if (renderable != nullptr)
  135. renderable->setOverrideBounds(bounds);
  136. if(mInternal != nullptr && !mPreviewMode)
  137. {
  138. AABox bounds = mBounds;
  139. bounds.transformAffine(SO()->getWorldMatrix());
  140. mInternal->setBounds(bounds);
  141. }
  142. }
  143. }
  144. }
  145. void CAnimation::setUseBounds(bool enable)
  146. {
  147. mUseBounds = enable;
  148. _updateBounds();
  149. }
  150. void CAnimation::setEnableCull(bool enable)
  151. {
  152. mEnableCull = enable;
  153. if (mInternal != nullptr && !mPreviewMode)
  154. mInternal->setCulling(enable);
  155. }
  156. UINT32 CAnimation::getNumClips() const
  157. {
  158. if (mInternal != nullptr)
  159. return mInternal->getNumClips();
  160. return 0;
  161. }
  162. HAnimationClip CAnimation::getClip(UINT32 idx) const
  163. {
  164. if (mInternal != nullptr)
  165. return mInternal->getClip(idx);
  166. return HAnimationClip();
  167. }
  168. void CAnimation::onInitialized()
  169. {
  170. }
  171. void CAnimation::onDestroyed()
  172. {
  173. destroyInternal();
  174. }
  175. void CAnimation::onDisabled()
  176. {
  177. destroyInternal();
  178. }
  179. void CAnimation::onEnabled()
  180. {
  181. if(mPreviewMode)
  182. {
  183. destroyInternal();
  184. mPreviewMode = false;
  185. }
  186. if(SceneManager::instance().isRunning())
  187. restoreInternal(false);
  188. }
  189. void CAnimation::update()
  190. {
  191. bool isRunning = SceneManager::instance().isRunning();
  192. if (mInternal == nullptr || !isRunning)
  193. return;
  194. HAnimationClip newPrimaryClip = mInternal->getClip(0);
  195. if (newPrimaryClip != mPrimaryPlayingClip)
  196. _refreshClipMappings();
  197. if (_scriptUpdateFloatProperties)
  198. _scriptUpdateFloatProperties();
  199. }
  200. void CAnimation::onTransformChanged(TransformChangedFlags flags)
  201. {
  202. if (!SO()->getActive())
  203. return;
  204. if ((flags & (TCF_Transform)) != 0)
  205. _updateBounds(false);
  206. }
  207. void CAnimation::restoreInternal(bool previewMode)
  208. {
  209. if (mInternal != nullptr)
  210. destroyInternal();
  211. mInternal = Animation::create();
  212. mAnimatedRenderable = SO()->getComponent<CRenderable>();
  213. if (!previewMode)
  214. {
  215. mInternal->onEventTriggered.connect(std::bind(&CAnimation::eventTriggered, this, _1, _2));
  216. mInternal->setWrapMode(mWrapMode);
  217. mInternal->setSpeed(mSpeed);
  218. mInternal->setCulling(mEnableCull);
  219. }
  220. _updateBounds();
  221. if (!previewMode)
  222. {
  223. if (mDefaultClip.isLoaded())
  224. mInternal->play(mDefaultClip);
  225. mPrimaryPlayingClip = mInternal->getClip(0);
  226. if (mPrimaryPlayingClip.isLoaded())
  227. {
  228. if (_scriptRebuildFloatProperties)
  229. _scriptRebuildFloatProperties(mPrimaryPlayingClip);
  230. }
  231. }
  232. setBoneMappings();
  233. if(!previewMode)
  234. updateSceneObjectMapping();
  235. if (mAnimatedRenderable != nullptr)
  236. mAnimatedRenderable->_registerAnimation(mThisHandle);
  237. }
  238. void CAnimation::destroyInternal()
  239. {
  240. if (mAnimatedRenderable != nullptr)
  241. mAnimatedRenderable->_unregisterAnimation();
  242. mPrimaryPlayingClip = nullptr;
  243. mMappingInfos.clear();
  244. // This should release the last reference and destroy the internal listener
  245. mInternal = nullptr;
  246. }
  247. bool CAnimation::_togglePreviewMode(bool enabled)
  248. {
  249. bool isRunning = SceneManager::instance().isRunning();
  250. if(enabled)
  251. {
  252. // Cannot enable preview while running
  253. if (isRunning)
  254. return false;
  255. restoreInternal(true);
  256. mPreviewMode = true;
  257. return true;
  258. }
  259. else
  260. {
  261. if (!isRunning)
  262. destroyInternal();
  263. mPreviewMode = false;
  264. return false;
  265. }
  266. }
  267. bool CAnimation::_getGenericCurveValue(UINT32 curveIdx, float& value)
  268. {
  269. if (mInternal == nullptr)
  270. return false;
  271. return mInternal->getGenericCurveValue(curveIdx, value);
  272. }
  273. void CAnimation::mapCurveToSceneObject(const String& curve, const HSceneObject& so)
  274. {
  275. if (mInternal == nullptr)
  276. return;
  277. mInternal->mapCurveToSceneObject(curve, so);
  278. }
  279. void CAnimation::unmapSceneObject(const HSceneObject& so)
  280. {
  281. if (mInternal == nullptr)
  282. return;
  283. mInternal->unmapSceneObject(so);
  284. }
  285. void CAnimation::_addBone(const HBone& bone)
  286. {
  287. if (mInternal == nullptr)
  288. return;
  289. HSceneObject currentSO = bone->SO();
  290. SceneObjectMappingInfo newMapping;
  291. newMapping.sceneObject = currentSO;
  292. newMapping.isMappedToBone = true;
  293. newMapping.bone = bone;
  294. mMappingInfos.push_back(newMapping);
  295. mInternal->mapCurveToSceneObject(bone->getName(), newMapping.sceneObject);
  296. }
  297. void CAnimation::_removeBone(const HBone& bone)
  298. {
  299. if (mInternal == nullptr)
  300. return;
  301. HSceneObject newSO;
  302. for (UINT32 i = 0; i < (UINT32)mMappingInfos.size(); i++)
  303. {
  304. if (mMappingInfos[i].bone == bone)
  305. {
  306. mMappingInfos.erase(mMappingInfos.begin() + i);
  307. mInternal->unmapSceneObject(mMappingInfos[i].sceneObject);
  308. i--;
  309. }
  310. }
  311. }
  312. void CAnimation::_notifyBoneChanged(const HBone& bone)
  313. {
  314. if (mInternal == nullptr)
  315. return;
  316. for (UINT32 i = 0; i < (UINT32)mMappingInfos.size(); i++)
  317. {
  318. if (mMappingInfos[i].bone == bone)
  319. {
  320. mInternal->unmapSceneObject(mMappingInfos[i].sceneObject);
  321. mInternal->mapCurveToSceneObject(bone->getName(), mMappingInfos[i].sceneObject);
  322. break;
  323. }
  324. }
  325. }
  326. void CAnimation::_registerRenderable(const HRenderable& renderable)
  327. {
  328. mAnimatedRenderable = renderable;
  329. _updateBounds();
  330. }
  331. void CAnimation::_unregisterRenderable()
  332. {
  333. mAnimatedRenderable = nullptr;
  334. }
  335. void CAnimation::_updateBounds(bool updateRenderable)
  336. {
  337. SPtr<Renderable> renderable;
  338. if (updateRenderable && mAnimatedRenderable != nullptr)
  339. renderable = mAnimatedRenderable->_getRenderable();
  340. if (mUseBounds)
  341. {
  342. if (renderable != nullptr)
  343. {
  344. renderable->setUseOverrideBounds(true);
  345. renderable->setOverrideBounds(mBounds);
  346. }
  347. if (mInternal != nullptr)
  348. {
  349. AABox bounds = mBounds;
  350. bounds.transformAffine(SO()->getWorldMatrix());
  351. mInternal->setBounds(bounds);
  352. }
  353. }
  354. else
  355. {
  356. if (renderable != nullptr)
  357. renderable->setUseOverrideBounds(false);
  358. if (mInternal != nullptr)
  359. {
  360. AABox bounds;
  361. if (mAnimatedRenderable != nullptr)
  362. bounds = mAnimatedRenderable->getBounds().getBox();
  363. mInternal->setBounds(bounds);
  364. }
  365. }
  366. }
  367. void CAnimation::setBoneMappings()
  368. {
  369. mMappingInfos.clear();
  370. SceneObjectMappingInfo rootMapping;
  371. rootMapping.sceneObject = SO();
  372. rootMapping.isMappedToBone = true;
  373. mMappingInfos.push_back(rootMapping);
  374. mInternal->mapCurveToSceneObject("", rootMapping.sceneObject);
  375. Vector<HBone> childBones = findChildBones();
  376. for (auto& entry : childBones)
  377. _addBone(entry);
  378. }
  379. void CAnimation::updateSceneObjectMapping()
  380. {
  381. Vector<SceneObjectMappingInfo> newMappingInfos;
  382. for(auto& entry : mMappingInfos)
  383. {
  384. if (entry.isMappedToBone)
  385. newMappingInfos.push_back(entry);
  386. else
  387. unmapSceneObject(entry.sceneObject);
  388. }
  389. if (mPrimaryPlayingClip.isLoaded())
  390. {
  391. HSceneObject root = SO();
  392. const auto& findMappings = [&](const String& name, AnimationCurveFlags flags)
  393. {
  394. if (flags.isSet(AnimationCurveFlag::ImportedCurve))
  395. return;
  396. HSceneObject currentSO = root->findPath(name);
  397. bool found = false;
  398. for (UINT32 i = 0; i < (UINT32)newMappingInfos.size(); i++)
  399. {
  400. if (newMappingInfos[i].sceneObject == currentSO)
  401. {
  402. found = true;
  403. break;
  404. }
  405. }
  406. if (!found)
  407. {
  408. SceneObjectMappingInfo newMappingInfo;
  409. newMappingInfo.isMappedToBone = false;
  410. newMappingInfo.sceneObject = currentSO;
  411. newMappingInfos.push_back(newMappingInfo);
  412. mapCurveToSceneObject(name, currentSO);
  413. }
  414. };
  415. SPtr<AnimationCurves> curves = mPrimaryPlayingClip->getCurves();
  416. for(auto& curve : curves->position)
  417. findMappings(curve.name, curve.flags);
  418. for(auto& curve : curves->rotation)
  419. findMappings(curve.name, curve.flags);
  420. for(auto& curve : curves->scale)
  421. findMappings(curve.name, curve.flags);
  422. }
  423. mMappingInfos = newMappingInfos;
  424. }
  425. void CAnimation::_refreshClipMappings()
  426. {
  427. mPrimaryPlayingClip = mInternal->getClip(0);
  428. if (_scriptRebuildFloatProperties)
  429. _scriptRebuildFloatProperties(mPrimaryPlayingClip);
  430. updateSceneObjectMapping();
  431. }
  432. Vector<HBone> CAnimation::findChildBones()
  433. {
  434. Stack<HSceneObject> todo;
  435. todo.push(SO());
  436. Vector<HBone> bones;
  437. while (todo.size() > 0)
  438. {
  439. HSceneObject currentSO = todo.top();
  440. todo.pop();
  441. HBone bone = currentSO->getComponent<CBone>();
  442. if (bone != nullptr)
  443. {
  444. bone->_setParent(getHandle(), true);
  445. bones.push_back(bone);
  446. }
  447. int childCount = currentSO->getNumChildren();
  448. for (int i = 0; i < childCount; i++)
  449. {
  450. HSceneObject child = currentSO->getChild(i);
  451. if (child->getComponent<CAnimation>() != nullptr)
  452. continue;
  453. todo.push(child);
  454. }
  455. }
  456. return bones;
  457. }
  458. void CAnimation::eventTriggered(const HAnimationClip& clip, const String& name)
  459. {
  460. onEventTriggered(clip, name);
  461. if(_scriptOnEventTriggered)
  462. _scriptOnEventTriggered(clip, name);
  463. }
  464. RTTITypeBase* CAnimation::getRTTIStatic()
  465. {
  466. return CAnimationRTTI::instance();
  467. }
  468. RTTITypeBase* CAnimation::getRTTI() const
  469. {
  470. return CAnimation::getRTTIStatic();
  471. }
  472. }