// // RedSpineBakeModel.cpp // empty2dx-desktop // // Created by Liang zhong on 2022/11/5. // #include "RedAnimationBakeModel.h" #include "RedSpineBakeManage.h" RedAnimationBakeModel::RedAnimationBakeModel(){ } RedAnimationBakeModel::~RedAnimationBakeModel(){ } RedAnimationBakeModel::RedAnimationBakeModel(const std::string aFileName,const std::string& aAnimateName){ fileName = aFileName; animateName = aAnimateName; } RedSlotBakeModel* RedAnimationBakeModel::getSlotFromKey(int akey){ return slotArr[akey]; } RedSlotBakeModel* RedAnimationBakeModel::findSlotFromKey(int akey){ if (slotArr.find(akey) == slotArr.end()){ return nullptr; } return slotArr[akey]; } RedSlotBakeModel* RedAnimationBakeModel::getSlotByDrawOrder(int aIndex,int aFrameNum,int &aCurrentDrawOrderIndex){ if (aCurrentDrawOrderIndex<(drawOrderArrIndexSize-1)) { const DrawOrderMD &dmd = drawOrderArrIndex[aCurrentDrawOrderIndex+1]; if (dmd.frame &dmdArr = drawOrderArr[dmd.arrIndex]; aCurrentDrawOrderIndex = aCurrentDrawOrderIndex+1; return slotArrVector[dmdArr[aIndex]]; }else{ const DrawOrderMD &dmd2 = drawOrderArrIndex[aCurrentDrawOrderIndex]; const int resIndex = drawOrderArr[dmd2.arrIndex][aIndex]; return slotArrVector[resIndex]; } }else{ aCurrentDrawOrderIndex = (int)drawOrderArrIndex.size()-1; DrawOrderMD dmd = drawOrderArrIndex[aCurrentDrawOrderIndex]; std::vector &dmdArr = drawOrderArr[dmd.arrIndex]; return slotArrVector[dmdArr[aIndex]]; } return nullptr; } void RedAnimationBakeModel::handleEventByFrame(Node* target, std::function cb){ for(int i = 0; i < eventArr.size(); i++){ EventMD emd = eventArr.at(i); float time = emd.frame * 1.f / currentFrameRate; target->scheduleOnce([=](float dt){ for(int j = 0; j < emd.eventNames.size(); j++){ std::string eventName = emd.eventNames.at(j); CCLOG("[sc : 事件回调 %s]", eventName.c_str()); if(cb){ cb(eventName); } } }, time, StringUtils::format("spine-wwise:%d",emd.frame)); } } //绘制专用 void RedAnimationBakeModel::addSlotByName(RedSlotBakeModel *aSlot){ slotArr.insert(std::pair(aSlot->getSlotIndex(), aSlot)); } void RedAnimationBakeModel::setBeginLastDraw(){ beginLastDraw = true; } bool RedAnimationBakeModel::isBeginLastDraw(){ return beginLastDraw; } void RedAnimationBakeModel::setBakeFinish(float alastDrawOverTime){ isSpineBakeFinish = true; lastDrawOverTime = alastDrawOverTime; std::vector unuseSlotIndexArr; //删除slotArr中无用的slot for (auto it=slotArr.begin();it!=slotArr.end();) { RedSlotBakeModel *slot = it->second; slot->finishBake(); if (slot->slotShoudBeDrawSlot()==false) { unuseSlotIndexArr.push_back(slot->getSlotIndex()); it = slotArr.erase(it); }else{ maxXPos = MAX(maxXPos,slot->getMaxXPos()); maxYPos = MAX(maxYPos,slot->getMaxYPos()); minXPos = MIN(minXPos,slot->getMinXPos()); minYPos = MIN(minYPos,slot->getMinYPos()); it++; } } //移除drawOrderArr中无用的SlotIndex for (auto iter = drawOrderArr.begin(); iter != drawOrderArr.end(); iter++) { for (auto inner_iter = iter->begin(); inner_iter != iter->end(); ) { // 判断当前元素是否需要删除 auto findIter = std::find(unuseSlotIndexArr.begin(), unuseSlotIndexArr.end(), *inner_iter); if (findIter != unuseSlotIndexArr.end()) { inner_iter = iter->erase(inner_iter);// 如果找到了元素 }else{ inner_iter++;// 指向下一个元素 } } } leftBottom = Vec2(minXPos,minYPos);//计算leftTopPos的中心点的位置,用于计算slot是否在屏幕内 rightTopPos = Vec2(maxXPos,maxYPos);//计算rightBottomPos的size,用于计算Slot是否在屏幕内 leftBottomSubSizePos = Vec2(minXPos + (maxXPos - minXPos),minYPos + (maxYPos- minYPos));//方便出屏幕判断,预先将leftBottom里面去加上Size,因为leftBottom出界需要判断自己右上角,减少之后的计算 rightTopSubSizePos = Vec2(maxXPos - (maxXPos - minXPos),maxYPos - (maxYPos- minYPos));//方便出屏幕判断,预先将Rightop里面去减去Size,因为Righttop出界需要判断自己左下角,减少之后的计算 if (RedSpineBakeManage::getInstance()->getAnimateByName(fileName,animateName)==nullptr) { RedSpineBakeManage::getInstance()->setCurrentAnimationBakeModel(animateName,this); } } bool RedAnimationBakeModel::isBakeFinish(){ return isSpineBakeFinish; } int RedAnimationBakeModel::getSlotCount(){ return slotArrSize; } const std::vector& RedAnimationBakeModel::getAllSlotKey(){ return drawOrderArr[0]; } void RedAnimationBakeModel::setFileName(const std::string& aFileName){ fileName = aFileName; } const std::string& RedAnimationBakeModel::getFileName(){ return fileName; } void RedAnimationBakeModel::drawOneFrame(){ totalBakeFrame += 1; for (int i=0; istartBakeOneFrame(); } } void RedAnimationBakeModel::updateDrawOrder(spine::Vector &aDrawList){ // CCLOG("totalBakeFrame:%d ------------------------------------------------------",totalBakeFrame); std::vector tmpDrawOrder; for (int i = 0, n = (int)aDrawList.size(); i < n; ++i) { spine::Slot* slot = aDrawList[i]; tmpDrawOrder.push_back(slot->getData().getIndex()); } if(drawOrderArr.size()==0){ drawOrderArr.push_back(tmpDrawOrder); DrawOrderMD dmd = {totalBakeFrame, 0}; drawOrderArrIndex.push_back(dmd);//记录每帧对应用哪个DrawOrder // CCLOG("Add 0"); }else{ std::vector currentDrawOrder = drawOrderArr.back(); bool is_equal = (tmpDrawOrder.size() == currentDrawOrder.size()) && std::equal(tmpDrawOrder.begin(), tmpDrawOrder.end(), currentDrawOrder.begin()); if(is_equal==false){ int findIndex = -1; //先找找drawOrderArr里面有没有相等的 for (int i=0; i eventNames; eventNames.push_back(eventName); EventMD emd = {totalBakeFrame, eventNames}; eventArr.push_back(emd); CCLOG("[sc bake : %s-%s 没找到事件,新建一个 frame: %d event: %s ]", fileName.c_str(), animateName.c_str(), totalBakeFrame, eventName.c_str()); } else{ CCLOG("[sc bake : %s-%s 找到事件,添加一个 frame: %d event: %s ]", fileName.c_str(), animateName.c_str(), totalBakeFrame, eventName.c_str()); } } //增加一个需要被记录的外接bone的名字 void RedAnimationBakeModel::addboneAttachNames(std::string aName){ boneAttachNames.push_back(aName); std::vector posArr; boneAttachs.insert(std::pair>(aName,posArr)); boneAttachsVector.clear(); for (auto& boneAttach : boneAttachs) { std::vector& attachPoints = boneAttach.second; // 获取挂点坐标数组 boneAttachsVector.push_back(attachPoints); } } const std::vector& RedAnimationBakeModel::getAllboneAttachNames(){ return boneAttachNames; } void RedAnimationBakeModel::bakeAModePointBeginPos(std::string aName,Point aPoint){ boneAttachsBeginPos[aName] = aPoint; } void RedAnimationBakeModel::bakeAModePoint(std::string aName,Point aPoint){ aPoint = aPoint-boneAttachsBeginPos[aName]; boneAttachs[aName].push_back(aPoint); } const Point& RedAnimationBakeModel::getABakeModePoint(std::string aName,int aFrame){ return boneAttachs[aName][aFrame]; } const Point& RedAnimationBakeModel::getABakeModePoint(int aIndex,int aFrame){ return boneAttachsVector[aIndex][aFrame]; } int RedAnimationBakeModel::getTotalBakeFrame(){ return totalBakeFrame; } void RedAnimationBakeModel::setTotalBakeFrame(int atotalBakeFrame){ totalBakeFrame = atotalBakeFrame; } void RedAnimationBakeModel::setCurrentFrameRate(int aRate){ currentFrameRate = aRate; } int RedAnimationBakeModel::getCurrentFrameRate(){ return currentFrameRate; } void RedAnimationBakeModel::setLastDrawOverTime(float aLastDrawOverTime){ lastDrawOverTime = aLastDrawOverTime; } float RedAnimationBakeModel::getLastDrawOverTime(){ return lastDrawOverTime; } void RedAnimationBakeModel::setAimationName(const std::string& animName){ animateName = animName; } const std::string& RedAnimationBakeModel::getAimationName(){ return animateName; } bool RedAnimationBakeModel::isMixAnimation(){ return false; } void RedAnimationBakeModel::setMaxXPos(int aMaxXPos){ maxXPos = aMaxXPos; } int RedAnimationBakeModel::getMaxXPos(){ return maxXPos; } void RedAnimationBakeModel::setMaxYPos(int aMaxYPos){ maxYPos = aMaxYPos; } int RedAnimationBakeModel::getMaxYPos(){ return maxYPos; } void RedAnimationBakeModel::setMinXPos(int aMinXPos){ minXPos = aMinXPos; } int RedAnimationBakeModel::getMinXPos(){ return minXPos; } void RedAnimationBakeModel::setMinYPos(int aMinYPos){ minYPos = aMinYPos; } int RedAnimationBakeModel::getMinYPos(){ return minYPos; } void RedAnimationBakeModel::setLeftBottom(const Vec2& pos){ leftBottom = pos; } const Vec2& RedAnimationBakeModel::getLeftBottom(){ return leftBottom; } void RedAnimationBakeModel::setRightTopPos(const Vec2& pos){ rightTopPos = pos; } const Vec2& RedAnimationBakeModel::getRightTopPos(){ return rightTopPos; } void RedAnimationBakeModel::setLeftBottomSubSizePos(const Vec2& pos){ leftBottomSubSizePos = pos; } const Vec2& RedAnimationBakeModel::getLeftBottomSubSizePos(){ return leftBottomSubSizePos; } void RedAnimationBakeModel::setRightTopSubSizePos(const Vec2& pos){ rightTopSubSizePos = pos; } const Vec2& RedAnimationBakeModel::getRightTopSubSizePos(){ return rightTopSubSizePos; } void RedAnimationBakeModel::setSlotArr(const std::map& aSlotArr){ slotArr = aSlotArr; //提高查询性能专用,slotArr的Vector版 slotArrVector.clear(); int maxIndex = 1; for (auto it = slotArr.begin(); it != slotArr.end(); ++it){ RedSlotBakeModel *value = it->second; if (value->getSlotIndex()>maxIndex) { maxIndex = value->getSlotIndex(); } } slotArrVector.resize(maxIndex+1); for (auto it = slotArr.begin(); it != slotArr.end(); ++it){ RedSlotBakeModel *value = it->second; slotArrVector[value->getSlotIndex()] =value; } slotArrSize = (int)slotArr.size(); } const std::map& RedAnimationBakeModel::getSlotArr(){ return slotArr; } void RedAnimationBakeModel::setDrawOrderArr(std::vector>& aDrawOrderArr){ drawOrderArr = aDrawOrderArr; } const std::vector>& RedAnimationBakeModel::getDrawOrderArr(){ return drawOrderArr; } void RedAnimationBakeModel::setDrawOrderArrIndex(const std::vector& aDrawOrderArrIndex){ drawOrderArrIndex = aDrawOrderArrIndex; drawOrderArrIndexSize = (int)drawOrderArrIndex.size(); } const std::vector& RedAnimationBakeModel::getDrawOrderArrIndex(){ return drawOrderArrIndex; } void RedAnimationBakeModel::setEventArr(const std::vector& aEventArr){ eventArr = aEventArr; } const std::vector& RedAnimationBakeModel::getEventArr(){ return eventArr; } void RedAnimationBakeModel::setBoneAttachs(std::map>& aBoneAttachs){ boneAttachs = aBoneAttachs; for (auto& boneAttach : boneAttachs) { std::vector& attachPoints = boneAttach.second; // 获取挂点坐标数组 boneAttachsVector.push_back(attachPoints); } } //获取指定Key的BoneAttachs在数组的什么位置 int RedAnimationBakeModel::getBoneAttachsSearchIndex(std::string aKey){ int index=-1; for (auto& boneAttach : boneAttachs) { index++; std::string aName = boneAttach.first; // 获取骨骼名称 if (aName==aKey) { return index; } } return index; } const std::map>& RedAnimationBakeModel::getBoneAttachs(){ return boneAttachs; } std::vector RedAnimationBakeModel::getAllgetBoneAttachs() { std::vector keys; // 遍历 boneAttachs map 中的所有键,并将它们存储在 keys vector 中 for (const auto& kv : boneAttachs) { keys.push_back(kv.first); } return keys; }