SkeletonAnimation.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /******************************************************************************
  2. * Spine Runtimes Software License v2.5
  3. *
  4. * Copyright (c) 2013-2016, Esoteric Software
  5. * All rights reserved.
  6. *
  7. * You are granted a perpetual, non-exclusive, non-sublicensable, and
  8. * non-transferable license to use, install, execute, and perform the Spine
  9. * Runtimes software and derivative works solely for personal or internal
  10. * use. Without the written permission of Esoteric Software (see Section 2 of
  11. * the Spine Software License Agreement), you may not (a) modify, translate,
  12. * adapt, or develop new applications using the Spine Runtimes or otherwise
  13. * create derivative works or improvements of the Spine Runtimes or (b) remove,
  14. * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
  15. * or other intellectual property or proprietary rights notices on or in the
  16. * Software, including any copy thereof. Redistributions in binary or source
  17. * form must include this license and terms.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22. * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  24. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
  25. * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  26. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. * POSSIBILITY OF SUCH DAMAGE.
  29. *****************************************************************************/
  30. #include <spine/SkeletonAnimation.h>
  31. #include <spine/spine-cocos2dx.h>
  32. #include <spine/extension.h>
  33. #include <algorithm>
  34. USING_NS_CC;
  35. using std::min;
  36. using std::max;
  37. using std::vector;
  38. namespace spine {
  39. typedef struct _TrackEntryListeners {
  40. StartListener startListener;
  41. InterruptListener interruptListener;
  42. EndListener endListener;
  43. DisposeListener disposeListener;
  44. CompleteListener completeListener;
  45. EventListener eventListener;
  46. } _TrackEntryListeners;
  47. void animationCallback (spAnimationState* state, spEventType type, spTrackEntry* entry, spEvent* event) {
  48. ((SkeletonAnimation*)state->rendererObject)->onAnimationStateEvent(entry, type, event);
  49. }
  50. void trackEntryCallback (spAnimationState* state, spEventType type, spTrackEntry* entry, spEvent* event) {
  51. ((SkeletonAnimation*)state->rendererObject)->onTrackEntryEvent(entry, type, event);
  52. if (type == SP_ANIMATION_DISPOSE)
  53. if (entry->rendererObject) delete (spine::_TrackEntryListeners*)entry->rendererObject;
  54. }
  55. static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
  56. if (!entry->rendererObject) {
  57. entry->rendererObject = new spine::_TrackEntryListeners();
  58. entry->listener = trackEntryCallback;
  59. }
  60. return (_TrackEntryListeners*)entry->rendererObject;
  61. }
  62. //
  63. SkeletonAnimation* SkeletonAnimation::createWithData (spSkeletonData* skeletonData, bool ownsSkeletonData) {
  64. SkeletonAnimation* node = new SkeletonAnimation();
  65. node->initWithData(skeletonData, ownsSkeletonData);
  66. node->autorelease();
  67. return node;
  68. }
  69. SkeletonAnimation* SkeletonAnimation::createWithJsonFile (const std::string& skeletonJsonFile, spAtlas* atlas, float scale) {
  70. SkeletonAnimation* node = new SkeletonAnimation();
  71. node->initWithJsonFile(skeletonJsonFile, atlas, scale);
  72. node->autorelease();
  73. return node;
  74. }
  75. SkeletonAnimation* SkeletonAnimation::createWithJsonFile (const std::string& skeletonJsonFile, const std::string& atlasFile, float scale) {
  76. SkeletonAnimation* node = new SkeletonAnimation();
  77. spAtlas* atlas = spAtlas_createFromFile(atlasFile.c_str(), 0);
  78. node->initWithJsonFile(skeletonJsonFile, atlas, scale);
  79. node->autorelease();
  80. return node;
  81. }
  82. SkeletonAnimation* SkeletonAnimation::createWithBinaryFile (const std::string& skeletonBinaryFile, spAtlas* atlas, float scale) {
  83. SkeletonAnimation* node = new SkeletonAnimation();
  84. node->initWithBinaryFile(skeletonBinaryFile, atlas, scale);
  85. node->autorelease();
  86. return node;
  87. }
  88. SkeletonAnimation* SkeletonAnimation::createWithBinaryFile (const std::string& skeletonBinaryFile, const std::string& atlasFile, float scale) {
  89. SkeletonAnimation* node = new SkeletonAnimation();
  90. spAtlas* atlas = spAtlas_createFromFile(atlasFile.c_str(), 0);
  91. node->initWithBinaryFile(skeletonBinaryFile, atlas, scale);
  92. node->autorelease();
  93. return node;
  94. }
  95. void SkeletonAnimation::initialize () {
  96. super::initialize();
  97. _ownsAnimationStateData = true;
  98. _state = spAnimationState_create(spAnimationStateData_create(_skeleton->data));
  99. _state->rendererObject = this;
  100. _state->listener = animationCallback;
  101. _spAnimationState* stateInternal = (_spAnimationState*)_state;
  102. _firstDraw = true;
  103. }
  104. SkeletonAnimation::SkeletonAnimation ()
  105. : SkeletonRenderer() {
  106. }
  107. SkeletonAnimation::~SkeletonAnimation () {
  108. if (_ownsAnimationStateData) spAnimationStateData_dispose(_state->data);
  109. spAnimationState_dispose(_state);
  110. }
  111. void SkeletonAnimation::update (float deltaTime) {
  112. super::update(deltaTime);
  113. deltaTime *= _timeScale;
  114. spAnimationState_update(_state, deltaTime);
  115. spAnimationState_apply(_state, _skeleton);
  116. spSkeleton_updateWorldTransform(_skeleton);
  117. }
  118. void SkeletonAnimation::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags) {
  119. if (_firstDraw) {
  120. _firstDraw = false;
  121. update(0);
  122. }
  123. super::draw(renderer, transform, transformFlags);
  124. }
  125. void SkeletonAnimation::setAnimationStateData (spAnimationStateData* stateData) {
  126. CCASSERT(stateData, "stateData cannot be null.");
  127. if (_ownsAnimationStateData) spAnimationStateData_dispose(_state->data);
  128. spAnimationState_dispose(_state);
  129. _ownsAnimationStateData = false;
  130. _state = spAnimationState_create(stateData);
  131. _state->rendererObject = this;
  132. _state->listener = animationCallback;
  133. }
  134. void SkeletonAnimation::setMix (const std::string& fromAnimation, const std::string& toAnimation, float duration) {
  135. spAnimationStateData_setMixByName(_state->data, fromAnimation.c_str(), toAnimation.c_str(), duration);
  136. }
  137. spTrackEntry* SkeletonAnimation::setAnimation (int trackIndex, const std::string& name, bool loop) {
  138. spAnimation* animation = spSkeletonData_findAnimation(_skeleton->data, name.c_str());
  139. if (!animation) {
  140. log("Spine: Animation not found: %s", name.c_str());
  141. return 0;
  142. }
  143. return spAnimationState_setAnimation(_state, trackIndex, animation, loop);
  144. }
  145. spTrackEntry* SkeletonAnimation::addAnimation (int trackIndex, const std::string& name, bool loop, float delay) {
  146. spAnimation* animation = spSkeletonData_findAnimation(_skeleton->data, name.c_str());
  147. if (!animation) {
  148. log("Spine: Animation not found: %s", name.c_str());
  149. return 0;
  150. }
  151. return spAnimationState_addAnimation(_state, trackIndex, animation, loop, delay);
  152. }
  153. spTrackEntry* SkeletonAnimation::setEmptyAnimation (int trackIndex, float mixDuration) {
  154. return spAnimationState_setEmptyAnimation(_state, trackIndex, mixDuration);
  155. }
  156. void SkeletonAnimation::setEmptyAnimations (float mixDuration) {
  157. spAnimationState_setEmptyAnimations(_state, mixDuration);
  158. }
  159. spTrackEntry* SkeletonAnimation::addEmptyAnimation (int trackIndex, float mixDuration, float delay) {
  160. return spAnimationState_addEmptyAnimation(_state, trackIndex, mixDuration, delay);
  161. }
  162. spAnimation* SkeletonAnimation::findAnimation(const std::string& name) const {
  163. return spSkeletonData_findAnimation(_skeleton->data, name.c_str());
  164. }
  165. spTrackEntry* SkeletonAnimation::getCurrent (int trackIndex) {
  166. return spAnimationState_getCurrent(_state, trackIndex);
  167. }
  168. void SkeletonAnimation::clearTracks () {
  169. spAnimationState_clearTracks(_state);
  170. }
  171. void SkeletonAnimation::clearTrack (int trackIndex) {
  172. spAnimationState_clearTrack(_state, trackIndex);
  173. }
  174. void SkeletonAnimation::onAnimationStateEvent (spTrackEntry* entry, spEventType type, spEvent* event) {
  175. switch (type) {
  176. case SP_ANIMATION_START:
  177. if (_startListener) _startListener(entry);
  178. break;
  179. case SP_ANIMATION_INTERRUPT:
  180. if (_interruptListener) _interruptListener(entry);
  181. break;
  182. case SP_ANIMATION_END:
  183. if (_endListener) _endListener(entry);
  184. break;
  185. case SP_ANIMATION_DISPOSE:
  186. if (_disposeListener) _disposeListener(entry);
  187. break;
  188. case SP_ANIMATION_COMPLETE:
  189. if (_completeListener) _completeListener(entry);
  190. break;
  191. case SP_ANIMATION_EVENT:
  192. if (_eventListener) _eventListener(entry, event);
  193. break;
  194. }
  195. }
  196. void SkeletonAnimation::onTrackEntryEvent (spTrackEntry* entry, spEventType type, spEvent* event) {
  197. if (!entry->rendererObject) return;
  198. _TrackEntryListeners* listeners = (_TrackEntryListeners*)entry->rendererObject;
  199. switch (type) {
  200. case SP_ANIMATION_START:
  201. if (listeners->startListener) listeners->startListener(entry);
  202. break;
  203. case SP_ANIMATION_INTERRUPT:
  204. if (listeners->interruptListener) listeners->interruptListener(entry);
  205. break;
  206. case SP_ANIMATION_END:
  207. if (listeners->endListener) listeners->endListener(entry);
  208. break;
  209. case SP_ANIMATION_DISPOSE:
  210. if (listeners->disposeListener) listeners->disposeListener(entry);
  211. break;
  212. case SP_ANIMATION_COMPLETE:
  213. if (listeners->completeListener) listeners->completeListener(entry);
  214. break;
  215. case SP_ANIMATION_EVENT:
  216. if (listeners->eventListener) listeners->eventListener(entry, event);
  217. break;
  218. }
  219. }
  220. void SkeletonAnimation::setStartListener (const StartListener& listener) {
  221. _startListener = listener;
  222. }
  223. void SkeletonAnimation::setInterruptListener (const InterruptListener& listener) {
  224. _interruptListener = listener;
  225. }
  226. void SkeletonAnimation::setEndListener (const EndListener& listener) {
  227. _endListener = listener;
  228. }
  229. void SkeletonAnimation::setDisposeListener (const DisposeListener& listener) {
  230. _disposeListener = listener;
  231. }
  232. void SkeletonAnimation::setCompleteListener (const CompleteListener& listener) {
  233. _completeListener = listener;
  234. }
  235. void SkeletonAnimation::setEventListener (const EventListener& listener) {
  236. _eventListener = listener;
  237. }
  238. void SkeletonAnimation::setTrackStartListener (spTrackEntry* entry, const StartListener& listener) {
  239. getListeners(entry)->startListener = listener;
  240. }
  241. void SkeletonAnimation::setTrackInterruptListener (spTrackEntry* entry, const InterruptListener& listener) {
  242. getListeners(entry)->interruptListener = listener;
  243. }
  244. void SkeletonAnimation::setTrackEndListener (spTrackEntry* entry, const EndListener& listener) {
  245. getListeners(entry)->endListener = listener;
  246. }
  247. void SkeletonAnimation::setTrackDisposeListener (spTrackEntry* entry, const DisposeListener& listener) {
  248. getListeners(entry)->disposeListener = listener;
  249. }
  250. void SkeletonAnimation::setTrackCompleteListener (spTrackEntry* entry, const CompleteListener& listener) {
  251. getListeners(entry)->completeListener = listener;
  252. }
  253. void SkeletonAnimation::setTrackEventListener (spTrackEntry* entry, const EventListener& listener) {
  254. getListeners(entry)->eventListener = listener;
  255. }
  256. spAnimationState* SkeletonAnimation::getState() const {
  257. return _state;
  258. }
  259. }