diff --git a/native/cocos/editor-support/spine-creator-support/SkeletonCache.cpp b/native/cocos/editor-support/spine-creator-support/SkeletonCache.cpp index 568a243659e..e348fc2b037 100644 --- a/native/cocos/editor-support/spine-creator-support/SkeletonCache.cpp +++ b/native/cocos/editor-support/spine-creator-support/SkeletonCache.cpp @@ -317,9 +317,9 @@ void SkeletonCache::renderAnimationFrame(AnimationData *animationData) { } - auto *verticesMap = SkeletonDataMgr::getInstance()->getSkeletonDataInfo(_uuid); - if (!verticesMap) return; - auto &attachmentVerticesMap = *verticesMap; + auto *skeletonDataInfo = SkeletonDataMgr::getInstance()->getSkeletonDataInfo(_uuid); + if (!skeletonDataInfo) return; + auto &attachmentVerticesMap = skeletonDataInfo->attachmentVerticesMap; auto &drawOrder = _skeleton->getDrawOrder(); for (size_t i = 0, n = drawOrder.size(); i < n; ++i) { slot = drawOrder[i]; diff --git a/native/cocos/editor-support/spine-creator-support/SkeletonDataMgr.cpp b/native/cocos/editor-support/spine-creator-support/SkeletonDataMgr.cpp index 828f4115b73..eb840f66d38 100644 --- a/native/cocos/editor-support/spine-creator-support/SkeletonDataMgr.cpp +++ b/native/cocos/editor-support/spine-creator-support/SkeletonDataMgr.cpp @@ -77,38 +77,26 @@ extern "C" AttachmentVertices *generateAttachmentVertices(Attachment *attachment } namespace cc { -class SkeletonDataInfo { -public: - SkeletonDataInfo() = default; - - ~SkeletonDataInfo() { - if (data) { - delete data; - data = nullptr; - } - - if (atlas) { - delete atlas; - atlas = nullptr; - } - - if (attachmentLoader) { - delete attachmentLoader; - attachmentLoader = nullptr; - } +SkeletonDataInfo::~SkeletonDataInfo() { + if (data) { + delete data; + data = nullptr; + } - for (const auto& pair : attachmentVerticesMap) { - delete pair.second; - } + if (atlas) { + delete atlas; + atlas = nullptr; } - SkeletonData *data = nullptr; - Atlas *atlas = nullptr; - AttachmentLoader *attachmentLoader = nullptr; - std::vector texturesIndex; - std::unordered_map attachmentVerticesMap; -}; + if (attachmentLoader) { + delete attachmentLoader; + attachmentLoader = nullptr; + } + for (const auto &pair : attachmentVerticesMap) { + delete pair.second; + } +} void saveAttachmentVertices(SkeletonDataInfo *info) { auto &attachmentVerticesMap = info->attachmentVerticesMap; @@ -162,13 +150,21 @@ void SkeletonDataMgr::setSkeletonData(const std::string &uuid, SkeletonData *dat saveAttachmentVertices(info); } -std::unordered_map - *SkeletonDataMgr::getSkeletonDataInfo(const std::string &uuid) { +SkeletonDataInfo *SkeletonDataMgr::getSkeletonDataInfo(const std::string &uuid) { auto dataIt = _dataMap.find(uuid); if (dataIt == _dataMap.end()) { return nullptr; } - return &dataIt->second->attachmentVerticesMap; + return dataIt->second; +} + +std::vector SkeletonDataMgr::getSkeletonDataInfos() const { + std::vector infos; + infos.reserve(_dataMap.size()); + for (const auto &pair : _dataMap) { + infos.push_back(pair.second); + } + return infos; } SkeletonData *SkeletonDataMgr::retainByUUID(const std::string &uuid) { diff --git a/native/cocos/editor-support/spine-creator-support/SkeletonDataMgr.h b/native/cocos/editor-support/spine-creator-support/SkeletonDataMgr.h index e871486af16..bf687c26387 100644 --- a/native/cocos/editor-support/spine-creator-support/SkeletonDataMgr.h +++ b/native/cocos/editor-support/spine-creator-support/SkeletonDataMgr.h @@ -34,6 +34,7 @@ #include #include #include +#include "AttachmentVertices.h" #include "base/RefCounted.h" #include "spine/SkeletonData.h" #include "spine/spine.h" @@ -41,9 +42,22 @@ using namespace spine; namespace cc { -class SkeletonDataInfo; class AttachmentVertices; + +class SkeletonDataInfo { +public: + SkeletonDataInfo() = default; + + ~SkeletonDataInfo(); + + SkeletonData *data = nullptr; + Atlas *atlas = nullptr; + AttachmentLoader *attachmentLoader = nullptr; + std::vector texturesIndex; + std::unordered_map attachmentVerticesMap; +}; + /** * Cache skeleton data. */ @@ -73,14 +87,15 @@ class SkeletonDataMgr final { // equal to 'deleteByUUID' void releaseByUUID(const std::string &uuid); - std::unordered_map - *getSkeletonDataInfo(const std::string &uuid); + SkeletonDataInfo *getSkeletonDataInfo(const std::string &uuid); using destroyCallback = std::function; void setDestroyCallback(destroyCallback callback) { _destroyCallback = std::move(callback); } + std::vector getSkeletonDataInfos() const; + private: static SkeletonDataMgr *instance; destroyCallback _destroyCallback = nullptr; diff --git a/native/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp b/native/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp index b8628ce0f66..ebf7988408e 100644 --- a/native/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp +++ b/native/cocos/editor-support/spine-creator-support/SkeletonRenderer.cpp @@ -67,6 +67,21 @@ enum DebugType { extern "C" AttachmentVertices *generateAttachmentVertices(Attachment *attachment); namespace cc { + +/** + * The slot-associated attachment may exist on different skeletonData, so setSlotTexture needs to traverse all skeletonData. + */ +AttachmentVertices *getAttachmentVertices(Attachment *attachment) { + const auto &vecInfos = SkeletonDataMgr::getInstance()->getSkeletonDataInfos(); + for (const auto &info : vecInfos) { + auto &attachmentVerticesMap = info->attachmentVerticesMap; + if (attachmentVerticesMap.count(attachment) > 0) { + return attachmentVerticesMap[attachment]; + } + } + return nullptr; +} + SkeletonRenderer *SkeletonRenderer::create() { return new SkeletonRenderer(); } @@ -412,9 +427,9 @@ void SkeletonRenderer::render(float /*deltaTime*/) { void *effect = nullptr; #endif - auto *verticesMap = SkeletonDataMgr::getInstance()->getSkeletonDataInfo(_uuid); - if (!verticesMap) return; - auto &attachmentVerticesMap = *verticesMap; + auto *skeletonDataInfo = SkeletonDataMgr::getInstance()->getSkeletonDataInfo(_uuid); + if (!skeletonDataInfo) return; + auto &attachmentVerticesMap = skeletonDataInfo->attachmentVerticesMap; auto &drawOrder = _skeleton->getDrawOrder(); for (size_t i = 0, n = drawOrder.size(); i < n; ++i) { isFull = 0; @@ -449,7 +464,8 @@ void SkeletonRenderer::render(float /*deltaTime*/) { if (iterAttachment != attachmentVerticesMap.end()) { attachmentVertices = iterAttachment->second; } else { - attachmentVertices = nullptr; + //attachment maybe set from other skeletonData + attachmentVertices = getAttachmentVertices(tmpAttachment); } auto iter = _slotTextureSet.find(slot); @@ -1160,10 +1176,7 @@ void SkeletonRenderer::setSlotTexture(const std::string &slotName, cc::Texture2D if (!attachment) return; auto width = tex2d->getWidth(); auto height = tex2d->getHeight(); - auto *verticesMap = SkeletonDataMgr::getInstance()->getSkeletonDataInfo(_uuid); - if (!verticesMap) return; - auto &attachmentVerticesMap = *verticesMap; - auto *attachmentVertices = attachmentVerticesMap.at(attachment); + auto *attachmentVertices = getAttachmentVertices(slot->getAttachment()); if (createAttachment) { attachment = attachment->copy(); diff --git a/native/tools/swig-config/spine_3_8.i b/native/tools/swig-config/spine_3_8.i index 5c29aab1867..ba2a930b163 100644 --- a/native/tools/swig-config/spine_3_8.i +++ b/native/tools/swig-config/spine_3_8.i @@ -52,6 +52,7 @@ using namespace spine; %ignore spine::Polygon::Polygon; %ignore spine::Polygon::_vertices; +%ignore cc::SkeletonDataInfo; %ignore cc::SlotCacheInfo; %ignore cc::SkeletonRenderer::create; %ignore cc::SkeletonRenderer::initWithJsonFile; @@ -116,6 +117,7 @@ using namespace spine; %ignore cc::SkeletonDataMgr::retainByUUID; %ignore cc::SkeletonDataMgr::releaseByUUID; %ignore cc::SkeletonDataMgr::getSkeletonDataInfo; +%ignore cc::SkeletonDataMgr::getSkeletonDataInfos(); %ignore cc::SkeletonCacheAnimation::render; %ignore cc::SkeletonCacheAnimation::requestDrawInfo; %ignore cc::SkeletonCacheAnimation::requestMaterial; diff --git a/native/tools/swig-config/spine_4_2.i b/native/tools/swig-config/spine_4_2.i index 31b632acc92..9dc91c149a0 100644 --- a/native/tools/swig-config/spine_4_2.i +++ b/native/tools/swig-config/spine_4_2.i @@ -51,6 +51,7 @@ using namespace spine; %ignore spine::Polygon::Polygon; %ignore spine::Polygon::_vertices; +%ignore cc::SkeletonDataInfo; %ignore cc::SlotCacheInfo; %ignore cc::SkeletonRenderer::create; %ignore cc::SkeletonRenderer::initWithJsonFile; @@ -114,6 +115,7 @@ using namespace spine; %ignore cc::SkeletonDataMgr::retainByUUID; %ignore cc::SkeletonDataMgr::releaseByUUID; %ignore cc::SkeletonDataMgr::getSkeletonDataInfo; +%ignore cc::SkeletonDataMgr::getSkeletonDataInfos(); %ignore cc::SkeletonCacheAnimation::render; %ignore cc::SkeletonCacheAnimation::requestDrawInfo; %ignore cc::SkeletonCacheAnimation::requestMaterial;