前言:
cocos2dx 中spine 的换皮功能是一种静态的方法,也就是在创建 spine 动画的时候就必须将所有的皮肤全部加载,然后在代码中直接换皮,并且这种换皮是整体的切换,对于我们实际开发中这种方式是相当的不理想的。
注意:
本代码本人还只是简单的测试,如果还存在其它问题可以留言。
原理介绍:
对于spine动画而言动画的构成由 1、bone(骨骼)2、slot (槽)3、attachment(附件)组成,而动画中的图片资源都是通过附件来存储的。在spine的源文件由一个 xxx.atlas 文件 xxx.json 文件构成, xxx.atlas 文件其实就相当于我们的 plist 合图。 xxx.json 就是我们的动画描述文件,里面包含了。 bone、IK、slot、skin、animation、event 的描述。在解析后,所有图片附件都是元始于 skin 的,然后会挂载在 slot 下,也就是如果要换皮就需要替换 skin 和 slot 下对应的 attachment。
更新(2016/07/07):
今天又研究了下,其实还可以再简化一些,原先是创建新的attachment 替换旧的,其实我们可以基于旧的attachment修改显示的纹理就行了,简化后代码见最后修改代码。
更新(2016/07/08):
基于前面两个版本,因为换装一般都需要换来换去,那么如果能够保留原先的皮肤方便换回去还是很有必要的。因此本版本主要增加此类功能。
exmaple:
void* region = skeletonNode->replaceAttachmentImage("head", "head", Sprite::create("Images/head.png")->getSpriteFrame());
region = skeletonNode->replaceAttachmentByRegion("head", "head", region);
版本一实现代码:
1、接口声明:
bool replaceAttachmentImage(const char* slotName, const char* attachmentName, cocos2d::SpriteFrame* frame, const char* attachment2 = nullptr);
2、接口实现:
static spAtlasPage* createNewPage(cocos2d::SpriteFrame* frame, spAttachment* oldAttachment)
{
spAtlasPage *page = nullptr;
spAtlasRegion* region = nullptr;
switch (oldAttachment->type)
{
case SP_ATTACHMENT_REGION:
{
spRegionAttachment* attachment = SUB_CAST(spRegionAttachment, oldAttachment);
region = SUB_CAST(spAtlasRegion, attachment->rendererObject);
break;
}
case SP_ATTACHMENT_MESH:
{
spMeshAttachment* attachment = SUB_CAST(spMeshAttachment, oldAttachment);
region = SUB_CAST(spAtlasRegion, attachment->rendererObject);
break;
}
case SP_ATTACHMENT_SKINNED_MESH:
{
spSkinnedMeshAttachment* attachment = SUB_CAST(spSkinnedMeshAttachment, oldAttachment);
region = SUB_CAST(spAtlasRegion, attachment->rendererObject);
break;
}
}
if (region == nullptr || region->page == nullptr) return page;
Texture2D* texture = frame->getTexture();
char pageName[20];
itoa((int)texture, pageName, 16);
spAtlasPage *searchPage = region->page->atlas->pages;
spAtlasPage* lastPage = searchPage;
while (searchPage != nullptr)
{
if (strcmp(searchPage->name, pageName) == 0)
{
page = searchPage;
break;
}
searchPage = searchPage->next;
if (searchPage != nullptr)
lastPage = searchPage;
}
if (page != nullptr) return page;
page = spAtlasPage_create(CONST_CAST(spAtlas*, region->page->atlas), pageName);
texture->retain();
page->rendererObject = texture;
page->width = texture->getPixelsWide();
page->height = texture->getPixelsHigh();
lastPage->next = page;
page->format = region->page->format;
page->minFilter = region->page->minFilter;
page->magFilter = region->page->magFilter;
page->uWrap = region->page->uWrap;
page->vWrap = region->page->vWrap;
return page;
}
static spAtlasRegion* createRegion(spAtlasPage *page, cocos2d::SpriteFrame* frame, spAttachment* oldAttachment)
{
const char* name = oldAttachment->name;
Texture2D* texture = frame->getTexture();
spAtlasRegion *region = spAtlasRegion_create();
region->page = page;
MALLOC_STR(region->name, name);
region->rotate = frame->isRotated();
cocos2d::Rect rect = frame->getRectInPixels();
region->x = rect.getMinX();
region->y = rect.getMinY();
region->width = rect.size.width;
region->height = rect.size.height;
cocos2d::Size originSize = frame->getOriginalSizeInPixels();
region->originalWidth = originSize.width;
region->originalHeight = originSize.height;
region->u = region->x / (float)page->width;
region->v = region->y / (float)page->height;
if (region->rotate) {
region->u2 = (region->x + region->height) / (float)page->width;
region->v2 = (region->y + region->width) / (float)page->height;
}
else {
region->u2 = (region->x + region->width) / (float)page->width;
region->v2 = (region->y + region->height) / (float)page->height;
}
cocos2d::Vec2 offset = frame->getOffsetInPixels();
region->offsetX = offset.x;
region->offsetY = offset.y;
region->index = -1;
spAtlasRegion* lastRegion, *nextRegion;
lastRegion = page->atlas->regions;
nextRegion = region->next;
while (nextRegion != nullptr)
{
lastRegion = nextRegion;
nextRegion = nextRegion->next;
}
lastRegion->next = region;
return region;
}
bool SkeletonRenderer::replaceAttachmentImage(const char* slotName, const char* attachmentName, cocos2d::SpriteFrame* frame, const char* attachment2 /* = nullptr*/)
{
spAttachment* oldAttachment = getAttachment(slotName, attachmentName);
if (oldAttachment == nullptr) return false;
spAttachment* newAttchment = nullptr;
const char* name = oldAttachment->name;
spAtlasPage *page = createNewPage(frame, oldAttachment);
if (page == nullptr) return false;
spAtlasRegion *region = createRegion(page, frame, oldAttachment);
switch (oldAttachment->type)
{
case SP_ATTACHMENT_REGION:
{
spRegionAttachment* attachment;
attachment = spRegionAttachment_create(name);
attachment->rendererObject = region;
spRegionAttachment_setUVs(attachment, region->u, region->v, region->u2, region->v2, region->rotate);
attachment->regionOffsetX = region->offsetX;
attachment->regionOffsetY = region->offsetY;
attachment->regionWidth = region->width;
attachment->regionHeight = region->height;
attachment->regionOriginalWidth = region->originalWidth;
attachment->regionOriginalHeight = region->originalHeight;
newAttchment = SUPER(attachment);
spRegionAttachment* oldRegion = SUB_CAST(spRegionAttachment, oldAttachment);
attachment->x = oldRegion->x;
attachment->y = oldRegion->y;
attachment->scaleX = oldRegion->scaleX;
attachment->scaleY = oldRegion->scaleY;
attachment->rotation = oldRegion->rotation;
attachment->width = oldRegion->width;
attachment->height = oldRegion->height;
attachment->r = oldRegion->r;
attachment->g = oldRegion->g;
attachment->b = oldRegion->b;
attachment->a = oldRegion->a;
spRegionAttachment_updateOffset(attachment);
break;
}
case SP_ATTACHMENT_MESH:
{
spMeshAttachment* attachment;
attachment = spMeshAttachment_create(name);
attachment->rendererObject = region;
attachment->regionU = region->u;
attachment->regionV = region->v;
attachment->regionU2 = region->u2;
attachment->regionV2 = region->v2;
attachment->regionRotate = region->rotate;
attachment->regionOffsetX = region->offsetX;
attachment->regionOffsetY = region->offsetY;
attachment->regionWidth = region->width;
attachment->regionHeight = region->height;
attachment->regionOriginalWidth = region->originalWidth;
attachment->regionOriginalHeight = region->originalHeight;
newAttchment = SUPER(attachment);
spMeshAttachment* oldMesh = SUB_CAST(spMeshAttachment, oldAttachment);
attachment->verticesCount = oldMesh->verticesCount;
attachment->vertices = oldMesh->vertices;
oldMesh->vertices = 0;
attachment->trianglesCount = oldMesh->trianglesCount;
attachment->triangles = oldMesh->triangles;
oldMesh->triangles = 0;
attachment->regionUVs = oldMesh->regionUVs;
oldMesh->regionUVs = 0;
spMeshAttachment_updateUVs(attachment);
attachment->r = oldMesh->r;
attachment->g = oldMesh->g;
attachment->b = oldMesh->b;
attachment->a = oldMesh->a;
attachment->hullLength = oldMesh->hullLength;
attachment->edgesCount = oldMesh->edgesCount;
attachment->edges = oldMesh->edges;
oldMesh->edges = 0;
attachment->width = oldMesh->width;
attachment->height = oldMesh->height;
break;
}
case SP_ATTACHMENT_SKINNED_MESH:
{
spSkinnedMeshAttachment* attachment;
attachment = spSkinnedMeshAttachment_create(name);
attachment->rendererObject = region;
attachment->regionU = region->u;
attachment->regionV = region->v;
attachment->regionU2 = region->u2;
attachment->regionV2 = region->v2;
attachment->regionRotate = region->rotate;
attachment->regionOffsetX = region->offsetX;
attachment->regionOffsetY = region->offsetY;
attachment->regionWidth = region->width;
attachment->regionHeight = region->height;
attachment->regionOriginalWidth = region->originalWidth;
attachment->regionOriginalHeight = region->originalHeight;
newAttchment = SUPER(attachment);
spSkinnedMeshAttachment* oldMesh = SUB_CAST(spSkinnedMeshAttachment, oldAttachment);
int verticesCount, b, w, nn;
float* vertices;
attachment->uvsCount = oldMesh->uvsCount;
attachment->regionUVs = oldMesh->regionUVs;
oldMesh->regionUVs = 0;
attachment->bonesCount = oldMesh->bonesCount;
attachment->weightsCount = oldMesh->weightsCount;
attachment->bones = oldMesh->bones;
oldMesh->bones = 0;
attachment->weights = oldMesh->weights;
oldMesh->weights = 0;
attachment->trianglesCount = oldMesh->trianglesCount;
attachment->triangles = oldMesh->triangles;
oldMesh->triangles = 0;
spSkinnedMeshAttachment_updateUVs(attachment);
attachment->r = oldMesh->r;
attachment->g = oldMesh->g;
attachment->b = oldMesh->b;
attachment->a = oldMesh->a;
attachment->hullLength = oldMesh->hullLength;
attachment->edges = oldMesh->edges;
oldMesh->edges = 0;
attachment->edgesCount = oldMesh->edgesCount;
attachment->width = oldMesh->width;
attachment->height = oldMesh->height;
break;
}
}
if (newAttchment == nullptr)
return false;
spSkin* skin = _skeleton->skin == nullptr ? _skeleton->data->defaultSkin : _skeleton->skin;
for (int i = 0; i < _skeleton->slotsCount; ++i)
{
spSlot* slot = _skeleton->slots[i];
if (slot->data->attachmentName != nullptr && strcmp(slot->data->attachmentName, attachmentName) == 0)
{
if (attachment2 == nullptr) CONST_CAST(spAttachment*, slot->attachment) = newAttchment;
return spSkin_setAttachment(skin, i, attachment2 == nullptr ? attachmentName : attachment2, newAttchment);
}
}
return false;
}
int spSkin_setAttachment(const spSkin* self, int slotIndex, const char* name, spAttachment* attachment) // 在 skin.c 文件中添加
{
_Entry* entry = SUB_CAST(_spSkin, self)->entries;
while (entry)
{
if (entry->slotIndex == slotIndex && strcmp(entry->name, name) == 0)
{
spAttachment* odlAttachment = entry->attachment;
entry->attachment = attachment;
spAttachment_dispose(odlAttachment);
return 1;
}
entry = entry->next;
}
return 0;
}
2016/07/07 更新,基于版本一修改:
bool SkeletonRenderer::replaceAttachmentImage(const char* slotName, const char* attachmentName, cocos2d::SpriteFrame* frame, const char* attachment2 /* = nullptr*/)
{
spAttachment* oldAttachment = nullptr;
spSkin* skin = _skeleton->skin == nullptr ? _skeleton->data->defaultSkin : _skeleton->skin;
for (int i = 0; i < _skeleton->slotsCount; ++i)
{
spSlot* slot = _skeleton->slots[i];
if (slot->data->attachmentName != nullptr && strcmp(slot->data->attachmentName, attachmentName) == 0)
{
oldAttachment = spSkin_getAttachment(skin, i, attachment2 == nullptr ? attachmentName : attachment2);
}
}
if (oldAttachment == nullptr) return false;
spAttachment* newAttchment = nullptr;
const char* name = oldAttachment->name;
spAtlasPage *page = createNewPage(frame, oldAttachment);
if (page == nullptr) return false;
spAtlasRegion *region = createRegion(page, frame, oldAttachment);
switch (oldAttachment->type)
{
case SP_ATTACHMENT_REGION:
{
spRegionAttachment* oldRegion = SUB_CAST(spRegionAttachment, oldAttachment);
oldRegion->rendererObject = region;
spRegionAttachment_setUVs(oldRegion, region->u, region->v, region->u2, region->v2, region->rotate);
oldRegion->regionOffsetX = region->offsetX;
oldRegion->regionOffsetY = region->offsetY;
oldRegion->regionWidth = region->width;
oldRegion->regionHeight = region->height;
oldRegion->regionOriginalWidth = region->originalWidth;
oldRegion->regionOriginalHeight = region->originalHeight;
spRegionAttachment_updateOffset(oldRegion);
break;
}
case SP_ATTACHMENT_MESH:
{
spMeshAttachment* oldMesh = SUB_CAST(spMeshAttachment, oldAttachment);
oldMesh->rendererObject = region;
oldMesh->regionU = region->u;
oldMesh->regionV = region->v;
oldMesh->regionU2 = region->u2;
oldMesh->regionV2 = region->v2;
oldMesh->regionRotate = region->rotate;
oldMesh->regionOffsetX = region->offsetX;
oldMesh->regionOffsetY = region->offsetY;
oldMesh->regionWidth = region->width;
oldMesh->regionHeight = region->height;
oldMesh->regionOriginalWidth = region->originalWidth;
oldMesh->regionOriginalHeight = region->originalHeight;
spMeshAttachment_updateUVs(oldMesh);
break;
}
case SP_ATTACHMENT_SKINNED_MESH:
{
spSkinnedMeshAttachment* oldMesh = SUB_CAST(spSkinnedMeshAttachment, oldAttachment);
oldMesh->rendererObject = region;
oldMesh->regionU = region->u;
oldMesh->regionV = region->v;
oldMesh->regionU2 = region->u2;
oldMesh->regionV2 = region->v2;
oldMesh->regionRotate = region->rotate;
oldMesh->regionOffsetX = region->offsetX;
oldMesh->regionOffsetY = region->offsetY;
oldMesh->regionWidth = region->width;
oldMesh->regionHeight = region->height;
oldMesh->regionOriginalWidth = region->originalWidth;
oldMesh->regionOriginalHeight = region->originalHeight;
spSkinnedMeshAttachment_updateUVs(oldMesh);
break;
}
}
return false;
}
slotName: 要替换皮肤附件所在slot名字
attachmentName: 要替换皮肤在 slot 上的 附件名字
frame: 要替换皮肤图片的 SpriteFrame,为了能够像spine一样利用合图的优势,这里使用的是SpriteFrame,同一个合图上的 SpriteFrame 会复用一个 spAtlasPage。
attachmentName2: 如果存在那种 slot 下有多个 切换用的 皮肤图片,而在slot下的名字都是同一个,那么就需要 传递这个名字默认为 nullptr
example:
skeletonNode = SkeletonAnimation::createWithFile("spine/alien.json", "spine/alien.atlas", 0.5f); // 此spine动画为spine 自带的 example 那个爆头动画
skeletonNode->replaceAttachmentImage("head", "head", Sprite::create("Images/r1.png")->getSpriteFrame(), "burst01");
skeletonNode->replaceAttachmentImage("head", "head", Sprite::create("Images/r1.png")->getSpriteFrame(), "burst02");
skeletonNode->replaceAttachmentImage("head", "head", Sprite::create("Images/r1.png")->getSpriteFrame());
2016/07/07 更新
bool SkeletonRenderer::replaceAttachmentImage(const char* slotName, const char* attachmentName, cocos2d::SpriteFrame* frame, const char* attachment2 /* = nullptr*/)
{
spAttachment* oldAttachment = nullptr;
spSkin* skin = _skeleton->skin == nullptr ? _skeleton->data->defaultSkin : _skeleton->skin;
for (int i = 0; i < _skeleton->slotsCount; ++i)
{
spSlot* slot = _skeleton->slots[i];
if (slot->data->attachmentName != nullptr && strcmp(slot->data->attachmentName, attachmentName) == 0)
{
oldAttachment = spSkin_getAttachment(skin, i, attachment2 == nullptr ? attachmentName : attachment2);
}
}
if (oldAttachment == nullptr) return false;
spAttachment* newAttchment = nullptr;
const char* name = oldAttachment->name;
spAtlasPage *page = createNewPage(frame, oldAttachment);
if (page == nullptr) return false;
spAtlasRegion *region = createRegion(page, frame, oldAttachment);
switch (oldAttachment->type)
{
case SP_ATTACHMENT_REGION:
{
spRegionAttachment* oldRegion = SUB_CAST(spRegionAttachment, oldAttachment);
oldRegion->rendererObject = region;
spRegionAttachment_setUVs(oldRegion, region->u, region->v, region->u2, region->v2, region->rotate);
oldRegion->regionOffsetX = region->offsetX;
oldRegion->regionOffsetY = region->offsetY;
oldRegion->regionWidth = region->width;
oldRegion->regionHeight = region->height;
oldRegion->regionOriginalWidth = region->originalWidth;
oldRegion->regionOriginalHeight = region->originalHeight;
spRegionAttachment_updateOffset(oldRegion);
break;
}
case SP_ATTACHMENT_MESH:
{
spMeshAttachment* oldMesh = SUB_CAST(spMeshAttachment, oldAttachment);
oldMesh->rendererObject = region;
oldMesh->regionU = region->u;
oldMesh->regionV = region->v;
oldMesh->regionU2 = region->u2;
oldMesh->regionV2 = region->v2;
oldMesh->regionRotate = region->rotate;
oldMesh->regionOffsetX = region->offsetX;
oldMesh->regionOffsetY = region->offsetY;
oldMesh->regionWidth = region->width;
oldMesh->regionHeight = region->height;
oldMesh->regionOriginalWidth = region->originalWidth;
oldMesh->regionOriginalHeight = region->originalHeight;
spMeshAttachment_updateUVs(oldMesh);
break;
}
case SP_ATTACHMENT_SKINNED_MESH:
{
spSkinnedMeshAttachment* oldMesh = SUB_CAST(spSkinnedMeshAttachment, oldAttachment);
oldMesh->rendererObject = region;
oldMesh->regionU = region->u;
oldMesh->regionV = region->v;
oldMesh->regionU2 = region->u2;
oldMesh->regionV2 = region->v2;
oldMesh->regionRotate = region->rotate;
oldMesh->regionOffsetX = region->offsetX;
oldMesh->regionOffsetY = region->offsetY;
oldMesh->regionWidth = region->width;
oldMesh->regionHeight = region->height;
oldMesh->regionOriginalWidth = region->originalWidth;
oldMesh->regionOriginalHeight = region->originalHeight;
spSkinnedMeshAttachment_updateUVs(oldMesh);
break;
}
}
return false;
}
2016/07/08 版本三:
spAtlasRegion* replaceAttachmentImage(const char* slotName, const char* attachmentName, cocos2d::SpriteFrame* frame, const char* attachment2 = nullptr);
spAtlasRegion* replaceAttachmentByRegion(const char* slotName, const char* attachmentName, void* region, const char* attachment2 = nullptr);
private:
spAttachment* getAttachmentFromSlot(const char* slotName, const char* attachmentName, const char* attachment2 = nullptr);
spAtlasRegion* changeAttachment(spAttachment* attachment, spAtlasRegion* region);
static spAtlasPage* createNewPage(cocos2d::SpriteFrame* frame, spAttachment* oldAttachment)
{
spAtlasPage *page = nullptr;
spAtlasRegion* region = nullptr;
switch (oldAttachment->type)
{
case SP_ATTACHMENT_REGION:
{
spRegionAttachment* attachment = SUB_CAST(spRegionAttachment, oldAttachment);
region = SUB_CAST(spAtlasRegion, attachment->rendererObject);
break;
}
case SP_ATTACHMENT_MESH:
{
spMeshAttachment* attachment = SUB_CAST(spMeshAttachment, oldAttachment);
region = SUB_CAST(spAtlasRegion, attachment->rendererObject);
break;
}
case SP_ATTACHMENT_SKINNED_MESH:
{
spSkinnedMeshAttachment* attachment = SUB_CAST(spSkinnedMeshAttachment, oldAttachment);
region = SUB_CAST(spAtlasRegion, attachment->rendererObject);
break;
}
}
if (region == nullptr || region->page == nullptr) return page;
Texture2D* texture = frame->getTexture();
char pageName[20];
itoa((int)texture, pageName, 16);
spAtlasPage *searchPage = region->page->atlas->pages;
spAtlasPage* lastPage = searchPage;
while (searchPage != nullptr)
{
if (strcmp(searchPage->name, pageName) == 0)
{
page = searchPage;
break;
}
searchPage = searchPage->next;
if (searchPage != nullptr)
lastPage = searchPage;
}
if (page != nullptr) return page;
page = spAtlasPage_create(CONST_CAST(spAtlas*, region->page->atlas), pageName);
texture->retain();
page->rendererObject = texture;
page->width = texture->getPixelsWide();
page->height = texture->getPixelsHigh();
lastPage->next = page;
page->format = region->page->format;
page->minFilter = region->page->minFilter;
page->magFilter = region->page->magFilter;
page->uWrap = region->page->uWrap;
page->vWrap = region->page->vWrap;
return page;
}
static spAtlasRegion* createRegion(spAtlasPage *page, cocos2d::SpriteFrame* frame, spAttachment* oldAttachment)
{
const char* name = oldAttachment->name;
Texture2D* texture = frame->getTexture();
spAtlasRegion *region = spAtlasRegion_create();
region->page = page;
MALLOC_STR(region->name, name);
region->rotate = frame->isRotated();
cocos2d::Rect rect = frame->getRectInPixels();
region->x = rect.getMinX();
region->y = rect.getMinY();
region->width = rect.size.width;
region->height = rect.size.height;
cocos2d::Size originSize = frame->getOriginalSizeInPixels();
region->originalWidth = originSize.width;
region->originalHeight = originSize.height;
region->u = region->x / (float)page->width;
region->v = region->y / (float)page->height;
if (region->rotate) {
region->u2 = (region->x + region->height) / (float)page->width;
region->v2 = (region->y + region->width) / (float)page->height;
}
else {
region->u2 = (region->x + region->width) / (float)page->width;
region->v2 = (region->y + region->height) / (float)page->height;
}
cocos2d::Vec2 offset = frame->getOffsetInPixels();
region->offsetX = offset.x;
region->offsetY = offset.y;
region->index = -1;
spAtlasRegion* lastRegion, *nextRegion;
lastRegion = page->atlas->regions;
nextRegion = region->next;
while (nextRegion != nullptr)
{
lastRegion = nextRegion;
nextRegion = nextRegion->next;
}
lastRegion->next = region;
return region;
}
spAttachment* SkeletonRenderer::getAttachmentFromSlot(const char* slotName, const char* attachmentName, const char* attachment2 /*= nullptr*/)
{
spAttachment* attachment = nullptr;
spSkin* skin = _skeleton->skin == nullptr ? _skeleton->data->defaultSkin : _skeleton->skin;
for (int i = 0; i < _skeleton->slotsCount; ++i)
{
spSlot* slot = _skeleton->slots[i];
if (slot->data->attachmentName != nullptr && strcmp(slot->data->attachmentName, attachmentName) == 0)
{
attachment = spSkin_getAttachment(skin, i, attachment2 == nullptr ? attachmentName : attachment2);
}
}
return attachment;
}
spAtlasRegion* SkeletonRenderer::changeAttachment(spAttachment* oldAttachment, spAtlasRegion* region)
{
spAtlasRegion* oldRegion = nullptr;
if (oldAttachment == nullptr || region == nullptr) return oldRegion;
switch (oldAttachment->type)
{
case SP_ATTACHMENT_REGION:
{
spRegionAttachment* oldRegionAttachment = SUB_CAST(spRegionAttachment, oldAttachment);
oldRegion = (spAtlasRegion*)oldRegionAttachment->rendererObject;
oldRegionAttachment->rendererObject = region;
spRegionAttachment_setUVs(oldRegionAttachment, region->u, region->v, region->u2, region->v2, region->rotate);
oldRegionAttachment->regionOffsetX = region->offsetX;
oldRegionAttachment->regionOffsetY = region->offsetY;
oldRegionAttachment->regionWidth = region->width;
oldRegionAttachment->regionHeight = region->height;
oldRegionAttachment->regionOriginalWidth = region->originalWidth;
oldRegionAttachment->regionOriginalHeight = region->originalHeight;
spRegionAttachment_updateOffset(oldRegionAttachment);
break;
}
case SP_ATTACHMENT_MESH:
{
spMeshAttachment* oldMesh = SUB_CAST(spMeshAttachment, oldAttachment);
oldRegion = (spAtlasRegion*)oldMesh->rendererObject;
oldMesh->rendererObject = region;
oldMesh->regionU = region->u;
oldMesh->regionV = region->v;
oldMesh->regionU2 = region->u2;
oldMesh->regionV2 = region->v2;
oldMesh->regionRotate = region->rotate;
oldMesh->regionOffsetX = region->offsetX;
oldMesh->regionOffsetY = region->offsetY;
oldMesh->regionWidth = region->width;
oldMesh->regionHeight = region->height;
oldMesh->regionOriginalWidth = region->originalWidth;
oldMesh->regionOriginalHeight = region->originalHeight;
spMeshAttachment_updateUVs(oldMesh);
break;
}
case SP_ATTACHMENT_SKINNED_MESH:
{
spSkinnedMeshAttachment* oldMesh = SUB_CAST(spSkinnedMeshAttachment, oldAttachment);
oldRegion = (spAtlasRegion*)oldMesh->rendererObject;
oldMesh->rendererObject = region;
oldMesh->regionU = region->u;
oldMesh->regionV = region->v;
oldMesh->regionU2 = region->u2;
oldMesh->regionV2 = region->v2;
oldMesh->regionRotate = region->rotate;
oldMesh->regionOffsetX = region->offsetX;
oldMesh->regionOffsetY = region->offsetY;
oldMesh->regionWidth = region->width;
oldMesh->regionHeight = region->height;
oldMesh->regionOriginalWidth = region->originalWidth;
oldMesh->regionOriginalHeight = region->originalHeight;
spSkinnedMeshAttachment_updateUVs(oldMesh);
break;
}
}
return oldRegion;
}
spAtlasRegion* SkeletonRenderer::replaceAttachmentImage(const char* slotName, const char* attachmentName, cocos2d::SpriteFrame* frame, const char* attachment2 /* = nullptr*/)
{
spAttachment* oldAttachment = getAttachmentFromSlot(slotName, attachmentName, attachment2);
if (oldAttachment == nullptr) return false;
spAttachment* newAttchment = nullptr;
const char* name = oldAttachment->name;
spAtlasPage *page = createNewPage(frame, oldAttachment);
if (page == nullptr) return false;
spAtlasRegion *region = createRegion(page, frame, oldAttachment);
return replaceAttachmentByRegion(slotName, attachmentName, region, attachment2);
}
spAtlasRegion* SkeletonRenderer::replaceAttachmentByRegion(const char* slotName, const char* attachmentName, void* region, const char* attachment2 /* = nullptr */)
{
return changeAttachment(getAttachmentFromSlot(slotName, attachmentName, attachment2), (spAtlasRegion*)region);
}