123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745 |
- //
- // RedBakeNode.cpp
- // cocos2d_libs
- //
- // Created by Liang zhong on 2022/11/11.
- //
- #include "RedBakeNode.h"
- #include "RedMixAnimationBakeModel.h"
- #include "CommandBuff.h"
- #include "RedSpineBakeManage.h"
- RedBakeNode *RedBakeNode::create(const std::string aFileName){
- RedBakeNode *rb = new RedBakeNode(aFileName);
- rb->autorelease();
- return rb;
- }
- RedBakeNode *RedBakeNode::create(){
- RedBakeNode *rb = new RedBakeNode();
- rb->autorelease();
- return rb;
- }
- RedBakeNode::RedBakeNode() {
- zeroPos = Vec2(0,0);
- _drawSelf = false;
- setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP, NULL));
- }
- RedBakeNode::RedBakeNode(const std::string aFileName){
- _fileName = aFileName;
- zeroPos = Vec2(0,0);
- setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP, NULL));
- _schUpdate = CC_SCHEDULE_SELECTOR(RedBakeNode::update);
- this->schedule(_schUpdate, 0);
- }
-
- RedBakeNode::~RedBakeNode(){
- CC_SAFE_RELEASE(_texture);
- this->unschedule(CC_SCHEDULE_SELECTOR(RedBakeNode::update));
- for (int i=0; i<_slotFrameArray.size(); i++) {
- delete[] _slotFrameArray[i].triangles.verts;
- }
- for (V3F_C4B_T2F *item : _vertArr){
- delete[] item;
- }
- _vertArr.clear(); // 清空容器
- }
- void RedBakeNode::setBakeDataFile(const std::string& aFileName) {
- _fileNameFull = aFileName;
-
- if (_fileNameFull.empty()) {
- _fileName = "";
- _stopSelfDraw();
- return;
- }
-
- std::string path = "";
- auto p = _fileNameFull.rfind("/");
- if (p != std::string::npos) {
- path = _fileNameFull.substr(0, p+1);
- _fileName = _fileNameFull.substr(p+1);
- } else {
- _fileName = _fileNameFull;
- }
- if (_fileName.find(".rb") != std::string::npos) {
- _fileName = _fileName.substr(0, _fileName.size()-3);
- }
- // FIXME:
- RedSpineBakeManage::getInstance()->loadAnimationFile(_fileName, path);
- }
- const std::string& RedBakeNode::getBakeDataFile() const {
- return _fileNameFull;
- }
- std::vector<std::string> RedBakeNode::getAnimations() {
- std::vector<std::string> anims;
- RedSpineBakeManage::getInstance()->fetchAnimations(_fileName, anims);
- return anims;
- }
- void RedBakeNode::setBakeFrame(RedBakeNodeFrame frame) {
- _curFrame = frame;
- if (_curFrame.animationName.size() == 0) {
- // 清空显示
- _stopSelfDraw();
- } else {
- if (switchAnimation(_curFrame.animationName, _curFrame.loop)) {
- stopAutoDraw();
- _startSelfDraw();
- updateSelfFunc(_curFrame.elapsedTime, true);
- _firstDraw = false;
- }
- }
- }
- RedBakeNodeFrame RedBakeNode::getBakeFrame() {
- return _curFrame;
- }
- float RedBakeNode::getAnimDuration(const std::string& tl) {
- auto anim = RedSpineBakeManage::getInstance()->getAnimateByName(_fileName, tl);
- if (anim) {
- return (float)anim->getTotalBakeFrame() / (float)anim->getCurrentFrameRate();
- }
- return .0;
- }
- void RedBakeNode::drawBake (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags){
- cocos2d::Texture2D* texture = _texture;
- if (_isFlipX) {
- newTransform = transform;
- newTransform.m[0] *= -1; // 将X轴缩放值取反
- }
-
- //如果当前节点没有现实,每次都判断是否在屏幕内,如果已经显示每五帧判断一次
- if (isInScreen==true) {
- if (_currentBakeFrame%5==0) {
- animationIsInscreen();
- }
- }else{
- animationIsInscreen();
- }
- if (isInScreen) {
- Point offsetPos = {0,0};
- if (_fatherNode!=nullptr) {
- if (_fatherNodePosIndex==-1) {
- _fatherNodePosIndex = _fatherNode->getFatherBoneOffsetIndex(_fatherNodeBoneName);
- }
- Point posInt;
- if (_fatherNodePosIndex==-1) {
- posInt = _fatherNode->getFatherBoneOffset(_fatherNodeBoneName);
- }else{
- posInt = _fatherNode->getFatherBoneOffsetByIndex(_fatherNodePosIndex);
- }
- offsetPos.x = (float)posInt.x + _disPos.x;
- offsetPos.y = (float)posInt.y + _disPos.y;
- }
-
-
-
- for (int i = 0; i<_currentBakeAnimation->getSlotCount(); i++) {
- RedSlotBakeModel *slotBake = _currentBakeAnimation->getSlotByDrawOrder(i, _currentBakeFrame,_currentDrawOrderIndex);
- const std::string& slotName = slotBake->getSlotName();
- BKAE_FRAME_PLAY &bfp = *_slotFrameArrayVect[slotBake->getSlotIndex()];//这行性能远快于下面的map,作用一样
- if(_attachNodeMapSize>0){
- if(bfp.hasAttachNode){
- if (_singleAttachNode==nullptr) {
- _attachNodeMap[slotName]->drawSelfFunc(renderer, transform, transformFlags);
- }else{
- _singleAttachNode->drawSelfFunc(renderer, transform, transformFlags);
- }
- }
- }
- if(slotBake->slotShoudBeDrawSlot()){
- //判断当前slot在当前帧是否需要跳过渲染,判断是否在屏幕内
- if(slotBake->getFrameSkip(_currentBakeFrame)){
- slotBake->setFrameSkip(_currentBakeFrame, bfp);
- }else{
- if (texture==nullptr) {
- texture = slotBake->getTexture(_currentBakeFrame);
- }
- BlendFunc &blendFuc = slotBake->getBlendFunc(_currentBakeFrame);
- V3F_C4B_T2F *beginVert = nullptr;
- bool shouldMerge = false;
- if (_currentBakeFrame>1&&_currentBakeFrame<=_totalBakeFrame) {
- shouldMerge = true;
- }
- beginVert = _vertArr[bfp.vertMapIndex];
- slotBake->getTriangles(_currentBakeFrame,bfp, offsetPos, _currentFrameFracpart, beginVert,shouldMerge);
- cocos2d::TrianglesCommand::Triangles triangles = bfp.triangles;
- triangles.verts = beginVert;
-
- if(slotName == "slot_duihua"){
- _speechPos = Vec2(offsetPos.x,offsetPos.y);
- // CCLOG("[sc bake : speechPos %f, %f", _speechPos.x, _speechPos.y);
- }
- #if COCOS2D_VERSION < 0x00040000
- if(_isFlipX){
- CommandBuff::getInstance()->addCommand(renderer, _globalZOrder, texture, _glProgramState, blendFuc, triangles, newTransform, transformFlags);
- }else{
- CommandBuff::getInstance()->addCommand(renderer, _globalZOrder, texture, _glProgramState, blendFuc, triangles, transform, transformFlags);
- }
- #else
- if(_isFlipX){
- CommandBuff::getInstance()->addCommand(renderer, _globalZOrder, texture, blendFuc, triangles, newTransform, transformFlags);
- }else{
- CommandBuff::getInstance()->addCommand(renderer, _globalZOrder, texture, blendFuc, triangles, transform, transformFlags);
- }
- #endif
- }
- }
- }
- }
- }
- void RedBakeNode::drawMixBake (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags){
- RedMixAnimationBakeModel *mixAni = (RedMixAnimationBakeModel *)_currentBakeAnimation;
- if (isInScreen==true) {
- if (_currentBakeFrame%5==0) {
- animationIsInscreen();
- }
- }else{
- animationIsInscreen();
- }
- if (isInScreen) {
- Point offsetPos = {0,0};
- if (_fatherNode!=nullptr) {
- Point posInt = _fatherNode->getFatherBoneOffset(_fatherNodeBoneName);
- offsetPos.x = (float)posInt.x + _disPos.x;
- offsetPos.y = (float)posInt.y + _disPos.y;
- // CCLOG("%d/%d---%f,%f",_currentBakeFrame,_totalBakeFrame,offsetPos.x,offsetPos.y);
- }
- std::vector<int> keys = mixAni->getMixBakeFrameArrAllKey();
- for (int i = 0; i<keys.size(); i++) {
- int zOrderIndex = keys[i];
- cocos2d::Texture2D* texture = mixAni->getTexture(zOrderIndex);
- BlendFunc blendFuc = mixAni->getBlendFunc(zOrderIndex);
- cocos2d::TrianglesCommand::Triangles triangles = mixAni->getTriangles(zOrderIndex,_realCurrentBakeFrame);
- for (int j=0; j<triangles.vertCount; j++) {
- triangles.verts[j].vertices.x += offsetPos.x;
- triangles.verts[j].vertices.y += offsetPos.y;
- }
- #if COCOS2D_VERSION < 0x00040000
- CommandBuff::getInstance()->addCommand(renderer, _globalZOrder, texture, _glProgramState, blendFuc, triangles, transform, transformFlags);
- #else
- CommandBuff::getInstance()->addCommand(renderer, _globalZOrder, texture, blendFuc, triangles, transform, transformFlags);
- #endif
- }
- }
- }
- void RedBakeNode::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags) {
- if (_drawSelf) {
- drawSelfFunc(renderer, transform, transformFlags);
- }
- }
- void RedBakeNode::update (float deltaTime){
- if (_drawSelf==false) {
- return;
- }
- updateSelfFunc(deltaTime);
- // CCLOG("%d",_currentBakeFrame);
- }
- void RedBakeNode::updateSelfFunc(float deltaTime, bool bInFrameMode){
- if (_currentBakeAnimation==nullptr) {
- return ;
- }
-
- if (_attachNodeMapSize>0) {
- if (_singleAttachNode) {
- _singleAttachNode->updateSelfFunc(deltaTime, bInFrameMode);
- if (_attachNodeMapHasChanged == true) {
- _attachNodeMapHasChanged = false;
- }
- }else{
- for (auto it = _attachNodeMap.begin(); it != _attachNodeMap.end(); ++it) {
- RedBakeNode* value = it->second;
- value->updateSelfFunc(deltaTime, bInFrameMode);
- if (_attachNodeMapHasChanged == true) {
- _attachNodeMapHasChanged = false;
- break;
- }
- }
- }
- }
-
- if (_currentAnimationIsFinished==false) {
- //如果动画还没播放完毕
- if (_currentAnimationIsPaused==false) {
- float delta = deltaTime*(float)_currentBakeAnimation->getCurrentFrameRate();
- _realCurrentBakeFrame += delta;
- // CCLOG("%f",_realCurrentBakeFrame);
- float intpart;
- _currentFrameFracpart = modf(_realCurrentBakeFrame, &intpart);
- // _currentBakeFrame = intpart+1;
- _currentBakeFrame = MIN(intpart+1, _totalBakeFrame);
- // CCLOG("sc : 帧数 %d", _currentBakeFrame);
- // CCLOG("%d",_currentBakeFrame);
- // _currentBakeFrame++;//如果没有暂停且时间够一帧就播放一个动画
- }
- //因为最后一帧的时长不一定是一整帧,我们是按15帧烘培的,spine是按30帧K的,所以可能存在最后一帧误差,烘培的时候算上了这个
- if (_realCurrentBakeFrame>=(_totalBakeFrame-1.0+_currentBakeAnimation->getLastDrawOverTime())) {
- if (_currentBakeAnimation->isMixAnimation()) {
- //如果是动画混合播完,就接下一个动画
- RedMixAnimationBakeModel *mixAni = (RedMixAnimationBakeModel *)_currentBakeAnimation;
- if (_listener) {
- _listener(_currentBakeAnimation->getAimationName(),RBN_STATE::MixPreAniEnd);
- }
- _currentBakeAnimation = mixAni->getNextAnimation();
- delete mixAni;
- resetPlayInfo();
- _currentAnimationIsFinished = false;
- _currentAnimationIsPaused = false;
-
- }else{
- if(_isLoop==true){
- // 单帧模式下不能每次都设置到第一、二帧
- if (bInFrameMode) {
- _currentBakeFrame = (int(_realCurrentBakeFrame) % _totalBakeFrame) + 1;
- } else {
- // float tmp_realCurrentBakeFrame =_realCurrentBakeFrame-_totalBakeFrame;
- // resetPlayInfo();//如果循环就重制
- _realCurrentBakeFrame = 1+_currentFrameFracpart;//把刚刚上次循环多余的时间也加上
- float intpart;
- _currentFrameFracpart = modf(_realCurrentBakeFrame, &intpart);
- _currentBakeFrame = MIN(intpart+1, _totalBakeFrame);
- }
- } else {
- //如果不循环就停滞,同时通知
- _currentBakeFrame = _totalBakeFrame;
- _currentAnimationIsFinished = true;
- if (_listener) {
- _listener(_currentBakeAnimation->getAimationName(),RBN_STATE::Complete);
- }
- }
- }
- }
- }
- }
- bool RedBakeNode::switchAnimation(const std::string& animationName, bool loop){
- if (_currentAnimationIsFinished==false) {
- stopCurrentAnimation();//如果有正在播放的,就先停下来
- }
-
- _currentBakeAnimation = RedSpineBakeManage::getInstance()->getAnimateByName(_fileName, animationName);
- if (_currentBakeAnimation==nullptr) {
- CCASSERT(0, ("动画没有找到" + animationName).c_str());
- return false;
- }
- _isFirstReset = true;
- resetPlayInfo();
- _isLoop = loop;
- _currentAnimationIsFinished = false;
- _currentAnimationIsPaused = false;
- _reloadVertMap();
-
- return true;
- }
- bool RedBakeNode::playAnimation (const std::string& animationName, bool loop, float spdRate) {
- if (_fileName.empty()) {
- _stopSelfDraw();
- return false;
- }
-
- if (switchAnimation(animationName, loop)) {
- startAutoDraw();
- }
- float frameRate = 15;
- frameRate*=spdRate;
-
- if(_currentBakeAnimation){
- _currentBakeAnimation->setCurrentFrameRate(frameRate);
- handleEvent(_eventCallBack);
- }
-
- return true;
- }
- bool RedBakeNode::stopCurrentAnimation(){
- if (_currentAnimationIsFinished) {
- return false;
- }
- _currentAnimationIsFinished = true;
- _currentAnimationIsPaused = false;
- if (_listener) {
- _listener(_currentBakeAnimation->getAimationName(),RBN_STATE::Break);
- }
-
- return true;
- }
- bool RedBakeNode::IscurrentAnimationFinished(){
- return _currentAnimationIsFinished;
- }
- bool RedBakeNode::pauseCurrentAnimation(){
- if (_currentAnimationIsFinished) {
- return false;
- }
- _currentAnimationIsPaused = true;
- if (_listener) {
- _listener(_currentBakeAnimation->getAimationName(),RBN_STATE::Pause);
- }
- return true;
- }
- bool RedBakeNode::resumeCurrentAnimation(){
- if (_currentAnimationIsFinished) {
- return false;
- }
- _currentAnimationIsPaused = false;
- if (_listener) {
- _listener(_currentBakeAnimation->getAimationName(),RBN_STATE::Resume);
- }
- return true;
- }
- bool RedBakeNode::currentAnimationIsPaused(){
- return _currentAnimationIsPaused;
- }
- bool RedBakeNode::playMixAnimation(const std::string& animationName, bool loop,float aMixTime){
- Point pos;
- pos.x = 0;
- pos.y = 0;
- return playMixAnimation(animationName, loop, aMixTime, pos);
- }
- bool RedBakeNode::playMixAnimation(const std::string& animationName, bool loop,float aMixTime,Point aDis){
- if (_currentAnimationIsFinished==false) {
- //如果当前动画没有结束
- if(_currentBakeAnimation->isMixAnimation()){
- return false;
- }
- }
-
- RedMixAnimationBakeModel *mixAnimation = new RedMixAnimationBakeModel();
- const std::map<int,BKAE_FRAME_PLAY> aPreAniBakeFrame = _slotFrameArray;
- bool success = mixAnimation->setMixInfo(_currentBakeFrame, aMixTime, aPreAniBakeFrame, animationName,_currentBakeAnimation->getAimationName(), _fileName,aDis);
- if (success) {
- _currentBakeAnimation = mixAnimation;
- _currentBakeFrame = 0;
- _isLoop = loop;
- _totalBakeFrame = _currentBakeAnimation->getTotalBakeFrame();
- _currentAnimationIsFinished = false;
- }else{
- delete mixAnimation;
- playAnimation(animationName, loop);
- }
- return true;
- }
- void RedBakeNode::updateLoop(bool loop){
- _isLoop = loop;
- }
- //当前动画是否X翻转
- void RedBakeNode::setFlipX(bool aFlipX){
- _isFlipX = aFlipX;
- }
- //当前动画是否翻转
- bool RedBakeNode::isFlipX(){
- return _isFlipX;
- }
- void RedBakeNode::setBakeSpineID(std::string aId){
- _bakeSpineID = aId;
- }
- void RedBakeNode::resetPlayInfo(){
- _firstDraw = true;
- _currentBakeFrame = 1;
- _realCurrentBakeFrame = 1.0;
- _currentFrameFracpart = 0;
- _currentDrawOrderIndex = 0;
- _totalBakeFrame = _currentBakeAnimation->getTotalBakeFrame();
- if (_slotFrameArray.size()==0||_isFirstReset==true) {
- int maxIndex = 1;
- for (int i = 0; i<_currentBakeAnimation->getSlotCount(); i++) {
- int key = _currentBakeAnimation->getAllSlotKey()[i];
- RedSlotBakeModel* slot = _currentBakeAnimation->getSlotFromKey(key);
- _slotFrameArray.insert(std::pair<int,BKAE_FRAME_PLAY>(slot->getSlotIndex(), BKAE_FRAME_PLAY()));
- if (slot->getSlotIndex()>maxIndex) {
- maxIndex = slot->getSlotIndex();
- }
- }
- _slotFrameArrayVect.clear();
- _slotFrameArrayVect.resize(maxIndex+1);
- for (auto it = _slotFrameArray.begin(); it != _slotFrameArray.end(); ++it){
- int key = it->first;
- BKAE_FRAME_PLAY &value = it->second;
- _slotFrameArrayVect[key] = &value;
- }
- }
- for (int i = 0; i<_currentBakeAnimation->getSlotCount(); i++) {
- int key = _currentBakeAnimation->getAllSlotKey()[i];
- _currentBakeAnimation->getSlotFromKey(key)->initBKAE_FRAME_PLAY(_slotFrameArray.at(key));
- }
- _isFirstReset = false;
- }
- void RedBakeNode::setRBNListener(RBNListener& aListener){
- _listener = aListener;
- }
- //判断某个Slot是否在屏幕内
- bool RedBakeNode::animationIsInscreen(){
- if(_currentBakeAnimation==nullptr){
- isInScreen = false;
- return isInScreen;
- }
- int bigMore = 100;
- Vec2 leftBottom = _currentBakeAnimation->getLeftBottomSubSizePos();
- Vec2 rightTop = _currentBakeAnimation->getRightTopSubSizePos();
- Vec2 globalPos = convertToWorldSpace(zeroPos);
- Vec2 leftBottomWorld = leftBottom+globalPos;
- Vec2 rightTopWorld = rightTop+globalPos;
-
- auto winSize = Director::getInstance()->getWinSize();
- if (leftBottomWorld.x<(0-bigMore)||leftBottomWorld.y<(0-bigMore)||rightTopWorld.x>(winSize.width+bigMore)||rightTopWorld.y>(winSize.height+bigMore)) {
- // CCLOG("跑出去了------------%s",_currentBakeAnimation->getAimationName().c_str());
- isInScreen = false;
- return isInScreen;
- }
- isInScreen = true;
- return isInScreen;
- }
- void RedBakeNode::mergeTwoVert(V3F_C4B_T2F *beginVert,V3F_C4B_T2F *endVert,int aCount,Point offsetPos){
- if (aCount==0) {
- return;
- }
- float dis = _currentFrameFracpart;
-
- if (beginVert[0].colors!=endVert[0].colors) {
- for (int i=0; i<aCount; i++) {
- beginVert[i].vertices.x = beginVert[i].vertices.x + dis*(endVert[i].vertices.x - beginVert[i].vertices.x)+offsetPos.x;
- beginVert[i].vertices.y = beginVert[i].vertices.y + dis*(endVert[i].vertices.y - beginVert[i].vertices.y)+offsetPos.y;
- // beginVert[i].vertices.z = beginVert[i].vertices.z + dis*(endVert[i].vertices.z - beginVert[i].vertices.z);
- beginVert[i].colors.r = beginVert[i].colors.r + dis*(endVert[i].colors.r - beginVert[i].colors.r);
- beginVert[i].colors.g = beginVert[i].colors.g + dis*(endVert[i].colors.g - beginVert[i].colors.g);
- beginVert[i].colors.b = beginVert[i].colors.b + dis*(endVert[i].colors.b - beginVert[i].colors.b);
- beginVert[i].colors.a = beginVert[i].colors.a + dis*(endVert[i].colors.a - beginVert[i].colors.a);
- // endVert[i].texCoords.u = beginVert[i].texCoords.u + dis*(endVert[i].texCoords.u - beginVert[i].texCoords.u);
- // endVert[i].texCoords.v = beginVert[i].texCoords.v + dis*(endVert[i].texCoords.v - beginVert[i].texCoords.v);
- }
- }else{
- for (int i=0; i<aCount; i++) {
- beginVert[i].vertices.x = beginVert[i].vertices.x + dis*(endVert[i].vertices.x - beginVert[i].vertices.x)+offsetPos.x;
- beginVert[i].vertices.y = beginVert[i].vertices.y + dis*(endVert[i].vertices.y - beginVert[i].vertices.y)+offsetPos.y;
- }
- }
-
- }
- //当Attach修改的时候,需要更新下singleattch和attchsize
- void RedBakeNode::attachNodeBeUpdated(){
- if(_attachNodeMap.size()==1){
- _singleAttachNode = _attachNodeMap.at(_attachNodeMap.begin()->first);
- }else{
- _singleAttachNode = nullptr;
- }
- _attachNodeMapSize = (int)_attachNodeMap.size();
- }
- void RedBakeNode::addAttachNodeBeforeSlot(std::string aSlotName,RedBakeNode * aBakeNode){
- aBakeNode->_stopSelfDraw();
- _attachNodeMap.insert(std::pair<std::string, RedBakeNode *>(aSlotName,aBakeNode));
- _attachNodeMapHasChanged = true;
- attachNodeBeUpdated();
- }
- void RedBakeNode::removeAttachNode(std::string aSlotName){
- auto iter = _attachNodeMap.find(aSlotName);
- if (iter != _attachNodeMap.end()) {
- RedBakeNode * aBakeNode = iter->second;
- aBakeNode->_startSelfDraw();
- _attachNodeMap.erase(iter);
- _attachNodeMapHasChanged = true;
- }
- attachNodeBeUpdated();
- }
- //删除全部绘制附着slot
- void RedBakeNode::removeAllAttachNode(){
- for (auto it = _attachNodeMap.begin(); it != _attachNodeMap.end(); ++it) {
- RedBakeNode* value = it->second;
- value->_startSelfDraw();
- }
- _attachNodeMap.clear();
- _attachNodeMapHasChanged = true;
- attachNodeBeUpdated();
- }
- void RedBakeNode::startAutoDraw() {
- _startSelfDraw();
- if (_schUpdate == nullptr) {
- _schUpdate = CC_SCHEDULE_SELECTOR(RedBakeNode::update);
- this->schedule(_schUpdate, 0);
- }
- }
- void RedBakeNode::stopAutoDraw() {
- if (_schUpdate) {
- this->unschedule(_schUpdate);
- _schUpdate = nullptr;
- }
- }
- //关闭自我绘制功能,由其他RedBakeNode来绘制
- void RedBakeNode::_stopSelfDraw(){
- _drawSelf = false;
- }
- //开启自我绘制功能
- void RedBakeNode::_startSelfDraw(){
- _drawSelf = true;
- }
- void RedBakeNode::drawSelfFunc(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t transformFlags){
- if (_currentBakeAnimation==nullptr) {
- return ;
- }
- if (_firstDraw) {
- _firstDraw = false;
- updateSelfFunc(0);
- }
- if(_currentBakeAnimation!=nullptr){
- if (_totalBakeFrame<1) {
- _totalBakeFrame = _currentBakeAnimation->getTotalBakeFrame();
- resetPlayInfo();
- }
- if(_currentBakeAnimation->isMixAnimation()){
- drawMixBake(renderer, transform, transformFlags);
- }else{
- drawBake(renderer, transform, transformFlags);
- }
- }
- }
- void RedBakeNode::handleEvent(std::function<void(std::string)> cb){
- _currentBakeAnimation->handleEventByFrame(this, cb);
- }
- //添加父Bakenode,确保自己和父node一起运动,aBoneName是父node关于自己的连接点
- void RedBakeNode::addFatherNodeBindMove(std::string aBoneName,RedBakeNode * aBakeNode){
- if(aBoneName.length()>0&&aBakeNode){
- _fatherNode = aBakeNode;
- _fatherNodeBoneName = aBoneName;
- _fatherNodePosIndex = -1;
- }
- }
- //添加父Bakenode,确保自己和父node一起运动,aBoneName是父node关于自己的连接点
- void RedBakeNode::removeFatherNode(){
- _fatherNode = nullptr;
- _fatherNodeBoneName = "";
- }
- //获取父节点对应bone的偏移量
- const Point RedBakeNode::getFatherBoneOffset(std::string aBoneName){
- // if(_currentBakeAnimation==nullptr){
- // return Point(0,0);
- // }
- if (_currentBakeFrame<=1) {//_currentBakeFrame是从1开始的,getABakeModePoint是从0
- return _currentBakeAnimation->getABakeModePoint(aBoneName, 0);
- }
- const Point &begin = _currentBakeAnimation->getABakeModePoint(aBoneName, _currentBakeFrame-2);
- const Point &end = _currentBakeAnimation->getABakeModePoint(aBoneName, _currentBakeFrame-1);
- Point res;
- res.x = begin.x + _currentFrameFracpart*(end.x - begin.x);
- res.y = begin.y + _currentFrameFracpart*(end.y - begin.y);
- return res;
- }
- //获取父节点对应bone的偏移量
- const Point RedBakeNode::getFatherBoneOffsetByIndex(int aIndex){
- if (_currentBakeFrame<=1) {//_currentBakeFrame是从1开始的,getABakeModePoint是从0
- return _currentBakeAnimation->getABakeModePoint(aIndex, 0);
- }
- const Point &begin = _currentBakeAnimation->getABakeModePoint(aIndex, _currentBakeFrame-2);
- const Point &end = _currentBakeAnimation->getABakeModePoint(aIndex, _currentBakeFrame-1);
- Point res;
- res.x = begin.x + _currentFrameFracpart*(end.x - begin.x);
- res.y = begin.y + _currentFrameFracpart*(end.y - begin.y);
- return res;
- }
- //获取父节点对应bone的偏移量对应的数组索引,用来加速性能
- int RedBakeNode::getFatherBoneOffsetIndex(std::string aBoneName){
- return _currentBakeAnimation->getBoneAttachsSearchIndex(aBoneName);
- }
- void RedBakeNode::_reloadVertMap(){
- for (V3F_C4B_T2F *item : _vertArr){
- delete[] item;
- }
- _vertArr.clear(); // 清空容器
- for (int i = 0; i<_currentBakeAnimation->getSlotCount(); i++) {
- int key = _currentBakeAnimation->getAllSlotKey()[i];
- RedSlotBakeModel *slotBake = _currentBakeAnimation->getSlotFromKey(key);
-
- int vertCount = slotBake->getVertCount();
- _vertArr.push_back(new V3F_C4B_T2F[vertCount]);
- BKAE_FRAME_PLAY &bfp = _slotFrameArray.at(slotBake->getSlotIndex());
- if (_attachNodeMap.count(slotBake->getSlotName()) > 0) {
- bfp.hasAttachNode = true;
- }
- bfp.vertMapIndex =(int)_vertArr.size()-1;
- }
- }
- //用来记录多个spine合并播放时,骨骼连接点初始的位置差
- void RedBakeNode::setDisPos(Point aPos){
- _disPos.x = aPos.x;
- _disPos.y = aPos.y;
- }
- //用来指定动画起始位子,这样上下半身走路可以同步,不会同手同脚
- void RedBakeNode::updateRealCurrentBakeFrame(float aReal){
- _realCurrentBakeFrame = aReal;
- float intpart;
- _currentFrameFracpart = modf(_realCurrentBakeFrame, &intpart);
- _currentBakeFrame = MIN(intpart+1, _totalBakeFrame);
- }
- //获取当前播放的位置
- float RedBakeNode::getRealCurrentBakeFrame(){
- return _realCurrentBakeFrame;
- }
- void RedBakeNode::setTexture(Texture2D * texture) {
- CC_SAFE_RETAIN(texture);
- CC_SAFE_RELEASE(_texture);
- _texture = texture;
- }
- void RedBakeNode::setEventCallBack(std::function<void(std::string)> cb){
- _eventCallBack = cb;
- }
- Vec2 RedBakeNode::getSpeechPos(){
- Vec2 pos = _speechPos;
- return pos;
- }
|