AnimationController.cpp 33 KB

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