AnimationController.cpp 33 KB

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