123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 |
- //
- // RedBakeSpineIO.cpp
- // cocos2d_libs
- //
- // Created by ZhengSong on 2023/2/16.
- //
- #include "RedBakeSpineIO.h"
- #include <fstream>
- namespace spine {
- const static std::string REDSPINEBAKE_EXTENSION = ".rb";
- RedBakeSpineIO::RedBakeSpineIO() {
-
- }
- RedBakeSpineIO::~RedBakeSpineIO() {
- }
- static RedBakeSpineIO* _instance = nullptr;
- RedBakeSpineIO* RedBakeSpineIO::getInstance() {
- if(_instance == nullptr) {
- _instance = new RedBakeSpineIO();
- }
- return _instance;
- }
- void RedBakeSpineIO::write(const std::string& filePath, const std::unordered_map<std::string, RedAnimationBakeModel*>& datas) {
- if(datas.empty()) {
- CCASSERT(false, "没有数据");
- return;
- }
- std::ofstream outFile(filePath, std::ios::out | std::ios::binary);
-
- ::RedSpineBakeProto::BakeDataIndex dataIndex_pb;
- google::protobuf::Map<std::string, ::RedSpineBakeProto::DataInfo>* bakeDataIdx_pb = dataIndex_pb.mutable_dataindex();
-
- uint64_t currentOffset = 0;
- for(auto iter = datas.begin(); iter != datas.end(); iter++) {
- const std::string& animName = iter->first;
- RedAnimationBakeModel* bakeModel = iter->second;
- if(bakeModel == nullptr) {
- CCASSERT(false, "spine还没有烘培完");
- return;
- }
- ::RedSpineBakeProto::RedAnimationBakeModel bakeModel_pb;
- _writeAnimationBakeModel(bakeModel, bakeModel_pb);
-
- std::string serializedModel;
- bakeModel_pb.SerializeToString(&serializedModel);
-
- // 计算每个数据的长度,并保存位置信息
- ::RedSpineBakeProto::DataInfo dataInfo_pb;
- dataInfo_pb.set_offset(currentOffset);
- dataInfo_pb.set_length(serializedModel.size());
- (*bakeDataIdx_pb)[animName] = dataInfo_pb;
-
- //把烘培的数据写入到指定路径
- outFile.write(serializedModel.c_str(), dataInfo_pb.length());
-
- currentOffset += dataInfo_pb.length();
- }
- //烘培数据的索引文件写入到指定路径
- string outIndex;
- dataIndex_pb.SerializeToString(&outIndex);
- outFile.write(outIndex.c_str(), outIndex.size());
-
- uint32_t idxOffset = currentOffset;
- uint32_t outIndexSize = outIndex.size();
- // 将两个32位整数写入文件
- outFile.write(reinterpret_cast<const char*>(&idxOffset), sizeof(uint32_t));
- outFile.write(reinterpret_cast<const char*>(&outIndexSize), sizeof(uint32_t));
- // 检查是否写入成功
- if (!outFile) {
- ///写入失败
- }
-
- outFile.close();
- }
- void RedBakeSpineIO::_writeAnimationBakeModel(RedAnimationBakeModel* model, ::RedSpineBakeProto::RedAnimationBakeModel& model_pb) {
- //fileName
- const std::string& fileName = model->getFileName();
- model_pb.set_filename(fileName);
- //animateName
- const std::string& animateName = model->getAimationName();
- model_pb.set_animatename(animateName);
- //boneAttach
- ::google::protobuf::Map< std::string, ::RedSpineBakeProto::Vec2Array >* boneAttachs_pb = model_pb.mutable_boneattachs();
- const std::map<std::string,std::vector<Point>>& boneAttachs = model->getBoneAttachs();
- for(auto iter = boneAttachs.begin(); iter != boneAttachs.end(); iter++) {
- const std::string& boneAttachName = iter->first;
- const std::vector<Point>& posArray = iter->second;
- ::RedSpineBakeProto::Vec2Array posArray_pb;
- for(int i = 0; i < posArray.size(); ++i) {
- const Point& pos = posArray.at(i);
- ::RedSpineBakeProto::Vec2* pos_pb = posArray_pb.add_arr();
- pos_pb->set_x(pos.x);
- pos_pb->set_y(pos.y);
- }
- (*boneAttachs_pb)[boneAttachName] = posArray_pb;
- }
- //slotArr
- ::google::protobuf::Map<::google::protobuf::int32, ::RedSpineBakeProto::RedSlotBakeModel >* slotArr_pb = model_pb.mutable_slotarr();
- const std::map<int,RedSlotBakeModel*>& slotArr = model->getSlotArr();
- RedSlotBakeModel* slotModel = nullptr;
- for(auto iter : slotArr) {
- int slotIdx = iter.first;
- slotModel = iter.second;
- ::RedSpineBakeProto::RedSlotBakeModel slotModel_pb;
- _writeSlotBakeModel(slotModel, slotModel_pb);
- (*slotArr_pb)[slotIdx] = slotModel_pb;
- }
- //drawOrderArr
- ::RedSpineBakeProto::DrawOrderArray* drawOrderArray_pb = model_pb.mutable_draworderarr();
- const std::vector<std::vector<int>>& drawOrderArray = model->getDrawOrderArr();
- for(int i = 0; i < drawOrderArray.size(); ++i) {
- ::RedSpineBakeProto::DrawOrderArray_DrawOrders* container = drawOrderArray_pb->add_container();
- const std::vector<int>& arr = drawOrderArray.at(i);
- for(int j = 0; j < arr.size(); ++j) {
- int order = arr.at(j);
- container->add_draworder(order);
- }
- }
- //drawOrderArrIndex
- const std::vector<DrawOrderMD>& drawOrderArrIndex = model->getDrawOrderArrIndex();
- for(int i = 0; i < drawOrderArrIndex.size(); ++i) {
- const DrawOrderMD& drawOrderMD = drawOrderArrIndex.at(i);
- ::RedSpineBakeProto::DrawOrderMD* drawOrderMD_pb = model_pb.add_draworderarrindex();
- drawOrderMD_pb->set_frame(drawOrderMD.frame);
- drawOrderMD_pb->set_arrindex(drawOrderMD.arrIndex);
- }
- //eventArr
- const std::vector<EventMD>& eventArr = model->getEventArr();
- for(int i = 0; i < eventArr.size(); ++i){
- const EventMD& eventMD = eventArr.at(i);
- ::RedSpineBakeProto::EventMD* eventMD_pb = model_pb.add_eventarr();
- eventMD_pb->set_frame(eventMD.frame);
- for(int j = 0; j < eventMD.eventNames.size(); ++j){
- std::string eventName = eventMD.eventNames.at(j);
- eventMD_pb->add_eventname(eventName);
- }
- }
- //totalBakeFrame
- int totalBakeFrame = model->getTotalBakeFrame();
- model_pb.set_totalbakeframe(totalBakeFrame);
- //边界
- int maxXPos = model->getMaxXPos();
- int maxYPos = model->getMaxYPos();
- int minXPos = model->getMinXPos();
- int minYPos = model->getMinYPos();
- model_pb.set_maxxpos(maxXPos);
- model_pb.set_maxypos(maxYPos);
- model_pb.set_minxpos(minXPos);
- model_pb.set_minypos(minYPos);
- const Vec2& leftBottomPos = model->getLeftBottom();
- const Vec2& rightTopPos = model->getRightTopPos();
- const Vec2& leftBottomSubSizePos = model->getLeftBottomSubSizePos();
- const Vec2& rightTopSubSizePos = model->getRightTopSubSizePos();
- model_pb.mutable_leftbottompos()->set_x(leftBottomPos.x);
- model_pb.mutable_leftbottompos()->set_y(leftBottomPos.y);
- model_pb.mutable_righttoppos()->set_x(rightTopPos.x);
- model_pb.mutable_righttoppos()->set_y(rightTopPos.y);
- model_pb.mutable_leftbottomsubsizepos()->set_x(leftBottomSubSizePos.x);
- model_pb.mutable_leftbottomsubsizepos()->set_y(leftBottomSubSizePos.y);
- model_pb.mutable_righttopsubsizepos()->set_x(rightTopSubSizePos.x);
- model_pb.mutable_righttopsubsizepos()->set_y(rightTopSubSizePos.y);
- //当前帧率
- int currentFrameRate = model->getCurrentFrameRate();
- model_pb.set_currentframerate(currentFrameRate);
- //lastDrawOverTime
- float lastDrawOverTime = model->getLastDrawOverTime();
- model_pb.set_lastdrawovertime(lastDrawOverTime);
- }
- void RedBakeSpineIO::_writeSlotBakeModel(RedSlotBakeModel* model, ::RedSpineBakeProto::RedSlotBakeModel& model_pb) {
- //slotName
- model_pb.set_slotname(model->getSlotName());
- //slotIndex
- int slotIndex = model->getSlotIndex();
- model_pb.set_slotindex(slotIndex);
- //posarray
- const std::vector<std::vector<BAKE_POS_INT>>& posArray = model->getPosArray();
- ::RedSpineBakeProto::PosArray* bakePosArray = model_pb.mutable_posarray();
- for(int i = 0; i < posArray.size(); i++) {
- const vector<BAKE_POS_INT>& arr = posArray.at(i);
- ::RedSpineBakeProto::PosArray_BakePosArray* container = bakePosArray->add_container();
- for(int j = 0; j < arr.size(); j++) {
- const BAKE_POS_INT& bpi = arr.at(j);
- ::RedSpineBakeProto::Vec2* bakePos = container->add_pos();
- bakePos->set_x(bpi.xPos);
- bakePos->set_y(bpi.yPos);
- }
- }
- //blendFuncArray
- const std::vector<BlendFunc>& blendFuncArray = model->getBlendFuncArray();
- for(int i = 0; i < blendFuncArray.size(); i++) {
- const BlendFunc& blend = blendFuncArray.at(i);
- ::RedSpineBakeProto::BlendFunc* bakeBlend = model_pb.add_blendfuncarray();
- bakeBlend->set_src(blend.src);
- bakeBlend->set_dst(blend.dst);
- }
- //colorArray
- const std::vector<Color3B>& colorArray = model->getColorArray();
- for(int i = 0; i < colorArray.size(); i++) {
- const Color3B& color = colorArray.at(i);
- ::RedSpineBakeProto::Color3B* bakeColor = model_pb.add_colorarray();
- bakeColor->set_r(color.r);
- bakeColor->set_g(color.g);
- bakeColor->set_b(color.b);
- }
- //alphaArray
- const std::vector<GLubyte>& alphaArray = model->getAlphaArray();
- for(int i = 0; i < alphaArray.size(); i++) {
- GLubyte alpha = alphaArray.at(i);
- model_pb.add_alphaarray(alpha);
- }
- //uvArray
- const std::vector<std::vector<Tex2F>>& uvArray = model->getUvArray();
- ::RedSpineBakeProto::UVArray* bakeUvArray = model_pb.mutable_uvarray();
- for(int i = 0; i < uvArray.size(); i++) {
- ::RedSpineBakeProto::UVArray_TexArray* texArray= bakeUvArray->add_container();
- const std::vector<Tex2F>& arr = uvArray.at(i);
- for(int j = 0; j < arr.size(); j++) {
- const Tex2F& tex = arr.at(j);
- ::RedSpineBakeProto::Tex2F* bakeTex = texArray->add_texes();
- bakeTex->set_u(tex.u);
- bakeTex->set_v(tex.v);
- }
- }
- //indicesArray
- const std::vector<std::vector<unsigned short>>& indicesArray = model->getIndicesArray();
- ::RedSpineBakeProto::IndicesArray*bakeIndicesArray = model_pb.mutable_indicesarray();
- for(int i = 0; i < indicesArray.size(); i++) {
- const std::vector<unsigned short>& array = indicesArray.at(i);
- ::RedSpineBakeProto::IndicesArray_Indices* bakeIndices = bakeIndicesArray->add_container();
- for(int j = 0; j < array.size(); j++) {
- unsigned short indice = array.at(j);
- bakeIndices->add_indices(indice);
- }
- }
- //frameChangeArr
- const std::vector<GLubyte>& frameChangeArr = model->getFrameChangeArr();
- for(int i = 0; i < frameChangeArr.size(); i++) {
- GLubyte frameChangeValue = frameChangeArr.at(i);
- model_pb.add_framechangearr(frameChangeValue);
- }
- //pos
- int maxXPos = model->getMaxXPos();
- int maxYPos = model->getMaxYPos();
- int minXPos = model->getMinXPos();
- int minYPos = model->getMinYPos();
- model_pb.set_maxxpos(maxXPos);
- model_pb.set_maxypos(maxYPos);
- model_pb.set_minxpos(minXPos);
- model_pb.set_minypos(minYPos);
- //textureArray
- const std::vector<cocos2d::Texture2D*>& textureArray = model->getTextureArray();
- for (int i = 0; i < textureArray.size(); i++) {
- Texture2D* tex = textureArray.at(i);
- std::string fullPath = tex->getPath();
- size_t lastPos = fullPath.find_last_of('/');
- std::string fileName = fullPath.substr(lastPos + 1, fullPath.size() - lastPos);
- model_pb.add_texfilenamearr(fileName);
- }
- }
- void RedBakeSpineIO::readAnimationBakeModel(const ::RedSpineBakeProto::RedAnimationBakeModel& model_pb, RedAnimationBakeModel* model, const std::string& filePath) {
- _readAnimationBakeModel(model_pb, model, filePath);
- }
- void RedBakeSpineIO::_readAnimationBakeModel(const ::RedSpineBakeProto::RedAnimationBakeModel& model_pb, RedAnimationBakeModel* model, const std::string& filePath) {
- //fileName
- const std::string& fileName = model_pb.filename();
- model->setFileName(fileName);
- //animateName
- const std::string& animateName = model_pb.animatename();
- model->setAimationName(animateName);
- //boneAttach
- std::map<std::string, std::vector<Point>> boneAttachs;
- const ::google::protobuf::Map<std::string, ::RedSpineBakeProto::Vec2Array>& boneattachs_pb = model_pb.boneattachs();
- for(auto iter = boneattachs_pb.begin(); iter != boneattachs_pb.end(); ++ iter) {
- const string& boneattachName = iter->first;
- const ::RedSpineBakeProto::Vec2Array& posArray_pb = iter->second;
- std::vector<Point> posArray;
- for (int i = 0; i < posArray_pb.arr_size(); ++i) {
- const ::RedSpineBakeProto::Vec2& pos_pb = posArray_pb.arr(i);
- Point pos;
- pos.x = pos_pb.x();
- pos.y = pos_pb.y();
- posArray.push_back(pos);
- }
- boneAttachs[boneattachName] = posArray;
- }
- model->setBoneAttachs(boneAttachs);
- //totalBakeFrame
- int totalBakeFrame = model_pb.totalbakeframe();
- model->setTotalBakeFrame(totalBakeFrame);
- //slotArr
- std::map<int, RedSlotBakeModel *> slotArr;
- const ::google::protobuf::Map<::google::protobuf::int32, ::RedSpineBakeProto::RedSlotBakeModel>& slotArr_pb = model_pb.slotarr();
- for(auto iter = slotArr_pb.begin(); iter != slotArr_pb.end(); ++iter) {
- int slotIdx = iter->first;
- const ::RedSpineBakeProto::RedSlotBakeModel& slotModel_pb = iter->second;
- RedSlotBakeModel* slotModel = new RedSlotBakeModel(slotModel_pb.slotname(), slotModel_pb.slotindex());
- _readSlotBakeModel(slotModel_pb, slotModel, filePath, nullptr);
- slotArr[slotIdx] = slotModel;
- }
- model->setSlotArr(slotArr);
- //drawOrderArr
- std::vector<std::vector<int>> drawOrderArr;
- const ::RedSpineBakeProto::DrawOrderArray& drawOrderArray_pb = model_pb.draworderarr();
- for(int i = 0; i < drawOrderArray_pb.container_size(); ++i) {
- const ::RedSpineBakeProto::DrawOrderArray_DrawOrders& drawOrders_pb = drawOrderArray_pb.container(i);
- int draworderSize = drawOrders_pb.draworder_size();
- std::vector<int> drawOrders;
- drawOrders.reserve(draworderSize);
- for(int j = 0; j < draworderSize; ++j) {
- int order = drawOrders_pb.draworder(j);
- drawOrders.push_back(order);
- }
- drawOrderArr.push_back(drawOrders);
- }
- model->setDrawOrderArr(drawOrderArr);
- //drawOrderArrIndex
- int drawOrderArrIndexSize = model_pb.draworderarrindex().size();
- std::vector<DrawOrderMD> drawOrderArrIndex;
- drawOrderArrIndex.reserve(drawOrderArrIndexSize);
- for(int i = 0; i < drawOrderArrIndexSize; i++) {
- const ::RedSpineBakeProto::DrawOrderMD& drawOrderMD_pb = model_pb.draworderarrindex(i);
- DrawOrderMD drawOrderMD;
- drawOrderMD.frame = drawOrderMD_pb.frame();
- drawOrderMD.arrIndex = drawOrderMD_pb.arrindex();
- drawOrderArrIndex.push_back(drawOrderMD);
- }
- model->setDrawOrderArrIndex(drawOrderArrIndex);
- //eventArr
- int eventArrSize = model_pb.eventarr().size();
- std::vector<EventMD> eventArr;
- eventArr.reserve(eventArrSize);
- for(int i = 0; i < eventArrSize; i++) {
- const ::RedSpineBakeProto::EventMD& eventMD_pb = model_pb.eventarr(i);
- EventMD eventMD;
- eventMD.frame = eventMD_pb.frame();
- int eventNamesSize = eventMD_pb.eventname_size();
- eventMD.eventNames.reserve(eventNamesSize);
- for(int j = 0; j < eventNamesSize; ++j) {
- std::string eventName = eventMD_pb.eventname(j);
- eventMD.eventNames.push_back(eventName);
- }
- eventArr.push_back(eventMD);
- }
- model->setEventArr(eventArr);
- //帧率
- int rate = model_pb.currentframerate();
- model->setCurrentFrameRate(rate);
- //lastDrawOverTime
- float lastDrawOverTime = model_pb.lastdrawovertime();
- model->setLastDrawOverTime(lastDrawOverTime);
- }
- void RedBakeSpineIO::_readSlotBakeModel(const ::RedSpineBakeProto::RedSlotBakeModel& model_pb, RedSlotBakeModel* model, const std::string& filePath, const std::function<void()>& finishCb) {
- std::string slotName = model_pb.slotname();
- model->setSlotName(slotName);
- int slotIndex = model_pb.slotindex();
- model->setSlotIndex(slotIndex);
- //posarray
- {
- const ::RedSpineBakeProto::PosArray& bakePosArray = model_pb.posarray();
- int posArraySize = bakePosArray.container_size();
- for(int i = 0; i < posArraySize; i++) {
- const ::RedSpineBakeProto::PosArray_BakePosArray& container = bakePosArray.container(i);
- int containerSize = container.pos_size();
- std::vector<BAKE_POS_INT> posArray;
- posArray.reserve(containerSize);//预设内存
- for (int j = 0; j < containerSize; j++) {
- const ::RedSpineBakeProto::Vec2& bakePos = container.pos(j);
- BAKE_POS_INT pos;
- pos.xPos = bakePos.x();
- pos.yPos = bakePos.y();
- posArray.push_back(pos);
- }
- model->addPosArray(posArray);
- }
- }
- //blendFuncArray
- {
- int blendFuncArraySize = model_pb.blendfuncarray_size();
- for(int i = 0; i < blendFuncArraySize; i++) {
- const ::RedSpineBakeProto::BlendFunc& bakeBlend = model_pb.blendfuncarray(i);
- BlendFunc blend;
- blend.src = bakeBlend.src();
- blend.dst = bakeBlend.dst();
- model->addBlendFuncToArray(blend);
- }
- }
- //colorArray
- {
- int colorArraySize = model_pb.colorarray_size();
- for(int i = 0; i < colorArraySize; i++) {
- const ::RedSpineBakeProto::Color3B& bakeColor = model_pb.colorarray(i);
- Color3B color;
- color.r = bakeColor.r();
- color.g = bakeColor.g();
- color.b = bakeColor.b();
- model->addColorToArray(color);
- }
- }
- //alphaArray
- {
- int alphaArraySize = model_pb.alphaarray_size();
- for(int i = 0; i < alphaArraySize; i++) {
- ::google::protobuf::uint32 bakeAlpha = model_pb.alphaarray(i);
- model->addAlphaToArray(bakeAlpha);
- }
- }
- //uvArray
- {
- const ::RedSpineBakeProto::UVArray& bakeUVArray = model_pb.uvarray();
- int containerSize = bakeUVArray.container_size();
- for(int i = 0; i < containerSize; i++) {
- const ::RedSpineBakeProto::UVArray_TexArray& container = bakeUVArray.container(i);
- int texesSize = container.texes_size();
- std::vector<Tex2F> uvArray;
- uvArray.reserve(texesSize);//预设内存
- for(int j = 0; j < texesSize; j++) {
- const ::RedSpineBakeProto::Tex2F& bakeTex = container.texes(j);
- Tex2F tex;
- tex.u = bakeTex.u();
- tex.v = bakeTex.v();
- uvArray.push_back(tex);
- }
- model->addUvArray(uvArray);
- }
- }
- //indicesArray
- {
- const ::RedSpineBakeProto::IndicesArray& bakeIndices = model_pb.indicesarray();
- int containerSize = bakeIndices.container_size();
- for(int i = 0; i < containerSize; i++) {
- const ::RedSpineBakeProto::IndicesArray_Indices& container = bakeIndices.container(i);
- int indicesSize = container.indices_size();
- std::vector<unsigned short> indicesArray;
- indicesArray.reserve(indicesSize);//预设内存
- for(int j = 0; j < indicesSize; j++) {
- ::google::protobuf::uint32 indices = container.indices(j);
- indicesArray.push_back(indices);
- }
- model->addIndicesArray(indicesArray);
- }
- }
- //frameChangeArr
- {
- int frameChangeArrSize = model_pb.framechangearr_size();
- for(int i = 0; i < frameChangeArrSize; i++) {
- ::google::protobuf::uint32 frame = model_pb.framechangearr(i);
- model->addFrameChangeToArr(frame);
- }
- }
- //bounds
- {
- int maxXPos = model_pb.maxxpos();
- int maxYPos = model_pb.maxypos();
- int minXPos = model_pb.minxpos();
- int minYPos = model_pb.minypos();
- model->setMaxXPos(maxXPos);
- model->setMaxYPos(maxYPos);
- model->setMinXPos(minXPos);
- model->setMinYPos(minYPos);
- }
- //textureArray
- {
- ///会在外部指定使用的图片!!!
- // auto loadTexture = [=](){
- // int textureArraySize = model_pb.texfilenamearr_size();
- // for(int i = 0; i < textureArraySize; i++) {
- // const std::string& fileName = model_pb.texfilenamearr(i);
- // Texture2D* tex2d = Director::getInstance()->getTextureCache()->addImage(filePath+fileName);
- // if(tex2d == nullptr) {
- // CCASSERT(false, "文件路径不对");
- // }
- // model->addTextureToArray(tex2d);
- // }
- // if(finishCb) {
- // finishCb();
- // }
- // };
- // loadTexture();
- if(finishCb) {
- finishCb();
- }
- }
- model->initBakeFrameInfos();
- }
- } //namespace
|