123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- //
- // RedMixAnimationBakeModel.cpp
- // cocos2d_libs
- //
- // Created by Liang zhong on 2022/11/12.
- //
- #include "RedMixAnimationBakeModel.h"
- bool stringVectorEquals(const std::vector<std::string>& v1, const std::vector<std::string>& 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; i<nextAnimation->getSlotCount(); 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<int,BKAE_FRAME_PLAY> 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<std::string> 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<std::string,link_Bone_Point>(boneName,link));
- }
-
-
- for (int i = 0; i<nextAnimation->getSlotCount(); 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<int, BKAE_FRAME_PLAY>(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<int, MIX_BAKE_FRAME_PLAY>(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<int> RedMixAnimationBakeModel::getMixBakeFrameArrAllKey(){
- std::vector<int> 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<preTriangles.vertCount; i++) {
- V3F_C4B_T2F &preVert = preTriangles.verts[i];
- V3F_C4B_T2F &nextVert = nextTriangles.verts[i];
- currentVert[i].vertices.x = preVert.vertices.x + (nextVert.vertices.x-preVert.vertices.x)*step;
- currentVert[i].vertices.y = preVert.vertices.y + (nextVert.vertices.y-preVert.vertices.y)*step;
- currentVert[i].vertices.z = preVert.vertices.z + (nextVert.vertices.z-preVert.vertices.z)*step;
- currentVert[i].colors.r = preVert.colors.r + (nextVert.colors.r-preVert.colors.r)*step;
- currentVert[i].colors.g = preVert.colors.g + (nextVert.colors.g-preVert.colors.g)*step;
- currentVert[i].colors.b = preVert.colors.b + (nextVert.colors.b-preVert.colors.b)*step;
- currentVert[i].colors.a = preVert.colors.a + (nextVert.colors.a-preVert.colors.a)*step;
- currentVert[i].texCoords = nextTriangles.verts[i].texCoords;
- }
- return currentTriangles;
- }
- RedAnimationBakeModel *RedMixAnimationBakeModel::getNextAnimation(){
- return nextAnimation;
- }
- const Point& RedMixAnimationBakeModel::getABakeModePoint(std::string aName,int aFrame){
- currentBonePos.x = 0;
- currentBonePos.y = 0;
- if (mixLinkBone.count(aName) != 0){
- link_Bone_Point link = mixLinkBone.at(aName);
- float step = (float)aFrame/ (float)totalBakeFrame;
- currentBonePos.x = link.prePos.x + (link.nextPos.x-link.prePos.x)*step;
- currentBonePos.y = link.prePos.y + (link.nextPos.y-link.prePos.y)*step;
-
- currentBonePos.x += currentDisPos.x*(1-step);
- currentBonePos.y += currentDisPos.y*(1-step);
- }
- return currentBonePos;
- }
|