SpriterInstance2D.cpp 7.6 KB

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