AnimationState.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. //
  2. // Copyright (c) 2008-2015 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 "../Graphics/AnimatedModel.h"
  23. #include "../Graphics/Animation.h"
  24. #include "../Graphics/AnimationState.h"
  25. #include "../IO/Deserializer.h"
  26. #include "../Graphics/DrawableEvents.h"
  27. #include "../IO/Log.h"
  28. #include "../IO/Serializer.h"
  29. #include "../DebugNew.h"
  30. namespace Urho3D
  31. {
  32. AnimationStateTrack::AnimationStateTrack() :
  33. track_(0),
  34. bone_(0),
  35. weight_(1.0f),
  36. keyFrame_(0)
  37. {
  38. }
  39. AnimationStateTrack::~AnimationStateTrack()
  40. {
  41. }
  42. AnimationState::AnimationState(AnimatedModel* model, Animation* animation) :
  43. model_(model),
  44. animation_(animation),
  45. startBone_(0),
  46. looped_(false),
  47. weight_(0.0f),
  48. time_(0.0f),
  49. layer_(0)
  50. {
  51. // Set default start bone (use all tracks.)
  52. SetStartBone(0);
  53. }
  54. AnimationState::AnimationState(Node* node, Animation* animation) :
  55. node_(node),
  56. animation_(animation),
  57. startBone_(0),
  58. looped_(false),
  59. weight_(1.0f),
  60. time_(0.0f),
  61. layer_(0)
  62. {
  63. if (animation_)
  64. {
  65. // Setup animation track to scene node mapping
  66. if (node_)
  67. {
  68. const Vector<AnimationTrack>& tracks = animation_->GetTracks();
  69. stateTracks_.Clear();
  70. for (unsigned i = 0; i < tracks.Size(); ++i)
  71. {
  72. const StringHash& nameHash = tracks[i].nameHash_;
  73. AnimationStateTrack stateTrack;
  74. stateTrack.track_ = &tracks[i];
  75. if (node_->GetNameHash() == nameHash || tracks.Size() == 1)
  76. stateTrack.node_ = node_;
  77. else
  78. {
  79. Node* targetNode = node_->GetChild(nameHash, true);
  80. if (targetNode)
  81. stateTrack.node_ = targetNode;
  82. else
  83. LOGWARNING("Node " + tracks[i].name_ + " not found for node animation " + animation_->GetName());
  84. }
  85. if (stateTrack.node_)
  86. stateTracks_.Push(stateTrack);
  87. }
  88. }
  89. }
  90. }
  91. AnimationState::~AnimationState()
  92. {
  93. }
  94. void AnimationState::SetStartBone(Bone* startBone)
  95. {
  96. if (!model_ || !animation_)
  97. return;
  98. Skeleton& skeleton = model_->GetSkeleton();
  99. if (!startBone)
  100. {
  101. Bone* rootBone = skeleton.GetRootBone();
  102. if (!rootBone)
  103. return;
  104. startBone = rootBone;
  105. }
  106. // Do not reassign if the start bone did not actually change, and we already have valid bone nodes
  107. if (startBone == startBone_ && !stateTracks_.Empty())
  108. return;
  109. startBone_ = startBone;
  110. const Vector<AnimationTrack>& tracks = animation_->GetTracks();
  111. stateTracks_.Clear();
  112. if (!startBone->node_)
  113. return;
  114. for (unsigned i = 0; i < tracks.Size(); ++i)
  115. {
  116. AnimationStateTrack stateTrack;
  117. stateTrack.track_ = &tracks[i];
  118. // Include those tracks that are either the start bone itself, or its children
  119. Bone* trackBone = 0;
  120. const StringHash& nameHash = tracks[i].nameHash_;
  121. if (nameHash == startBone->nameHash_)
  122. trackBone = startBone;
  123. else
  124. {
  125. Node* trackBoneNode = startBone->node_->GetChild(nameHash, true);
  126. if (trackBoneNode)
  127. trackBone = skeleton.GetBone(nameHash);
  128. }
  129. if (trackBone && trackBone->node_)
  130. {
  131. stateTrack.bone_ = trackBone;
  132. stateTrack.node_ = trackBone->node_;
  133. stateTracks_.Push(stateTrack);
  134. }
  135. }
  136. model_->MarkAnimationDirty();
  137. }
  138. void AnimationState::SetLooped(bool looped)
  139. {
  140. looped_ = looped;
  141. }
  142. void AnimationState::SetWeight(float weight)
  143. {
  144. // Weight can only be set in model mode. In node animation it is hardcoded to full
  145. if (model_)
  146. {
  147. weight = Clamp(weight, 0.0f, 1.0f);
  148. if (weight != weight_)
  149. {
  150. weight_ = weight;
  151. model_->MarkAnimationDirty();
  152. }
  153. }
  154. }
  155. void AnimationState::SetTime(float time)
  156. {
  157. if (!animation_)
  158. return;
  159. time = Clamp(time, 0.0f, animation_->GetLength());
  160. if (time != time_)
  161. {
  162. time_ = time;
  163. if (model_)
  164. model_->MarkAnimationDirty();
  165. }
  166. }
  167. void AnimationState::SetBoneWeight(unsigned index, float weight, bool recursive)
  168. {
  169. if (index >= stateTracks_.Size())
  170. return;
  171. weight = Clamp(weight, 0.0f, 1.0f);
  172. if (weight != stateTracks_[index].weight_)
  173. {
  174. stateTracks_[index].weight_ = weight;
  175. if (model_)
  176. model_->MarkAnimationDirty();
  177. }
  178. if (recursive)
  179. {
  180. Node* boneNode = stateTracks_[index].node_;
  181. if (boneNode)
  182. {
  183. const Vector<SharedPtr<Node> >& children = boneNode->GetChildren();
  184. for (unsigned i = 0; i < children.Size(); ++i)
  185. {
  186. unsigned childTrackIndex = GetTrackIndex(children[i]);
  187. if (childTrackIndex != M_MAX_UNSIGNED)
  188. SetBoneWeight(childTrackIndex, weight, true);
  189. }
  190. }
  191. }
  192. }
  193. void AnimationState::SetBoneWeight(const String& name, float weight, bool recursive)
  194. {
  195. SetBoneWeight(GetTrackIndex(name), weight, recursive);
  196. }
  197. void AnimationState::SetBoneWeight(StringHash nameHash, float weight, bool recursive)
  198. {
  199. SetBoneWeight(GetTrackIndex(nameHash), weight, recursive);
  200. }
  201. void AnimationState::AddWeight(float delta)
  202. {
  203. if (delta == 0.0f)
  204. return;
  205. SetWeight(GetWeight() + delta);
  206. }
  207. void AnimationState::AddTime(float delta)
  208. {
  209. if (!animation_ || (!model_ && !node_))
  210. return;
  211. float length = animation_->GetLength();
  212. if (delta == 0.0f || length == 0.0f)
  213. return;
  214. float oldTime = GetTime();
  215. float time = oldTime + delta;
  216. if (looped_)
  217. {
  218. while (time >= length)
  219. time -= length;
  220. while (time < 0.0f)
  221. time += length;
  222. }
  223. SetTime(time);
  224. // Process animation triggers
  225. if (animation_->GetNumTriggers())
  226. {
  227. bool wrap = false;
  228. if (delta > 0.0f)
  229. {
  230. if (oldTime > time)
  231. {
  232. oldTime -= length;
  233. wrap = true;
  234. }
  235. }
  236. if (delta < 0.0f)
  237. {
  238. if (time > oldTime)
  239. {
  240. time -= length;
  241. wrap = true;
  242. }
  243. }
  244. if (oldTime > time)
  245. Swap(oldTime, time);
  246. const Vector<AnimationTriggerPoint>& triggers = animation_->GetTriggers();
  247. for (Vector<AnimationTriggerPoint>::ConstIterator i = triggers.Begin(); i != triggers.End(); ++i)
  248. {
  249. float frameTime = i->time_;
  250. if (looped_ && wrap)
  251. frameTime = fmodf(frameTime, length);
  252. if (oldTime <= frameTime && time > frameTime)
  253. {
  254. using namespace AnimationTrigger;
  255. Node* senderNode = model_ ? model_->GetNode() : node_;
  256. VariantMap& eventData = senderNode->GetEventDataMap();
  257. eventData[P_NODE] = senderNode;
  258. eventData[P_NAME] = animation_->GetAnimationName();
  259. eventData[P_TIME] = i->time_;
  260. eventData[P_DATA] = i->data_;
  261. senderNode->SendEvent(E_ANIMATIONTRIGGER, eventData);
  262. }
  263. }
  264. }
  265. }
  266. void AnimationState::SetLayer(unsigned char layer)
  267. {
  268. if (layer != layer_)
  269. {
  270. layer_ = layer;
  271. if (model_)
  272. model_->MarkAnimationOrderDirty();
  273. }
  274. }
  275. AnimatedModel* AnimationState::GetModel() const
  276. {
  277. return model_;
  278. }
  279. Node* AnimationState::GetNode() const
  280. {
  281. return node_;
  282. }
  283. Bone* AnimationState::GetStartBone() const
  284. {
  285. return model_ ? startBone_ : 0;
  286. }
  287. float AnimationState::GetBoneWeight(unsigned index) const
  288. {
  289. return index < stateTracks_.Size() ? stateTracks_[index].weight_ : 0.0f;
  290. }
  291. float AnimationState::GetBoneWeight(const String& name) const
  292. {
  293. return GetBoneWeight(GetTrackIndex(name));
  294. }
  295. float AnimationState::GetBoneWeight(StringHash nameHash) const
  296. {
  297. return GetBoneWeight(GetTrackIndex(nameHash));
  298. }
  299. unsigned AnimationState::GetTrackIndex(const String& name) const
  300. {
  301. for (unsigned i = 0; i < stateTracks_.Size(); ++i)
  302. {
  303. Node* node = stateTracks_[i].node_;
  304. if (node && node->GetName() == name)
  305. return i;
  306. }
  307. return M_MAX_UNSIGNED;
  308. }
  309. unsigned AnimationState::GetTrackIndex(Node* node) const
  310. {
  311. for (unsigned i = 0; i < stateTracks_.Size(); ++i)
  312. {
  313. if (stateTracks_[i].node_ == node)
  314. return i;
  315. }
  316. return M_MAX_UNSIGNED;
  317. }
  318. unsigned AnimationState::GetTrackIndex(StringHash nameHash) const
  319. {
  320. for (unsigned i = 0; i < stateTracks_.Size(); ++i)
  321. {
  322. Node* node = stateTracks_[i].node_;
  323. if (node && node->GetNameHash() == nameHash)
  324. return i;
  325. }
  326. return M_MAX_UNSIGNED;
  327. }
  328. float AnimationState::GetLength() const
  329. {
  330. return animation_ ? animation_->GetLength() : 0.0f;
  331. }
  332. void AnimationState::Apply()
  333. {
  334. if (!animation_ || !IsEnabled())
  335. return;
  336. if (model_)
  337. ApplyToModel();
  338. else
  339. ApplyToNodes();
  340. }
  341. void AnimationState::ApplyToModel()
  342. {
  343. for (Vector<AnimationStateTrack>::Iterator i = stateTracks_.Begin(); i != stateTracks_.End(); ++i)
  344. {
  345. AnimationStateTrack& stateTrack = *i;
  346. float finalWeight = weight_ * stateTrack.weight_;
  347. // Do not apply if zero effective weight or the bone has animation disabled
  348. if (Equals(finalWeight, 0.0f) || !stateTrack.bone_->animated_)
  349. continue;
  350. if (Equals(finalWeight, 1.0f))
  351. ApplyTrackFullWeightSilent(stateTrack);
  352. else
  353. ApplyTrackBlendedSilent(stateTrack, finalWeight);
  354. }
  355. }
  356. void AnimationState::ApplyToNodes()
  357. {
  358. // When applying to a node hierarchy, can only use full weight (nothing to blend to)
  359. for (Vector<AnimationStateTrack>::Iterator i = stateTracks_.Begin(); i != stateTracks_.End(); ++i)
  360. ApplyTrackFullWeight(*i);
  361. }
  362. void AnimationState::ApplyTrackFullWeight(AnimationStateTrack& stateTrack)
  363. {
  364. const AnimationTrack* track = stateTrack.track_;
  365. Node* node = stateTrack.node_;
  366. if (track->keyFrames_.Empty() || !node)
  367. return;
  368. unsigned& frame = stateTrack.keyFrame_;
  369. track->GetKeyFrameIndex(time_, frame);
  370. // Check if next frame to interpolate to is valid, or if wrapping is needed (looping animation only)
  371. unsigned nextFrame = frame + 1;
  372. bool interpolate = true;
  373. if (nextFrame >= track->keyFrames_.Size())
  374. {
  375. if (!looped_)
  376. {
  377. nextFrame = frame;
  378. interpolate = false;
  379. }
  380. else
  381. nextFrame = 0;
  382. }
  383. const AnimationKeyFrame* keyFrame = &track->keyFrames_[frame];
  384. unsigned char channelMask = track->channelMask_;
  385. if (!interpolate)
  386. {
  387. // No interpolation, full weight
  388. if (channelMask & CHANNEL_POSITION)
  389. node->SetPosition(keyFrame->position_);
  390. if (channelMask & CHANNEL_ROTATION)
  391. node->SetRotation(keyFrame->rotation_);
  392. if (channelMask & CHANNEL_SCALE)
  393. node->SetScale(keyFrame->scale_);
  394. }
  395. else
  396. {
  397. const AnimationKeyFrame* nextKeyFrame = &track->keyFrames_[nextFrame];
  398. float timeInterval = nextKeyFrame->time_ - keyFrame->time_;
  399. if (timeInterval < 0.0f)
  400. timeInterval += animation_->GetLength();
  401. float t = timeInterval > 0.0f ? (time_ - keyFrame->time_) / timeInterval : 1.0f;
  402. // Interpolation, full weight
  403. if (channelMask & CHANNEL_POSITION)
  404. node->SetPosition(keyFrame->position_.Lerp(nextKeyFrame->position_, t));
  405. if (channelMask & CHANNEL_ROTATION)
  406. node->SetRotation(keyFrame->rotation_.Slerp(nextKeyFrame->rotation_, t));
  407. if (channelMask & CHANNEL_SCALE)
  408. node->SetScale(keyFrame->scale_.Lerp(nextKeyFrame->scale_, t));
  409. }
  410. }
  411. void AnimationState::ApplyTrackFullWeightSilent(AnimationStateTrack& stateTrack)
  412. {
  413. const AnimationTrack* track = stateTrack.track_;
  414. Node* node = stateTrack.node_;
  415. if (track->keyFrames_.Empty() || !node)
  416. return;
  417. unsigned& frame = stateTrack.keyFrame_;
  418. track->GetKeyFrameIndex(time_, frame);
  419. // Check if next frame to interpolate to is valid, or if wrapping is needed (looping animation only)
  420. unsigned nextFrame = frame + 1;
  421. bool interpolate = true;
  422. if (nextFrame >= track->keyFrames_.Size())
  423. {
  424. if (!looped_)
  425. {
  426. nextFrame = frame;
  427. interpolate = false;
  428. }
  429. else
  430. nextFrame = 0;
  431. }
  432. const AnimationKeyFrame* keyFrame = &track->keyFrames_[frame];
  433. unsigned char channelMask = track->channelMask_;
  434. if (!interpolate)
  435. {
  436. // No interpolation, full weight
  437. if (channelMask & CHANNEL_POSITION)
  438. node->SetPositionSilent(keyFrame->position_);
  439. if (channelMask & CHANNEL_ROTATION)
  440. node->SetRotationSilent(keyFrame->rotation_);
  441. if (channelMask & CHANNEL_SCALE)
  442. node->SetScaleSilent(keyFrame->scale_);
  443. }
  444. else
  445. {
  446. const AnimationKeyFrame* nextKeyFrame = &track->keyFrames_[nextFrame];
  447. float timeInterval = nextKeyFrame->time_ - keyFrame->time_;
  448. if (timeInterval < 0.0f)
  449. timeInterval += animation_->GetLength();
  450. float t = timeInterval > 0.0f ? (time_ - keyFrame->time_) / timeInterval : 1.0f;
  451. // Interpolation, full weight
  452. if (channelMask & CHANNEL_POSITION)
  453. node->SetPositionSilent(keyFrame->position_.Lerp(nextKeyFrame->position_, t));
  454. if (channelMask & CHANNEL_ROTATION)
  455. node->SetRotationSilent(keyFrame->rotation_.Slerp(nextKeyFrame->rotation_, t));
  456. if (channelMask & CHANNEL_SCALE)
  457. node->SetScaleSilent(keyFrame->scale_.Lerp(nextKeyFrame->scale_, t));
  458. }
  459. }
  460. void AnimationState::ApplyTrackBlendedSilent(AnimationStateTrack& stateTrack, float weight)
  461. {
  462. const AnimationTrack* track = stateTrack.track_;
  463. Node* node = stateTrack.node_;
  464. if (track->keyFrames_.Empty() || !node)
  465. return;
  466. unsigned& frame = stateTrack.keyFrame_;
  467. track->GetKeyFrameIndex(time_, frame);
  468. // Check if next frame to interpolate to is valid, or if wrapping is needed (looping animation only)
  469. unsigned nextFrame = frame + 1;
  470. bool interpolate = true;
  471. if (nextFrame >= track->keyFrames_.Size())
  472. {
  473. if (!looped_)
  474. {
  475. nextFrame = frame;
  476. interpolate = false;
  477. }
  478. else
  479. nextFrame = 0;
  480. }
  481. const AnimationKeyFrame* keyFrame = &track->keyFrames_[frame];
  482. unsigned char channelMask = track->channelMask_;
  483. if (!interpolate)
  484. {
  485. // No interpolation, blend between old transform & animation
  486. if (channelMask & CHANNEL_POSITION)
  487. node->SetPositionSilent(node->GetPosition().Lerp(keyFrame->position_, weight));
  488. if (channelMask & CHANNEL_ROTATION)
  489. node->SetRotationSilent(node->GetRotation().Slerp(keyFrame->rotation_, weight));
  490. if (channelMask & CHANNEL_SCALE)
  491. node->SetScaleSilent(node->GetScale().Lerp(keyFrame->scale_, weight));
  492. }
  493. else
  494. {
  495. const AnimationKeyFrame* nextKeyFrame = &track->keyFrames_[nextFrame];
  496. float timeInterval = nextKeyFrame->time_ - keyFrame->time_;
  497. if (timeInterval < 0.0f)
  498. timeInterval += animation_->GetLength();
  499. float t = timeInterval > 0.0f ? (time_ - keyFrame->time_) / timeInterval : 1.0f;
  500. // Interpolation, blend between old transform & animation
  501. if (channelMask & CHANNEL_POSITION)
  502. {
  503. node->SetPositionSilent(node->GetPosition().Lerp(
  504. keyFrame->position_.Lerp(nextKeyFrame->position_, t), weight));
  505. }
  506. if (channelMask & CHANNEL_ROTATION)
  507. {
  508. node->SetRotationSilent(node->GetRotation().Slerp(
  509. keyFrame->rotation_.Slerp(nextKeyFrame->rotation_, t), weight));
  510. }
  511. if (channelMask & CHANNEL_SCALE)
  512. {
  513. node->SetScaleSilent(node->GetScale().Lerp(
  514. keyFrame->scale_.Lerp(nextKeyFrame->scale_, t), weight));
  515. }
  516. }
  517. }
  518. }