AnimationController.cpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. //
  2. // Copyright (c) 2008-2016 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "../Precompiled.h"
  23. #include "../Core/Context.h"
  24. #include "../Core/Profiler.h"
  25. #include "../Graphics/AnimatedModel.h"
  26. #include "../Graphics/Animation.h"
  27. #include "../Graphics/AnimationController.h"
  28. #include "../Graphics/AnimationState.h"
  29. #include "../IO/FileSystem.h"
  30. #include "../IO/Log.h"
  31. #include "../IO/MemoryBuffer.h"
  32. #include "../Resource/ResourceCache.h"
  33. #include "../Scene/Scene.h"
  34. #include "../Scene/SceneEvents.h"
  35. #include "../DebugNew.h"
  36. namespace Atomic
  37. {
  38. static const unsigned char CTRL_LOOPED = 0x1;
  39. static const unsigned char CTRL_STARTBONE = 0x2;
  40. static const unsigned char CTRL_AUTOFADE = 0x4;
  41. static const unsigned char CTRL_SETTIME = 0x08;
  42. static const unsigned char CTRL_SETWEIGHT = 0x10;
  43. static const unsigned char CTRL_REMOVEONCOMPLETION = 0x20;
  44. static const unsigned char CTRL_ADDITIVE = 0x40;
  45. static const float EXTRA_ANIM_FADEOUT_TIME = 0.1f;
  46. static const float COMMAND_STAY_TIME = 0.25f;
  47. static const unsigned MAX_NODE_ANIMATION_STATES = 256;
  48. extern const char* LOGIC_CATEGORY;
  49. AnimationController::AnimationController(Context* context) :
  50. Component(context),
  51. // ATOMIC BEGIN
  52. animationResourcesAttr_(Animation::GetTypeStatic()),
  53. autoPlay_(true),
  54. autoPlayed_(false)
  55. // ATOMIC END
  56. {
  57. }
  58. AnimationController::~AnimationController()
  59. {
  60. }
  61. void AnimationController::RegisterObject(Context* context)
  62. {
  63. context->RegisterFactory<AnimationController>(LOGIC_CATEGORY);
  64. ATOMIC_ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
  65. ATOMIC_MIXED_ACCESSOR_ATTRIBUTE("Animations", GetAnimationsAttr, SetAnimationsAttr, VariantVector, Variant::emptyVariantVector,
  66. AM_FILE | AM_NOEDIT);
  67. ATOMIC_ACCESSOR_ATTRIBUTE("Network Animations", GetNetAnimationsAttr, SetNetAnimationsAttr, PODVector<unsigned char>,
  68. Variant::emptyBuffer, AM_NET | AM_LATESTDATA | AM_NOEDIT);
  69. ATOMIC_MIXED_ACCESSOR_ATTRIBUTE("Node Animation States", GetNodeAnimationStatesAttr, SetNodeAnimationStatesAttr, VariantVector,
  70. Variant::emptyVariantVector, AM_FILE | AM_NOEDIT);
  71. // ATOMIC BEGIN
  72. ATOMIC_MIXED_ACCESSOR_ATTRIBUTE("Animation", GetAnimationAttr, SetAnimationAttr, ResourceRef, ResourceRef(Animation::GetTypeStatic()), AM_DEFAULT);
  73. ATOMIC_ATTRIBUTE("Autoplay", bool, autoPlay_, true, AM_DEFAULT);
  74. ATOMIC_ACCESSOR_ATTRIBUTE("AnimationResources", GetAnimationResourcesAttr, SetAnimationResourcesAttr, ResourceRefList, ResourceRefList(Animation::GetTypeStatic()), AM_DEFAULT);
  75. // ATOMIC END
  76. }
  77. void AnimationController::OnSetEnabled()
  78. {
  79. Scene* scene = GetScene();
  80. if (scene)
  81. {
  82. if (IsEnabledEffective())
  83. SubscribeToEvent(scene, E_SCENEPOSTUPDATE, ATOMIC_HANDLER(AnimationController, HandleScenePostUpdate));
  84. else
  85. UnsubscribeFromEvent(scene, E_SCENEPOSTUPDATE);
  86. }
  87. }
  88. void AnimationController::Update(float timeStep)
  89. {
  90. // ATOMIC BEGIN
  91. if (autoPlay_ && !autoPlayed_ && animation_.NotNull())
  92. {
  93. autoPlayed_ = true;
  94. Play(animation_->GetAnimationName(), 0, true);
  95. }
  96. // ATOMIC END
  97. // Loop through animations
  98. for (unsigned i = 0; i < animations_.Size();)
  99. {
  100. AnimationControl& ctrl = animations_[i];
  101. AnimationState* state = GetAnimationState(ctrl.hash_);
  102. bool remove = false;
  103. if (!state)
  104. remove = true;
  105. else
  106. {
  107. // Advance the animation
  108. if (ctrl.speed_ != 0.0f)
  109. state->AddTime(ctrl.speed_ * timeStep);
  110. float targetWeight = ctrl.targetWeight_;
  111. float fadeTime = ctrl.fadeTime_;
  112. // If non-looped animation at the end, activate autofade as applicable
  113. if (!state->IsLooped() && state->GetTime() >= state->GetLength() && ctrl.autoFadeTime_ > 0.0f)
  114. {
  115. targetWeight = 0.0f;
  116. fadeTime = ctrl.autoFadeTime_;
  117. }
  118. // Process weight fade
  119. float currentWeight = state->GetWeight();
  120. if (currentWeight != targetWeight)
  121. {
  122. if (fadeTime > 0.0f)
  123. {
  124. float weightDelta = 1.0f / fadeTime * timeStep;
  125. if (currentWeight < targetWeight)
  126. currentWeight = Min(currentWeight + weightDelta, targetWeight);
  127. else if (currentWeight > targetWeight)
  128. currentWeight = Max(currentWeight - weightDelta, targetWeight);
  129. state->SetWeight(currentWeight);
  130. }
  131. else
  132. state->SetWeight(targetWeight);
  133. }
  134. // Remove if weight zero and target weight zero
  135. if (state->GetWeight() == 0.0f && (targetWeight == 0.0f || fadeTime == 0.0f) && ctrl.removeOnCompletion_)
  136. remove = true;
  137. }
  138. // Decrement the command time-to-live values
  139. if (ctrl.setTimeTtl_ > 0.0f)
  140. ctrl.setTimeTtl_ = Max(ctrl.setTimeTtl_ - timeStep, 0.0f);
  141. if (ctrl.setWeightTtl_ > 0.0f)
  142. ctrl.setWeightTtl_ = Max(ctrl.setWeightTtl_ - timeStep, 0.0f);
  143. if (remove)
  144. {
  145. if (state)
  146. RemoveAnimationState(state);
  147. animations_.Erase(i);
  148. MarkNetworkUpdate();
  149. }
  150. else
  151. ++i;
  152. }
  153. // Node hierarchy animations need to be applied manually
  154. for (Vector<SharedPtr<AnimationState> >::Iterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
  155. (*i)->Apply();
  156. }
  157. bool AnimationController::Play(const String& name, unsigned char layer, bool looped, float fadeInTime)
  158. {
  159. // ATOMIC BEGIN
  160. Animation* newAnimation = 0;
  161. // Check if we're using attached animation resource
  162. if (animation_.NotNull() && animation_->GetAnimationName() == name)
  163. {
  164. newAnimation = animation_;
  165. }
  166. else
  167. {
  168. for (unsigned i = 0; i < animationResources_.Size(); i++)
  169. {
  170. // ATOMIC BEGIN
  171. // Check whether the animation resource isn't loaded
  172. if (animationResources_[i] == NULL)
  173. continue;
  174. // ATOMIC END
  175. if (name == animationResources_[i]->GetAnimationName())
  176. {
  177. newAnimation = animationResources_[i];
  178. break;
  179. }
  180. }
  181. }
  182. // Get the animation resource first to be able to get the canonical resource name
  183. // (avoids potential adding of duplicate animations)
  184. if (!newAnimation)
  185. newAnimation = GetSubsystem<ResourceCache>()->GetResource<Animation>(name);
  186. if (!newAnimation)
  187. return false;
  188. // ATOMIC END
  189. // Check if already exists
  190. unsigned index;
  191. AnimationState* state;
  192. FindAnimation(newAnimation->GetName(), index, state);
  193. if (!state)
  194. {
  195. state = AddAnimationState(newAnimation);
  196. if (!state)
  197. return false;
  198. }
  199. if (index == M_MAX_UNSIGNED)
  200. {
  201. AnimationControl newControl;
  202. newControl.name_ = newAnimation->GetName();
  203. newControl.hash_ = newAnimation->GetNameHash();
  204. animations_.Push(newControl);
  205. index = animations_.Size() - 1;
  206. }
  207. state->SetLayer(layer);
  208. state->SetLooped(looped);
  209. animations_[index].targetWeight_ = 1.0f;
  210. animations_[index].fadeTime_ = fadeInTime;
  211. MarkNetworkUpdate();
  212. return true;
  213. }
  214. bool AnimationController::PlayExclusive(const String& name, unsigned char layer, bool looped, float fadeTime)
  215. {
  216. FadeOthers(name, 0.0f, fadeTime);
  217. return Play(name, layer, looped, fadeTime);
  218. }
  219. bool AnimationController::Stop(const String& name, float fadeOutTime)
  220. {
  221. unsigned index;
  222. AnimationState* state;
  223. FindAnimation(name, index, state);
  224. if (index != M_MAX_UNSIGNED)
  225. {
  226. animations_[index].targetWeight_ = 0.0f;
  227. animations_[index].fadeTime_ = fadeOutTime;
  228. MarkNetworkUpdate();
  229. }
  230. return index != M_MAX_UNSIGNED || state != 0;
  231. }
  232. void AnimationController::StopLayer(unsigned char layer, float fadeOutTime)
  233. {
  234. bool needUpdate = false;
  235. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End(); ++i)
  236. {
  237. AnimationState* state = GetAnimationState(i->hash_);
  238. if (state && state->GetLayer() == layer)
  239. {
  240. i->targetWeight_ = 0.0f;
  241. i->fadeTime_ = fadeOutTime;
  242. needUpdate = true;
  243. }
  244. }
  245. if (needUpdate)
  246. MarkNetworkUpdate();
  247. }
  248. void AnimationController::StopAll(float fadeOutTime)
  249. {
  250. if (animations_.Size())
  251. {
  252. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End(); ++i)
  253. {
  254. i->targetWeight_ = 0.0f;
  255. i->fadeTime_ = fadeOutTime;
  256. }
  257. MarkNetworkUpdate();
  258. }
  259. }
  260. bool AnimationController::Fade(const String& name, float targetWeight, float fadeTime)
  261. {
  262. unsigned index;
  263. AnimationState* state;
  264. FindAnimation(name, index, state);
  265. if (index == M_MAX_UNSIGNED)
  266. return false;
  267. animations_[index].targetWeight_ = Clamp(targetWeight, 0.0f, 1.0f);
  268. animations_[index].fadeTime_ = fadeTime;
  269. MarkNetworkUpdate();
  270. return true;
  271. }
  272. bool AnimationController::FadeOthers(const String& name, float targetWeight, float fadeTime)
  273. {
  274. unsigned index;
  275. AnimationState* state;
  276. FindAnimation(name, index, state);
  277. if (index == M_MAX_UNSIGNED || !state)
  278. return false;
  279. unsigned char layer = state->GetLayer();
  280. bool needUpdate = false;
  281. for (unsigned i = 0; i < animations_.Size(); ++i)
  282. {
  283. if (i != index)
  284. {
  285. AnimationControl& control = animations_[i];
  286. AnimationState* otherState = GetAnimationState(control.hash_);
  287. if (otherState && otherState->GetLayer() == layer)
  288. {
  289. control.targetWeight_ = Clamp(targetWeight, 0.0f, 1.0f);
  290. control.fadeTime_ = fadeTime;
  291. needUpdate = true;
  292. }
  293. }
  294. }
  295. if (needUpdate)
  296. MarkNetworkUpdate();
  297. return true;
  298. }
  299. bool AnimationController::SetLayer(const String& name, unsigned char layer)
  300. {
  301. AnimationState* state = GetAnimationState(name);
  302. if (!state)
  303. return false;
  304. state->SetLayer(layer);
  305. MarkNetworkUpdate();
  306. return true;
  307. }
  308. bool AnimationController::SetStartBone(const String& name, const String& startBoneName)
  309. {
  310. // Start bone can only be set in model mode
  311. AnimatedModel* model = GetComponent<AnimatedModel>();
  312. if (!model)
  313. return false;
  314. AnimationState* state = model->GetAnimationState(name);
  315. if (!state)
  316. return false;
  317. Bone* bone = model->GetSkeleton().GetBone(startBoneName);
  318. state->SetStartBone(bone);
  319. MarkNetworkUpdate();
  320. return true;
  321. }
  322. bool AnimationController::SetTime(const String& name, float time)
  323. {
  324. unsigned index;
  325. AnimationState* state;
  326. FindAnimation(name, index, state);
  327. if (index == M_MAX_UNSIGNED || !state)
  328. return false;
  329. time = Clamp(time, 0.0f, state->GetLength());
  330. state->SetTime(time);
  331. // Prepare "set time" command for network replication
  332. animations_[index].setTime_ = (unsigned short)(time / state->GetLength() * 65535.0f);
  333. animations_[index].setTimeTtl_ = COMMAND_STAY_TIME;
  334. ++animations_[index].setTimeRev_;
  335. MarkNetworkUpdate();
  336. return true;
  337. }
  338. bool AnimationController::SetSpeed(const String& name, float speed)
  339. {
  340. unsigned index;
  341. AnimationState* state;
  342. FindAnimation(name, index, state);
  343. if (index == M_MAX_UNSIGNED)
  344. return false;
  345. animations_[index].speed_ = speed;
  346. MarkNetworkUpdate();
  347. return true;
  348. }
  349. bool AnimationController::SetWeight(const String& name, float weight)
  350. {
  351. unsigned index;
  352. AnimationState* state;
  353. FindAnimation(name, index, state);
  354. if (index == M_MAX_UNSIGNED || !state)
  355. return false;
  356. weight = Clamp(weight, 0.0f, 1.0f);
  357. state->SetWeight(weight);
  358. // Prepare "set weight" command for network replication
  359. animations_[index].setWeight_ = (unsigned char)(weight * 255.0f);
  360. animations_[index].setWeightTtl_ = COMMAND_STAY_TIME;
  361. ++animations_[index].setWeightRev_;
  362. // Cancel any ongoing weight fade
  363. animations_[index].targetWeight_ = weight;
  364. animations_[index].fadeTime_ = 0.0f;
  365. MarkNetworkUpdate();
  366. return true;
  367. }
  368. bool AnimationController::SetRemoveOnCompletion(const String& name, bool removeOnCompletion)
  369. {
  370. unsigned index;
  371. AnimationState* state;
  372. FindAnimation(name, index, state);
  373. if (index == M_MAX_UNSIGNED || !state)
  374. return false;
  375. animations_[index].removeOnCompletion_ = removeOnCompletion;
  376. MarkNetworkUpdate();
  377. return true;
  378. }
  379. bool AnimationController::SetLooped(const String& name, bool enable)
  380. {
  381. AnimationState* state = GetAnimationState(name);
  382. if (!state)
  383. return false;
  384. state->SetLooped(enable);
  385. MarkNetworkUpdate();
  386. return true;
  387. }
  388. bool AnimationController::SetBlendMode(const String& name, AnimationBlendMode mode)
  389. {
  390. AnimationState* state = GetAnimationState(name);
  391. if (!state)
  392. return false;
  393. state->SetBlendMode(mode);
  394. MarkNetworkUpdate();
  395. return true;
  396. }
  397. bool AnimationController::SetAutoFade(const String& name, float fadeOutTime)
  398. {
  399. unsigned index;
  400. AnimationState* state;
  401. FindAnimation(name, index, state);
  402. if (index == M_MAX_UNSIGNED)
  403. return false;
  404. animations_[index].autoFadeTime_ = Max(fadeOutTime, 0.0f);
  405. MarkNetworkUpdate();
  406. return true;
  407. }
  408. bool AnimationController::IsPlaying(const String& name) const
  409. {
  410. unsigned index;
  411. AnimationState* state;
  412. FindAnimation(name, index, state);
  413. return index != M_MAX_UNSIGNED;
  414. }
  415. bool AnimationController::IsFadingIn(const String& name) const
  416. {
  417. unsigned index;
  418. AnimationState* state;
  419. FindAnimation(name, index, state);
  420. if (index == M_MAX_UNSIGNED || !state)
  421. return false;
  422. return animations_[index].fadeTime_ && animations_[index].targetWeight_ > state->GetWeight();
  423. }
  424. bool AnimationController::IsFadingOut(const String& name) const
  425. {
  426. unsigned index;
  427. AnimationState* state;
  428. FindAnimation(name, index, state);
  429. if (index == M_MAX_UNSIGNED || !state)
  430. return false;
  431. return (animations_[index].fadeTime_ && animations_[index].targetWeight_ < state->GetWeight())
  432. || (!state->IsLooped() && state->GetTime() >= state->GetLength() && animations_[index].autoFadeTime_);
  433. }
  434. bool AnimationController::IsAtEnd(const String& name) const
  435. {
  436. unsigned index;
  437. AnimationState* state;
  438. FindAnimation(name, index, state);
  439. if (index == M_MAX_UNSIGNED || !state)
  440. return false;
  441. else
  442. return state->GetTime() >= state->GetLength();
  443. }
  444. unsigned char AnimationController::GetLayer(const String& name) const
  445. {
  446. AnimationState* state = GetAnimationState(name);
  447. return (unsigned char)(state ? state->GetLayer() : 0);
  448. }
  449. Bone* AnimationController::GetStartBone(const String& name) const
  450. {
  451. AnimationState* state = GetAnimationState(name);
  452. return state ? state->GetStartBone() : 0;
  453. }
  454. const String& AnimationController::GetStartBoneName(const String& name) const
  455. {
  456. Bone* bone = GetStartBone(name);
  457. return bone ? bone->name_ : String::EMPTY;
  458. }
  459. float AnimationController::GetTime(const String& name) const
  460. {
  461. AnimationState* state = GetAnimationState(name);
  462. return state ? state->GetTime() : 0.0f;
  463. }
  464. float AnimationController::GetWeight(const String& name) const
  465. {
  466. AnimationState* state = GetAnimationState(name);
  467. return state ? state->GetWeight() : 0.0f;
  468. }
  469. bool AnimationController::IsLooped(const String& name) const
  470. {
  471. AnimationState* state = GetAnimationState(name);
  472. return state ? state->IsLooped() : false;
  473. }
  474. AnimationBlendMode AnimationController::GetBlendMode(const String& name) const
  475. {
  476. AnimationState* state = GetAnimationState(name);
  477. return state ? state->GetBlendMode() : ABM_LERP;
  478. }
  479. float AnimationController::GetLength(const String& name) const
  480. {
  481. AnimationState* state = GetAnimationState(name);
  482. return state ? state->GetLength() : 0.0f;
  483. }
  484. float AnimationController::GetSpeed(const String& name) const
  485. {
  486. unsigned index;
  487. AnimationState* state;
  488. FindAnimation(name, index, state);
  489. return index != M_MAX_UNSIGNED ? animations_[index].speed_ : 0.0f;
  490. }
  491. float AnimationController::GetFadeTarget(const String& name) const
  492. {
  493. unsigned index;
  494. AnimationState* state;
  495. FindAnimation(name, index, state);
  496. return index != M_MAX_UNSIGNED ? animations_[index].targetWeight_ : 0.0f;
  497. }
  498. float AnimationController::GetFadeTime(const String& name) const
  499. {
  500. unsigned index;
  501. AnimationState* state;
  502. FindAnimation(name, index, state);
  503. return index != M_MAX_UNSIGNED ? animations_[index].targetWeight_ : 0.0f;
  504. }
  505. float AnimationController::GetAutoFade(const String& name) const
  506. {
  507. unsigned index;
  508. AnimationState* state;
  509. FindAnimation(name, index, state);
  510. return index != M_MAX_UNSIGNED ? animations_[index].autoFadeTime_ : 0.0f;
  511. }
  512. bool AnimationController::GetRemoveOnCompletion(const String& name) const
  513. {
  514. unsigned index;
  515. AnimationState* state;
  516. FindAnimation(name, index, state);
  517. return index != M_MAX_UNSIGNED ? animations_[index].removeOnCompletion_ : false;
  518. }
  519. AnimationState* AnimationController::GetAnimationState(const String& name) const
  520. {
  521. return GetAnimationState(StringHash(name));
  522. }
  523. AnimationState* AnimationController::GetAnimationState(StringHash nameHash) const
  524. {
  525. // Model mode
  526. AnimatedModel* model = GetComponent<AnimatedModel>();
  527. if (model)
  528. return model->GetAnimationState(nameHash);
  529. // Node hierarchy mode
  530. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
  531. {
  532. Animation* animation = (*i)->GetAnimation();
  533. if (animation->GetNameHash() == nameHash || animation->GetAnimationNameHash() == nameHash)
  534. return *i;
  535. }
  536. return 0;
  537. }
  538. void AnimationController::SetAnimationsAttr(const VariantVector& value)
  539. {
  540. animations_.Clear();
  541. animations_.Reserve(value.Size() / 5); // Incomplete data is discarded
  542. unsigned index = 0;
  543. while (index + 4 < value.Size()) // Prevent out-of-bound index access
  544. {
  545. AnimationControl newControl;
  546. newControl.name_ = value[index++].GetString();
  547. newControl.hash_ = StringHash(newControl.name_);
  548. newControl.speed_ = value[index++].GetFloat();
  549. newControl.targetWeight_ = value[index++].GetFloat();
  550. newControl.fadeTime_ = value[index++].GetFloat();
  551. newControl.autoFadeTime_ = value[index++].GetFloat();
  552. animations_.Push(newControl);
  553. }
  554. }
  555. void AnimationController::SetNetAnimationsAttr(const PODVector<unsigned char>& value)
  556. {
  557. MemoryBuffer buf(value);
  558. AnimatedModel* model = GetComponent<AnimatedModel>();
  559. // Check which animations we need to remove
  560. HashSet<StringHash> processedAnimations;
  561. unsigned numAnimations = buf.ReadVLE();
  562. while (numAnimations--)
  563. {
  564. String animName = buf.ReadString();
  565. StringHash animHash(animName);
  566. processedAnimations.Insert(animHash);
  567. // Check if the animation state exists. If not, add new
  568. AnimationState* state = GetAnimationState(animHash);
  569. if (!state)
  570. {
  571. Animation* newAnimation = GetSubsystem<ResourceCache>()->GetResource<Animation>(animName);
  572. state = AddAnimationState(newAnimation);
  573. if (!state)
  574. {
  575. ATOMIC_LOGERROR("Animation update applying aborted due to unknown animation");
  576. return;
  577. }
  578. }
  579. // Check if the internal control structure exists. If not, add new
  580. unsigned index;
  581. for (index = 0; index < animations_.Size(); ++index)
  582. {
  583. if (animations_[index].hash_ == animHash)
  584. break;
  585. }
  586. if (index == animations_.Size())
  587. {
  588. AnimationControl newControl;
  589. newControl.name_ = animName;
  590. newControl.hash_ = animHash;
  591. animations_.Push(newControl);
  592. }
  593. unsigned char ctrl = buf.ReadUByte();
  594. state->SetLayer(buf.ReadUByte());
  595. state->SetLooped((ctrl & CTRL_LOOPED) != 0);
  596. state->SetBlendMode((ctrl & CTRL_ADDITIVE) != 0 ? ABM_ADDITIVE : ABM_LERP);
  597. animations_[index].speed_ = (float)buf.ReadShort() / 2048.0f; // 11 bits of decimal precision, max. 16x playback speed
  598. animations_[index].targetWeight_ = (float)buf.ReadUByte() / 255.0f; // 8 bits of decimal precision
  599. animations_[index].fadeTime_ = (float)buf.ReadUByte() / 64.0f; // 6 bits of decimal precision, max. 4 seconds fade
  600. if (ctrl & CTRL_STARTBONE)
  601. {
  602. StringHash boneHash = buf.ReadStringHash();
  603. if (model)
  604. state->SetStartBone(model->GetSkeleton().GetBone(boneHash));
  605. }
  606. else
  607. state->SetStartBone(0);
  608. if (ctrl & CTRL_AUTOFADE)
  609. animations_[index].autoFadeTime_ = (float)buf.ReadUByte() / 64.0f; // 6 bits of decimal precision, max. 4 seconds fade
  610. else
  611. animations_[index].autoFadeTime_ = 0.0f;
  612. animations_[index].removeOnCompletion_ = (ctrl & CTRL_REMOVEONCOMPLETION) != 0;
  613. if (ctrl & CTRL_SETTIME)
  614. {
  615. unsigned char setTimeRev = buf.ReadUByte();
  616. unsigned short setTime = buf.ReadUShort();
  617. // Apply set time command only if revision differs
  618. if (setTimeRev != animations_[index].setTimeRev_)
  619. {
  620. state->SetTime(((float)setTime / 65535.0f) * state->GetLength());
  621. animations_[index].setTimeRev_ = setTimeRev;
  622. }
  623. }
  624. if (ctrl & CTRL_SETWEIGHT)
  625. {
  626. unsigned char setWeightRev = buf.ReadUByte();
  627. unsigned char setWeight = buf.ReadUByte();
  628. // Apply set weight command only if revision differs
  629. if (setWeightRev != animations_[index].setWeightRev_)
  630. {
  631. state->SetWeight((float)setWeight / 255.0f);
  632. animations_[index].setWeightRev_ = setWeightRev;
  633. }
  634. }
  635. }
  636. // Set any extra animations to fade out
  637. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End(); ++i)
  638. {
  639. if (!processedAnimations.Contains(i->hash_))
  640. {
  641. i->targetWeight_ = 0.0f;
  642. i->fadeTime_ = EXTRA_ANIM_FADEOUT_TIME;
  643. }
  644. }
  645. }
  646. void AnimationController::SetNodeAnimationStatesAttr(const VariantVector& value)
  647. {
  648. ResourceCache* cache = GetSubsystem<ResourceCache>();
  649. nodeAnimationStates_.Clear();
  650. unsigned index = 0;
  651. unsigned numStates = index < value.Size() ? value[index++].GetUInt() : 0;
  652. // Prevent negative or overly large value being assigned from the editor
  653. if (numStates > M_MAX_INT)
  654. numStates = 0;
  655. if (numStates > MAX_NODE_ANIMATION_STATES)
  656. numStates = MAX_NODE_ANIMATION_STATES;
  657. nodeAnimationStates_.Reserve(numStates);
  658. while (numStates--)
  659. {
  660. if (index + 2 < value.Size())
  661. {
  662. // Note: null animation is allowed here for editing
  663. const ResourceRef& animRef = value[index++].GetResourceRef();
  664. SharedPtr<AnimationState> newState(new AnimationState(GetNode(), cache->GetResource<Animation>(animRef.name_)));
  665. nodeAnimationStates_.Push(newState);
  666. newState->SetLooped(value[index++].GetBool());
  667. newState->SetTime(value[index++].GetFloat());
  668. }
  669. else
  670. {
  671. // If not enough data, just add an empty animation state
  672. SharedPtr<AnimationState> newState(new AnimationState(GetNode(), 0));
  673. nodeAnimationStates_.Push(newState);
  674. }
  675. }
  676. }
  677. VariantVector AnimationController::GetAnimationsAttr() const
  678. {
  679. VariantVector ret;
  680. ret.Reserve(animations_.Size() * 5);
  681. for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i)
  682. {
  683. ret.Push(i->name_);
  684. ret.Push(i->speed_);
  685. ret.Push(i->targetWeight_);
  686. ret.Push(i->fadeTime_);
  687. ret.Push(i->autoFadeTime_);
  688. }
  689. return ret;
  690. }
  691. const PODVector<unsigned char>& AnimationController::GetNetAnimationsAttr() const
  692. {
  693. attrBuffer_.Clear();
  694. AnimatedModel* model = GetComponent<AnimatedModel>();
  695. unsigned validAnimations = 0;
  696. for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i)
  697. {
  698. if (GetAnimationState(i->hash_))
  699. ++validAnimations;
  700. }
  701. attrBuffer_.WriteVLE(validAnimations);
  702. for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i)
  703. {
  704. AnimationState* state = GetAnimationState(i->hash_);
  705. if (!state)
  706. continue;
  707. unsigned char ctrl = 0;
  708. Bone* startBone = state->GetStartBone();
  709. if (state->IsLooped())
  710. ctrl |= CTRL_LOOPED;
  711. if (state->GetBlendMode() == ABM_ADDITIVE)
  712. ctrl |= CTRL_ADDITIVE;
  713. if (startBone && model && startBone != model->GetSkeleton().GetRootBone())
  714. ctrl |= CTRL_STARTBONE;
  715. if (i->autoFadeTime_ > 0.0f)
  716. ctrl |= CTRL_AUTOFADE;
  717. if (i->removeOnCompletion_)
  718. ctrl |= CTRL_REMOVEONCOMPLETION;
  719. if (i->setTimeTtl_ > 0.0f)
  720. ctrl |= CTRL_SETTIME;
  721. if (i->setWeightTtl_ > 0.0f)
  722. ctrl |= CTRL_SETWEIGHT;
  723. attrBuffer_.WriteString(i->name_);
  724. attrBuffer_.WriteUByte(ctrl);
  725. attrBuffer_.WriteUByte(state->GetLayer());
  726. attrBuffer_.WriteShort((short)Clamp(i->speed_ * 2048.0f, -32767.0f, 32767.0f));
  727. attrBuffer_.WriteUByte((unsigned char)(i->targetWeight_ * 255.0f));
  728. attrBuffer_.WriteUByte((unsigned char)Clamp(i->fadeTime_ * 64.0f, 0.0f, 255.0f));
  729. if (ctrl & CTRL_STARTBONE)
  730. attrBuffer_.WriteStringHash(startBone->nameHash_);
  731. if (ctrl & CTRL_AUTOFADE)
  732. attrBuffer_.WriteUByte((unsigned char)Clamp(i->autoFadeTime_ * 64.0f, 0.0f, 255.0f));
  733. if (ctrl & CTRL_SETTIME)
  734. {
  735. attrBuffer_.WriteUByte(i->setTimeRev_);
  736. attrBuffer_.WriteUShort(i->setTime_);
  737. }
  738. if (ctrl & CTRL_SETWEIGHT)
  739. {
  740. attrBuffer_.WriteUByte(i->setWeightRev_);
  741. attrBuffer_.WriteUByte(i->setWeight_);
  742. }
  743. }
  744. return attrBuffer_.GetBuffer();
  745. }
  746. VariantVector AnimationController::GetNodeAnimationStatesAttr() const
  747. {
  748. VariantVector ret;
  749. ret.Reserve(nodeAnimationStates_.Size() * 3 + 1);
  750. ret.Push(nodeAnimationStates_.Size());
  751. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
  752. {
  753. AnimationState* state = *i;
  754. Animation* animation = state->GetAnimation();
  755. ret.Push(GetResourceRef(animation, Animation::GetTypeStatic()));
  756. ret.Push(state->IsLooped());
  757. ret.Push(state->GetTime());
  758. }
  759. return ret;
  760. }
  761. void AnimationController::OnSceneSet(Scene* scene)
  762. {
  763. if (scene && IsEnabledEffective())
  764. SubscribeToEvent(scene, E_SCENEPOSTUPDATE, ATOMIC_HANDLER(AnimationController, HandleScenePostUpdate));
  765. else if (!scene)
  766. UnsubscribeFromEvent(E_SCENEPOSTUPDATE);
  767. }
  768. AnimationState* AnimationController::AddAnimationState(Animation* animation)
  769. {
  770. if (!animation)
  771. return 0;
  772. // Model mode
  773. AnimatedModel* model = GetComponent<AnimatedModel>();
  774. if (model)
  775. return model->AddAnimationState(animation);
  776. // Node hierarchy mode
  777. SharedPtr<AnimationState> newState(new AnimationState(node_, animation));
  778. nodeAnimationStates_.Push(newState);
  779. return newState;
  780. }
  781. void AnimationController::RemoveAnimationState(AnimationState* state)
  782. {
  783. if (!state)
  784. return;
  785. // Model mode
  786. AnimatedModel* model = GetComponent<AnimatedModel>();
  787. if (model)
  788. {
  789. model->RemoveAnimationState(state);
  790. return;
  791. }
  792. // Node hierarchy mode
  793. for (Vector<SharedPtr<AnimationState> >::Iterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
  794. {
  795. if ((*i) == state)
  796. {
  797. nodeAnimationStates_.Erase(i);
  798. return;
  799. }
  800. }
  801. }
  802. void AnimationController::FindAnimation(const String& name, unsigned& index, AnimationState*& state) const
  803. {
  804. StringHash nameHash(GetInternalPath(name));
  805. // ATOMIC BEGIN
  806. // Check if we're using attached animation resource
  807. if (animation_.NotNull() && animation_->GetAnimationName() == name)
  808. {
  809. nameHash = animation_->GetName();
  810. }
  811. else
  812. {
  813. for (unsigned i = 0; i < animationResources_.Size(); i++)
  814. {
  815. // ATOMIC BEGIN
  816. // Check whether the animation resource isn't loaded
  817. if (animationResources_[i] == NULL)
  818. continue;
  819. // ATOMIC END
  820. if (name == animationResources_[i]->GetAnimationName())
  821. {
  822. nameHash = animationResources_[i]->GetName();
  823. break;
  824. }
  825. }
  826. }
  827. // ATOMIC END
  828. // Find the AnimationState
  829. state = GetAnimationState(nameHash);
  830. if (state)
  831. {
  832. // Either a resource name or animation name may be specified. We store resource names, so correct the hash if necessary
  833. nameHash = state->GetAnimation()->GetNameHash();
  834. }
  835. // Find the internal control structure
  836. index = M_MAX_UNSIGNED;
  837. for (unsigned i = 0; i < animations_.Size(); ++i)
  838. {
  839. if (animations_[i].hash_ == nameHash)
  840. {
  841. index = i;
  842. break;
  843. }
  844. }
  845. }
  846. void AnimationController::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
  847. {
  848. using namespace ScenePostUpdate;
  849. Update(eventData[P_TIMESTEP].GetFloat());
  850. }
  851. // ATOMIC BEGIN
  852. void AnimationController::SetAnimationAttr(const ResourceRef& value)
  853. {
  854. ResourceCache* cache = GetSubsystem<ResourceCache>();
  855. animation_ = cache->GetResource<Animation>(value.name_);
  856. }
  857. ResourceRef AnimationController::GetAnimationAttr() const
  858. {
  859. return GetResourceRef(animation_, Animation::GetTypeStatic());
  860. }
  861. void AnimationController::AddAnimationResource(Animation* animation)
  862. {
  863. if (!animation)
  864. return;
  865. SharedPtr<Animation> anim(animation);
  866. if (!animationResources_.Contains(anim))
  867. animationResources_.Push(anim);
  868. }
  869. void AnimationController::RemoveAnimationResource(Animation* animation)
  870. {
  871. if (!animation)
  872. return;
  873. animationResources_.Remove(SharedPtr<Animation>(animation));
  874. }
  875. void AnimationController::ClearAnimationResources()
  876. {
  877. animationResources_.Clear();
  878. }
  879. void AnimationController::SetAnimationResourcesAttr(const ResourceRefList& value)
  880. {
  881. animationResources_.Clear();
  882. ResourceCache* cache = GetSubsystem<ResourceCache>();
  883. for (unsigned i = 0; i < value.names_.Size(); ++i)
  884. {
  885. Animation* animation = cache->GetResource<Animation>(value.names_[i]);
  886. if (!animation)
  887. {
  888. //LOGERRORF("AnimationController::SetAnimationResourcesAttr - Unable to load animation: %s", value.names_[i].CString());
  889. animationResources_.Push(SharedPtr<Animation>(nullptr));
  890. }
  891. else
  892. {
  893. animationResources_.Push(SharedPtr<Animation>(animation));
  894. }
  895. }
  896. }
  897. const ResourceRefList& AnimationController::GetAnimationResourcesAttr() const
  898. {
  899. animationResourcesAttr_.names_.Resize(animationResources_.Size());
  900. for (unsigned i = 0; i < animationResources_.Size(); ++i)
  901. animationResourcesAttr_.names_[i] = GetResourceName(animationResources_[i]);
  902. return animationResourcesAttr_;
  903. }
  904. // ATOMIC END
  905. }