BsCAnimation.cpp 13 KB

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