123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- #include <cstring>
- #include "RUQCoreSpine.h"
- #include <spine/extension.h>
- #include "RUUtils.h"
- #include "AudioEngine.h"
- #include "RedWise.hpp"
- using namespace spine;
- NS_RU_BEGIN
- std::unordered_map<std::string, Atlas*> _mAtlasMap;
- std::unordered_map<std::string, SkeletonData*> _mSkeletonDataMap;
- Cocos2dTextureLoader textureLoader;
- Atlas* QCoreSpine::getAtlasByName(std::string name){
- auto iter = _mAtlasMap.find(name);
- if(iter!=_mAtlasMap.end()){
- return iter->second;
- }else{
- Atlas* atlas = new (__FILE__, __LINE__) Atlas(name.c_str(), &textureLoader, true);
- CCASSERT(atlas, "Error reading atlas file.");
- _mAtlasMap.insert(std::pair<std::string, Atlas*>(name,atlas));
- return atlas;
- }
- return nullptr;
- }
- SkeletonData* QCoreSpine::getSkeletonDataByName(std::string name,Atlas* atlas){
- auto iter = _mSkeletonDataMap.find(name);
- if(iter!=_mSkeletonDataMap.end()){
- return iter->second;
- }else{
- auto attachmentLoader = new (__FILE__, __LINE__) Cocos2dAtlasAttachmentLoader(atlas);
- // auto attachmentLoader = SUPER(Cocos2dAttachmentLoader_create(atlas));
-
- SkeletonBinary binary(attachmentLoader);
- binary.setScale(1.0f);
- SkeletonData* skeletonData = binary.readSkeletonDataFile(name.c_str());
- CCASSERT(skeletonData, !binary.getError().isEmpty() ? binary.getError().buffer() : "Error reading skeleton data.");
- _mSkeletonDataMap.insert(std::pair<std::string, SkeletonData*>(name,skeletonData));
- return skeletonData;
- }
- return nullptr;
- }
- QCoreSpine* QCoreSpine::createWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
- QCoreSpine* node = new QCoreSpine();
- node->initWithData(skeletonData, ownsSkeletonData);
- // FIXME how to set data name?
- node->autorelease();
- node->setContent();
- return node;
- }
- QCoreSpine* QCoreSpine::createWithJsonFile (const std::string& skeletonJsonFile, Atlas* atlas, float scale) {
- QCoreSpine* node = new QCoreSpine();
- node->initWithJsonFile(skeletonJsonFile, atlas, scale);
- node->setDataName(skeletonJsonFile);
- node->autorelease();
- node->setContent();
- return node;
- }
- QCoreSpine* QCoreSpine::createWithJsonFile (const std::string& skeletonJsonFile, const std::string& atlasFile, float scale) {
- QCoreSpine* node = new QCoreSpine();
- node->initWithJsonFile(skeletonJsonFile, atlasFile.c_str(), scale);
- node->setDataName(skeletonJsonFile);
- node->autorelease();
- node->setContent();
- return node;
- }
- QCoreSpine* QCoreSpine::createWithBinaryFile (const std::string& skeletonBinaryFile, Atlas* atlas, float scale) {
- QCoreSpine* node = new QCoreSpine();
- node->initWithBinaryFile(skeletonBinaryFile, atlas, scale);
- node->setDataName(skeletonBinaryFile);
- node->autorelease();
- node->setContent();
- return node;
- }
- QCoreSpine* QCoreSpine::createWithBinaryFile (const std::string& skeletonBinaryFile, const std::string& atlasFile, float scale) {
- QCoreSpine* node = new QCoreSpine();
- node->initWithBinaryFile(skeletonBinaryFile, atlasFile.c_str(), scale);
- node->setDataName(skeletonBinaryFile);
- node->autorelease();
- node->setContent();
- return node;
- }
- QCoreSpine* QCoreSpine::createWithBinaryFileAndCache (const std::string& skeletonBinaryFile, const std::string& atlasFile, float scale) {
- Atlas* atlas = getAtlasByName(atlasFile); // Atlas_createFromFile(atlasFile.c_str(), 0);
- auto skeletonData = getSkeletonDataByName(skeletonBinaryFile, atlas);
- reScaleSkeletonData(skeletonData,scale);
- QCoreSpine* node = createWithData(skeletonData,false);
- node->setScale(scale);
- node->setContent();
- return node;
- }
- QCoreSpine::QCoreSpine ()
- {
- _cbOnExit = nullptr;
- _dataName = "";
- }
- QCoreSpine::~QCoreSpine()
- {
- }
- void QCoreSpine::onExit() {
- if (_cbOnExit != nullptr) {
- _cbOnExit(_dataName, this);
- }
- Node::onExit();
- }
- SkeletonData* QCoreSpine::getSkeletonData(){
-
- SkeletonData*skData =getSkeleton()->getData();
- return skData;
- }
- float QCoreSpine::getAnimTime(std::string name){
- float durTime = 0.0f;
- spine::Animation* tAnimation= findAnimation(name);
- if (tAnimation) {
- durTime = tAnimation->getDuration();
- }
- return durTime;
- }
- void QCoreSpine::playBackAnim(const char* name,const std::function<void()> &func, bool isDeleteSelf,bool isLoop){
- _mCallFunc = func;
- auto track = setAnimation(0, name, isLoop);
- if(track){
- setTrackCompleteListener(track, [=] (TrackEntry* entry) {
- if(_mCallFunc){
- this->_mCallFunc();
- }
- if(isDeleteSelf){
- this->runAction(RemoveSelf::create());
- }
- });
- float dur = getAnimTime(name);
- track->setTrackTime(dur);
- setTimeScale(-1);
- }
- }
- void QCoreSpine::playAnim(string name,const std::function<void()> &func, bool isDeleteSelf ,bool isLoop,float delay,bool delFunc){
- if(delay>0){
- auto node = Node::create();
- this->addChild(node);
- node->runAction(Sequence::create(DelayTime::create(delay),CallFunc::create([=](){
-
- resetVar();
- _mCallFunc = func;
- auto track = setAnimation(0, name, isLoop);
- this->setTrackCompleteListener(track, [=](TrackEntry* entry){
- if(_mCallFunc){
- this->_mCallFunc();
- if(delFunc){
- _mCallFunc = nullptr;
- }
- }
- if(isDeleteSelf){
- this->runAction(RemoveSelf::create());
- }
- });
- }),RemoveSelf::create(),NULL));
- }else{
- resetVar();
- _mCallFunc = func;
- auto track = setAnimation(0, name, isLoop);
- this->setTrackCompleteListener(track, [=](TrackEntry* entry){
- if(_mCallFunc){
- if(delFunc){
- this->_mCallFunc = nullptr;
- }
- func();//回调可能会把自己删掉的,所以最后调
-
- }
- if(isDeleteSelf){
- this->runAction(RemoveSelf::create());
- }
- });
- }
- }
- void QCoreSpine::playAnimN(string name,const std::function<void(Node*)> &funcN, bool isDeleteSelf ,bool isLoop ){
- resetVar();
- _mCallFuncN = funcN;
- auto track = setAnimation(0, name, isLoop);
- this->setTrackCompleteListener(track, [=](TrackEntry* entry){
- if(_mCallFuncN){
- this->_mCallFuncN(this);
- }
- if(isDeleteSelf){
- this->runAction(RemoveSelf::create());
- }
- });
- }
- void QCoreSpine::playAnimInRange(const char* name){
- resetVar();
- int count = getSkeleton()->getData()->getAnimations().size();
- spine::Vector<spine::Animation*> sparr = getSkeleton()->getData()->getAnimations();
- for(int i = 0;i<count;i++){
- spine::Animation* sp = sparr[i];
- int len = strlen(name);
- if(len<0)continue;
- int p = std::strncmp(sp->getName().buffer(),name,len);
- if(p == 0){
- _randomNames.push_back(sp->getName().buffer());
- }
- }
- playRandomAnim();
- }
- void QCoreSpine::playAnimInRangeWithArray(std::vector<std::string> randomNames ,std::vector<int> randomRates){
- resetVar();
- _randomNames = randomNames;
- _randomRates = randomRates;
- playRandomAnim();
- }
- void QCoreSpine::playRandomAnim(){
- bool v = false;
- if (_randomNames.size() > 0) {
- if (_randomRates.size() > 0) {
- CCASSERT(_randomNames.size() == _randomRates.size() , "有问题");
- string animName = randomObjByRatio(_randomNames,_randomRates);
- v = true;
- setAnimation(0, animName, false);
- }
- }
- if(v){
- _mComplete = [=](){
- playRandomAnim();
- };
- }
- }
- void QCoreSpine::setContent(){
- this->setEventListener([=](spine::TrackEntry* entry, spine::Event* event){
- EventData eData = event->getData();
- if (eData.getAudioPath().buffer()) {
- ///spine的声音事件,强制截取后缀改为redwise事件
- // if (RedWise::getInstance()->isSFXEnable()) {
- // const std::string& mp3FileName = eData.getName().buffer();
- // const std::string& eventName = mp3FileName.substr(0, mp3FileName.rfind("."));
- // RedWise::getInstance()->postEvent(eventName);
- // }
- } else {
- ///其他spine事件
- const char* evenName = eData.getName().buffer();
- if (_mCallEvent) {
- _mCallEvent(entry,evenName);
- }
- }
- });
- setCompleteListener([=] (TrackEntry* entry) {
- if(_mComplete){
- _mComplete();
- }
- });
- }
- void QCoreSpine::setEventCallBack(const std::function<void(TrackEntry*,const char*)> &func){
- _mCallEvent = func;
- }
- void QCoreSpine::reScaleSkeletonData(SkeletonData* skeletonData,float scale){
- return;
- int i;
- for (i = 0; i < skeletonData->getBones().size(); ++i) {
- BoneData* data = skeletonData->getBones()[i];
- data->setScaleX(data->getScaleX()* scale);// *= scale;
- data->setScaleY(data->getScaleY()* scale);
- data->setLength(data->getLength()* scale);
- }
- // for (i = 0; i < skeletonData->getTransformConstraints().size(); ++i) {
- // TransformConstraintData* data = skeletonData->getTransformConstraints()[i];
- // data->offsetX *= scale;
- // data->offsetY *= scale;
- // }
- for (i = 0; i < skeletonData->getPathConstraints().size(); ++i) {
- PathConstraintData* data = skeletonData->getPathConstraints()[i];
- if (data->getPositionMode() == PositionMode_Fixed) data->setPosition(data->getPosition()*scale);// *= scale;
- if (data->getSpacingMode() == SpacingMode_Length || data->getSpacingMode() == SpacingMode_Fixed) data->setSpacing(data->getSpacing() * scale);// *= scale;
- }
-
- }
- void QCoreSpine::changeToOtherParent(Node* newParent)
- {
- this->retain();
-
- std::function<void(const string&, QCoreSpine*)> cbBack = _cbOnExit;
- _cbOnExit = nullptr;
-
- this->removeFromParentAndCleanup(false);
-
- _cbOnExit = cbBack;
-
- newParent->addChild(this);
- this->release();
- }
- std::function<void(const string&, QCoreSpine*)> QCoreSpine::setCbOnExit(std::function<void(const string&, QCoreSpine*)> cb) {
- auto t = _cbOnExit;
- _cbOnExit = cb;
- return t;
- }
- void QCoreSpine::setDataName(const string& name) {
- int pos = name.find(".");
- if (pos != -1) {
- _dataName = name.substr(0, pos);
- } else {
- _dataName = name;
- }
- }
- void QCoreSpine::changeSkeleton(const std::string& skeletonJsonFile, const std::string& atlasFile, float scale)
- {
- 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);
- this->setDataName(skeletonJsonFile);
-
- }
- void QCoreSpine::resetVar(){
- clearTracks();
- _mCallFunc = nullptr;
- _mCallFuncN = nullptr;
- _mCallEvent = nullptr;
- _mComplete = nullptr;
- _randomNames.clear();
- _randomRates.clear();
- }
- string QCoreSpine::getRunningSequenceName(){
- if(_state){
- auto trackEntry = this->getCurrent();
- if(trackEntry){
- auto anim = trackEntry->getAnimation();
- if(anim){
- return string(anim->getName().buffer());
- }
- }
- }
- return "";
- }
- #define PROPERTY_SPINE_JSON_NAME "jsonName"
- #define PROPERTY_SPINE_ATLAS_NAME "atlasName"
- #define PROPERTY_SPINE_ANIM_NAME "curAnimName"
- #define PROPERTY_SPINE_SCALE "spineScale"
- #define PROPERTY_SPINE_LOOP "loop"
- void QCoreSpineLoader::onHandlePropTypeString(cocos2d::Node * pNode, cocos2d::Node * pParent, const char* pPropertyName, const char * pString, redream::REDReader * ccbReader)
- {
- if(strcmp(pPropertyName, PROPERTY_SPINE_JSON_NAME) == 0) {
- _skelName = pString;
- checkRefreshSpine(pNode);
- } else if(strcmp(pPropertyName, PROPERTY_SPINE_ATLAS_NAME) == 0) {
- _atlasName = pString;
- checkRefreshSpine(pNode);
- } else if(strcmp(pPropertyName, PROPERTY_SPINE_ANIM_NAME) == 0) {
- _curAnimName = pString;
- checkRefreshSpine(pNode);
- } else {
- QCoreSpineLoader::onHandlePropTypeString(pNode, pParent, pPropertyName, pString, ccbReader);
- }
- }
- void QCoreSpineLoader::onHandlePropTypeFloat(cocos2d::Node * pNode, cocos2d::Node * pParent, const char* pPropertyName, float pFloat, redream::REDReader * ccbReader)
- {
- if(strcmp(pPropertyName, PROPERTY_SPINE_SCALE) == 0) {
- _spineScale = pFloat;
- checkRefreshSpine(pNode);
- }else {
- QCoreSpineLoader::onHandlePropTypeFloatScale(pNode, pParent, pPropertyName, pFloat, ccbReader);
- }
- }
- void QCoreSpineLoader::onHandlePropTypeCheck(cocos2d::Node * pNode, cocos2d::Node * pParent, const char* pPropertyName, bool pCheck, redream::REDReader * ccbReader)
- {
- if(strcmp(pPropertyName, PROPERTY_SPINE_LOOP) == 0) {
- _loop = pCheck;
- checkRefreshSpine(pNode);
- }else {
- QCoreSpineLoader::onHandlePropTypeCheck(pNode, pParent, pPropertyName, pCheck, ccbReader);
- }
- }
- void QCoreSpineLoader::checkRefreshSpine(cocos2d::Node * pNode)
- {
- if (_skelName.length() > 0 && _atlasName.length() > 0 && _spineScale > 0.0f)
- {
- QCoreSpine* spine = (QCoreSpine*)pNode;
- if (spine)
- {
- spine->changeSkeleton(_skelName,_atlasName,_spineScale);
- if (_curAnimName.length() > 0)
- {
- spine->setAnimation(0, _curAnimName, _loop);
- }
- }
- }
- }
- float QCoreSpine::getAnimDuration(std::string name){
- float durTime = 0.0f;
- spine::Animation* tAnimation= findAnimation(name);
- if (tAnimation) {
- durTime = tAnimation->getDuration();
- }
- return durTime;
- }
- NS_RU_END
|