// // RedMixAnimationBakeModel.cpp // cocos2d_libs // // Created by Liang zhong on 2022/11/12. // #include "RedMixAnimationBakeModel.h" bool stringVectorEquals(const std::vector& v1, const std::vector& v2) { if (v1.size() != v2.size()) { return false; } return std::equal(v1.begin(), v1.end(), v2.begin()); } bool RedMixAnimationBakeModel::animationCanbeMix(std::string aPreAniName,std::string aNextAniName,std::string aFileName){ RedAnimationBakeModel *nextAnimation = RedSpineBakeManage::getInstance()->getAnimateByName(aFileName,aNextAniName); RedAnimationBakeModel *preAnimation = RedSpineBakeManage::getInstance()->getAnimateByName(aFileName,aPreAniName); if (preAnimation->getSlotCount()!=nextAnimation->getSlotCount()) { CCLOG("Slot 数量不一致 Pre:%d Next:%d",preAnimation->getSlotCount(),nextAnimation->getSlotCount()); return false; } bool hasSameBone = stringVectorEquals(nextAnimation->getAllgetBoneAttachs(), preAnimation->getAllgetBoneAttachs()); if (hasSameBone==false) { CCLOG("外接骨骼不一样 "); return false; } for (int i = 0; igetSlotCount(); i++) { int key = nextAnimation->getAllSlotKey()[i]; RedSlotBakeModel *nextSlotBake = nextAnimation->getSlotFromKey(key);//因为key是next自己取出来的,所以不用find RedSlotBakeModel *preSlotBake = preAnimation->findSlotFromKey(key);//因为pre可能没有这个key,必须用find取,否则可以出现指针异常 if (preSlotBake==nullptr){ CCLOG("找不到对应的SlotIndex:%d",key); return false; } if (nextSlotBake->getSlotName()!=preSlotBake->getSlotName()) { CCLOG("对应的SlotName名字不一样:%s-%s",nextSlotBake->getSlotName().c_str(),preSlotBake->getSlotName().c_str()); return false; } BKAE_FRAME_PLAY nextBake; BKAE_FRAME_PLAY preBake; nextSlotBake->initBKAE_FRAME_PLAY(nextBake); preSlotBake->initBKAE_FRAME_PLAY(preBake); if (nextBake.triangles.vertCount!=preBake.triangles.vertCount) { CCLOG("Slot:%s的顶点数量不一致 nextBake:%d PreBake:%d",nextSlotBake->getSlotName().c_str(),nextBake.triangles.vertCount,preBake.triangles.vertCount); return false; } } return true; } bool RedMixAnimationBakeModel::setMixInfo(int currentFrame,float mixTime,const std::map aPreAniBakeFrame,std::string aNextAniName,std::string aPreAniName,std::string aFileName,Point aDis){ currentDisPos = aDis; nextAnimation = RedSpineBakeManage::getInstance()->getAnimateByName(aFileName,aNextAniName); preAnimation = RedSpineBakeManage::getInstance()->getAnimateByName(aFileName,aPreAniName); if (aPreAniBakeFrame.size()!=nextAnimation->getSlotCount()) { CCLOG("Pre:%d Next:%d",(int)aPreAniBakeFrame.size(),nextAnimation->getSlotCount()); CCASSERT(false, "有效Slot数量不相等"); return false; } bool hasSameBone = stringVectorEquals(nextAnimation->getAllgetBoneAttachs(), preAnimation->getAllgetBoneAttachs()); if (hasSameBone==false) { CCLOG("外接骨骼不一样 "); return false; } currentFrameRate = nextAnimation->getCurrentFrameRate(); preBakeFrameArr = aPreAniBakeFrame; totalBakeFrame = ceil(mixTime*nextAnimation->getCurrentFrameRate()); mixLinkBone.clear(); std::vector boneList = nextAnimation->getAllgetBoneAttachs(); for (auto boneName:boneList) { link_Bone_Point link; link.nextPos = nextAnimation->getABakeModePoint(boneName,0); link.prePos = preAnimation->getABakeModePoint(boneName,currentFrame-1); mixLinkBone.insert(std::pair(boneName,link)); } for (int i = 0; igetSlotCount(); i++) { int key = nextAnimation->getAllSlotKey()[i]; RedSlotBakeModel *slotBake = nextAnimation->getSlotFromKey(key); int slotIndex = slotBake->getSlotIndex(); if (aPreAniBakeFrame.find(slotIndex) == aPreAniBakeFrame.end()){ CCASSERT(false, "找不到对应的SlotIndex"); return false; } if (slotBake->getSlotName()!=aPreAniBakeFrame.at(slotIndex).slotName) { CCASSERT(false, "对应的SlotName名字不一样"); return false; } BKAE_FRAME_PLAY nextBake; slotBake->initBKAE_FRAME_PLAY(nextBake); slotBake->getTriangles(1, nextBake); nextBakeFrameArr.insert(std::pair(key,nextBake)); MIX_BAKE_FRAME_PLAY mixBake; mixBake.blendFuc = slotBake->getBlendFunc(1); mixBake.texture = slotBake->getTexture(1); mixBake.preTriangles = aPreAniBakeFrame.at(slotIndex).triangles; mixBake.nextTriangles = nextBake.triangles; if (nextBake.triangles.vertCount!=aPreAniBakeFrame.at(slotIndex).triangles.vertCount) { CCLOG("nextBake:%d PreBake:%d",nextBake.triangles.vertCount,aPreAniBakeFrame.at(slotIndex).triangles.vertCount); CCASSERT(false, "Slot的顶点数量不一致"); return false; } V3F_C4B_T2F *currentVert = new V3F_C4B_T2F[mixBake.nextTriangles.vertCount]; cocos2d::TrianglesCommand::Triangles currentTriangles; currentTriangles.indexCount = mixBake.nextTriangles.indexCount; currentTriangles.vertCount = mixBake.nextTriangles.vertCount; currentTriangles.verts = currentVert; currentTriangles.indices = mixBake.nextTriangles.indices; mixBake.currentTriangles = currentTriangles; mixBakeFrameArr.insert(std::pair(key,mixBake)); } leftBottomSubSizePos = nextAnimation->getLeftBottomSubSizePos(); rightTopSubSizePos = nextAnimation->getRightTopSubSizePos(); return true; } RedMixAnimationBakeModel::~RedMixAnimationBakeModel(){ for (auto it = mixBakeFrameArr.begin(); it != mixBakeFrameArr.end(); ++it) { MIX_BAKE_FRAME_PLAY &mixBake = it->second; delete[] mixBake.currentTriangles.verts; } } std::vector RedMixAnimationBakeModel::getMixBakeFrameArrAllKey(){ std::vector keys; for (const auto &pair : mixBakeFrameArr) { keys.push_back(pair.first); } return keys; } bool RedMixAnimationBakeModel::isMixAnimation(){ return true; } int RedMixAnimationBakeModel::getSlotCount(){ return nextAnimation->getSlotCount(); } cocos2d::Texture2D* RedMixAnimationBakeModel::getTexture(int slotIndex){ return mixBakeFrameArr.at(slotIndex).texture; } BlendFunc RedMixAnimationBakeModel::getBlendFunc(int slotIndex){ return mixBakeFrameArr.at(slotIndex).blendFuc; } cocos2d::TrianglesCommand::Triangles RedMixAnimationBakeModel::getTriangles(int slotIndex,float aRealCurrentBakeFrame){ float step = (float)aRealCurrentBakeFrame/ (float)totalBakeFrame; cocos2d::TrianglesCommand::Triangles &preTriangles = mixBakeFrameArr.at(slotIndex).preTriangles; cocos2d::TrianglesCommand::Triangles &nextTriangles = mixBakeFrameArr.at(slotIndex).nextTriangles; cocos2d::TrianglesCommand::Triangles ¤tTriangles = mixBakeFrameArr.at(slotIndex).currentTriangles; V3F_C4B_T2F *currentVert = currentTriangles.verts; for (int i = 0; i