SkeletonAnimation.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. /******************************************************************************
  2. * Spine Runtimes License Agreement
  3. * Last updated January 1, 2020. Replaces all prior versions.
  4. *
  5. * Copyright (c) 2013-2020, Esoteric Software LLC
  6. *
  7. * Integration of the Spine Runtimes into software or otherwise creating
  8. * derivative works of the Spine Runtimes is permitted under the terms and
  9. * conditions of Section 2 of the Spine Editor License Agreement:
  10. * http://esotericsoftware.com/spine-editor-license
  11. *
  12. * Otherwise, it is permitted to integrate the Spine Runtimes into software
  13. * or otherwise create derivative works of the Spine Runtimes (collectively,
  14. * "Products"), provided that each user of the Products must obtain their own
  15. * Spine Editor license and redistribution of the Products in any form must
  16. * include this license and copyright notice.
  17. *
  18. * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
  19. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
  24. * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *****************************************************************************/
  29. #include <spine/SkeletonAnimation.h>
  30. #include <spine/spine-cocos2dx.h>
  31. #include <spine/extension.h>
  32. #include <algorithm>
  33. USING_NS_CC;
  34. using std::min;
  35. using std::max;
  36. using std::vector;
  37. namespace spine {
  38. typedef struct _TrackEntryListeners {
  39. StartListener startListener;
  40. InterruptListener interruptListener;
  41. EndListener endListener;
  42. DisposeListener disposeListener;
  43. CompleteListener completeListener;
  44. EventListener eventListener;
  45. } _TrackEntryListeners;
  46. void animationCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
  47. ((SkeletonAnimation*)state->getRendererObject())->onAnimationStateEvent(entry, type, event);
  48. }
  49. void trackEntryCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
  50. ((SkeletonAnimation*)state->getRendererObject())->onTrackEntryEvent(entry, type, event);
  51. if (type == EventType_Dispose) {
  52. if (entry->getRendererObject()) {
  53. delete (spine::_TrackEntryListeners*)entry->getRendererObject();
  54. entry->setRendererObject(NULL);
  55. }
  56. }
  57. }
  58. static _TrackEntryListeners* getListeners (spine::TrackEntry* entry) {
  59. if (!entry->getRendererObject()) {
  60. entry->setRendererObject(new spine::_TrackEntryListeners());
  61. entry->setListener(trackEntryCallback);
  62. }
  63. return (_TrackEntryListeners*)entry->getRendererObject();
  64. }
  65. //
  66. SkeletonAnimation* SkeletonAnimation::createWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
  67. SkeletonAnimation* node = new SkeletonAnimation();
  68. node->initWithData(skeletonData, ownsSkeletonData);
  69. node->autorelease();
  70. return node;
  71. }
  72. SkeletonAnimation* SkeletonAnimation::createWithJsonFile (const std::string& skeletonJsonFile, Atlas* atlas, float scale) {
  73. SkeletonAnimation* node = new SkeletonAnimation();
  74. node->initWithJsonFile(skeletonJsonFile, atlas, scale);
  75. node->autorelease();
  76. return node;
  77. }
  78. SkeletonAnimation* SkeletonAnimation::createWithJsonFile (const std::string& skeletonJsonFile, const std::string& atlasFile, float scale) {
  79. SkeletonAnimation* node = new SkeletonAnimation();
  80. node->initWithJsonFile(skeletonJsonFile, atlasFile, scale);
  81. node->autorelease();
  82. return node;
  83. }
  84. SkeletonAnimation* SkeletonAnimation::createWithBinaryFile (const std::string& skeletonBinaryFile, Atlas* atlas, float scale) {
  85. SkeletonAnimation* node = new SkeletonAnimation();
  86. node->initWithBinaryFile(skeletonBinaryFile, atlas, scale);
  87. node->autorelease();
  88. return node;
  89. }
  90. SkeletonAnimation* SkeletonAnimation::createWithBinaryFile (const std::string& skeletonBinaryFile, const std::string& atlasFile, float scale) {
  91. SkeletonAnimation* node = new SkeletonAnimation();
  92. node->initWithBinaryFile(skeletonBinaryFile, atlasFile, scale);
  93. node->autorelease();
  94. return node;
  95. }
  96. void SkeletonAnimation::initialize () {
  97. super::initialize();
  98. _ownsAnimationStateData = true;
  99. _updateOnlyIfVisible = false;
  100. _state = new (__FILE__, __LINE__) AnimationState(new (__FILE__, __LINE__) AnimationStateData(_skeleton->getData()));
  101. _state->setRendererObject(this);
  102. _state->setListener(animationCallback);
  103. _firstDraw = true;
  104. }
  105. SkeletonAnimation::SkeletonAnimation ()
  106. : SkeletonRenderer() {
  107. }
  108. SkeletonAnimation::~SkeletonAnimation () {
  109. if (_ownsAnimationStateData && _state) delete _state->getData();
  110. delete _state;
  111. }
  112. void SkeletonAnimation::update (float deltaTime) {
  113. if(_checkOutScreen && beOutScreen()) return;
  114. if (_updateOnlyIfVisible && !isVisible()) return;
  115. super::update(deltaTime);
  116. deltaTime *= _timeScale;
  117. if (_preUpdateListener) _preUpdateListener(this);
  118. _state->update(deltaTime);
  119. _state->apply(*_skeleton);
  120. _skeleton->updateWorldTransform();
  121. if (_postUpdateListener) _postUpdateListener(this);
  122. }
  123. void SkeletonAnimation::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags) {
  124. if(_checkOutScreen && beOutScreen()) return;
  125. if (_firstDraw) {
  126. _firstDraw = false;
  127. update(0);
  128. }
  129. super::draw(renderer, transform, transformFlags);
  130. }
  131. void SkeletonAnimation::setAnimationStateData (AnimationStateData* stateData) {
  132. CCASSERT(stateData, "stateData cannot be null.");
  133. if (_ownsAnimationStateData) delete _state->getData();
  134. delete _state;
  135. _ownsAnimationStateData = false;
  136. _state = new (__FILE__, __LINE__) AnimationState(stateData);
  137. _state->setRendererObject(this);
  138. _state->setListener(animationCallback);
  139. }
  140. void SkeletonAnimation::setMix (const std::string& fromAnimation, const std::string& toAnimation, float duration) {
  141. _state->getData()->setMix(fromAnimation.c_str(), toAnimation.c_str(), duration);
  142. }
  143. TrackEntry* SkeletonAnimation::setAnimation (int trackIndex, const std::string& name, bool loop) {
  144. Animation* animation = _skeleton->getData()->findAnimation(name.c_str());
  145. if (!animation) {
  146. log("Spine: Animation not found: %s", name.c_str());
  147. return 0;
  148. }
  149. return _state->setAnimation(trackIndex, animation, loop);
  150. }
  151. TrackEntry* SkeletonAnimation::addAnimation (int trackIndex, const std::string& name, bool loop, float delay) {
  152. Animation* animation = _skeleton->getData()->findAnimation(name.c_str());
  153. if (!animation) {
  154. log("Spine: Animation not found: %s", name.c_str());
  155. return 0;
  156. }
  157. return _state->addAnimation(trackIndex, animation, loop, delay);
  158. }
  159. TrackEntry* SkeletonAnimation::setEmptyAnimation (int trackIndex, float mixDuration) {
  160. return _state->setEmptyAnimation(trackIndex, mixDuration);
  161. }
  162. void SkeletonAnimation::setEmptyAnimations (float mixDuration) {
  163. _state->setEmptyAnimations(mixDuration);
  164. }
  165. TrackEntry* SkeletonAnimation::addEmptyAnimation (int trackIndex, float mixDuration, float delay) {
  166. return _state->addEmptyAnimation(trackIndex, mixDuration, delay);
  167. }
  168. Animation* SkeletonAnimation::findAnimation(const std::string& name) const {
  169. return _skeleton->getData()->findAnimation(name.c_str());
  170. }
  171. TrackEntry* SkeletonAnimation::getCurrent (int trackIndex) {
  172. return _state->getCurrent(trackIndex);
  173. }
  174. void SkeletonAnimation::clearTracks () {
  175. _state->clearTracks();
  176. }
  177. void SkeletonAnimation::clearTrack (int trackIndex) {
  178. _state->clearTrack(trackIndex);
  179. }
  180. void SkeletonAnimation::onAnimationStateEvent (TrackEntry* entry, EventType type, Event* event) {
  181. switch (type) {
  182. case EventType_Start:
  183. if (_startListener) _startListener(entry);
  184. break;
  185. case EventType_Interrupt:
  186. if (_interruptListener) _interruptListener(entry);
  187. break;
  188. case EventType_End:
  189. if (_endListener) _endListener(entry);
  190. break;
  191. case EventType_Dispose:
  192. if (_disposeListener) _disposeListener(entry);
  193. break;
  194. case EventType_Complete:
  195. if (_completeListener) _completeListener(entry);
  196. break;
  197. case EventType_Event:
  198. if (_eventListener) _eventListener(entry, event);
  199. break;
  200. }
  201. }
  202. void SkeletonAnimation::setDataFile(const std::string& dataFile)
  203. {
  204. _dataFile = dataFile;
  205. changeSkeleton(_dataFile, _atlasFile);
  206. }
  207. void SkeletonAnimation::setAtlasFile(const std::string& atlasFile)
  208. {
  209. _atlasFile = atlasFile;
  210. changeSkeleton(_dataFile, _atlasFile);
  211. }
  212. void SkeletonAnimation::changeSkeleton(const std::string& skeletonJsonFile, const std::string& atlasFile, float scale)
  213. {
  214. if (skeletonJsonFile == "" || atlasFile == ""){
  215. return;
  216. }
  217. if (_ownsAnimationStateData)
  218. {
  219. if (_state)
  220. {
  221. delete _state->getData();
  222. delete _state;
  223. }
  224. }
  225. if (_ownsSkeletonData && _skeleton)
  226. {
  227. delete _skeleton->getData();
  228. }
  229. if (_ownsSkeleton && _skeleton)
  230. {
  231. delete _skeleton;
  232. }
  233. if (_ownsAtlas && _atlas)
  234. {
  235. delete _atlas;
  236. }
  237. if (_attachmentLoader) delete _attachmentLoader;
  238. if (_clipper)
  239. {
  240. delete _clipper;
  241. }
  242. this->initWithBinaryFile(skeletonJsonFile, atlasFile,scale);
  243. }
  244. void SkeletonAnimation::onTrackEntryEvent (TrackEntry* entry, EventType type, Event* event) {
  245. if (!entry->getRendererObject()) return;
  246. _TrackEntryListeners* listeners = (_TrackEntryListeners*)entry->getRendererObject();
  247. switch (type) {
  248. case EventType_Start:
  249. if (listeners->startListener) listeners->startListener(entry);
  250. break;
  251. case EventType_Interrupt:
  252. if (listeners->interruptListener) listeners->interruptListener(entry);
  253. break;
  254. case EventType_End:
  255. if (listeners->endListener) listeners->endListener(entry);
  256. break;
  257. case EventType_Dispose:
  258. if (listeners->disposeListener) listeners->disposeListener(entry);
  259. break;
  260. case EventType_Complete:
  261. if (listeners->completeListener) listeners->completeListener(entry);
  262. break;
  263. case EventType_Event:
  264. if (listeners->eventListener) listeners->eventListener(entry, event);
  265. break;
  266. }
  267. }
  268. void SkeletonAnimation::setStartListener (const StartListener& listener) {
  269. _startListener = listener;
  270. }
  271. void SkeletonAnimation::setInterruptListener (const InterruptListener& listener) {
  272. _interruptListener = listener;
  273. }
  274. void SkeletonAnimation::setEndListener (const EndListener& listener) {
  275. _endListener = listener;
  276. }
  277. void SkeletonAnimation::setDisposeListener (const DisposeListener& listener) {
  278. _disposeListener = listener;
  279. }
  280. void SkeletonAnimation::setCompleteListener (const CompleteListener& listener) {
  281. _completeListener = listener;
  282. }
  283. void SkeletonAnimation::setEventListener (const EventListener& listener) {
  284. _eventListener = listener;
  285. }
  286. void SkeletonAnimation::setPreUpdateWorldTransformsListener(const UpdateWorldTransformsListener &listener) {
  287. _preUpdateListener = listener;
  288. }
  289. void SkeletonAnimation::setPostUpdateWorldTransformsListener(const UpdateWorldTransformsListener &listener) {
  290. _postUpdateListener = listener;
  291. }
  292. void SkeletonAnimation::setTrackStartListener (TrackEntry* entry, const StartListener& listener) {
  293. getListeners(entry)->startListener = listener;
  294. }
  295. void SkeletonAnimation::setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener) {
  296. getListeners(entry)->interruptListener = listener;
  297. }
  298. void SkeletonAnimation::setTrackEndListener (TrackEntry* entry, const EndListener& listener) {
  299. getListeners(entry)->endListener = listener;
  300. }
  301. void SkeletonAnimation::setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener) {
  302. getListeners(entry)->disposeListener = listener;
  303. }
  304. void SkeletonAnimation::setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener) {
  305. getListeners(entry)->completeListener = listener;
  306. }
  307. void SkeletonAnimation::setTrackEventListener (TrackEntry* entry, const EventListener& listener) {
  308. getListeners(entry)->eventListener = listener;
  309. }
  310. AnimationState* SkeletonAnimation::getState() const {
  311. return _state;
  312. }
  313. void SkeletonAnimation::setUpdateOnlyIfVisible(bool status) {
  314. _updateOnlyIfVisible = status;
  315. }
  316. void SkeletonAnimation::setNotCheckDrawAndUpdateIfOutScreen(const cocos2d::Size& contentSz, const cocos2d::Vec2& anchorPoint) {
  317. _checkOutScreen = true;
  318. _checkContentSz = contentSz;
  319. _anchorPoint = anchorPoint;
  320. }
  321. bool SkeletonAnimation::beOutScreen(){
  322. Vec2 pos2World = getParent()->convertToWorldSpace(getPosition());
  323. Size wSz = Director::getInstance()->getWinSize();
  324. Vec2 leftBottomOffset(-_anchorPoint.x*_checkContentSz.width, -_anchorPoint.y*_checkContentSz.height);
  325. if( !Rect(Vec2(0,0), wSz).intersectsRect(Rect(pos2World+Vec2(-10,-10) + leftBottomOffset, _checkContentSz+Size(20,20))) ){
  326. //CCLOG("不在屏幕内,返回! %p", this);
  327. return true;
  328. }
  329. return false;
  330. }
  331. //============================SpineAction================================
  332. /************************************************************
  333. SpineActionInstant
  334. ************************************************************/
  335. SpineActionInstant* SpineActionInstant::create(SkeletonFrame startFrame)
  336. {
  337. SpineActionInstant *ret = new (std::nothrow) SpineActionInstant();
  338. if (ret)
  339. {
  340. if (ret->initWithSkeletonFrame(startFrame))
  341. {
  342. ret->autorelease();
  343. }
  344. else
  345. {
  346. CC_SAFE_DELETE(ret);
  347. }
  348. }
  349. return ret;
  350. }
  351. bool SpineActionInstant::initWithSkeletonFrame(SkeletonFrame startFrame)
  352. {
  353. _startFrame = startFrame;
  354. return true;
  355. }
  356. SpineActionInstant::~SpineActionInstant()
  357. {
  358. }
  359. SpineActionInstant* SpineActionInstant::clone() const
  360. {
  361. // no copy constructor
  362. auto a = new (std::nothrow) SpineActionInstant();
  363. a->initWithSkeletonFrame(_startFrame);
  364. a->autorelease();
  365. return a;
  366. }
  367. SpineActionInstant* SpineActionInstant::reverse() const
  368. {
  369. // returns a copy of itself
  370. return this->clone();
  371. }
  372. void SpineActionInstant::update(float time)
  373. {
  374. SkeletonAnimation* animNode = dynamic_cast<SkeletonAnimation*>(_target);
  375. if (animNode == nullptr)
  376. return;
  377. if(!strcmp(_startFrame.animation.c_str(), "Null") || !strcmp(_startFrame.animation.c_str(), "")){
  378. animNode->setEmptyAnimations(0);
  379. animNode->update(0);
  380. } else {
  381. animNode->clearTracks();
  382. animNode->setToSetupPose();
  383. animNode->setAnimation(0, _startFrame.animation, _startFrame.loop);
  384. animNode->scheduleUpdate();
  385. }
  386. }
  387. }