123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- /******************************************************************************
- * Spine Runtimes License Agreement
- * Last updated January 1, 2020. Replaces all prior versions.
- *
- * Copyright (c) 2013-2020, Esoteric Software LLC
- *
- * Integration of the Spine Runtimes into software or otherwise creating
- * derivative works of the Spine Runtimes is permitted under the terms and
- * conditions of Section 2 of the Spine Editor License Agreement:
- * http://esotericsoftware.com/spine-editor-license
- *
- * Otherwise, it is permitted to integrate the Spine Runtimes into software
- * or otherwise create derivative works of the Spine Runtimes (collectively,
- * "Products"), provided that each user of the Products must obtain their own
- * Spine Editor license and redistribution of the Products in any form must
- * include this license and copyright notice.
- *
- * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
- * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
- #include <spine/SkeletonAnimation.h>
- #include <spine/spine-cocos2dx.h>
- #include <spine/extension.h>
- #include <algorithm>
- USING_NS_CC;
- using std::min;
- using std::max;
- using std::vector;
- namespace spine {
- typedef struct _TrackEntryListeners {
- StartListener startListener;
- InterruptListener interruptListener;
- EndListener endListener;
- DisposeListener disposeListener;
- CompleteListener completeListener;
- EventListener eventListener;
- } _TrackEntryListeners;
- void animationCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
- ((SkeletonAnimation*)state->getRendererObject())->onAnimationStateEvent(entry, type, event);
- }
- void trackEntryCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
- ((SkeletonAnimation*)state->getRendererObject())->onTrackEntryEvent(entry, type, event);
- if (type == EventType_Dispose) {
- if (entry->getRendererObject()) {
- delete (spine::_TrackEntryListeners*)entry->getRendererObject();
- entry->setRendererObject(NULL);
- }
- }
- }
- static _TrackEntryListeners* getListeners (spine::TrackEntry* entry) {
- if (!entry->getRendererObject()) {
- entry->setRendererObject(new spine::_TrackEntryListeners());
- entry->setListener(trackEntryCallback);
- }
- return (_TrackEntryListeners*)entry->getRendererObject();
- }
- //
- SkeletonAnimation* SkeletonAnimation::createWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
- SkeletonAnimation* node = new SkeletonAnimation();
- node->initWithData(skeletonData, ownsSkeletonData);
- node->autorelease();
- return node;
- }
- SkeletonAnimation* SkeletonAnimation::createWithJsonFile (const std::string& skeletonJsonFile, Atlas* atlas, float scale) {
- SkeletonAnimation* node = new SkeletonAnimation();
- node->initWithJsonFile(skeletonJsonFile, atlas, scale);
- node->autorelease();
- return node;
- }
- SkeletonAnimation* SkeletonAnimation::createWithJsonFile (const std::string& skeletonJsonFile, const std::string& atlasFile, float scale) {
- SkeletonAnimation* node = new SkeletonAnimation();
- node->initWithJsonFile(skeletonJsonFile, atlasFile, scale);
- node->autorelease();
- return node;
- }
- SkeletonAnimation* SkeletonAnimation::createWithBinaryFile (const std::string& skeletonBinaryFile, Atlas* atlas, float scale) {
- SkeletonAnimation* node = new SkeletonAnimation();
- node->initWithBinaryFile(skeletonBinaryFile, atlas, scale);
- node->autorelease();
- return node;
- }
- SkeletonAnimation* SkeletonAnimation::createWithBinaryFile (const std::string& skeletonBinaryFile, const std::string& atlasFile, float scale) {
- SkeletonAnimation* node = new SkeletonAnimation();
- node->initWithBinaryFile(skeletonBinaryFile, atlasFile, scale);
- node->autorelease();
- return node;
- }
- void SkeletonAnimation::initialize () {
- super::initialize();
- _ownsAnimationStateData = true;
- _updateOnlyIfVisible = false;
- _state = new (__FILE__, __LINE__) AnimationState(new (__FILE__, __LINE__) AnimationStateData(_skeleton->getData()));
- _state->setRendererObject(this);
- _state->setListener(animationCallback);
- _firstDraw = true;
- }
- SkeletonAnimation::SkeletonAnimation ()
- : SkeletonRenderer() {
- }
- SkeletonAnimation::~SkeletonAnimation () {
- if (_ownsAnimationStateData && _state) delete _state->getData();
- delete _state;
- }
- void SkeletonAnimation::update (float deltaTime) {
- if(_checkOutScreen && beOutScreen()) return;
- if (_updateOnlyIfVisible && !isVisible()) return;
- super::update(deltaTime);
- deltaTime *= _timeScale;
- if (_preUpdateListener) _preUpdateListener(this);
- _state->update(deltaTime);
- _state->apply(*_skeleton);
- _skeleton->updateWorldTransform();
- if (_postUpdateListener) _postUpdateListener(this);
- }
- void SkeletonAnimation::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags) {
- if(_checkOutScreen && beOutScreen()) return;
- if (_firstDraw) {
- _firstDraw = false;
- update(0);
- }
- super::draw(renderer, transform, transformFlags);
- }
- void SkeletonAnimation::setAnimationStateData (AnimationStateData* stateData) {
- CCASSERT(stateData, "stateData cannot be null.");
- if (_ownsAnimationStateData) delete _state->getData();
- delete _state;
- _ownsAnimationStateData = false;
- _state = new (__FILE__, __LINE__) AnimationState(stateData);
- _state->setRendererObject(this);
- _state->setListener(animationCallback);
- }
- void SkeletonAnimation::setMix (const std::string& fromAnimation, const std::string& toAnimation, float duration) {
- _state->getData()->setMix(fromAnimation.c_str(), toAnimation.c_str(), duration);
- }
- TrackEntry* SkeletonAnimation::setAnimation (int trackIndex, const std::string& name, bool loop) {
- Animation* animation = _skeleton->getData()->findAnimation(name.c_str());
- if (!animation) {
- log("Spine: Animation not found: %s", name.c_str());
- return 0;
- }
- return _state->setAnimation(trackIndex, animation, loop);
- }
- TrackEntry* SkeletonAnimation::addAnimation (int trackIndex, const std::string& name, bool loop, float delay) {
- Animation* animation = _skeleton->getData()->findAnimation(name.c_str());
- if (!animation) {
- log("Spine: Animation not found: %s", name.c_str());
- return 0;
- }
- return _state->addAnimation(trackIndex, animation, loop, delay);
- }
- TrackEntry* SkeletonAnimation::setEmptyAnimation (int trackIndex, float mixDuration) {
- return _state->setEmptyAnimation(trackIndex, mixDuration);
- }
- void SkeletonAnimation::setEmptyAnimations (float mixDuration) {
- _state->setEmptyAnimations(mixDuration);
- }
- TrackEntry* SkeletonAnimation::addEmptyAnimation (int trackIndex, float mixDuration, float delay) {
- return _state->addEmptyAnimation(trackIndex, mixDuration, delay);
- }
- Animation* SkeletonAnimation::findAnimation(const std::string& name) const {
- return _skeleton->getData()->findAnimation(name.c_str());
- }
- TrackEntry* SkeletonAnimation::getCurrent (int trackIndex) {
- return _state->getCurrent(trackIndex);
- }
- void SkeletonAnimation::clearTracks () {
- _state->clearTracks();
- }
- void SkeletonAnimation::clearTrack (int trackIndex) {
- _state->clearTrack(trackIndex);
- }
- void SkeletonAnimation::onAnimationStateEvent (TrackEntry* entry, EventType type, Event* event) {
- switch (type) {
- case EventType_Start:
- if (_startListener) _startListener(entry);
- break;
- case EventType_Interrupt:
- if (_interruptListener) _interruptListener(entry);
- break;
- case EventType_End:
- if (_endListener) _endListener(entry);
- break;
- case EventType_Dispose:
- if (_disposeListener) _disposeListener(entry);
- break;
- case EventType_Complete:
- if (_completeListener) _completeListener(entry);
- break;
- case EventType_Event:
- if (_eventListener) _eventListener(entry, event);
- break;
- }
- }
- void SkeletonAnimation::setDataFile(const std::string& dataFile)
- {
- _dataFile = dataFile;
- changeSkeleton(_dataFile, _atlasFile);
- }
-
- void SkeletonAnimation::setAtlasFile(const std::string& atlasFile)
- {
- _atlasFile = atlasFile;
- changeSkeleton(_dataFile, _atlasFile);
- }
- void SkeletonAnimation::changeSkeleton(const std::string& skeletonJsonFile, const std::string& atlasFile, float scale)
- {
- if (skeletonJsonFile == "" || atlasFile == ""){
- return;
- }
-
- if (_ownsAnimationStateData)
- {
- if (_state)
- {
- delete _state->getData();
- delete _state;
- }
- }
-
- if (_ownsSkeletonData && _skeleton)
- {
- delete _skeleton->getData();
- }
- if (_ownsSkeleton && _skeleton)
- {
- delete _skeleton;
- }
- if (_ownsAtlas && _atlas)
- {
- delete _atlas;
- }
- if (_attachmentLoader) delete _attachmentLoader;
- if (_clipper)
- {
- delete _clipper;
- }
-
- this->initWithBinaryFile(skeletonJsonFile, atlasFile,scale);
- }
- void SkeletonAnimation::onTrackEntryEvent (TrackEntry* entry, EventType type, Event* event) {
- if (!entry->getRendererObject()) return;
- _TrackEntryListeners* listeners = (_TrackEntryListeners*)entry->getRendererObject();
- switch (type) {
- case EventType_Start:
- if (listeners->startListener) listeners->startListener(entry);
- break;
- case EventType_Interrupt:
- if (listeners->interruptListener) listeners->interruptListener(entry);
- break;
- case EventType_End:
- if (listeners->endListener) listeners->endListener(entry);
- break;
- case EventType_Dispose:
- if (listeners->disposeListener) listeners->disposeListener(entry);
- break;
- case EventType_Complete:
- if (listeners->completeListener) listeners->completeListener(entry);
- break;
- case EventType_Event:
- if (listeners->eventListener) listeners->eventListener(entry, event);
- break;
- }
- }
- void SkeletonAnimation::setStartListener (const StartListener& listener) {
- _startListener = listener;
- }
- void SkeletonAnimation::setInterruptListener (const InterruptListener& listener) {
- _interruptListener = listener;
- }
- void SkeletonAnimation::setEndListener (const EndListener& listener) {
- _endListener = listener;
- }
- void SkeletonAnimation::setDisposeListener (const DisposeListener& listener) {
- _disposeListener = listener;
- }
- void SkeletonAnimation::setCompleteListener (const CompleteListener& listener) {
- _completeListener = listener;
- }
- void SkeletonAnimation::setEventListener (const EventListener& listener) {
- _eventListener = listener;
- }
- void SkeletonAnimation::setPreUpdateWorldTransformsListener(const UpdateWorldTransformsListener &listener) {
- _preUpdateListener = listener;
- }
- void SkeletonAnimation::setPostUpdateWorldTransformsListener(const UpdateWorldTransformsListener &listener) {
- _postUpdateListener = listener;
- }
- void SkeletonAnimation::setTrackStartListener (TrackEntry* entry, const StartListener& listener) {
- getListeners(entry)->startListener = listener;
- }
- void SkeletonAnimation::setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener) {
- getListeners(entry)->interruptListener = listener;
- }
- void SkeletonAnimation::setTrackEndListener (TrackEntry* entry, const EndListener& listener) {
- getListeners(entry)->endListener = listener;
- }
- void SkeletonAnimation::setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener) {
- getListeners(entry)->disposeListener = listener;
- }
- void SkeletonAnimation::setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener) {
- getListeners(entry)->completeListener = listener;
- }
- void SkeletonAnimation::setTrackEventListener (TrackEntry* entry, const EventListener& listener) {
- getListeners(entry)->eventListener = listener;
- }
- AnimationState* SkeletonAnimation::getState() const {
- return _state;
- }
- void SkeletonAnimation::setUpdateOnlyIfVisible(bool status) {
- _updateOnlyIfVisible = status;
- }
- void SkeletonAnimation::setNotCheckDrawAndUpdateIfOutScreen(const cocos2d::Size& contentSz, const cocos2d::Vec2& anchorPoint) {
- _checkOutScreen = true;
- _checkContentSz = contentSz;
- _anchorPoint = anchorPoint;
- }
- bool SkeletonAnimation::beOutScreen(){
- Vec2 pos2World = getParent()->convertToWorldSpace(getPosition());
- Size wSz = Director::getInstance()->getWinSize();
- Vec2 leftBottomOffset(-_anchorPoint.x*_checkContentSz.width, -_anchorPoint.y*_checkContentSz.height);
- if( !Rect(Vec2(0,0), wSz).intersectsRect(Rect(pos2World+Vec2(-10,-10) + leftBottomOffset, _checkContentSz+Size(20,20))) ){
- //CCLOG("不在屏幕内,返回! %p", this);
- return true;
- }
- return false;
- }
- //============================SpineAction================================
- /************************************************************
- SpineActionInstant
- ************************************************************/
- SpineActionInstant* SpineActionInstant::create(SkeletonFrame startFrame)
- {
- SpineActionInstant *ret = new (std::nothrow) SpineActionInstant();
- if (ret)
- {
- if (ret->initWithSkeletonFrame(startFrame))
- {
- ret->autorelease();
- }
- else
- {
- CC_SAFE_DELETE(ret);
- }
- }
-
- return ret;
- }
- bool SpineActionInstant::initWithSkeletonFrame(SkeletonFrame startFrame)
- {
- _startFrame = startFrame;
- return true;
- }
- SpineActionInstant::~SpineActionInstant()
- {
- }
- SpineActionInstant* SpineActionInstant::clone() const
- {
- // no copy constructor
- auto a = new (std::nothrow) SpineActionInstant();
- a->initWithSkeletonFrame(_startFrame);
- a->autorelease();
- return a;
- }
- SpineActionInstant* SpineActionInstant::reverse() const
- {
- // returns a copy of itself
- return this->clone();
- }
- void SpineActionInstant::update(float time)
- {
- SkeletonAnimation* animNode = dynamic_cast<SkeletonAnimation*>(_target);
- if (animNode == nullptr)
- return;
- if(!strcmp(_startFrame.animation.c_str(), "Null") || !strcmp(_startFrame.animation.c_str(), "")){
- animNode->setEmptyAnimations(0);
- animNode->update(0);
- } else {
- animNode->clearTracks();
- animNode->setToSetupPose();
- animNode->setAnimation(0, _startFrame.animation, _startFrame.loop);
- animNode->scheduleUpdate();
- }
- }
- }
|