AnimationController.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "AnimatedModel.h"
  25. #include "Animation.h"
  26. #include "AnimationController.h"
  27. #include "AnimationState.h"
  28. #include "Context.h"
  29. #include "MemoryBuffer.h"
  30. #include "Profiler.h"
  31. #include "ResourceCache.h"
  32. #include "Scene.h"
  33. #include "SceneEvents.h"
  34. #include "VectorBuffer.h"
  35. #include "DebugNew.h"
  36. static String noBoneName;
  37. OBJECTTYPESTATIC(AnimationController);
  38. AnimationController::AnimationController(Context* context) :
  39. Component(context)
  40. {
  41. }
  42. AnimationController::~AnimationController()
  43. {
  44. }
  45. void AnimationController::RegisterObject(Context* context)
  46. {
  47. context->RegisterFactory<AnimationController>();
  48. ACCESSOR_ATTRIBUTE(AnimationController, VAR_BUFFER, "Animations", GetAnimationsAttr, SetAnimationsAttr, PODVector<unsigned char>, PODVector<unsigned char>(), AM_DEFAULT);
  49. }
  50. void AnimationController::Update(float timeStep)
  51. {
  52. AnimatedModel* model = GetComponent<AnimatedModel>();
  53. if (!model)
  54. return;
  55. PROFILE(UpdateAnimationController);
  56. // Loop through animations
  57. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End();)
  58. {
  59. bool remove = false;
  60. AnimationState* state = model->GetAnimationState(i->hash_);
  61. if (!state)
  62. remove = true;
  63. else
  64. {
  65. // Advance the animation
  66. if (i->speed_ != 0.0f)
  67. state->AddTime(i->speed_ * timeStep);
  68. float targetWeight = i->targetWeight_;
  69. float fadeTime = i->fadeTime_;
  70. // If non-looped animation at the end, activate autofade as applicable
  71. if (!state->IsLooped() && state->GetTime() >= state->GetLength() && i->autoFadeTime_ > 0.0f)
  72. {
  73. targetWeight = 0.0f;
  74. fadeTime = i->autoFadeTime_;
  75. }
  76. // Process weight fade
  77. float currentWeight = state->GetWeight();
  78. if (currentWeight != targetWeight && fadeTime > 0.0f)
  79. {
  80. float weightDelta = 1.0f / fadeTime * timeStep;
  81. if (currentWeight < targetWeight)
  82. currentWeight = Min(currentWeight + weightDelta, targetWeight);
  83. else if (currentWeight > targetWeight)
  84. currentWeight = Max(currentWeight - weightDelta, targetWeight);
  85. state->SetWeight(currentWeight);
  86. }
  87. // Remove if weight zero and target weight zero
  88. if (state->GetWeight() == 0.0f && (targetWeight == 0.0f || fadeTime == 0.0f))
  89. remove = true;
  90. }
  91. if (remove)
  92. {
  93. if (state)
  94. model->RemoveAnimationState(state);
  95. i = animations_.Erase(i);
  96. }
  97. else
  98. ++i;
  99. }
  100. }
  101. bool AnimationController::Play(const String& name, int layer, bool looped, float fadeInTime)
  102. {
  103. AnimatedModel* model = GetComponent<AnimatedModel>();
  104. if (!model)
  105. return false;
  106. // Check if already exists
  107. unsigned index;
  108. AnimationState* state;
  109. FindAnimation(name, index, state);
  110. if (!state)
  111. {
  112. Animation* newAnimation = GetSubsystem<ResourceCache>()->GetResource<Animation>(name);
  113. state = model->AddAnimationState(newAnimation);
  114. if (!state)
  115. return false;
  116. }
  117. if (index == M_MAX_UNSIGNED)
  118. {
  119. AnimationControl newControl;
  120. Animation* animation = state->GetAnimation();
  121. newControl.hash_ = animation->GetNameHash();
  122. animations_.Push(newControl);
  123. index = animations_.Size() - 1;
  124. }
  125. state->SetLayer(layer);
  126. state->SetLooped(looped);
  127. if (fadeInTime > 0.0f)
  128. {
  129. animations_[index].targetWeight_ = 1.0f;
  130. animations_[index].fadeTime_ = fadeInTime;
  131. }
  132. else
  133. state->SetWeight(1.0f);
  134. return true;
  135. }
  136. bool AnimationController::PlayExclusive(const String& name, int layer, bool looped, float fadeTime)
  137. {
  138. FadeOthers(name, 0.0f, fadeTime);
  139. return Play(name, layer, looped, fadeTime);
  140. }
  141. bool AnimationController::Stop(const String& name, float fadeOutTime)
  142. {
  143. AnimatedModel* model = GetComponent<AnimatedModel>();
  144. if (!model)
  145. return false;
  146. unsigned index;
  147. AnimationState* state;
  148. FindAnimation(name, index, state);
  149. if (fadeOutTime <= 0.0f)
  150. {
  151. if (index != M_MAX_UNSIGNED)
  152. animations_.Erase(animations_.Begin() + index);
  153. if (state)
  154. model->RemoveAnimationState(state);
  155. }
  156. else
  157. {
  158. if (index != M_MAX_UNSIGNED)
  159. {
  160. animations_[index].targetWeight_ = 0.0f;
  161. animations_[index].fadeTime_ = fadeOutTime;
  162. }
  163. }
  164. return index != M_MAX_UNSIGNED || state != 0;
  165. }
  166. void AnimationController::StopLayer(int layer, float fadeOutTime)
  167. {
  168. AnimatedModel* model = GetComponent<AnimatedModel>();
  169. if (!model)
  170. return;
  171. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End();)
  172. {
  173. AnimationState* state = model->GetAnimationState(i->hash_);
  174. bool remove = false;
  175. if (state && state->GetLayer() == layer)
  176. {
  177. if (fadeOutTime <= 0.0f)
  178. {
  179. remove = true;
  180. if (state)
  181. model->RemoveAnimationState(state);
  182. }
  183. else
  184. {
  185. i->targetWeight_ = 0.0f;
  186. i->fadeTime_ = fadeOutTime;
  187. }
  188. }
  189. if (remove)
  190. i = animations_.Erase(i);
  191. else
  192. ++i;
  193. }
  194. }
  195. void AnimationController::StopAll(float fadeOutTime)
  196. {
  197. AnimatedModel* model = GetComponent<AnimatedModel>();
  198. if (!model)
  199. return;
  200. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End();)
  201. {
  202. bool remove = false;
  203. if (fadeOutTime <= 0.0f)
  204. {
  205. remove = true;
  206. AnimationState* state = model->GetAnimationState(i->hash_);
  207. if (state)
  208. model->RemoveAnimationState(state);
  209. }
  210. else
  211. {
  212. i->targetWeight_ = 0.0f;
  213. i->fadeTime_ = fadeOutTime;
  214. }
  215. if (remove)
  216. i = animations_.Erase(i);
  217. else
  218. ++i;
  219. }
  220. }
  221. bool AnimationController::Fade(const String& name, float targetWeight, float fadeTime)
  222. {
  223. unsigned index;
  224. AnimationState* state;
  225. FindAnimation(name, index, state);
  226. if (index == M_MAX_UNSIGNED)
  227. return false;
  228. animations_[index].targetWeight_ = Clamp(targetWeight, 0.0f, 1.0f);
  229. animations_[index].fadeTime_ = Max(fadeTime, M_EPSILON);
  230. return true;
  231. }
  232. bool AnimationController::FadeOthers(const String& name, float targetWeight, float fadeTime)
  233. {
  234. unsigned index;
  235. AnimationState* state;
  236. FindAnimation(name, index, state);
  237. if (index == M_MAX_UNSIGNED || !state)
  238. return false;
  239. AnimatedModel* model = GetComponent<AnimatedModel>();
  240. int layer = state->GetLayer();
  241. for (unsigned i = 0; i < animations_.Size(); ++i)
  242. {
  243. if (i != index)
  244. {
  245. AnimationControl& control = animations_[i];
  246. AnimationState* otherState = model->GetAnimationState(control.hash_);
  247. if (otherState && otherState->GetLayer() == layer)
  248. {
  249. control.targetWeight_ = Clamp(targetWeight, 0.0f, 1.0f);
  250. control.fadeTime_ = Max(fadeTime, M_EPSILON);
  251. }
  252. }
  253. }
  254. return true;
  255. }
  256. bool AnimationController::SetLayer(const String& name, int layer)
  257. {
  258. AnimationState* state = FindAnimationState(name);
  259. if (!state)
  260. return false;
  261. state->SetLayer(layer);
  262. return true;
  263. }
  264. bool AnimationController::SetStartBone(const String& name, const String& startBoneName)
  265. {
  266. AnimationState* state = FindAnimationState(name);
  267. if (!state)
  268. return false;
  269. AnimatedModel* model = GetComponent<AnimatedModel>();
  270. Bone* bone = model->GetSkeleton().GetBone(startBoneName);
  271. state->SetStartBone(bone);
  272. return true;
  273. }
  274. bool AnimationController::SetTime(const String& name, float time)
  275. {
  276. AnimationState* state = FindAnimationState(name);
  277. if (!state)
  278. return false;
  279. state->SetTime(time);
  280. return true;
  281. }
  282. bool AnimationController::SetSpeed(const String& name, float speed)
  283. {
  284. unsigned index;
  285. AnimationState* state;
  286. FindAnimation(name, index, state);
  287. if (index == M_MAX_UNSIGNED)
  288. return false;
  289. animations_[index].speed_ = speed;
  290. return true;
  291. }
  292. bool AnimationController::SetWeight(const String& name, float weight)
  293. {
  294. unsigned index;
  295. AnimationState* state;
  296. FindAnimation(name, index, state);
  297. if (index == M_MAX_UNSIGNED || !state)
  298. return false;
  299. state->SetWeight(weight);
  300. // Stop any ongoing fade
  301. animations_[index].fadeTime_ = 0.0f;
  302. return true;
  303. }
  304. bool AnimationController::SetLooped(const String& name, bool enable)
  305. {
  306. AnimationState* state = FindAnimationState(name);
  307. if (!state)
  308. return false;
  309. state->SetLooped(enable);
  310. return true;
  311. }
  312. bool AnimationController::SetAutoFade(const String& name, float fadeOutTime)
  313. {
  314. unsigned index;
  315. AnimationState* state;
  316. FindAnimation(name, index, state);
  317. if (index == M_MAX_UNSIGNED)
  318. return false;
  319. animations_[index].autoFadeTime_ = Max(fadeOutTime, 0.0f);
  320. return true;
  321. }
  322. bool AnimationController::IsPlaying(const String& name) const
  323. {
  324. unsigned index;
  325. AnimationState* state;
  326. FindAnimation(name, index, state);
  327. return index != M_MAX_UNSIGNED;
  328. }
  329. bool AnimationController::IsFadingIn(const String& name) const
  330. {
  331. unsigned index;
  332. AnimationState* state;
  333. FindAnimation(name, index, state);
  334. if (index == M_MAX_UNSIGNED || !state)
  335. return false;
  336. return animations_[index].fadeTime_ && animations_[index].targetWeight_ > state->GetWeight();
  337. }
  338. bool AnimationController::IsFadingOut(const String& name) const
  339. {
  340. unsigned index;
  341. AnimationState* state;
  342. FindAnimation(name, index, state);
  343. if (index == M_MAX_UNSIGNED || !state)
  344. return false;
  345. return (animations_[index].fadeTime_ && animations_[index].targetWeight_ < state->GetWeight())
  346. || (!state->IsLooped() && state->GetTime() >= state->GetLength() && animations_[index].autoFadeTime_);
  347. }
  348. int AnimationController::GetLayer(const String& name) const
  349. {
  350. AnimationState* state = FindAnimationState(name);
  351. if (!state)
  352. return 0;
  353. return state->GetLayer();
  354. }
  355. Bone* AnimationController::GetStartBone(const String& name) const
  356. {
  357. AnimationState* state = FindAnimationState(name);
  358. if (!state)
  359. return 0;
  360. return state->GetStartBone();
  361. }
  362. const String& AnimationController::GetStartBoneName(const String& name) const
  363. {
  364. Bone* bone = GetStartBone(name);
  365. return bone ? bone->name_ : noBoneName;
  366. }
  367. float AnimationController::GetTime(const String& name) const
  368. {
  369. AnimationState* state = FindAnimationState(name);
  370. return state ? state->GetTime() : 0.0f;
  371. }
  372. float AnimationController::GetWeight(const String& name) const
  373. {
  374. AnimationState* state = FindAnimationState(name);
  375. return state ? state->GetWeight() : 0.0f;
  376. }
  377. bool AnimationController::IsLooped(const String& name) const
  378. {
  379. AnimationState* state = FindAnimationState(name);
  380. return state ? state->IsLooped() : false;
  381. }
  382. float AnimationController::GetLength(const String& name) const
  383. {
  384. AnimationState* state = FindAnimationState(name);
  385. return state ? state->GetLength() : 0.0f;
  386. }
  387. float AnimationController::GetSpeed(const String& name) const
  388. {
  389. unsigned index;
  390. AnimationState* state;
  391. FindAnimation(name, index, state);
  392. if (index == M_MAX_UNSIGNED)
  393. return 0.0f;
  394. return animations_[index].speed_;
  395. }
  396. float AnimationController::GetFadeTarget(const String& name) const
  397. {
  398. unsigned index;
  399. AnimationState* state;
  400. FindAnimation(name, index, state);
  401. if (index == M_MAX_UNSIGNED)
  402. return 0.0f;
  403. return animations_[index].targetWeight_;
  404. }
  405. float AnimationController::GetFadeTime(const String& name) const
  406. {
  407. unsigned index;
  408. AnimationState* state;
  409. FindAnimation(name, index, state);
  410. if (index == M_MAX_UNSIGNED)
  411. return 0.0f;
  412. return animations_[index].targetWeight_;
  413. }
  414. float AnimationController::GetAutoFade(const String& name) const
  415. {
  416. unsigned index;
  417. AnimationState* state;
  418. FindAnimation(name, index, state);
  419. if (index == M_MAX_UNSIGNED)
  420. return 0.0f;
  421. return animations_[index].autoFadeTime_;
  422. }
  423. void AnimationController::SetAnimationsAttr(PODVector<unsigned char> value)
  424. {
  425. MemoryBuffer buf(value);
  426. animations_.Resize(buf.ReadVLE());
  427. for (Vector<AnimationControl>::Iterator i = animations_.Begin(); i != animations_.End(); ++i)
  428. {
  429. i->hash_ = buf.ReadStringHash();
  430. i->speed_ = buf.ReadFloat();
  431. i->targetWeight_ = buf.ReadFloat();
  432. i->fadeTime_ = buf.ReadFloat();
  433. i->autoFadeTime_ = buf.ReadFloat();
  434. }
  435. }
  436. PODVector<unsigned char> AnimationController::GetAnimationsAttr() const
  437. {
  438. VectorBuffer buf;
  439. buf.WriteVLE(animations_.Size());
  440. for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i)
  441. {
  442. buf.WriteStringHash(i->hash_);
  443. buf.WriteFloat(i->speed_);
  444. buf.WriteFloat(i->targetWeight_);
  445. buf.WriteFloat(i->fadeTime_);
  446. buf.WriteFloat(i->autoFadeTime_);
  447. }
  448. return buf.GetBuffer();
  449. }
  450. void AnimationController::OnNodeSet(Node* node)
  451. {
  452. if (node)
  453. {
  454. Scene* scene = node->GetScene();
  455. if (scene)
  456. SubscribeToEvent(scene, E_SCENEPOSTUPDATE, HANDLER(AnimationController, HandleScenePostUpdate));
  457. }
  458. }
  459. void AnimationController::FindAnimation(const String& name, unsigned& index, AnimationState*& state) const
  460. {
  461. AnimatedModel* model = GetComponent<AnimatedModel>();
  462. StringHash nameHash(name);
  463. // Find the AnimationState
  464. state = model ? model->GetAnimationState(nameHash) : 0;
  465. if (state)
  466. {
  467. // Either a resource name or animation name may be specified. We store resource names, so correct the hash if necessary
  468. nameHash = state->GetAnimation()->GetNameHash();
  469. }
  470. // Find the internal control structure
  471. index = M_MAX_UNSIGNED;
  472. for (unsigned i = 0; i < animations_.Size(); ++i)
  473. {
  474. if (animations_[i].hash_ == nameHash)
  475. {
  476. index = i;
  477. break;
  478. }
  479. }
  480. }
  481. AnimationState* AnimationController::FindAnimationState(const String& name) const
  482. {
  483. AnimatedModel* model = GetComponent<AnimatedModel>();
  484. return model ? model->GetAnimationState(name) : 0;
  485. }
  486. void AnimationController::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
  487. {
  488. using namespace ScenePostUpdate;
  489. Update(eventData[P_TIMESTEP].GetFloat());
  490. }