RedAnimationBakeModel.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. //
  2. // RedSpineBakeModel.cpp
  3. // empty2dx-desktop
  4. //
  5. // Created by Liang zhong on 2022/11/5.
  6. //
  7. #include "RedAnimationBakeModel.h"
  8. #include "RedSpineBakeManage.h"
  9. RedAnimationBakeModel::RedAnimationBakeModel(){
  10. }
  11. RedAnimationBakeModel::~RedAnimationBakeModel(){
  12. }
  13. RedAnimationBakeModel::RedAnimationBakeModel(const std::string aFileName,const std::string& aAnimateName){
  14. fileName = aFileName;
  15. animateName = aAnimateName;
  16. }
  17. RedSlotBakeModel* RedAnimationBakeModel::getSlotFromKey(int akey){
  18. return slotArr[akey];
  19. }
  20. RedSlotBakeModel* RedAnimationBakeModel::findSlotFromKey(int akey){
  21. if (slotArr.find(akey) == slotArr.end()){
  22. return nullptr;
  23. }
  24. return slotArr[akey];
  25. }
  26. RedSlotBakeModel* RedAnimationBakeModel::getSlotByDrawOrder(int aIndex,int aFrameNum,int &aCurrentDrawOrderIndex){
  27. if (aCurrentDrawOrderIndex<(drawOrderArrIndexSize-1)) {
  28. const DrawOrderMD &dmd = drawOrderArrIndex[aCurrentDrawOrderIndex+1];
  29. if (dmd.frame<aFrameNum) {
  30. std::vector<int> &dmdArr = drawOrderArr[dmd.arrIndex];
  31. aCurrentDrawOrderIndex = aCurrentDrawOrderIndex+1;
  32. return slotArrVector[dmdArr[aIndex]];
  33. }else{
  34. const DrawOrderMD &dmd2 = drawOrderArrIndex[aCurrentDrawOrderIndex];
  35. const int resIndex = drawOrderArr[dmd2.arrIndex][aIndex];
  36. return slotArrVector[resIndex];
  37. }
  38. }else{
  39. aCurrentDrawOrderIndex = (int)drawOrderArrIndex.size()-1;
  40. DrawOrderMD dmd = drawOrderArrIndex[aCurrentDrawOrderIndex];
  41. std::vector<int> &dmdArr = drawOrderArr[dmd.arrIndex];
  42. return slotArrVector[dmdArr[aIndex]];
  43. }
  44. return nullptr;
  45. }
  46. void RedAnimationBakeModel::handleEventByFrame(Node* target, std::function<void(std::string)> cb){
  47. for(int i = 0; i < eventArr.size(); i++){
  48. EventMD emd = eventArr.at(i);
  49. float time = emd.frame * 1.f / currentFrameRate;
  50. target->scheduleOnce([=](float dt){
  51. for(int j = 0; j < emd.eventNames.size(); j++){
  52. std::string eventName = emd.eventNames.at(j);
  53. CCLOG("[sc : 事件回调 %s]", eventName.c_str());
  54. if(cb){
  55. cb(eventName);
  56. }
  57. }
  58. }, time, StringUtils::format("spine-wwise:%d",emd.frame));
  59. }
  60. }
  61. //绘制专用
  62. void RedAnimationBakeModel::addSlotByName(RedSlotBakeModel *aSlot){
  63. slotArr.insert(std::pair<int, RedSlotBakeModel *>(aSlot->getSlotIndex(), aSlot));
  64. }
  65. void RedAnimationBakeModel::setBeginLastDraw(){
  66. beginLastDraw = true;
  67. }
  68. bool RedAnimationBakeModel::isBeginLastDraw(){
  69. return beginLastDraw;
  70. }
  71. void RedAnimationBakeModel::setBakeFinish(float alastDrawOverTime){
  72. isSpineBakeFinish = true;
  73. lastDrawOverTime = alastDrawOverTime;
  74. std::vector<int> unuseSlotIndexArr;
  75. //删除slotArr中无用的slot
  76. for (auto it=slotArr.begin();it!=slotArr.end();) {
  77. RedSlotBakeModel *slot = it->second;
  78. slot->finishBake();
  79. if (slot->slotShoudBeDrawSlot()==false) {
  80. unuseSlotIndexArr.push_back(slot->getSlotIndex());
  81. it = slotArr.erase(it);
  82. }else{
  83. maxXPos = MAX(maxXPos,slot->getMaxXPos());
  84. maxYPos = MAX(maxYPos,slot->getMaxYPos());
  85. minXPos = MIN(minXPos,slot->getMinXPos());
  86. minYPos = MIN(minYPos,slot->getMinYPos());
  87. it++;
  88. }
  89. }
  90. //移除drawOrderArr中无用的SlotIndex
  91. for (auto iter = drawOrderArr.begin(); iter != drawOrderArr.end(); iter++) {
  92. for (auto inner_iter = iter->begin(); inner_iter != iter->end(); ) {
  93. // 判断当前元素是否需要删除
  94. auto findIter = std::find(unuseSlotIndexArr.begin(), unuseSlotIndexArr.end(), *inner_iter);
  95. if (findIter != unuseSlotIndexArr.end()) {
  96. inner_iter = iter->erase(inner_iter);// 如果找到了元素
  97. }else{
  98. inner_iter++;// 指向下一个元素
  99. }
  100. }
  101. }
  102. leftBottom = Vec2(minXPos,minYPos);//计算leftTopPos的中心点的位置,用于计算slot是否在屏幕内
  103. rightTopPos = Vec2(maxXPos,maxYPos);//计算rightBottomPos的size,用于计算Slot是否在屏幕内
  104. leftBottomSubSizePos = Vec2(minXPos + (maxXPos - minXPos),minYPos + (maxYPos- minYPos));//方便出屏幕判断,预先将leftBottom里面去加上Size,因为leftBottom出界需要判断自己右上角,减少之后的计算
  105. rightTopSubSizePos = Vec2(maxXPos - (maxXPos - minXPos),maxYPos - (maxYPos- minYPos));//方便出屏幕判断,预先将Rightop里面去减去Size,因为Righttop出界需要判断自己左下角,减少之后的计算
  106. if (RedSpineBakeManage::getInstance()->getAnimateByName(fileName,animateName)==nullptr) {
  107. RedSpineBakeManage::getInstance()->setCurrentAnimationBakeModel(animateName,this);
  108. }
  109. }
  110. bool RedAnimationBakeModel::isBakeFinish(){
  111. return isSpineBakeFinish;
  112. }
  113. int RedAnimationBakeModel::getSlotCount(){
  114. return slotArrSize;
  115. }
  116. const std::vector<int>& RedAnimationBakeModel::getAllSlotKey(){
  117. return drawOrderArr[0];
  118. }
  119. void RedAnimationBakeModel::setFileName(const std::string& aFileName){
  120. fileName = aFileName;
  121. }
  122. const std::string& RedAnimationBakeModel::getFileName(){
  123. return fileName;
  124. }
  125. void RedAnimationBakeModel::drawOneFrame(){
  126. totalBakeFrame += 1;
  127. for (int i=0; i<slotArr.size(); i++) {
  128. slotArr.at(i)->startBakeOneFrame();
  129. }
  130. }
  131. void RedAnimationBakeModel::updateDrawOrder(spine::Vector<spine::Slot *> &aDrawList){
  132. // CCLOG("totalBakeFrame:%d ------------------------------------------------------",totalBakeFrame);
  133. std::vector<int> tmpDrawOrder;
  134. for (int i = 0, n = (int)aDrawList.size(); i < n; ++i) {
  135. spine::Slot* slot = aDrawList[i];
  136. tmpDrawOrder.push_back(slot->getData().getIndex());
  137. }
  138. if(drawOrderArr.size()==0){
  139. drawOrderArr.push_back(tmpDrawOrder);
  140. DrawOrderMD dmd = {totalBakeFrame, 0};
  141. drawOrderArrIndex.push_back(dmd);//记录每帧对应用哪个DrawOrder
  142. // CCLOG("Add 0");
  143. }else{
  144. std::vector<int> currentDrawOrder = drawOrderArr.back();
  145. bool is_equal = (tmpDrawOrder.size() == currentDrawOrder.size()) && std::equal(tmpDrawOrder.begin(), tmpDrawOrder.end(), currentDrawOrder.begin());
  146. if(is_equal==false){
  147. int findIndex = -1;
  148. //先找找drawOrderArr里面有没有相等的
  149. for (int i=0; i<drawOrderArr.size(); i++) {
  150. currentDrawOrder = drawOrderArr.back();
  151. is_equal = (tmpDrawOrder.size() == currentDrawOrder.size()) && std::equal(tmpDrawOrder.begin(), tmpDrawOrder.end(), currentDrawOrder.begin());
  152. if (is_equal) {
  153. findIndex = i;
  154. }
  155. }
  156. if (findIndex==-1) {
  157. //原本里面没有
  158. drawOrderArr.push_back(tmpDrawOrder);
  159. DrawOrderMD dmd = {totalBakeFrame, int(drawOrderArr.size()-1)};
  160. drawOrderArrIndex.push_back(dmd);//记录每帧对应用哪个DrawOrder
  161. // CCLOG("X-Add %d totalBakeFrame:%d",(int)drawOrderArr.size()-1,totalBakeFrame);
  162. }else{
  163. //找到了
  164. DrawOrderMD dmd = {totalBakeFrame, findIndex};
  165. drawOrderArrIndex.push_back(dmd);//记录每帧对应用哪个DrawOrder
  166. // CCLOG("m-Add %d",findIndex);
  167. }
  168. }
  169. }
  170. }
  171. //增加一个需要被记录的事件
  172. void RedAnimationBakeModel::addEventData(std::string eventName){
  173. int currentFrame = totalBakeFrame;
  174. int findIndex = -1;
  175. for(int i = 0; i < eventArr.size(); i++){
  176. EventMD currentEvent = eventArr.at(i);
  177. if(currentEvent.frame == currentFrame){
  178. currentEvent.eventNames.push_back(eventName);
  179. findIndex = i;
  180. break;
  181. }
  182. }
  183. if(findIndex==-1){
  184. std::vector<std::string> eventNames;
  185. eventNames.push_back(eventName);
  186. EventMD emd = {totalBakeFrame, eventNames};
  187. eventArr.push_back(emd);
  188. CCLOG("[sc bake : %s-%s 没找到事件,新建一个 frame: %d event: %s ]", fileName.c_str(), animateName.c_str(), totalBakeFrame, eventName.c_str());
  189. }
  190. else{
  191. CCLOG("[sc bake : %s-%s 找到事件,添加一个 frame: %d event: %s ]", fileName.c_str(), animateName.c_str(), totalBakeFrame, eventName.c_str());
  192. }
  193. }
  194. //增加一个需要被记录的外接bone的名字
  195. void RedAnimationBakeModel::addboneAttachNames(std::string aName){
  196. boneAttachNames.push_back(aName);
  197. std::vector<Point> posArr;
  198. boneAttachs.insert(std::pair<std::string,std::vector<Point>>(aName,posArr));
  199. boneAttachsVector.clear();
  200. for (auto& boneAttach : boneAttachs) {
  201. std::vector<Point>& attachPoints = boneAttach.second; // 获取挂点坐标数组
  202. boneAttachsVector.push_back(attachPoints);
  203. }
  204. }
  205. const std::vector<std::string>& RedAnimationBakeModel::getAllboneAttachNames(){
  206. return boneAttachNames;
  207. }
  208. void RedAnimationBakeModel::bakeAModePointBeginPos(std::string aName,Point aPoint){
  209. boneAttachsBeginPos[aName] = aPoint;
  210. }
  211. void RedAnimationBakeModel::bakeAModePoint(std::string aName,Point aPoint){
  212. aPoint = aPoint-boneAttachsBeginPos[aName];
  213. boneAttachs[aName].push_back(aPoint);
  214. }
  215. const Point& RedAnimationBakeModel::getABakeModePoint(std::string aName,int aFrame){
  216. return boneAttachs[aName][aFrame];
  217. }
  218. const Point& RedAnimationBakeModel::getABakeModePoint(int aIndex,int aFrame){
  219. return boneAttachsVector[aIndex][aFrame];
  220. }
  221. int RedAnimationBakeModel::getTotalBakeFrame(){
  222. return totalBakeFrame;
  223. }
  224. void RedAnimationBakeModel::setTotalBakeFrame(int atotalBakeFrame){
  225. totalBakeFrame = atotalBakeFrame;
  226. }
  227. void RedAnimationBakeModel::setCurrentFrameRate(int aRate){
  228. currentFrameRate = aRate;
  229. }
  230. int RedAnimationBakeModel::getCurrentFrameRate(){
  231. return currentFrameRate;
  232. }
  233. void RedAnimationBakeModel::setLastDrawOverTime(float aLastDrawOverTime){
  234. lastDrawOverTime = aLastDrawOverTime;
  235. }
  236. float RedAnimationBakeModel::getLastDrawOverTime(){
  237. return lastDrawOverTime;
  238. }
  239. void RedAnimationBakeModel::setAimationName(const std::string& animName){
  240. animateName = animName;
  241. }
  242. const std::string& RedAnimationBakeModel::getAimationName(){
  243. return animateName;
  244. }
  245. bool RedAnimationBakeModel::isMixAnimation(){
  246. return false;
  247. }
  248. void RedAnimationBakeModel::setMaxXPos(int aMaxXPos){
  249. maxXPos = aMaxXPos;
  250. }
  251. int RedAnimationBakeModel::getMaxXPos(){
  252. return maxXPos;
  253. }
  254. void RedAnimationBakeModel::setMaxYPos(int aMaxYPos){
  255. maxYPos = aMaxYPos;
  256. }
  257. int RedAnimationBakeModel::getMaxYPos(){
  258. return maxYPos;
  259. }
  260. void RedAnimationBakeModel::setMinXPos(int aMinXPos){
  261. minXPos = aMinXPos;
  262. }
  263. int RedAnimationBakeModel::getMinXPos(){
  264. return minXPos;
  265. }
  266. void RedAnimationBakeModel::setMinYPos(int aMinYPos){
  267. minYPos = aMinYPos;
  268. }
  269. int RedAnimationBakeModel::getMinYPos(){
  270. return minYPos;
  271. }
  272. void RedAnimationBakeModel::setLeftBottom(const Vec2& pos){
  273. leftBottom = pos;
  274. }
  275. const Vec2& RedAnimationBakeModel::getLeftBottom(){
  276. return leftBottom;
  277. }
  278. void RedAnimationBakeModel::setRightTopPos(const Vec2& pos){
  279. rightTopPos = pos;
  280. }
  281. const Vec2& RedAnimationBakeModel::getRightTopPos(){
  282. return rightTopPos;
  283. }
  284. void RedAnimationBakeModel::setLeftBottomSubSizePos(const Vec2& pos){
  285. leftBottomSubSizePos = pos;
  286. }
  287. const Vec2& RedAnimationBakeModel::getLeftBottomSubSizePos(){
  288. return leftBottomSubSizePos;
  289. }
  290. void RedAnimationBakeModel::setRightTopSubSizePos(const Vec2& pos){
  291. rightTopSubSizePos = pos;
  292. }
  293. const Vec2& RedAnimationBakeModel::getRightTopSubSizePos(){
  294. return rightTopSubSizePos;
  295. }
  296. void RedAnimationBakeModel::setSlotArr(const std::map<int,RedSlotBakeModel*>& aSlotArr){
  297. slotArr = aSlotArr;
  298. //提高查询性能专用,slotArr的Vector版
  299. slotArrVector.clear();
  300. int maxIndex = 1;
  301. for (auto it = slotArr.begin(); it != slotArr.end(); ++it){
  302. RedSlotBakeModel *value = it->second;
  303. if (value->getSlotIndex()>maxIndex) {
  304. maxIndex = value->getSlotIndex();
  305. }
  306. }
  307. slotArrVector.resize(maxIndex+1);
  308. for (auto it = slotArr.begin(); it != slotArr.end(); ++it){
  309. RedSlotBakeModel *value = it->second;
  310. slotArrVector[value->getSlotIndex()] =value;
  311. }
  312. slotArrSize = (int)slotArr.size();
  313. }
  314. const std::map<int,RedSlotBakeModel*>& RedAnimationBakeModel::getSlotArr(){
  315. return slotArr;
  316. }
  317. void RedAnimationBakeModel::setDrawOrderArr(std::vector<std::vector<int>>& aDrawOrderArr){
  318. drawOrderArr = aDrawOrderArr;
  319. }
  320. const std::vector<std::vector<int>>& RedAnimationBakeModel::getDrawOrderArr(){
  321. return drawOrderArr;
  322. }
  323. void RedAnimationBakeModel::setDrawOrderArrIndex(const std::vector<DrawOrderMD>& aDrawOrderArrIndex){
  324. drawOrderArrIndex = aDrawOrderArrIndex;
  325. drawOrderArrIndexSize = (int)drawOrderArrIndex.size();
  326. }
  327. const std::vector<DrawOrderMD>& RedAnimationBakeModel::getDrawOrderArrIndex(){
  328. return drawOrderArrIndex;
  329. }
  330. void RedAnimationBakeModel::setEventArr(const std::vector<EventMD>& aEventArr){
  331. eventArr = aEventArr;
  332. }
  333. const std::vector<EventMD>& RedAnimationBakeModel::getEventArr(){
  334. return eventArr;
  335. }
  336. void RedAnimationBakeModel::setBoneAttachs(std::map<std::string,std::vector<Point>>& aBoneAttachs){
  337. boneAttachs = aBoneAttachs;
  338. for (auto& boneAttach : boneAttachs) {
  339. std::vector<Point>& attachPoints = boneAttach.second; // 获取挂点坐标数组
  340. boneAttachsVector.push_back(attachPoints);
  341. }
  342. }
  343. //获取指定Key的BoneAttachs在数组的什么位置
  344. int RedAnimationBakeModel::getBoneAttachsSearchIndex(std::string aKey){
  345. int index=-1;
  346. for (auto& boneAttach : boneAttachs) {
  347. index++;
  348. std::string aName = boneAttach.first; // 获取骨骼名称
  349. if (aName==aKey) {
  350. return index;
  351. }
  352. }
  353. return index;
  354. }
  355. const std::map<std::string,std::vector<Point>>& RedAnimationBakeModel::getBoneAttachs(){
  356. return boneAttachs;
  357. }
  358. std::vector<std::string> RedAnimationBakeModel::getAllgetBoneAttachs() {
  359. std::vector<std::string> keys;
  360. // 遍历 boneAttachs map 中的所有键,并将它们存储在 keys vector 中
  361. for (const auto& kv : boneAttachs) {
  362. keys.push_back(kv.first);
  363. }
  364. return keys;
  365. }