AnimationController.cpp 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  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. if (name == animationResources_[i]->GetAnimationName())
  171. {
  172. newAnimation = animationResources_[i];
  173. break;
  174. }
  175. }
  176. }
  177. // Get the animation resource first to be able to get the canonical resource name
  178. // (avoids potential adding of duplicate animations)
  179. if (!newAnimation)
  180. newAnimation = GetSubsystem<ResourceCache>()->GetResource<Animation>(name);
  181. if (!newAnimation)
  182. return false;
  183. // ATOMIC END
  184. // Check if already exists
  185. unsigned index;
  186. AnimationState* state;
  187. FindAnimation(newAnimation->GetName(), index, state);
  188. if (!state)
  189. {
  190. state = AddAnimationState(newAnimation);
  191. if (!state)
  192. return false;
  193. }
  194. if (index == M_MAX_UNSIGNED)
  195. {
  196. AnimationControl newControl;
  197. newControl.name_ = newAnimation->GetName();
  198. newControl.hash_ = newAnimation->GetNameHash();
  199. animations_.Push(newControl);
  200. index = animations_.Size() - 1;
  201. }
  202. state->SetLayer(layer);
  203. state->SetLooped(looped);
  204. animations_[index].targetWeight_ = 1.0f;
  205. animations_[index].fadeTime_ = fadeInTime;
  206. MarkNetworkUpdate();
  207. return true;
  208. }
  209. bool AnimationController::PlayExclusive(const String& name, unsigned char layer, bool looped, float fadeTime)
  210. {
  211. FadeOthers(name, 0.0f, fadeTime);
  212. return Play(name, layer, looped, fadeTime);
  213. }
  214. bool AnimationController::Stop(const String& name, float fadeOutTime)
  215. {
  216. unsigned index;
  217. AnimationState* state;
  218. FindAnimation(name, index, state);
  219. if (index != M_MAX_UNSIGNED)
  220. {
  221. animations_[index].targetWeight_ = 0.0f;
  222. animations_[index].fadeTime_ = fadeOutTime;
  223. MarkNetworkUpdate();
  224. }
  225. return index != M_MAX_UNSIGNED || state != 0;
  226. }
  227. void AnimationController::StopLayer(unsigned char layer, float fadeOutTime)
  228. {
  229. bool needUpdate = false;
  230. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End(); ++i)
  231. {
  232. AnimationState* state = GetAnimationState(i->hash_);
  233. if (state && state->GetLayer() == layer)
  234. {
  235. i->targetWeight_ = 0.0f;
  236. i->fadeTime_ = fadeOutTime;
  237. needUpdate = true;
  238. }
  239. }
  240. if (needUpdate)
  241. MarkNetworkUpdate();
  242. }
  243. void AnimationController::StopAll(float fadeOutTime)
  244. {
  245. if (animations_.Size())
  246. {
  247. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End(); ++i)
  248. {
  249. i->targetWeight_ = 0.0f;
  250. i->fadeTime_ = fadeOutTime;
  251. }
  252. MarkNetworkUpdate();
  253. }
  254. }
  255. bool AnimationController::Fade(const String& name, float targetWeight, float fadeTime)
  256. {
  257. unsigned index;
  258. AnimationState* state;
  259. FindAnimation(name, index, state);
  260. if (index == M_MAX_UNSIGNED)
  261. return false;
  262. animations_[index].targetWeight_ = Clamp(targetWeight, 0.0f, 1.0f);
  263. animations_[index].fadeTime_ = fadeTime;
  264. MarkNetworkUpdate();
  265. return true;
  266. }
  267. bool AnimationController::FadeOthers(const String& name, float targetWeight, float fadeTime)
  268. {
  269. unsigned index;
  270. AnimationState* state;
  271. FindAnimation(name, index, state);
  272. if (index == M_MAX_UNSIGNED || !state)
  273. return false;
  274. unsigned char layer = state->GetLayer();
  275. bool needUpdate = false;
  276. for (unsigned i = 0; i < animations_.Size(); ++i)
  277. {
  278. if (i != index)
  279. {
  280. AnimationControl& control = animations_[i];
  281. AnimationState* otherState = GetAnimationState(control.hash_);
  282. if (otherState && otherState->GetLayer() == layer)
  283. {
  284. control.targetWeight_ = Clamp(targetWeight, 0.0f, 1.0f);
  285. control.fadeTime_ = fadeTime;
  286. needUpdate = true;
  287. }
  288. }
  289. }
  290. if (needUpdate)
  291. MarkNetworkUpdate();
  292. return true;
  293. }
  294. bool AnimationController::SetLayer(const String& name, unsigned char layer)
  295. {
  296. AnimationState* state = GetAnimationState(name);
  297. if (!state)
  298. return false;
  299. state->SetLayer(layer);
  300. MarkNetworkUpdate();
  301. return true;
  302. }
  303. bool AnimationController::SetStartBone(const String& name, const String& startBoneName)
  304. {
  305. // Start bone can only be set in model mode
  306. AnimatedModel* model = GetComponent<AnimatedModel>();
  307. if (!model)
  308. return false;
  309. AnimationState* state = model->GetAnimationState(name);
  310. if (!state)
  311. return false;
  312. Bone* bone = model->GetSkeleton().GetBone(startBoneName);
  313. state->SetStartBone(bone);
  314. MarkNetworkUpdate();
  315. return true;
  316. }
  317. bool AnimationController::SetTime(const String& name, float time)
  318. {
  319. unsigned index;
  320. AnimationState* state;
  321. FindAnimation(name, index, state);
  322. if (index == M_MAX_UNSIGNED || !state)
  323. return false;
  324. time = Clamp(time, 0.0f, state->GetLength());
  325. state->SetTime(time);
  326. // Prepare "set time" command for network replication
  327. animations_[index].setTime_ = (unsigned short)(time / state->GetLength() * 65535.0f);
  328. animations_[index].setTimeTtl_ = COMMAND_STAY_TIME;
  329. ++animations_[index].setTimeRev_;
  330. MarkNetworkUpdate();
  331. return true;
  332. }
  333. bool AnimationController::SetSpeed(const String& name, float speed)
  334. {
  335. unsigned index;
  336. AnimationState* state;
  337. FindAnimation(name, index, state);
  338. if (index == M_MAX_UNSIGNED)
  339. return false;
  340. animations_[index].speed_ = speed;
  341. MarkNetworkUpdate();
  342. return true;
  343. }
  344. bool AnimationController::SetWeight(const String& name, float weight)
  345. {
  346. unsigned index;
  347. AnimationState* state;
  348. FindAnimation(name, index, state);
  349. if (index == M_MAX_UNSIGNED || !state)
  350. return false;
  351. weight = Clamp(weight, 0.0f, 1.0f);
  352. state->SetWeight(weight);
  353. // Prepare "set weight" command for network replication
  354. animations_[index].setWeight_ = (unsigned char)(weight * 255.0f);
  355. animations_[index].setWeightTtl_ = COMMAND_STAY_TIME;
  356. ++animations_[index].setWeightRev_;
  357. // Cancel any ongoing weight fade
  358. animations_[index].targetWeight_ = weight;
  359. animations_[index].fadeTime_ = 0.0f;
  360. MarkNetworkUpdate();
  361. return true;
  362. }
  363. bool AnimationController::SetRemoveOnCompletion(const String& name, bool removeOnCompletion)
  364. {
  365. unsigned index;
  366. AnimationState* state;
  367. FindAnimation(name, index, state);
  368. if (index == M_MAX_UNSIGNED || !state)
  369. return false;
  370. animations_[index].removeOnCompletion_ = removeOnCompletion;
  371. MarkNetworkUpdate();
  372. return true;
  373. }
  374. bool AnimationController::SetLooped(const String& name, bool enable)
  375. {
  376. AnimationState* state = GetAnimationState(name);
  377. if (!state)
  378. return false;
  379. state->SetLooped(enable);
  380. MarkNetworkUpdate();
  381. return true;
  382. }
  383. bool AnimationController::SetBlendMode(const String& name, AnimationBlendMode mode)
  384. {
  385. AnimationState* state = GetAnimationState(name);
  386. if (!state)
  387. return false;
  388. state->SetBlendMode(mode);
  389. MarkNetworkUpdate();
  390. return true;
  391. }
  392. bool AnimationController::SetAutoFade(const String& name, float fadeOutTime)
  393. {
  394. unsigned index;
  395. AnimationState* state;
  396. FindAnimation(name, index, state);
  397. if (index == M_MAX_UNSIGNED)
  398. return false;
  399. animations_[index].autoFadeTime_ = Max(fadeOutTime, 0.0f);
  400. MarkNetworkUpdate();
  401. return true;
  402. }
  403. bool AnimationController::IsPlaying(const String& name) const
  404. {
  405. unsigned index;
  406. AnimationState* state;
  407. FindAnimation(name, index, state);
  408. return index != M_MAX_UNSIGNED;
  409. }
  410. bool AnimationController::IsFadingIn(const String& name) const
  411. {
  412. unsigned index;
  413. AnimationState* state;
  414. FindAnimation(name, index, state);
  415. if (index == M_MAX_UNSIGNED || !state)
  416. return false;
  417. return animations_[index].fadeTime_ && animations_[index].targetWeight_ > state->GetWeight();
  418. }
  419. bool AnimationController::IsFadingOut(const String& name) const
  420. {
  421. unsigned index;
  422. AnimationState* state;
  423. FindAnimation(name, index, state);
  424. if (index == M_MAX_UNSIGNED || !state)
  425. return false;
  426. return (animations_[index].fadeTime_ && animations_[index].targetWeight_ < state->GetWeight())
  427. || (!state->IsLooped() && state->GetTime() >= state->GetLength() && animations_[index].autoFadeTime_);
  428. }
  429. bool AnimationController::IsAtEnd(const String& name) const
  430. {
  431. unsigned index;
  432. AnimationState* state;
  433. FindAnimation(name, index, state);
  434. if (index == M_MAX_UNSIGNED || !state)
  435. return false;
  436. else
  437. return state->GetTime() >= state->GetLength();
  438. }
  439. unsigned char AnimationController::GetLayer(const String& name) const
  440. {
  441. AnimationState* state = GetAnimationState(name);
  442. return (unsigned char)(state ? state->GetLayer() : 0);
  443. }
  444. Bone* AnimationController::GetStartBone(const String& name) const
  445. {
  446. AnimationState* state = GetAnimationState(name);
  447. return state ? state->GetStartBone() : 0;
  448. }
  449. const String& AnimationController::GetStartBoneName(const String& name) const
  450. {
  451. Bone* bone = GetStartBone(name);
  452. return bone ? bone->name_ : String::EMPTY;
  453. }
  454. float AnimationController::GetTime(const String& name) const
  455. {
  456. AnimationState* state = GetAnimationState(name);
  457. return state ? state->GetTime() : 0.0f;
  458. }
  459. float AnimationController::GetWeight(const String& name) const
  460. {
  461. AnimationState* state = GetAnimationState(name);
  462. return state ? state->GetWeight() : 0.0f;
  463. }
  464. bool AnimationController::IsLooped(const String& name) const
  465. {
  466. AnimationState* state = GetAnimationState(name);
  467. return state ? state->IsLooped() : false;
  468. }
  469. AnimationBlendMode AnimationController::GetBlendMode(const String& name) const
  470. {
  471. AnimationState* state = GetAnimationState(name);
  472. return state ? state->GetBlendMode() : ABM_LERP;
  473. }
  474. float AnimationController::GetLength(const String& name) const
  475. {
  476. AnimationState* state = GetAnimationState(name);
  477. return state ? state->GetLength() : 0.0f;
  478. }
  479. float AnimationController::GetSpeed(const String& name) const
  480. {
  481. unsigned index;
  482. AnimationState* state;
  483. FindAnimation(name, index, state);
  484. return index != M_MAX_UNSIGNED ? animations_[index].speed_ : 0.0f;
  485. }
  486. float AnimationController::GetFadeTarget(const String& name) const
  487. {
  488. unsigned index;
  489. AnimationState* state;
  490. FindAnimation(name, index, state);
  491. return index != M_MAX_UNSIGNED ? animations_[index].targetWeight_ : 0.0f;
  492. }
  493. float AnimationController::GetFadeTime(const String& name) const
  494. {
  495. unsigned index;
  496. AnimationState* state;
  497. FindAnimation(name, index, state);
  498. return index != M_MAX_UNSIGNED ? animations_[index].targetWeight_ : 0.0f;
  499. }
  500. float AnimationController::GetAutoFade(const String& name) const
  501. {
  502. unsigned index;
  503. AnimationState* state;
  504. FindAnimation(name, index, state);
  505. return index != M_MAX_UNSIGNED ? animations_[index].autoFadeTime_ : 0.0f;
  506. }
  507. bool AnimationController::GetRemoveOnCompletion(const String& name) const
  508. {
  509. unsigned index;
  510. AnimationState* state;
  511. FindAnimation(name, index, state);
  512. return index != M_MAX_UNSIGNED ? animations_[index].removeOnCompletion_ : false;
  513. }
  514. AnimationState* AnimationController::GetAnimationState(const String& name) const
  515. {
  516. return GetAnimationState(StringHash(name));
  517. }
  518. AnimationState* AnimationController::GetAnimationState(StringHash nameHash) const
  519. {
  520. // Model mode
  521. AnimatedModel* model = GetComponent<AnimatedModel>();
  522. if (model)
  523. return model->GetAnimationState(nameHash);
  524. // Node hierarchy mode
  525. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
  526. {
  527. Animation* animation = (*i)->GetAnimation();
  528. if (animation->GetNameHash() == nameHash || animation->GetAnimationNameHash() == nameHash)
  529. return *i;
  530. }
  531. return 0;
  532. }
  533. void AnimationController::SetAnimationsAttr(const VariantVector& value)
  534. {
  535. animations_.Clear();
  536. animations_.Reserve(value.Size() / 5); // Incomplete data is discarded
  537. unsigned index = 0;
  538. while (index + 4 < value.Size()) // Prevent out-of-bound index access
  539. {
  540. AnimationControl newControl;
  541. newControl.name_ = value[index++].GetString();
  542. newControl.hash_ = StringHash(newControl.name_);
  543. newControl.speed_ = value[index++].GetFloat();
  544. newControl.targetWeight_ = value[index++].GetFloat();
  545. newControl.fadeTime_ = value[index++].GetFloat();
  546. newControl.autoFadeTime_ = value[index++].GetFloat();
  547. animations_.Push(newControl);
  548. }
  549. }
  550. void AnimationController::SetNetAnimationsAttr(const PODVector<unsigned char>& value)
  551. {
  552. MemoryBuffer buf(value);
  553. AnimatedModel* model = GetComponent<AnimatedModel>();
  554. // Check which animations we need to remove
  555. HashSet<StringHash> processedAnimations;
  556. unsigned numAnimations = buf.ReadVLE();
  557. while (numAnimations--)
  558. {
  559. String animName = buf.ReadString();
  560. StringHash animHash(animName);
  561. processedAnimations.Insert(animHash);
  562. // Check if the animation state exists. If not, add new
  563. AnimationState* state = GetAnimationState(animHash);
  564. if (!state)
  565. {
  566. Animation* newAnimation = GetSubsystem<ResourceCache>()->GetResource<Animation>(animName);
  567. state = AddAnimationState(newAnimation);
  568. if (!state)
  569. {
  570. ATOMIC_LOGERROR("Animation update applying aborted due to unknown animation");
  571. return;
  572. }
  573. }
  574. // Check if the internal control structure exists. If not, add new
  575. unsigned index;
  576. for (index = 0; index < animations_.Size(); ++index)
  577. {
  578. if (animations_[index].hash_ == animHash)
  579. break;
  580. }
  581. if (index == animations_.Size())
  582. {
  583. AnimationControl newControl;
  584. newControl.name_ = animName;
  585. newControl.hash_ = animHash;
  586. animations_.Push(newControl);
  587. }
  588. unsigned char ctrl = buf.ReadUByte();
  589. state->SetLayer(buf.ReadUByte());
  590. state->SetLooped((ctrl & CTRL_LOOPED) != 0);
  591. state->SetBlendMode((ctrl & CTRL_ADDITIVE) != 0 ? ABM_ADDITIVE : ABM_LERP);
  592. animations_[index].speed_ = (float)buf.ReadShort() / 2048.0f; // 11 bits of decimal precision, max. 16x playback speed
  593. animations_[index].targetWeight_ = (float)buf.ReadUByte() / 255.0f; // 8 bits of decimal precision
  594. animations_[index].fadeTime_ = (float)buf.ReadUByte() / 64.0f; // 6 bits of decimal precision, max. 4 seconds fade
  595. if (ctrl & CTRL_STARTBONE)
  596. {
  597. StringHash boneHash = buf.ReadStringHash();
  598. if (model)
  599. state->SetStartBone(model->GetSkeleton().GetBone(boneHash));
  600. }
  601. else
  602. state->SetStartBone(0);
  603. if (ctrl & CTRL_AUTOFADE)
  604. animations_[index].autoFadeTime_ = (float)buf.ReadUByte() / 64.0f; // 6 bits of decimal precision, max. 4 seconds fade
  605. else
  606. animations_[index].autoFadeTime_ = 0.0f;
  607. animations_[index].removeOnCompletion_ = (ctrl & CTRL_REMOVEONCOMPLETION) != 0;
  608. if (ctrl & CTRL_SETTIME)
  609. {
  610. unsigned char setTimeRev = buf.ReadUByte();
  611. unsigned short setTime = buf.ReadUShort();
  612. // Apply set time command only if revision differs
  613. if (setTimeRev != animations_[index].setTimeRev_)
  614. {
  615. state->SetTime(((float)setTime / 65535.0f) * state->GetLength());
  616. animations_[index].setTimeRev_ = setTimeRev;
  617. }
  618. }
  619. if (ctrl & CTRL_SETWEIGHT)
  620. {
  621. unsigned char setWeightRev = buf.ReadUByte();
  622. unsigned char setWeight = buf.ReadUByte();
  623. // Apply set weight command only if revision differs
  624. if (setWeightRev != animations_[index].setWeightRev_)
  625. {
  626. state->SetWeight((float)setWeight / 255.0f);
  627. animations_[index].setWeightRev_ = setWeightRev;
  628. }
  629. }
  630. }
  631. // Set any extra animations to fade out
  632. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End(); ++i)
  633. {
  634. if (!processedAnimations.Contains(i->hash_))
  635. {
  636. i->targetWeight_ = 0.0f;
  637. i->fadeTime_ = EXTRA_ANIM_FADEOUT_TIME;
  638. }
  639. }
  640. }
  641. void AnimationController::SetNodeAnimationStatesAttr(const VariantVector& value)
  642. {
  643. ResourceCache* cache = GetSubsystem<ResourceCache>();
  644. nodeAnimationStates_.Clear();
  645. unsigned index = 0;
  646. unsigned numStates = index < value.Size() ? value[index++].GetUInt() : 0;
  647. // Prevent negative or overly large value being assigned from the editor
  648. if (numStates > M_MAX_INT)
  649. numStates = 0;
  650. if (numStates > MAX_NODE_ANIMATION_STATES)
  651. numStates = MAX_NODE_ANIMATION_STATES;
  652. nodeAnimationStates_.Reserve(numStates);
  653. while (numStates--)
  654. {
  655. if (index + 2 < value.Size())
  656. {
  657. // Note: null animation is allowed here for editing
  658. const ResourceRef& animRef = value[index++].GetResourceRef();
  659. SharedPtr<AnimationState> newState(new AnimationState(GetNode(), cache->GetResource<Animation>(animRef.name_)));
  660. nodeAnimationStates_.Push(newState);
  661. newState->SetLooped(value[index++].GetBool());
  662. newState->SetTime(value[index++].GetFloat());
  663. }
  664. else
  665. {
  666. // If not enough data, just add an empty animation state
  667. SharedPtr<AnimationState> newState(new AnimationState(GetNode(), 0));
  668. nodeAnimationStates_.Push(newState);
  669. }
  670. }
  671. }
  672. VariantVector AnimationController::GetAnimationsAttr() const
  673. {
  674. VariantVector ret;
  675. ret.Reserve(animations_.Size() * 5);
  676. for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i)
  677. {
  678. ret.Push(i->name_);
  679. ret.Push(i->speed_);
  680. ret.Push(i->targetWeight_);
  681. ret.Push(i->fadeTime_);
  682. ret.Push(i->autoFadeTime_);
  683. }
  684. return ret;
  685. }
  686. const PODVector<unsigned char>& AnimationController::GetNetAnimationsAttr() const
  687. {
  688. attrBuffer_.Clear();
  689. AnimatedModel* model = GetComponent<AnimatedModel>();
  690. unsigned validAnimations = 0;
  691. for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i)
  692. {
  693. if (GetAnimationState(i->hash_))
  694. ++validAnimations;
  695. }
  696. attrBuffer_.WriteVLE(validAnimations);
  697. for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i)
  698. {
  699. AnimationState* state = GetAnimationState(i->hash_);
  700. if (!state)
  701. continue;
  702. unsigned char ctrl = 0;
  703. Bone* startBone = state->GetStartBone();
  704. if (state->IsLooped())
  705. ctrl |= CTRL_LOOPED;
  706. if (state->GetBlendMode() == ABM_ADDITIVE)
  707. ctrl |= CTRL_ADDITIVE;
  708. if (startBone && model && startBone != model->GetSkeleton().GetRootBone())
  709. ctrl |= CTRL_STARTBONE;
  710. if (i->autoFadeTime_ > 0.0f)
  711. ctrl |= CTRL_AUTOFADE;
  712. if (i->removeOnCompletion_)
  713. ctrl |= CTRL_REMOVEONCOMPLETION;
  714. if (i->setTimeTtl_ > 0.0f)
  715. ctrl |= CTRL_SETTIME;
  716. if (i->setWeightTtl_ > 0.0f)
  717. ctrl |= CTRL_SETWEIGHT;
  718. attrBuffer_.WriteString(i->name_);
  719. attrBuffer_.WriteUByte(ctrl);
  720. attrBuffer_.WriteUByte(state->GetLayer());
  721. attrBuffer_.WriteShort((short)Clamp(i->speed_ * 2048.0f, -32767.0f, 32767.0f));
  722. attrBuffer_.WriteUByte((unsigned char)(i->targetWeight_ * 255.0f));
  723. attrBuffer_.WriteUByte((unsigned char)Clamp(i->fadeTime_ * 64.0f, 0.0f, 255.0f));
  724. if (ctrl & CTRL_STARTBONE)
  725. attrBuffer_.WriteStringHash(startBone->nameHash_);
  726. if (ctrl & CTRL_AUTOFADE)
  727. attrBuffer_.WriteUByte((unsigned char)Clamp(i->autoFadeTime_ * 64.0f, 0.0f, 255.0f));
  728. if (ctrl & CTRL_SETTIME)
  729. {
  730. attrBuffer_.WriteUByte(i->setTimeRev_);
  731. attrBuffer_.WriteUShort(i->setTime_);
  732. }
  733. if (ctrl & CTRL_SETWEIGHT)
  734. {
  735. attrBuffer_.WriteUByte(i->setWeightRev_);
  736. attrBuffer_.WriteUByte(i->setWeight_);
  737. }
  738. }
  739. return attrBuffer_.GetBuffer();
  740. }
  741. VariantVector AnimationController::GetNodeAnimationStatesAttr() const
  742. {
  743. VariantVector ret;
  744. ret.Reserve(nodeAnimationStates_.Size() * 3 + 1);
  745. ret.Push(nodeAnimationStates_.Size());
  746. for (Vector<SharedPtr<AnimationState> >::ConstIterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
  747. {
  748. AnimationState* state = *i;
  749. Animation* animation = state->GetAnimation();
  750. ret.Push(GetResourceRef(animation, Animation::GetTypeStatic()));
  751. ret.Push(state->IsLooped());
  752. ret.Push(state->GetTime());
  753. }
  754. return ret;
  755. }
  756. void AnimationController::OnSceneSet(Scene* scene)
  757. {
  758. if (scene && IsEnabledEffective())
  759. SubscribeToEvent(scene, E_SCENEPOSTUPDATE, ATOMIC_HANDLER(AnimationController, HandleScenePostUpdate));
  760. else if (!scene)
  761. UnsubscribeFromEvent(E_SCENEPOSTUPDATE);
  762. }
  763. AnimationState* AnimationController::AddAnimationState(Animation* animation)
  764. {
  765. if (!animation)
  766. return 0;
  767. // Model mode
  768. AnimatedModel* model = GetComponent<AnimatedModel>();
  769. if (model)
  770. return model->AddAnimationState(animation);
  771. // Node hierarchy mode
  772. SharedPtr<AnimationState> newState(new AnimationState(node_, animation));
  773. nodeAnimationStates_.Push(newState);
  774. return newState;
  775. }
  776. void AnimationController::RemoveAnimationState(AnimationState* state)
  777. {
  778. if (!state)
  779. return;
  780. // Model mode
  781. AnimatedModel* model = GetComponent<AnimatedModel>();
  782. if (model)
  783. {
  784. model->RemoveAnimationState(state);
  785. return;
  786. }
  787. // Node hierarchy mode
  788. for (Vector<SharedPtr<AnimationState> >::Iterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i)
  789. {
  790. if ((*i) == state)
  791. {
  792. nodeAnimationStates_.Erase(i);
  793. return;
  794. }
  795. }
  796. }
  797. void AnimationController::FindAnimation(const String& name, unsigned& index, AnimationState*& state) const
  798. {
  799. StringHash nameHash(GetInternalPath(name));
  800. // ATOMIC BEGIN
  801. // Check if we're using attached animation resource
  802. if (animation_.NotNull() && animation_->GetAnimationName() == name)
  803. {
  804. nameHash = animation_->GetName();
  805. }
  806. else
  807. {
  808. for (unsigned i = 0; i < animationResources_.Size(); i++)
  809. {
  810. if (name == animationResources_[i]->GetAnimationName())
  811. {
  812. nameHash = animationResources_[i]->GetName();
  813. break;
  814. }
  815. }
  816. }
  817. // ATOMIC END
  818. // Find the AnimationState
  819. state = GetAnimationState(nameHash);
  820. if (state)
  821. {
  822. // Either a resource name or animation name may be specified. We store resource names, so correct the hash if necessary
  823. nameHash = state->GetAnimation()->GetNameHash();
  824. }
  825. // Find the internal control structure
  826. index = M_MAX_UNSIGNED;
  827. for (unsigned i = 0; i < animations_.Size(); ++i)
  828. {
  829. if (animations_[i].hash_ == nameHash)
  830. {
  831. index = i;
  832. break;
  833. }
  834. }
  835. }
  836. void AnimationController::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
  837. {
  838. using namespace ScenePostUpdate;
  839. Update(eventData[P_TIMESTEP].GetFloat());
  840. }
  841. // ATOMIC BEGIN
  842. void AnimationController::SetAnimationAttr(const ResourceRef& value)
  843. {
  844. ResourceCache* cache = GetSubsystem<ResourceCache>();
  845. animation_ = cache->GetResource<Animation>(value.name_);
  846. }
  847. ResourceRef AnimationController::GetAnimationAttr() const
  848. {
  849. return GetResourceRef(animation_, Animation::GetTypeStatic());
  850. }
  851. void AnimationController::AddAnimationResource(Animation* animation)
  852. {
  853. if (!animation)
  854. return;
  855. SharedPtr<Animation> anim(animation);
  856. if (!animationResources_.Contains(anim))
  857. animationResources_.Push(anim);
  858. }
  859. void AnimationController::RemoveAnimationResource(Animation* animation)
  860. {
  861. if (!animation)
  862. return;
  863. animationResources_.Remove(SharedPtr<Animation>(animation));
  864. }
  865. void AnimationController::ClearAnimationResources()
  866. {
  867. animationResources_.Clear();
  868. }
  869. void AnimationController::SetAnimationResourcesAttr(const ResourceRefList& value)
  870. {
  871. animationResources_.Clear();
  872. ResourceCache* cache = GetSubsystem<ResourceCache>();
  873. for (unsigned i = 0; i < value.names_.Size(); ++i)
  874. {
  875. Animation* animation = cache->GetResource<Animation>(value.names_[i]);
  876. if (!animation)
  877. {
  878. //LOGERRORF("AnimationController::SetAnimationResourcesAttr - Unable to load animation: %s", value.names_[i].CString());
  879. animationResources_.Push(SharedPtr<Animation>(nullptr));
  880. }
  881. else
  882. {
  883. animationResources_.Push(SharedPtr<Animation>(animation));
  884. }
  885. }
  886. }
  887. const ResourceRefList& AnimationController::GetAnimationResourcesAttr() const
  888. {
  889. animationResourcesAttr_.names_.Resize(animationResources_.Size());
  890. for (unsigned i = 0; i < animationResources_.Size(); ++i)
  891. animationResourcesAttr_.names_[i] = GetResourceName(animationResources_[i]);
  892. return animationResourcesAttr_;
  893. }
  894. // ATOMIC END
  895. }