SpriterInstance2D.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. //
  2. // Copyright (c) 2008-2020 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 "../Graphics/DrawableEvents.h"
  24. #include "../Scene/Component.h"
  25. #include "../Scene/Node.h"
  26. #include "../Urho2D/SpriterInstance2D.h"
  27. #include <cmath>
  28. namespace Urho3D
  29. {
  30. namespace Spriter
  31. {
  32. SpriterInstance::SpriterInstance(Component* owner, SpriterData* spriteData) :
  33. owner_(owner),
  34. spriterData_(spriteData),
  35. spatialInfo_(0.f, 0.f, 0.f, 1.f, 1.f)
  36. {
  37. }
  38. SpriterInstance::~SpriterInstance()
  39. {
  40. Clear();
  41. OnSetAnimation(nullptr);
  42. OnSetEntity(nullptr);
  43. }
  44. bool SpriterInstance::SetEntity(int index)
  45. {
  46. if (!spriterData_)
  47. return false;
  48. if (index < (int)spriterData_->entities_.Size())
  49. {
  50. OnSetEntity(spriterData_->entities_[index]);
  51. return true;
  52. }
  53. return false;
  54. }
  55. bool SpriterInstance::SetEntity(const String& entityName)
  56. {
  57. if (!spriterData_)
  58. return false;
  59. for (unsigned i = 0; i < spriterData_->entities_.Size(); ++i)
  60. {
  61. if (spriterData_->entities_[i]->name_ == entityName)
  62. {
  63. OnSetEntity(spriterData_->entities_[i]);
  64. return true;
  65. }
  66. }
  67. return false;
  68. }
  69. bool SpriterInstance::SetAnimation(int index, LoopMode loopMode)
  70. {
  71. if (!entity_)
  72. return false;
  73. if (index < (int)entity_->animations_.Size())
  74. {
  75. OnSetAnimation(entity_->animations_[index], loopMode);
  76. return true;
  77. }
  78. return false;
  79. }
  80. bool SpriterInstance::SetAnimation(const String& animationName, LoopMode loopMode)
  81. {
  82. if (!entity_)
  83. return false;
  84. for (unsigned i = 0; i < entity_->animations_.Size(); ++i)
  85. {
  86. if (entity_->animations_[i]->name_ == animationName)
  87. {
  88. OnSetAnimation(entity_->animations_[i], loopMode);
  89. return true;
  90. }
  91. }
  92. return false;
  93. }
  94. void SpriterInstance::setSpatialInfo(const SpatialInfo& spatialInfo)
  95. {
  96. this->spatialInfo_ = spatialInfo;
  97. }
  98. void SpriterInstance::setSpatialInfo(float x, float y, float angle, float scaleX, float scaleY)
  99. {
  100. spatialInfo_ = SpatialInfo(x, y, angle, scaleX, scaleY);
  101. }
  102. void SpriterInstance::Update(float deltaTime)
  103. {
  104. if (!animation_)
  105. return;
  106. Clear();
  107. float lastTime = currentTime_;
  108. currentTime_ += deltaTime;
  109. if (currentTime_ > animation_->length_)
  110. {
  111. bool sendFinishEvent = false;
  112. if (looping_)
  113. {
  114. currentTime_ = Mod(currentTime_, animation_->length_);
  115. sendFinishEvent = true;
  116. }
  117. else
  118. {
  119. currentTime_ = animation_->length_;
  120. sendFinishEvent = lastTime != currentTime_;
  121. }
  122. if (sendFinishEvent && owner_)
  123. {
  124. Node* senderNode = owner_->GetNode();
  125. if (senderNode)
  126. {
  127. using namespace AnimationFinished;
  128. VariantMap& eventData = senderNode->GetEventDataMap();
  129. eventData[P_NODE] = senderNode;
  130. eventData[P_ANIMATION] = animation_;
  131. eventData[P_NAME] = animation_->name_;
  132. eventData[P_LOOPED] = looping_;
  133. senderNode->SendEvent(E_ANIMATIONFINISHED, eventData);
  134. }
  135. }
  136. }
  137. UpdateMainlineKey();
  138. UpdateTimelineKeys();
  139. }
  140. void SpriterInstance::OnSetEntity(Entity* entity)
  141. {
  142. if (entity == this->entity_)
  143. return;
  144. OnSetAnimation(nullptr);
  145. this->entity_ = entity;
  146. }
  147. void SpriterInstance::OnSetAnimation(Animation* animation, LoopMode loopMode)
  148. {
  149. if (animation == this->animation_)
  150. return;
  151. animation_ = animation;
  152. if (animation_)
  153. {
  154. if (loopMode == Default)
  155. looping_ = animation_->looping_;
  156. else if (loopMode == ForceLooped)
  157. looping_ = true;
  158. else
  159. looping_ = false;
  160. }
  161. currentTime_ = 0.0f;
  162. Clear();
  163. }
  164. void SpriterInstance::UpdateTimelineKeys()
  165. {
  166. for (unsigned i = 0; i < mainlineKey_->boneRefs_.Size(); ++i)
  167. {
  168. Ref* ref = mainlineKey_->boneRefs_[i];
  169. auto* timelineKey = (BoneTimelineKey*)GetTimelineKey(ref);
  170. if (ref->parent_ >= 0)
  171. {
  172. timelineKey->info_ = timelineKey->info_.UnmapFromParent(timelineKeys_[ref->parent_]->info_);
  173. }
  174. else
  175. {
  176. timelineKey->info_ = timelineKey->info_.UnmapFromParent(spatialInfo_);
  177. }
  178. timelineKeys_.Push(timelineKey);
  179. }
  180. for (unsigned i = 0; i < mainlineKey_->objectRefs_.Size(); ++i)
  181. {
  182. Ref* ref = mainlineKey_->objectRefs_[i];
  183. auto* timelineKey = (SpriteTimelineKey*)GetTimelineKey(ref);
  184. if (ref->parent_ >= 0)
  185. {
  186. timelineKey->info_ = timelineKey->info_.UnmapFromParent(timelineKeys_[ref->parent_]->info_);
  187. }
  188. else
  189. {
  190. timelineKey->info_ = timelineKey->info_.UnmapFromParent(spatialInfo_);
  191. }
  192. timelineKey->zIndex_ = ref->zIndex_;
  193. timelineKeys_.Push(timelineKey);
  194. }
  195. }
  196. void SpriterInstance::UpdateMainlineKey()
  197. {
  198. const PODVector<MainlineKey*>& mainlineKeys = animation_->mainlineKeys_;
  199. for (unsigned i = 0; i < mainlineKeys.Size(); ++i)
  200. {
  201. if (mainlineKeys[i]->time_ <= currentTime_)
  202. {
  203. mainlineKey_ = mainlineKeys[i];
  204. }
  205. if (mainlineKeys[i]->time_ >= currentTime_)
  206. {
  207. break;
  208. }
  209. }
  210. if (!mainlineKey_)
  211. {
  212. mainlineKey_ = mainlineKeys[0];
  213. }
  214. }
  215. TimelineKey* SpriterInstance::GetTimelineKey(Ref* ref) const
  216. {
  217. Timeline* timeline = animation_->timelines_[ref->timeline_];
  218. TimelineKey* timelineKey = timeline->keys_[ref->key_]->Clone();
  219. if (timeline->keys_.Size() == 1 || timelineKey->curveType_ == INSTANT)
  220. {
  221. return timelineKey;
  222. }
  223. unsigned nextTimelineKeyIndex = ref->key_ + 1;
  224. if (nextTimelineKeyIndex >= timeline->keys_.Size())
  225. {
  226. if (animation_->looping_)
  227. {
  228. nextTimelineKeyIndex = 0;
  229. }
  230. else
  231. {
  232. return timelineKey;
  233. }
  234. }
  235. TimelineKey* nextTimelineKey = timeline->keys_[nextTimelineKeyIndex];
  236. float nextTimelineKeyTime = nextTimelineKey->time_;
  237. if (nextTimelineKey->time_ < timelineKey->time_)
  238. {
  239. nextTimelineKeyTime += animation_->length_;
  240. }
  241. float t = timelineKey->GetTByCurveType(currentTime_, nextTimelineKeyTime);
  242. timelineKey->Interpolate(*nextTimelineKey, t);
  243. return timelineKey;
  244. }
  245. void SpriterInstance::Clear()
  246. {
  247. mainlineKey_ = nullptr;
  248. if (!timelineKeys_.Empty())
  249. {
  250. for (unsigned i = 0; i < timelineKeys_.Size(); ++i)
  251. {
  252. delete timelineKeys_[i];
  253. }
  254. timelineKeys_.Clear();
  255. }
  256. }
  257. }
  258. }