123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- //
- // 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<aFrameNum) {
- std::vector<int> &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<int> &dmdArr = drawOrderArr[dmd.arrIndex];
- return slotArrVector[dmdArr[aIndex]];
- }
- return nullptr;
- }
- void RedAnimationBakeModel::handleEventByFrame(Node* target, std::function<void(std::string)> 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<int, RedSlotBakeModel *>(aSlot->getSlotIndex(), aSlot));
- }
- void RedAnimationBakeModel::setBeginLastDraw(){
- beginLastDraw = true;
- }
- bool RedAnimationBakeModel::isBeginLastDraw(){
- return beginLastDraw;
- }
- void RedAnimationBakeModel::setBakeFinish(float alastDrawOverTime){
- isSpineBakeFinish = true;
- lastDrawOverTime = alastDrawOverTime;
-
- std::vector<int> 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<int>& 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; i<slotArr.size(); i++) {
- slotArr.at(i)->startBakeOneFrame();
- }
- }
- void RedAnimationBakeModel::updateDrawOrder(spine::Vector<spine::Slot *> &aDrawList){
-
- // CCLOG("totalBakeFrame:%d ------------------------------------------------------",totalBakeFrame);
- std::vector<int> 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<int> 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<drawOrderArr.size(); i++) {
- currentDrawOrder = drawOrderArr.back();
- is_equal = (tmpDrawOrder.size() == currentDrawOrder.size()) && std::equal(tmpDrawOrder.begin(), tmpDrawOrder.end(), currentDrawOrder.begin());
- if (is_equal) {
- findIndex = i;
- }
- }
- if (findIndex==-1) {
- //原本里面没有
- drawOrderArr.push_back(tmpDrawOrder);
- DrawOrderMD dmd = {totalBakeFrame, int(drawOrderArr.size()-1)};
- drawOrderArrIndex.push_back(dmd);//记录每帧对应用哪个DrawOrder
- // CCLOG("X-Add %d totalBakeFrame:%d",(int)drawOrderArr.size()-1,totalBakeFrame);
- }else{
- //找到了
- DrawOrderMD dmd = {totalBakeFrame, findIndex};
- drawOrderArrIndex.push_back(dmd);//记录每帧对应用哪个DrawOrder
- // CCLOG("m-Add %d",findIndex);
- }
- }
- }
- }
- //增加一个需要被记录的事件
- void RedAnimationBakeModel::addEventData(std::string eventName){
- int currentFrame = totalBakeFrame;
- int findIndex = -1;
- for(int i = 0; i < eventArr.size(); i++){
- EventMD currentEvent = eventArr.at(i);
- if(currentEvent.frame == currentFrame){
- currentEvent.eventNames.push_back(eventName);
- findIndex = i;
- break;
- }
- }
- if(findIndex==-1){
- std::vector<std::string> 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<Point> posArr;
- boneAttachs.insert(std::pair<std::string,std::vector<Point>>(aName,posArr));
- boneAttachsVector.clear();
- for (auto& boneAttach : boneAttachs) {
- std::vector<Point>& attachPoints = boneAttach.second; // 获取挂点坐标数组
- boneAttachsVector.push_back(attachPoints);
- }
- }
- const std::vector<std::string>& 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<int,RedSlotBakeModel*>& 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<int,RedSlotBakeModel*>& RedAnimationBakeModel::getSlotArr(){
- return slotArr;
- }
- void RedAnimationBakeModel::setDrawOrderArr(std::vector<std::vector<int>>& aDrawOrderArr){
- drawOrderArr = aDrawOrderArr;
- }
- const std::vector<std::vector<int>>& RedAnimationBakeModel::getDrawOrderArr(){
- return drawOrderArr;
- }
- void RedAnimationBakeModel::setDrawOrderArrIndex(const std::vector<DrawOrderMD>& aDrawOrderArrIndex){
- drawOrderArrIndex = aDrawOrderArrIndex;
- drawOrderArrIndexSize = (int)drawOrderArrIndex.size();
- }
- const std::vector<DrawOrderMD>& RedAnimationBakeModel::getDrawOrderArrIndex(){
- return drawOrderArrIndex;
- }
- void RedAnimationBakeModel::setEventArr(const std::vector<EventMD>& aEventArr){
- eventArr = aEventArr;
- }
- const std::vector<EventMD>& RedAnimationBakeModel::getEventArr(){
- return eventArr;
- }
- void RedAnimationBakeModel::setBoneAttachs(std::map<std::string,std::vector<Point>>& aBoneAttachs){
- boneAttachs = aBoneAttachs;
- for (auto& boneAttach : boneAttachs) {
- std::vector<Point>& 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<std::string,std::vector<Point>>& RedAnimationBakeModel::getBoneAttachs(){
- return boneAttachs;
- }
- std::vector<std::string> RedAnimationBakeModel::getAllgetBoneAttachs() {
- std::vector<std::string> keys;
- // 遍历 boneAttachs map 中的所有键,并将它们存储在 keys vector 中
- for (const auto& kv : boneAttachs) {
- keys.push_back(kv.first);
- }
- return keys;
- }
|