RedMixAnimationBakeModel.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. //
  2. // RedMixAnimationBakeModel.cpp
  3. // cocos2d_libs
  4. //
  5. // Created by Liang zhong on 2022/11/12.
  6. //
  7. #include "RedMixAnimationBakeModel.h"
  8. bool stringVectorEquals(const std::vector<std::string>& v1, const std::vector<std::string>& v2) {
  9. if (v1.size() != v2.size()) {
  10. return false;
  11. }
  12. return std::equal(v1.begin(), v1.end(), v2.begin());
  13. }
  14. bool RedMixAnimationBakeModel::animationCanbeMix(std::string aPreAniName,std::string aNextAniName,std::string aFileName){
  15. RedAnimationBakeModel *nextAnimation = RedSpineBakeManage::getInstance()->getAnimateByName(aFileName,aNextAniName);
  16. RedAnimationBakeModel *preAnimation = RedSpineBakeManage::getInstance()->getAnimateByName(aFileName,aPreAniName);
  17. if (preAnimation->getSlotCount()!=nextAnimation->getSlotCount()) {
  18. CCLOG("Slot 数量不一致 Pre:%d Next:%d",preAnimation->getSlotCount(),nextAnimation->getSlotCount());
  19. return false;
  20. }
  21. bool hasSameBone = stringVectorEquals(nextAnimation->getAllgetBoneAttachs(), preAnimation->getAllgetBoneAttachs());
  22. if (hasSameBone==false) {
  23. CCLOG("外接骨骼不一样 ");
  24. return false;
  25. }
  26. for (int i = 0; i<nextAnimation->getSlotCount(); i++) {
  27. int key = nextAnimation->getAllSlotKey()[i];
  28. RedSlotBakeModel *nextSlotBake = nextAnimation->getSlotFromKey(key);//因为key是next自己取出来的,所以不用find
  29. RedSlotBakeModel *preSlotBake = preAnimation->findSlotFromKey(key);//因为pre可能没有这个key,必须用find取,否则可以出现指针异常
  30. if (preSlotBake==nullptr){
  31. CCLOG("找不到对应的SlotIndex:%d",key);
  32. return false;
  33. }
  34. if (nextSlotBake->getSlotName()!=preSlotBake->getSlotName()) {
  35. CCLOG("对应的SlotName名字不一样:%s-%s",nextSlotBake->getSlotName().c_str(),preSlotBake->getSlotName().c_str());
  36. return false;
  37. }
  38. BKAE_FRAME_PLAY nextBake;
  39. BKAE_FRAME_PLAY preBake;
  40. nextSlotBake->initBKAE_FRAME_PLAY(nextBake);
  41. preSlotBake->initBKAE_FRAME_PLAY(preBake);
  42. if (nextBake.triangles.vertCount!=preBake.triangles.vertCount) {
  43. CCLOG("Slot:%s的顶点数量不一致 nextBake:%d PreBake:%d",nextSlotBake->getSlotName().c_str(),nextBake.triangles.vertCount,preBake.triangles.vertCount);
  44. return false;
  45. }
  46. }
  47. return true;
  48. }
  49. bool RedMixAnimationBakeModel::setMixInfo(int currentFrame,float mixTime,const std::map<int,BKAE_FRAME_PLAY> aPreAniBakeFrame,std::string aNextAniName,std::string aPreAniName,std::string aFileName,Point aDis){
  50. currentDisPos = aDis;
  51. nextAnimation = RedSpineBakeManage::getInstance()->getAnimateByName(aFileName,aNextAniName);
  52. preAnimation = RedSpineBakeManage::getInstance()->getAnimateByName(aFileName,aPreAniName);
  53. if (aPreAniBakeFrame.size()!=nextAnimation->getSlotCount()) {
  54. CCLOG("Pre:%d Next:%d",(int)aPreAniBakeFrame.size(),nextAnimation->getSlotCount());
  55. CCASSERT(false, "有效Slot数量不相等");
  56. return false;
  57. }
  58. bool hasSameBone = stringVectorEquals(nextAnimation->getAllgetBoneAttachs(), preAnimation->getAllgetBoneAttachs());
  59. if (hasSameBone==false) {
  60. CCLOG("外接骨骼不一样 ");
  61. return false;
  62. }
  63. currentFrameRate = nextAnimation->getCurrentFrameRate();
  64. preBakeFrameArr = aPreAniBakeFrame;
  65. totalBakeFrame = ceil(mixTime*nextAnimation->getCurrentFrameRate());
  66. mixLinkBone.clear();
  67. std::vector<std::string> boneList = nextAnimation->getAllgetBoneAttachs();
  68. for (auto boneName:boneList) {
  69. link_Bone_Point link;
  70. link.nextPos = nextAnimation->getABakeModePoint(boneName,0);
  71. link.prePos = preAnimation->getABakeModePoint(boneName,currentFrame-1);
  72. mixLinkBone.insert(std::pair<std::string,link_Bone_Point>(boneName,link));
  73. }
  74. for (int i = 0; i<nextAnimation->getSlotCount(); i++) {
  75. int key = nextAnimation->getAllSlotKey()[i];
  76. RedSlotBakeModel *slotBake = nextAnimation->getSlotFromKey(key);
  77. int slotIndex = slotBake->getSlotIndex();
  78. if (aPreAniBakeFrame.find(slotIndex) == aPreAniBakeFrame.end()){
  79. CCASSERT(false, "找不到对应的SlotIndex");
  80. return false;
  81. }
  82. if (slotBake->getSlotName()!=aPreAniBakeFrame.at(slotIndex).slotName) {
  83. CCASSERT(false, "对应的SlotName名字不一样");
  84. return false;
  85. }
  86. BKAE_FRAME_PLAY nextBake;
  87. slotBake->initBKAE_FRAME_PLAY(nextBake);
  88. slotBake->getTriangles(1, nextBake);
  89. nextBakeFrameArr.insert(std::pair<int, BKAE_FRAME_PLAY>(key,nextBake));
  90. MIX_BAKE_FRAME_PLAY mixBake;
  91. mixBake.blendFuc = slotBake->getBlendFunc(1);
  92. mixBake.texture = slotBake->getTexture(1);
  93. mixBake.preTriangles = aPreAniBakeFrame.at(slotIndex).triangles;
  94. mixBake.nextTriangles = nextBake.triangles;
  95. if (nextBake.triangles.vertCount!=aPreAniBakeFrame.at(slotIndex).triangles.vertCount) {
  96. CCLOG("nextBake:%d PreBake:%d",nextBake.triangles.vertCount,aPreAniBakeFrame.at(slotIndex).triangles.vertCount);
  97. CCASSERT(false, "Slot的顶点数量不一致");
  98. return false;
  99. }
  100. V3F_C4B_T2F *currentVert = new V3F_C4B_T2F[mixBake.nextTriangles.vertCount];
  101. cocos2d::TrianglesCommand::Triangles currentTriangles;
  102. currentTriangles.indexCount = mixBake.nextTriangles.indexCount;
  103. currentTriangles.vertCount = mixBake.nextTriangles.vertCount;
  104. currentTriangles.verts = currentVert;
  105. currentTriangles.indices = mixBake.nextTriangles.indices;
  106. mixBake.currentTriangles = currentTriangles;
  107. mixBakeFrameArr.insert(std::pair<int, MIX_BAKE_FRAME_PLAY>(key,mixBake));
  108. }
  109. leftBottomSubSizePos = nextAnimation->getLeftBottomSubSizePos();
  110. rightTopSubSizePos = nextAnimation->getRightTopSubSizePos();
  111. return true;
  112. }
  113. RedMixAnimationBakeModel::~RedMixAnimationBakeModel(){
  114. for (auto it = mixBakeFrameArr.begin(); it != mixBakeFrameArr.end(); ++it) {
  115. MIX_BAKE_FRAME_PLAY &mixBake = it->second;
  116. delete[] mixBake.currentTriangles.verts;
  117. }
  118. }
  119. std::vector<int> RedMixAnimationBakeModel::getMixBakeFrameArrAllKey(){
  120. std::vector<int> keys;
  121. for (const auto &pair : mixBakeFrameArr) {
  122. keys.push_back(pair.first);
  123. }
  124. return keys;
  125. }
  126. bool RedMixAnimationBakeModel::isMixAnimation(){
  127. return true;
  128. }
  129. int RedMixAnimationBakeModel::getSlotCount(){
  130. return nextAnimation->getSlotCount();
  131. }
  132. cocos2d::Texture2D* RedMixAnimationBakeModel::getTexture(int slotIndex){
  133. return mixBakeFrameArr.at(slotIndex).texture;
  134. }
  135. BlendFunc RedMixAnimationBakeModel::getBlendFunc(int slotIndex){
  136. return mixBakeFrameArr.at(slotIndex).blendFuc;
  137. }
  138. cocos2d::TrianglesCommand::Triangles RedMixAnimationBakeModel::getTriangles(int slotIndex,float aRealCurrentBakeFrame){
  139. float step = (float)aRealCurrentBakeFrame/ (float)totalBakeFrame;
  140. cocos2d::TrianglesCommand::Triangles &preTriangles = mixBakeFrameArr.at(slotIndex).preTriangles;
  141. cocos2d::TrianglesCommand::Triangles &nextTriangles = mixBakeFrameArr.at(slotIndex).nextTriangles;
  142. cocos2d::TrianglesCommand::Triangles &currentTriangles = mixBakeFrameArr.at(slotIndex).currentTriangles;
  143. V3F_C4B_T2F *currentVert = currentTriangles.verts;
  144. for (int i = 0; i<preTriangles.vertCount; i++) {
  145. V3F_C4B_T2F &preVert = preTriangles.verts[i];
  146. V3F_C4B_T2F &nextVert = nextTriangles.verts[i];
  147. currentVert[i].vertices.x = preVert.vertices.x + (nextVert.vertices.x-preVert.vertices.x)*step;
  148. currentVert[i].vertices.y = preVert.vertices.y + (nextVert.vertices.y-preVert.vertices.y)*step;
  149. currentVert[i].vertices.z = preVert.vertices.z + (nextVert.vertices.z-preVert.vertices.z)*step;
  150. currentVert[i].colors.r = preVert.colors.r + (nextVert.colors.r-preVert.colors.r)*step;
  151. currentVert[i].colors.g = preVert.colors.g + (nextVert.colors.g-preVert.colors.g)*step;
  152. currentVert[i].colors.b = preVert.colors.b + (nextVert.colors.b-preVert.colors.b)*step;
  153. currentVert[i].colors.a = preVert.colors.a + (nextVert.colors.a-preVert.colors.a)*step;
  154. currentVert[i].texCoords = nextTriangles.verts[i].texCoords;
  155. }
  156. return currentTriangles;
  157. }
  158. RedAnimationBakeModel *RedMixAnimationBakeModel::getNextAnimation(){
  159. return nextAnimation;
  160. }
  161. const Point& RedMixAnimationBakeModel::getABakeModePoint(std::string aName,int aFrame){
  162. currentBonePos.x = 0;
  163. currentBonePos.y = 0;
  164. if (mixLinkBone.count(aName) != 0){
  165. link_Bone_Point link = mixLinkBone.at(aName);
  166. float step = (float)aFrame/ (float)totalBakeFrame;
  167. currentBonePos.x = link.prePos.x + (link.nextPos.x-link.prePos.x)*step;
  168. currentBonePos.y = link.prePos.y + (link.nextPos.y-link.prePos.y)*step;
  169. currentBonePos.x += currentDisPos.x*(1-step);
  170. currentBonePos.y += currentDisPos.y*(1-step);
  171. }
  172. return currentBonePos;
  173. }