[cocos2d-x] Spine 组件所有特性原生平台适配

This commit is contained in:
SmallMain 2022-07-05 11:05:41 +08:00
parent f4599764fe
commit 3b1584ee1c
25 changed files with 1801 additions and 312 deletions

View File

@ -38,11 +38,10 @@ MeshBuffer::MeshBuffer(int vertexFormat)
}
MeshBuffer::MeshBuffer(int vertexFormat, size_t indexSize, size_t vertexSize)
: _vertexFormat(vertexFormat)
, _ib(indexSize)
, _vb(vertexSize * vertexFormat * sizeof(float))
{
_vb.setMaxSize(MAX_VERTEX_BUFFER_SIZE * _vertexFormat * sizeof(float));
: _vertexFormat(vertexFormat),
_ib(indexSize),
_vb(vertexSize * (vertexFormat == 7 ? 6 : (vertexFormat == 8 ? 7 : vertexFormat)) * sizeof(float)) {
_vb.setMaxSize(MAX_VERTEX_BUFFER_SIZE * (vertexFormat == 7 ? 6 : (vertexFormat == 8 ? 7 : vertexFormat)) * sizeof(float));
_ib.setMaxSize(INIT_INDEX_BUFFER_SIZE);
_vb.setFullCallback([this]
{
@ -66,6 +65,12 @@ MeshBuffer::MeshBuffer(int vertexFormat, size_t indexSize, size_t vertexSize)
case VF_XYUVCC:
glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Two_Color, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Two_Color->getBytes());
break;
case VF_XYUVCT:
glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Color_TexId, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Color_TexId->getBytes());
break;
case VF_XYUVCCT:
glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Two_Color_TexId, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Two_Color_TexId->getBytes());
break;
default:
CCASSERT(false, "MeshBuffer constructor unknow vertex format");
break;
@ -126,6 +131,12 @@ void MeshBuffer::next()
case VF_XYUVCC:
glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Two_Color, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Two_Color->getBytes());
break;
case VF_XYUVCT:
glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Color_TexId, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Color_TexId->getBytes());
break;
case VF_XYUVCCT:
glVB->init(DeviceGraphics::getInstance(), VertexFormat::XY_UV_Two_Color_TexId, Usage::DYNAMIC, nullptr, 0, (uint32_t)_vb.getCapacity() / VertexFormat::XY_UV_Two_Color_TexId->getBytes());
break;
default:
CCASSERT(false, "MeshBuffer constructor unknow vertex format");
break;

View File

@ -46,3 +46,6 @@
#define VF_XYUVC 5
#define VF_XYUVCC 6
#define VF_XYUVCT 7
#define VF_XYUVCCT 8

View File

@ -72,6 +72,45 @@ struct V2F_T2F_C4B_C4B
cocos2d::Color4B color2; // 4 bytes
};
/**
* Vertex Format with x y u v color texId.
*/
struct V2F_T2F_C4B_T1F
{
// vertices (2F)
cocos2d::Vec2 vertex; // 8 bytes
// tex coords (2F)
Tex2F texCoord; // 8 bytes
// colors (4B)
cocos2d::Color4B color; // 4 bytes
// tex id (1F)
GLfloat texId; // 4 bytes
};
/**
* Vertex Format with x y u v color1 color2 texId.
*/
struct V2F_T2F_C4B_C4B_T1F
{
// vertices (2F)
cocos2d::Vec2 vertex; // 8 bytes
// tex coords (2F)
Tex2F texCoord; // 8 bytes
// colors (4B)
cocos2d::Color4B color; // 4 bytes
// colors (4B)
cocos2d::Color4B color2; // 4 bytes
// tex id (1F)
GLfloat texId; // 4 bytes
};
struct Triangles
{
/**Vertex data pointer.*/
@ -96,6 +135,30 @@ struct TwoColorTriangles
int indexCount = 0;
};
struct TrianglesTexId
{
/**Vertex data pointer.*/
V2F_T2F_C4B_T1F* verts = nullptr;
/**Index data pointer.*/
unsigned short* indices = nullptr;
/**The number of vertices.*/
int vertCount = 0;
/**The number of indices.*/
int indexCount = 0;
};
struct TwoColorTrianglesTexId
{
/**Vertex data pointer.*/
V2F_T2F_C4B_C4B_T1F* verts = nullptr;
/**Index data pointer.*/
unsigned short* indices = nullptr;
/**The number of vertices.*/
int vertCount = 0;
/**The number of indices.*/
int indexCount = 0;
};
///////////////////////////////////////////////////////////////////////
// adapt to editor texture,this is a texture delegate,not real texture
///////////////////////////////////////////////////////////////////////

View File

@ -53,6 +53,30 @@ namespace spine {
cocos2d::middleware::Texture2D* _texture = nullptr;
};
struct TextureMultiData {
TextureMultiData(float textureId, int vertexFloatCount,
int indexOffset,
cocos2d::renderer::Texture* texture)
: textureId(textureId),
vertexFloatCount(vertexFloatCount),
indexOffset(indexOffset),
texture(texture){};
int vertexFloatCount = 0;
int indexOffset = 0;
float textureId = -1;
cocos2d::renderer::Texture* texture = nullptr;
};
struct SegmentMultiData {
public:
int indexCount = 0;
int vertexFloatCount = 0;
int blendMode = 0;
bool inEffect = false;
std::vector<TextureMultiData> textureDatas;
};
struct BoneData {
cocos2d::Mat4 globalTransformMatrix;
};

View File

@ -35,12 +35,17 @@
#include "renderer/scene/assembler/CustomAssembler.hpp"
#include "renderer/gfx/Texture.h"
#include "spine-creator-support/AttachUtil.h"
#include <climits>
USING_NS_CC;
USING_NS_MW;
using namespace cocos2d::renderer;
static const std::string techStage = "opaque";
static const std::string textureKey = "texture";
static const std::vector<std::string> textureKeys = {
"texture", "texture2", "texture3", "texture4",
"texture5", "texture6", "texture7", "texture8",
};
namespace spine {
@ -139,7 +144,75 @@ namespace spine {
_curFrameIndex = frameIdx;
}
std::vector<spine::SkeletonCache::SegmentMultiData>
SkeletonCacheAnimation::toMultiSegments(
const std::vector<spine::SkeletonCache::SegmentData*>& segments){
std::vector<spine::SkeletonCache::SegmentMultiData> multiSegments;
if (segments.size() <= 0) return multiSegments;
auto end = segments.end();
auto cur = segments.begin();
multiSegments.emplace_back();
auto* tmp = &multiSegments.back();
auto getTextureId = [&]() -> float {
auto glID = (*cur)->getTexture()->getNativeTexture()->getHandle();
auto result = _effectTextures.find(glID);
if (result == _effectTextures.end()) {
for (size_t i = 0; i < textureKeys.size(); i++) {
auto prop = _effect->getProperty(textureKeys[i]);
if (prop->getTexture()->getHandle() == glID) {
_effectTextures.insert(std::make_pair(glID, i));
return i;
}
}
_effectTextures.insert(std::make_pair(glID, -1));
return -1;
} else {
return result->second;
}
};
tmp->blendMode = (*cur)->blendMode;
tmp->indexCount = (*cur)->indexCount;
tmp->vertexFloatCount = (*cur)->vertexFloatCount;
float curTextureId = getTextureId();
tmp->textureDatas.emplace_back(curTextureId, (*cur)->vertexFloatCount, 0, (*cur)->getTexture()->getNativeTexture());
tmp->inEffect = curTextureId != -1;
cur++;
while (cur != end)
{
float curTextureId = getTextureId();
float tmpTextureId = tmp->textureDatas[0].textureId;
if ((*cur)->blendMode != tmp->blendMode ||
(tmpTextureId != -1 && curTextureId == -1) ||
tmpTextureId == -1) {
multiSegments.emplace_back();
tmp = &multiSegments.back();
tmp->blendMode = (*cur)->blendMode;
tmp->indexCount = (*cur)->indexCount;
tmp->vertexFloatCount = (*cur)->vertexFloatCount;
tmp->textureDatas.emplace_back(curTextureId, (*cur)->vertexFloatCount, 0, (*cur)->getTexture()->getNativeTexture());
tmp->inEffect = curTextureId != -1;
} else {
tmp->textureDatas.emplace_back(curTextureId, (*cur)->vertexFloatCount, tmp->indexCount, (*cur)->getTexture()->getNativeTexture());
tmp->indexCount += (*cur)->indexCount;
tmp->vertexFloatCount += (*cur)->vertexFloatCount;
}
cur++;
}
return multiSegments;
}
void SkeletonCacheAnimation::render(float dt) {
if (_useMulti) {
renderMulti(dt);
return;
}
if (!_nodeProxy || !_effect) {
return;
@ -378,6 +451,289 @@ namespace spine {
}
}
void SkeletonCacheAnimation::renderMulti(float dt) {
if (!_nodeProxy || !_effect) {
return;
}
CustomAssembler* assembler = (CustomAssembler*)_nodeProxy->getAssembler();
if (assembler == nullptr) {
return;
}
assembler->reset();
assembler->setUseModel(!_batch);
if (!_animationData) return;
SkeletonCache::FrameData* frameData = _animationData->getFrameData(_curFrameIndex);
if (!frameData) return;
auto& tmpSegments = frameData->getSegments();
auto& colors = frameData->getColors();
if (tmpSegments.size() == 0 || colors.size() == 0) return;
auto mgr = MiddlewareManager::getInstance();
if (!mgr->isRendering) return;
_nodeColor.a = _nodeProxy->getRealOpacity() / (float)255;
auto vertexFormat = _useTint ? VF_XYUVCCT : VF_XYUVCT;
middleware::MeshBuffer* mb = mgr->getMeshBuffer(vertexFormat);
middleware::IOBuffer& vb = mb->getVB();
middleware::IOBuffer& ib = mb->getIB();
const auto& srcVB = frameData->vb;
const auto& srcIB = frameData->ib;
// vertex size int bytes with one color
int vbs1 = sizeof(V2F_T2F_C4B_T1F);
// vertex size in floats with one color
int vs1 = vbs1 / sizeof(float);
// vertex size int bytes with two color
int vbs2 = sizeof(V2F_T2F_C4B_C4B_T1F);
// vertex size in floats with two color
int vs2 = vbs2 / sizeof(float);
int vbs3 = sizeof(V2F_T2F_C4B);
int vs3 = vbs3 / sizeof(float);
int vbs4 = sizeof(V2F_T2F_C4B_C4B);
int vs4 = vbs4 / sizeof(float);
int vs = _useTint ? vs2 : vs1;
int vbs = _useTint ? vbs2 : vbs1;
const cocos2d::Mat4& nodeWorldMat = _nodeProxy->getWorldMatrix();
int colorOffset = 0;
SkeletonCache::ColorData* nowColor = colors[colorOffset++];
auto maxVFOffset = nowColor->vertexFloatOffset;
Color4B finalColor;
Color4B darkColor;
float tempR = 0.0f, tempG = 0.0f, tempB = 0.0f, tempA = 0.0f;
float multiplier = 1.0f;
int srcVertexBytesOffset = 0;
int srcVertexBytes = 0;
int vertexBytes = 0;
int vertexFloats = 0;
int tintBytes = 0;
int srcIndexBytesOffset = 0;
int indexBytes = 0;
GLuint textureHandle = 0;
double effectHash = 0;
int blendMode = 0;
int dstVertexOffset = 0;
float* dstVertexBuffer = nullptr;
unsigned int* dstColorBuffer = nullptr;
unsigned short* dstIndexBuffer = nullptr;
bool needColor = false;
BlendFactor curBlendSrc = BlendFactor::ONE;
BlendFactor curBlendDst = BlendFactor::ZERO;
if (abs(_nodeColor.r - 1.0f) > 0.0001f ||
abs(_nodeColor.g - 1.0f) > 0.0001f ||
abs(_nodeColor.b - 1.0f) > 0.0001f ||
abs(_nodeColor.a - 1.0f) > 0.0001f ||
_premultipliedAlpha) {
needColor = true;
}
auto handleColor = [&](SkeletonCache::ColorData* colorData){
tempA = colorData->finalColor.a * _nodeColor.a;
multiplier = _premultipliedAlpha ? tempA / 255 : 1;
tempR = _nodeColor.r * multiplier;
tempG = _nodeColor.g * multiplier;
tempB = _nodeColor.b * multiplier;
finalColor.a = (GLubyte)tempA;
finalColor.r = (GLubyte)(colorData->finalColor.r * tempR);
finalColor.g = (GLubyte)(colorData->finalColor.g * tempG);
finalColor.b = (GLubyte)(colorData->finalColor.b * tempB);
darkColor.r = (GLubyte)(colorData->darkColor.r * tempR);
darkColor.g = (GLubyte)(colorData->darkColor.g * tempG);
darkColor.b = (GLubyte)(colorData->darkColor.b * tempB);
darkColor.a = _premultipliedAlpha ? 255 : 0;
};
handleColor(nowColor);
// 重新生成多纹理使用的 segments
auto segments = toMultiSegments(tmpSegments);
for (std::size_t segIndex = 0, segLen = segments.size(); segIndex < segLen; segIndex++) {
auto segment = &segments[segIndex];
srcVertexBytes = segment->vertexFloatCount * sizeof(float);
if (!_useTint) {
vertexBytes = srcVertexBytes;
vertexFloats = segment->vertexFloatCount;
} else {
tintBytes = segment->vertexFloatCount / vs4 * sizeof(float);
vertexBytes = srcVertexBytes + tintBytes;
vertexFloats = vertexBytes / sizeof(float);
}
// fill vertex buffer
vb.checkSpace(vertexBytes, true);
dstVertexOffset = (int)vb.getCurPos() / vbs;
dstVertexBuffer = (float*)vb.getCurBuffer();
dstColorBuffer = (unsigned int*)vb.getCurBuffer();
char* srcBuffer = (char*)srcVB.getBuffer() + srcVertexBytesOffset;
auto curTextureData = segment->textureDatas.begin();
auto curTextureDataVfc = (*curTextureData).vertexFloatCount * sizeof(float);
if (!_useTint) {
int t = 0;
for (std::size_t srcBufferIdx = 0; srcBufferIdx < srcVertexBytes; srcBufferIdx += vbs4) {
if (curTextureDataVfc <= srcBufferIdx) {
curTextureData++;
curTextureDataVfc += (*curTextureData).vertexFloatCount * sizeof(float);
}
vb.writeBytes(srcBuffer + srcBufferIdx, vbs3);
vb.writeFloat32((*curTextureData).textureId);
}
} else {
for (std::size_t srcBufferIdx = 0; srcBufferIdx < srcVertexBytes; srcBufferIdx += vbs4) {
if (curTextureDataVfc <= srcBufferIdx) {
curTextureData++;
curTextureDataVfc += (*curTextureData).vertexFloatCount * sizeof(float);
}
vb.writeBytes(srcBuffer + srcBufferIdx, vbs4);
vb.writeFloat32((*curTextureData).textureId);
}
}
// batch handle
if (_batch) {
cocos2d::Vec3* point = nullptr;
float tempZ = 0.0f;
for (auto posIndex = 0; posIndex < vertexFloats; posIndex += vs)
{
point = (cocos2d::Vec3*)(dstVertexBuffer + posIndex);
tempZ = point->z;
point->z = 0;
nodeWorldMat.transformPoint(point);
point->z = tempZ;
}
}
// handle vertex color
if (needColor) {
int srcVertexFloatOffset = srcVertexBytesOffset / sizeof(float);
if (_useTint) {
for (auto colorIndex = 0; colorIndex < vertexFloats; colorIndex += vs, srcVertexFloatOffset += vs4)
{
if (srcVertexFloatOffset >= maxVFOffset) {
nowColor = colors[colorOffset++];
handleColor(nowColor);
maxVFOffset = nowColor->vertexFloatOffset;
}
memcpy(dstColorBuffer + colorIndex + 4, &finalColor, sizeof(finalColor));
memcpy(dstColorBuffer + colorIndex + 5, &darkColor, sizeof(darkColor));
}
} else {
for (auto colorIndex = 0; colorIndex < vertexFloats; colorIndex += vs, srcVertexFloatOffset += vs4)
{
if (srcVertexFloatOffset >= maxVFOffset) {
nowColor = colors[colorOffset++];
handleColor(nowColor);
maxVFOffset = nowColor->vertexFloatOffset;
}
memcpy(dstColorBuffer + colorIndex + 4, &finalColor, sizeof(finalColor));
}
}
}
// move src vertex buffer offset
srcVertexBytesOffset += srcVertexBytes;
// fill index buffer
indexBytes = segment->indexCount * sizeof(unsigned short);
ib.checkSpace(indexBytes, true);
assembler->updateIARange(segIndex, (int)ib.getCurPos() / sizeof(unsigned short), segment->indexCount);
dstIndexBuffer = (unsigned short*)ib.getCurBuffer();
ib.writeBytes((char*)srcIB.getBuffer() + srcIndexBytesOffset, indexBytes);
curTextureData = ++segment->textureDatas.begin();
curTextureDataVfc = 0;
auto leftTextureData = segment->textureDatas.begin();
auto curTextureDataIo = curTextureData == segment->textureDatas.end() ? INT_MAX : (*curTextureData).indexOffset;
for (auto indexPos = 0; indexPos < segment->indexCount; indexPos++) {
if (curTextureDataIo <= indexPos) {
curTextureDataVfc += (*leftTextureData).vertexFloatCount / vs4;
leftTextureData = curTextureData;
curTextureData++;
curTextureDataIo = curTextureData == segment->textureDatas.end() ? INT_MAX : (*curTextureData).indexOffset;
}
dstIndexBuffer[indexPos] += dstVertexOffset + curTextureDataVfc;
}
srcIndexBytesOffset += indexBytes;
// set assembler glvb and glib
assembler->updateIABuffer(segIndex, mb->getGLVB(), mb->getGLIB());
// handle material
blendMode = segment->blendMode;
effectHash =
segment->inEffect
? ((blendMode << 16) + ((int)_useTint << 24) +
((int)_batch << 25) + ((int)_effect->getHash() << 26))
: (segment->textureDatas[0].texture->getHandle() + (blendMode << 16) + ((int)_useTint << 24) +
((int)_batch << 25) + ((int)_effect->getHash() << 26));
EffectVariant* renderEffect = assembler->getEffect(segIndex);
bool needUpdate = false;
if (renderEffect) {
double renderHash = renderEffect->getHash();
if (abs(renderHash - effectHash) >= 0.01) {
needUpdate = true;
}
}
else {
auto effect = new cocos2d::renderer::EffectVariant();
effect->autorelease();
effect->copy(_effect);
assembler->updateEffect(segIndex, effect);
renderEffect = effect;
needUpdate = true;
}
if (needUpdate) {
if (!segment->inEffect) {
renderEffect->setProperty(textureKey, segment->textureDatas[0].texture);
}
switch (blendMode) {
case BlendMode_Additive:
curBlendSrc = _premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA;
curBlendDst = BlendFactor::ONE;
break;
case BlendMode_Multiply:
curBlendSrc = BlendFactor::DST_COLOR;
curBlendDst = BlendFactor::ONE_MINUS_SRC_ALPHA;
break;
case BlendMode_Screen:
curBlendSrc = BlendFactor::ONE;
curBlendDst = BlendFactor::ONE_MINUS_SRC_COLOR;
break;
default:
curBlendSrc = _premultipliedAlpha ? BlendFactor::ONE : BlendFactor::SRC_ALPHA;
curBlendDst = BlendFactor::ONE_MINUS_SRC_ALPHA;
}
renderEffect->setBlend(true, BlendOp::ADD, curBlendSrc, curBlendDst,
BlendOp::ADD, curBlendSrc, curBlendDst);
}
renderEffect->updateHash(effectHash);
}
if (_attachUtil)
{
_attachUtil->syncAttachedNode(_nodeProxy, frameData);
}
}
Skeleton* SkeletonCacheAnimation::getSkeleton() const {
return _skeletonCache->getSkeleton();
}
@ -467,6 +823,10 @@ namespace spine {
_useTint = enabled;
}
void SkeletonCacheAnimation::setUseMulti(bool enabled) {
_useMulti = enabled;
}
void SkeletonCacheAnimation::setAnimation (const std::string& name, bool loop) {
_playTimes = loop ? 0 : 1;
_animationName = name;
@ -524,6 +884,7 @@ namespace spine {
}
void SkeletonCacheAnimation::setEffect(cocos2d::renderer::EffectVariant* effect) {
_effectTextures.clear();
if (effect == _effect) return;
CC_SAFE_RELEASE(_effect);
_effect = effect;

View File

@ -48,6 +48,10 @@ namespace spine {
virtual void render(float dt) override;
virtual uint32_t getRenderOrder() const override;
void renderMulti(float dt);
std::vector<spine::SkeletonCache::SegmentMultiData> toMultiSegments(
const std::vector<spine::SkeletonCache::SegmentData*>& segments);
Skeleton* getSkeleton() const;
void setTimeScale (float scale);
@ -78,6 +82,7 @@ namespace spine {
void onEnable();
void onDisable();
void setUseTint(bool enabled);
void setUseMulti(bool enabled);
void setAnimation (const std::string& name, bool loop);
void addAnimation (const std::string& name, bool loop, float delay = 0);
@ -118,6 +123,7 @@ namespace spine {
bool _isAniComplete = true;
std::string _animationName = "";
bool _useTint = false;
bool _useMulti = false;
struct AniQueueData {
std::string animationName = "";
@ -127,5 +133,7 @@ namespace spine {
std::queue<AniQueueData*> _animationQueue;
AniQueueData* _headAnimation = nullptr;
CacheModeAttachUtil* _attachUtil = nullptr;
std::unordered_map<GLuint, float> _effectTextures = std::unordered_map<GLuint, float>();
};
}

View File

@ -39,6 +39,7 @@
#include "SkeletonDataMgr.h"
#include "renderer/gfx/Texture.h"
#include "spine-creator-support/AttachUtil.h"
#include <utility>
USING_NS_CC;
USING_NS_MW;
@ -51,6 +52,10 @@ using namespace cocos2d::renderer;
static const std::string techStage = "opaque";
static const std::string textureKey = "texture";
static const std::vector<std::string> textureKeys = {
"texture", "texture2", "texture3", "texture4",
"texture5", "texture6", "texture7", "texture8",
};
static Cocos2dTextureLoader textureLoader;
@ -286,17 +291,17 @@ void SkeletonRenderer::render (float deltaTime) {
Color4F darkColor;
AttachmentVertices* attachmentVertices = nullptr;
bool inRange = _startSlotIndex != -1 || _endSlotIndex != -1 ? false : true;
auto vertexFormat = _useTint? VF_XYUVCC : VF_XYUVC;
auto vertexFormat = _useMulti ? (_useTint ? VF_XYUVCCT : VF_XYUVCT) : (_useTint? VF_XYUVCC : VF_XYUVC);
middleware::MeshBuffer* mb = mgr->getMeshBuffer(vertexFormat);
middleware::IOBuffer& vb = mb->getVB();
middleware::IOBuffer& ib = mb->getIB();
// vertex size int bytes with one color
int vbs1 = sizeof(V2F_T2F_C4B);
int vbs1 = _useMulti ? sizeof(V2F_T2F_C4B_T1F) : sizeof(V2F_T2F_C4B);
// vertex size in floats with one color
int vs1 = vbs1 / sizeof(float);
// vertex size int bytes with two color
int vbs2 = sizeof(V2F_T2F_C4B_C4B);
int vbs2 = _useMulti ? sizeof(V2F_T2F_C4B_C4B_T1F) :sizeof(V2F_T2F_C4B_C4B);
// verex size in floats with two color
int vs2 = vbs2 / sizeof(float);
const cocos2d::Mat4& nodeWorldMat = _nodeProxy->getWorldMatrix();
@ -311,6 +316,9 @@ void SkeletonRenderer::render (float deltaTime) {
GLuint preTextureIndex = -1;
GLuint curTextureIndex = -1;
float curTextureId = -1;
bool texInEffect = false;
int preISegWritePos = -1;
int curISegLen = 0;
@ -354,7 +362,13 @@ void SkeletonRenderer::render (float deltaTime) {
curBlendDst = BlendFactor::ONE_MINUS_SRC_ALPHA;
}
double curHash = curTextureIndex + (curBlendMode << 16) + ((int)_useTint << 24) + ((int)_batch << 25) + ((int)_effect->getHash() << 26);
double curHash =
(_useMulti && texInEffect)
? ((curBlendMode << 16) + ((int)_useTint << 24) +
((int)_batch << 25) + ((int)_effect->getHash() << 26))
: (curTextureIndex + (curBlendMode << 16) +
((int)_useTint << 24) + ((int)_batch << 25) +
((int)_effect->getHash() << 26));
EffectVariant* renderEffect = assembler->getEffect(materialLen);
bool needUpdate = false;
if (renderEffect) {
@ -374,7 +388,10 @@ void SkeletonRenderer::render (float deltaTime) {
}
if (needUpdate) {
renderEffect->setProperty(textureKey, texture->getNativeTexture());
if (!_useMulti || !texInEffect) {
renderEffect->setProperty(textureKey,
texture->getNativeTexture());
}
renderEffect->setBlend(true, BlendOp::ADD, curBlendSrc, curBlendDst,
BlendOp::ADD, curBlendSrc, curBlendDst);
}
@ -439,6 +456,8 @@ void SkeletonRenderer::render (float deltaTime) {
Triangles triangles;
TwoColorTriangles trianglesTwoColor;
TrianglesTexId trianglesTexId;
TwoColorTrianglesTexId trianglesTwoColorTexId;
if (slot->getAttachment()->getRTTI().isExactly(RegionAttachment::rtti)) {
RegionAttachment* attachment = (RegionAttachment*)slot->getAttachment();
@ -450,6 +469,7 @@ void SkeletonRenderer::render (float deltaTime) {
continue;
}
if (!_useMulti) {
if (!_useTint) {
triangles.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B);
@ -479,6 +499,39 @@ void SkeletonRenderer::render (float deltaTime) {
trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize);
}
} else {
if (!_useTint) {
trianglesTexId.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = trianglesTexId.vertCount * sizeof(V2F_T2F_C4B_T1F);
isFull |= vb.checkSpace(vbSize, true);
trianglesTexId.verts = (V2F_T2F_C4B_T1F*)vb.getCurBuffer();
for (int ii = 0; ii < trianglesTexId.vertCount; ii++) {
trianglesTexId.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
}
attachment->computeWorldVertices(slot->getBone(), (float*)trianglesTexId.verts, 0, vs1);
trianglesTexId.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = trianglesTexId.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
trianglesTexId.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTexId.indices, attachmentVertices->_triangles->indices, ibSize);
} else {
trianglesTwoColorTexId.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = trianglesTwoColorTexId.vertCount * sizeof(V2F_T2F_C4B_C4B_T1F);
isFull |= vb.checkSpace(vbSize, true);
trianglesTwoColorTexId.verts = (V2F_T2F_C4B_C4B_T1F*)vb.getCurBuffer();
for (int ii = 0; ii < trianglesTwoColorTexId.vertCount; ii++) {
trianglesTwoColorTexId.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
}
attachment->computeWorldVertices(slot->getBone(), (float*)trianglesTwoColorTexId.verts, 0, vs2);
trianglesTwoColorTexId.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = trianglesTwoColorTexId.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
trianglesTwoColorTexId.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColorTexId.indices, attachmentVertices->_triangles->indices, ibSize);
}
}
color.r = attachment->getColor().r;
color.g = attachment->getColor().g;
@ -488,7 +541,11 @@ void SkeletonRenderer::render (float deltaTime) {
if(_debugSlots) {
_debugBuffer->writeFloat32(DebugType::Slots);
_debugBuffer->writeFloat32(8);
float* vertices = _useTint ? (float*)trianglesTwoColor.verts : (float*)triangles.verts;
float* vertices =
_useMulti ? (_useTint ? (float*)trianglesTwoColorTexId.verts
: (float*)trianglesTexId.verts)
: (_useTint ? (float*)trianglesTwoColor.verts
: (float*)triangles.verts);
int stride = _useTint ? vs2 : vs1;
// Quadrangle has 4 vertex.
for (int ii = 0; ii < 4; ii ++) {
@ -507,6 +564,7 @@ void SkeletonRenderer::render (float deltaTime) {
continue;
}
if (!_useMulti) {
if (!_useTint) {
triangles.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = triangles.vertCount * sizeof(V2F_T2F_C4B);
@ -536,6 +594,39 @@ void SkeletonRenderer::render (float deltaTime) {
trianglesTwoColor.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColor.indices, attachmentVertices->_triangles->indices, ibSize);
}
} else {
if (!_useTint) {
trianglesTexId.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = trianglesTexId.vertCount * sizeof(V2F_T2F_C4B_T1F);
isFull |= vb.checkSpace(vbSize, true);
trianglesTexId.verts = (V2F_T2F_C4B_T1F*)vb.getCurBuffer();
for (int ii = 0; ii < trianglesTexId.vertCount; ii++) {
trianglesTexId.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
}
attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)trianglesTexId.verts, 0, vs1);
trianglesTexId.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = trianglesTexId.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
trianglesTexId.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTexId.indices, attachmentVertices->_triangles->indices, ibSize);
} else {
trianglesTwoColorTexId.vertCount = attachmentVertices->_triangles->vertCount;
vbSize = trianglesTwoColorTexId.vertCount * sizeof(V2F_T2F_C4B_C4B_T1F);
isFull |= vb.checkSpace(vbSize, true);
trianglesTwoColorTexId.verts = (V2F_T2F_C4B_C4B_T1F*)vb.getCurBuffer();
for (int ii = 0; ii < trianglesTwoColorTexId.vertCount; ii++) {
trianglesTwoColorTexId.verts[ii].texCoord = attachmentVertices->_triangles->verts[ii].texCoord;
}
attachment->computeWorldVertices(*slot, 0, attachment->getWorldVerticesLength(), (float*)trianglesTwoColorTexId.verts, 0, vs2);
trianglesTwoColorTexId.indexCount = attachmentVertices->_triangles->indexCount;
ibSize = trianglesTwoColorTexId.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
trianglesTwoColorTexId.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColorTexId.indices, attachmentVertices->_triangles->indices, ibSize);
}
}
color.r = attachment->getColor().r;
color.g = attachment->getColor().g;
@ -543,9 +634,22 @@ void SkeletonRenderer::render (float deltaTime) {
color.a = attachment->getColor().a;
if(_debugMesh) {
int indexCount = _useTint ? trianglesTwoColor.indexCount : triangles.indexCount;
unsigned short* indices = _useTint ? (unsigned short*)trianglesTwoColor.indices : (unsigned short*)triangles.indices;
float* vertices = _useTint ? (float*)trianglesTwoColor.verts : (float*)triangles.verts;
int indexCount =
_useMulti ? (_useTint ? trianglesTwoColorTexId.indexCount
: trianglesTexId.indexCount)
: (_useTint ? trianglesTwoColor.indexCount
: triangles.indexCount);
unsigned short* indices =
_useMulti
? (_useTint ? (unsigned short*)trianglesTwoColorTexId.indices
: (unsigned short*)trianglesTexId.indices)
: (_useTint ? (unsigned short*)trianglesTwoColor.indices
: (unsigned short*)triangles.indices);
float* vertices =
_useMulti ? (_useTint ? (float*)trianglesTwoColorTexId.verts
: (float*)trianglesTexId.verts)
: (_useTint ? (float*)trianglesTwoColor.verts
: (float*)triangles.verts);
int stride = _useTint ? vs2 : vs1;
_debugBuffer->writeFloat32(DebugType::Mesh);
@ -599,6 +703,7 @@ void SkeletonRenderer::render (float deltaTime) {
}
darkColor.a = _premultipliedAlpha ? 255 : 0;
if (!_useMulti) {
// One color tint logic
if (!_useTint) {
// Cliping logic
@ -802,11 +907,261 @@ void SkeletonRenderer::render (float deltaTime) {
}
texture = attachmentVertices->_texture;
curTextureIndex = attachmentVertices->_texture->getNativeTexture()->getHandle();
curTextureIndex =
attachmentVertices->_texture->getNativeTexture()->getHandle();
// If texture or blendMode change,will change material.
if (preTextureIndex != curTextureIndex || preBlendMode != slot->getData().getBlendMode() || isFull) {
if (preTextureIndex != curTextureIndex ||
preBlendMode != slot->getData().getBlendMode() || isFull) {
flush();
}
}
else {
texture = attachmentVertices->_texture;
curTextureIndex = attachmentVertices->_texture->getNativeTexture()->getHandle();
auto result = _effectTextures.find(curTextureIndex);
if (result == _effectTextures.end()) {
curTextureId = -1;
for (size_t i = 0; i < textureKeys.size(); i++) {
auto prop = _effect->getProperty(textureKeys[i]);
if (prop->getTexture()->getHandle() == curTextureIndex) {
curTextureId = i;
break;
}
}
_effectTextures.insert(std::make_pair(
curTextureIndex, curTextureId));
} else {
curTextureId = result->second;
}
if (curTextureId == -1) {
curTextureId = 0;
texInEffect = false;
} else {
texInEffect = true;
}
// One color tint logic
if (!_useTint) {
// Cliping logic
if (_clipper->isClipping()) {
_clipper->clipTriangles((float*)&trianglesTexId.verts[0].vertex, trianglesTexId.indices, trianglesTexId.indexCount, (float*)&trianglesTexId.verts[0].texCoord, vs1);
if (_clipper->getClippedTriangles().size() == 0) {
_clipper->clipEnd(*slot);
continue;
}
trianglesTexId.vertCount = (int)_clipper->getClippedVertices().size() >> 1;
vbSize = trianglesTexId.vertCount * sizeof(V2F_T2F_C4B_T1F);
isFull |= vb.checkSpace(vbSize, true);
trianglesTexId.verts = (V2F_T2F_C4B_T1F*)vb.getCurBuffer();
trianglesTexId.indexCount = (int)_clipper->getClippedTriangles().size();
ibSize = trianglesTexId.indexCount * sizeof(unsigned short);
ib.checkSpace(ibSize, true);
trianglesTexId.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTexId.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
float* verts = _clipper->getClippedVertices().buffer();
float* uvs = _clipper->getClippedUVs().buffer();
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = dark.g = dark.b = dark.a = 0;
for (int v = 0, vn = trianglesTexId.vertCount, vv = 0; v < vn; ++v, vv+=2) {
V2F_T2F_C4B_T1F* vertex = trianglesTexId.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->texId = (GLfloat)(curTextureId);
}
} else {
for (int v = 0, vn = trianglesTexId.vertCount, vv = 0; v < vn; ++v, vv+=2) {
V2F_T2F_C4B_T1F* vertex = trianglesTexId.verts + v;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->texId = (GLfloat)(curTextureId);
}
}
// No cliping logic
} else {
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = dark.g = dark.b = dark.a = 0;
for (int v = 0, vn = trianglesTexId.vertCount; v < vn; ++v) {
V2F_T2F_C4B_T1F* vertex = trianglesTexId.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->texId = (GLfloat)(curTextureId);
}
} else {
for (int v = 0, vn = trianglesTexId.vertCount; v < vn; ++v) {
V2F_T2F_C4B_T1F* vertex = trianglesTexId.verts + v;
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->texId = (GLfloat)(curTextureId);
}
}
}
}
// Two color tint logic
else {
if (_clipper->isClipping()) {
_clipper->clipTriangles((float*)&trianglesTwoColorTexId.verts[0].vertex, trianglesTwoColorTexId.indices, trianglesTwoColorTexId.indexCount, (float*)&trianglesTwoColorTexId.verts[0].texCoord, vs2);
if (_clipper->getClippedTriangles().size() == 0) {
_clipper->clipEnd(*slot);
continue;
}
trianglesTwoColorTexId.vertCount = (int)_clipper->getClippedVertices().size() >> 1;
vbSize = trianglesTwoColorTexId.vertCount * sizeof(V2F_T2F_C4B_C4B_T1F);
isFull |= vb.checkSpace(vbSize, true);
trianglesTwoColorTexId.verts = (V2F_T2F_C4B_C4B_T1F*)vb.getCurBuffer();
trianglesTwoColorTexId.indexCount = (int)_clipper->getClippedTriangles().size();
ibSize = trianglesTwoColorTexId.indexCount * sizeof(unsigned short);
trianglesTwoColorTexId.indices = (unsigned short*)ib.getCurBuffer();
memcpy(trianglesTwoColorTexId.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
float* verts = _clipper->getClippedVertices().buffer();
float* uvs = _clipper->getClippedUVs().buffer();
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = darkColor.r / 255.0f;
dark.g = darkColor.g / 255.0f;
dark.b = darkColor.b / 255.0f;
dark.a = darkColor.a / 255.0f;
for (int v = 0, vn = trianglesTwoColorTexId.vertCount, vv = 0; v < vn; ++v, vv += 2) {
V2F_T2F_C4B_C4B_T1F* vertex = trianglesTwoColorTexId.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = (GLubyte)darkColor.a;
vertex->texId = (GLfloat)(curTextureId);
}
} else {
for (int v = 0, vn = trianglesTwoColorTexId.vertCount, vv = 0; v < vn; ++v, vv += 2) {
V2F_T2F_C4B_C4B_T1F* vertex = trianglesTwoColorTexId.verts + v;
vertex->vertex.x = verts[vv];
vertex->vertex.y = verts[vv + 1];
vertex->texCoord.u = uvs[vv];
vertex->texCoord.v = uvs[vv + 1];
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = (GLubyte)darkColor.a;
vertex->texId = (GLfloat)(curTextureId);
}
}
} else {
if (effect) {
Color light;
Color dark;
light.r = color.r / 255.0f;
light.g = color.g / 255.0f;
light.b = color.b / 255.0f;
light.a = color.a / 255.0f;
dark.r = darkColor.r / 255.0f;
dark.g = darkColor.g / 255.0f;
dark.b = darkColor.b / 255.0f;
dark.a = darkColor.a / 255.0f;
for (int v = 0, vn = trianglesTwoColorTexId.vertCount; v < vn; ++v) {
V2F_T2F_C4B_C4B_T1F* vertex = trianglesTwoColorTexId.verts + v;
Color lightCopy = light;
Color darkCopy = dark;
effect->transform(vertex->vertex.x, vertex->vertex.y, vertex->texCoord.u, vertex->texCoord.v, lightCopy, darkCopy);
vertex->color.r = (GLubyte)(lightCopy.r * 255);
vertex->color.g = (GLubyte)(lightCopy.g * 255);
vertex->color.b = (GLubyte)(lightCopy.b * 255);
vertex->color.a = (GLubyte)(lightCopy.a * 255);
vertex->color2.r = (GLubyte)(darkCopy.r * 255);
vertex->color2.g = (GLubyte)(darkCopy.g * 255);
vertex->color2.b = (GLubyte)(darkCopy.b * 255);
vertex->color2.a = (GLubyte)darkColor.a;
vertex->texId = (GLfloat)(curTextureId);
}
} else {
for (int v = 0, vn = trianglesTwoColorTexId.vertCount; v < vn; ++v) {
V2F_T2F_C4B_C4B_T1F* vertex = trianglesTwoColorTexId.verts + v;
vertex->color.r = (GLubyte)color.r;
vertex->color.g = (GLubyte)color.g;
vertex->color.b = (GLubyte)color.b;
vertex->color.a = (GLubyte)color.a;
vertex->color2.r = (GLubyte)darkColor.r;
vertex->color2.g = (GLubyte)darkColor.g;
vertex->color2.b = (GLubyte)darkColor.b;
vertex->color2.a = (GLubyte)darkColor.a;
vertex->texId = (GLfloat)(curTextureId);
}
}
}
}
if (texInEffect) {
if (preBlendMode != slot->getData().getBlendMode() || isFull) {
flush();
}
} else if (preTextureIndex != curTextureIndex ||
preBlendMode != slot->getData().getBlendMode() ||
isFull) {
flush();
}
}
if (vbSize > 0 && ibSize > 0) {
auto vbs = vbs1;
@ -999,6 +1354,10 @@ void SkeletonRenderer::setUseTint(bool enabled) {
_useTint = enabled;
}
void SkeletonRenderer::setUseMulti(bool enabled) {
_useMulti = enabled;
}
void SkeletonRenderer::setVertexEffectDelegate(VertexEffectDelegate *effectDelegate) {
if (_effectDelegate == effectDelegate) {
return;
@ -1075,6 +1434,7 @@ void SkeletonRenderer::bindNodeProxy(cocos2d::renderer::NodeProxy* node) {
}
void SkeletonRenderer::setEffect(cocos2d::renderer::EffectVariant* effect) {
_effectTextures.clear();
if (effect == _effect) return;
CC_SAFE_RELEASE(_effect);
_effect = effect;

View File

@ -98,6 +98,8 @@ namespace spine {
/* Enables/disables two color tinting for this instance. May break batching */
void setUseTint(bool enabled);
void setUseMulti(bool enabled);
/* Sets the vertex effect to be used, set to 0 to disable vertex effects */
void setVertexEffectDelegate(VertexEffectDelegate* effectDelegate);
/* Sets the range of slots that should be rendered. Use -1, -1 to clear the range */
@ -164,6 +166,7 @@ namespace spine {
bool _premultipliedAlpha = false;
SkeletonClipping* _clipper = nullptr;
bool _useTint = false;
bool _useMulti = false;
std::string _uuid = "";
int _startSlotIndex = -1;
@ -172,6 +175,9 @@ namespace spine {
cocos2d::middleware::IOTypedArray* _debugBuffer = nullptr;
cocos2d::renderer::NodeProxy* _nodeProxy = nullptr;
cocos2d::renderer::EffectVariant* _effect = nullptr;
std::unordered_map<GLuint, float> _effectTextures = std::unordered_map<GLuint, float>();
RealTimeAttachUtil* _attachUtil = nullptr;
};

View File

@ -60,9 +60,12 @@ RegionAttachment *AtlasAttachmentLoader::newRegionAttachment(Skin &skin, const S
RegionAttachment &attachment = *attachmentP;
attachment.setRendererObject(regionP);
attachment.setUVs(region.u, region.v, region.u2, region.v2, region.rotate);
attachment.setUVs(region.u, region.v, region.u2, region.v2, region.degrees);
attachment._regionDegrees = region.degrees;
attachment._regionOffsetX = region.offsetX;
attachment._regionOffsetY = region.offsetY;
attachment._regionX = region.x;
attachment._regionY = region.y;
attachment._regionWidth = (float)region.width;
attachment._regionHeight = (float)region.height;
attachment._regionOriginalWidth = (float)region.originalWidth;
@ -90,6 +93,8 @@ MeshAttachment *AtlasAttachmentLoader::newMeshAttachment(Skin &skin, const Strin
attachment._regionDegrees = region.degrees;
attachment._regionOffsetX = region.offsetX;
attachment._regionOffsetY = region.offsetY;
attachment._regionX = region.x;
attachment._regionY = region.y;
attachment._regionWidth = (float)region.width;
attachment._regionHeight = (float)region.height;
attachment._regionOriginalWidth = (float)region.originalWidth;

View File

@ -98,8 +98,8 @@ void MeshAttachment::updateUVs() {
return;
}
case 270: {
float textureWidth = _regionWidth / (_regionU2 - _regionU);
float textureHeight = _regionHeight / (_regionV2 - _regionV);
float textureWidth = _regionHeight / (_regionV2 - _regionV);
float textureHeight = _regionWidth / (_regionU2 - _regionU);
u -= _regionOffsetY / textureWidth;
v -= _regionOffsetX / textureHeight;
width = _regionOriginalHeight / textureWidth;
@ -217,6 +217,22 @@ void MeshAttachment::setRegionOffsetY(float inValue) {
_regionOffsetY = inValue;
}
float MeshAttachment::getRegionX() {
return _regionX;
}
void MeshAttachment::setRegionX(float inValue) {
_regionX = inValue;
}
float MeshAttachment::getRegionY() {
return _regionY;
}
void MeshAttachment::setRegionY(float inValue) {
_regionY = inValue;
}
float MeshAttachment::getRegionWidth() {
return _regionWidth;
}

View File

@ -91,6 +91,12 @@ namespace spine {
float getRegionOffsetY();
void setRegionOffsetY(float inValue);
float getRegionX();
void setRegionX(float inValue);
float getRegionY();
void setRegionY(float inValue);
float getRegionWidth();
void setRegionWidth(float inValue);
@ -120,7 +126,7 @@ namespace spine {
MeshAttachment* newLinkedMesh();
private:
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
float _regionOffsetX, _regionOffsetY, _regionX, _regionY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
MeshAttachment* _parentMesh;
Vector<float> _uvs;
Vector<float> _regionUVs;

View File

@ -103,8 +103,8 @@ void RegionAttachment::updateOffset() {
_vertexOffset[BRY] = localYCos + localX2Sin;
}
void RegionAttachment::setUVs(float u, float v, float u2, float v2, bool rotate) {
if (rotate) {
void RegionAttachment::setUVs(float u, float v, float u2, float v2, float degrees) {
if (degrees == 90) {
_uvs[URX] = u;
_uvs[URY] = v2;
_uvs[BRX] = u;
@ -113,6 +113,15 @@ void RegionAttachment::setUVs(float u, float v, float u2, float v2, bool rotate)
_uvs[BLY] = v;
_uvs[ULX] = u2;
_uvs[ULY] = v2;
} else if (degrees == 270) {
_uvs[BLX] = u;
_uvs[BLY] = v2;
_uvs[ULX] = u;
_uvs[ULY] = v;
_uvs[URX] = u2;
_uvs[URY] = v;
_uvs[BRX] = u2;
_uvs[BRY] = v2;
} else {
_uvs[ULX] = u;
_uvs[ULY] = v2;
@ -223,6 +232,14 @@ void RegionAttachment::setPath(const String &inValue) {
_path = inValue;
}
float RegionAttachment::getRegionDegrees() {
return _regionDegrees;
}
void RegionAttachment::setRegionDegrees(float inValue) {
_regionDegrees = inValue;
}
float RegionAttachment::getRegionOffsetX() {
return _regionOffsetX;
}
@ -239,6 +256,22 @@ void RegionAttachment::setRegionOffsetY(float inValue) {
_regionOffsetY = inValue;
}
float RegionAttachment::getRegionX() {
return _regionX;
}
void RegionAttachment::setRegionX(float inValue) {
_regionX = inValue;
}
float RegionAttachment::getRegionY() {
return _regionY;
}
void RegionAttachment::setRegionY(float inValue) {
_regionY = inValue;
}
float RegionAttachment::getRegionWidth() {
return _regionWidth;
}

View File

@ -54,7 +54,7 @@ namespace spine {
void updateOffset();
void setUVs(float u, float v, float u2, float v2, bool rotate);
void setUVs(float u, float v, float u2, float v2, float degress);
/// Transforms the attachment's four vertices to world coordinates.
/// @param bone The parent bone.
@ -84,12 +84,21 @@ namespace spine {
const String& getPath();
void setPath(const String& inValue);
float getRegionDegrees();
void setRegionDegrees(float inValue);
float getRegionOffsetX();
void setRegionOffsetX(float inValue);
float getRegionOffsetY();
void setRegionOffsetY(float inValue);
float getRegionX();
void setRegionX(float inValue);
float getRegionY();
void setRegionY(float inValue);
float getRegionWidth();
void setRegionWidth(float inValue);
@ -118,7 +127,7 @@ namespace spine {
static const int BRY;
float _x, _y, _rotation, _scaleX, _scaleY, _width, _height;
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
float _regionOffsetX, _regionOffsetY, _regionX, _regionY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
Vector<float> _vertexOffset;
Vector<float> _uvs;
String _path;
@ -127,6 +136,7 @@ namespace spine {
float _regionU2;
float _regionV2;
Color _color;
float _regionDegrees;
};
}

View File

@ -143,6 +143,29 @@ Skin::AttachmentMap::Entries Skin::getAttachments() {
return _attachments.getEntries();
}
std::vector<std::map<std::string, Attachment *>> Skin::getAttachmentsForJSB() {
std::vector<std::map<std::string, Attachment *>> vec;
Skin::AttachmentMap::Entries entries = _attachments.getEntries();
size_t slotIndex = -1;
std::map<std::string, Attachment *>* map = nullptr;
while (entries.hasNext()) {
Skin::AttachmentMap::Entry &entry = entries.next();
if (slotIndex != entry._slotIndex){
slotIndex = entry._slotIndex;
vec.emplace_back();
map = &vec.back();
}
map->insert({ entry._name.buffer(), entry._attachment });
}
return vec;
}
void Skin::attachAll(Skeleton &skeleton, Skin &oldSkin) {
Vector<Slot *> &slots = skeleton.getSlots();
Skin::AttachmentMap::Entries entries = oldSkin.getAttachments();

View File

@ -147,6 +147,8 @@ public:
AttachmentMap::Entries getAttachments();
std::vector<std::map<std::string, Attachment *>> getAttachmentsForJSB();
Vector<BoneData*>& getBones();
Vector<ConstraintData*>& getConstraints();

View File

@ -44,6 +44,7 @@ const char* ATTRIB_NAME_UV4 = "a_uv4";
const char* ATTRIB_NAME_UV5 = "a_uv5";
const char* ATTRIB_NAME_UV6 = "a_uv6";
const char* ATTRIB_NAME_UV7 = "a_uv7";
const char* ATTRIB_NAME_TEXID = "a_texId";
const size_t ATTRIB_NAME_POSITION_HASH = std::hash<std::string>{}(ATTRIB_NAME_POSITION);
const size_t ATTRIB_NAME_NORMAL_HASH = std::hash<std::string>{}(ATTRIB_NAME_NORMAL);
@ -63,6 +64,7 @@ const size_t ATTRIB_NAME_UV4_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV4);
const size_t ATTRIB_NAME_UV5_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV5);
const size_t ATTRIB_NAME_UV6_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV6);
const size_t ATTRIB_NAME_UV7_HASH = std::hash<std::string>{}(ATTRIB_NAME_UV7);
const size_t ATTRIB_NAME_TEXID_HASH = std::hash<std::string>{}(ATTRIB_NAME_TEXID);
Rect Rect::ZERO;

View File

@ -152,6 +152,7 @@ extern const char* ATTRIB_NAME_UV4;
extern const char* ATTRIB_NAME_UV5;
extern const char* ATTRIB_NAME_UV6;
extern const char* ATTRIB_NAME_UV7;
extern const char* ATTRIB_NAME_TEXID;
extern const size_t ATTRIB_NAME_POSITION_HASH;
extern const size_t ATTRIB_NAME_NORMAL_HASH;
@ -171,6 +172,7 @@ extern const size_t ATTRIB_NAME_UV4_HASH;
extern const size_t ATTRIB_NAME_UV5_HASH;
extern const size_t ATTRIB_NAME_UV6_HASH;
extern const size_t ATTRIB_NAME_UV7_HASH;
extern const size_t ATTRIB_NAME_TEXID_HASH;
// vertex attribute type
enum class AttribType : uint16_t

View File

@ -48,6 +48,21 @@ static uint32_t attrTypeBytes(AttribType attrType)
return 0;
}
VertexFormat* VertexFormat::XY_UV_Two_Color_TexId = new VertexFormat(std::vector<Info>({
Info(ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2),
Info(ATTRIB_NAME_UV0, AttribType::FLOAT32, 2),
Info(ATTRIB_NAME_COLOR, AttribType::UINT8, 4, true),
Info(ATTRIB_NAME_COLOR0, AttribType::UINT8, 4, true),
Info(ATTRIB_NAME_TEXID, AttribType::FLOAT32, 1)
}));
VertexFormat* VertexFormat::XY_UV_Color_TexId = new VertexFormat(std::vector<Info>({
Info(ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2),
Info(ATTRIB_NAME_UV0, AttribType::FLOAT32, 2),
Info(ATTRIB_NAME_COLOR, AttribType::UINT8, 4, true),
Info(ATTRIB_NAME_TEXID, AttribType::FLOAT32, 1)
}));
VertexFormat* VertexFormat::XY_UV_Two_Color = new VertexFormat(std::vector<Info>({
Info(ATTRIB_NAME_POSITION, AttribType::FLOAT32, 2),
Info(ATTRIB_NAME_UV0, AttribType::FLOAT32, 2),

View File

@ -167,6 +167,14 @@ public:
*/
uint32_t getBytes() const { return _bytes; };
/*
* Builtin VertexFormat with 2d position, uv, color, color0, texId attributes
*/
static VertexFormat* XY_UV_Two_Color_TexId;
/*
* Builtin VertexFormat with 2d position, uv, color, texId attributes
*/
static VertexFormat* XY_UV_Color_TexId;
/*
* Builtin VertexFormat with 2d position, uv, color, color0 attributes
*/

View File

@ -3938,14 +3938,14 @@ getRegionOriginalWidth : function (
* @param {float} arg1
* @param {float} arg2
* @param {float} arg3
* @param {bool} arg4
* @param {float} arg4
*/
setUVs : function (
float,
float,
float,
float,
bool
float
)
{
},

View File

@ -5938,6 +5938,44 @@ static bool js_cocos2dx_spine_MeshAttachment_setRegionOffsetX(se::State& s)
}
SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionOffsetX)
static bool js_cocos2dx_spine_MeshAttachment_setRegionY(se::State& s)
{
spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_MeshAttachment_setRegionY : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
float arg0 = 0;
ok &= seval_to_float(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionY : Error processing arguments");
cobj->setRegionY(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionY)
static bool js_cocos2dx_spine_MeshAttachment_setRegionX(se::State& s)
{
spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_MeshAttachment_setRegionX : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
float arg0 = 0;
ok &= seval_to_float(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionX : Error processing arguments");
cobj->setRegionX(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionX)
static bool js_cocos2dx_spine_MeshAttachment_copy(se::State& s)
{
spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject();
@ -6579,6 +6617,42 @@ static bool js_cocos2dx_spine_MeshAttachment_getRegionOffsetX(se::State& s)
}
SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionOffsetX)
static bool js_cocos2dx_spine_MeshAttachment_getRegionY(se::State& s)
{
spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_MeshAttachment_getRegionY : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
float result = cobj->getRegionY();
ok &= float_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_MeshAttachment_getRegionY : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionY)
static bool js_cocos2dx_spine_MeshAttachment_getRegionX(se::State& s)
{
spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_MeshAttachment_getRegionX : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
float result = cobj->getRegionX();
ok &= float_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_MeshAttachment_getRegionX : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionX)
static bool js_cocos2dx_spine_MeshAttachment_getRegionV(se::State& s)
{
spine::MeshAttachment* cobj = (spine::MeshAttachment*)s.nativeThisObject();
@ -6662,6 +6736,8 @@ bool js_register_cocos2dx_spine_MeshAttachment(se::Object* obj)
cls->defineFunction("setRegionOriginalHeight", _SE(js_cocos2dx_spine_MeshAttachment_setRegionOriginalHeight));
cls->defineFunction("setRegionOffsetY", _SE(js_cocos2dx_spine_MeshAttachment_setRegionOffsetY));
cls->defineFunction("setRegionOffsetX", _SE(js_cocos2dx_spine_MeshAttachment_setRegionOffsetX));
cls->defineFunction("setRegionY", _SE(js_cocos2dx_spine_MeshAttachment_setRegionY));
cls->defineFunction("setRegionX", _SE(js_cocos2dx_spine_MeshAttachment_setRegionX));
cls->defineFunction("copy", _SE(js_cocos2dx_spine_MeshAttachment_copy));
cls->defineFunction("getRegionOriginalWidth", _SE(js_cocos2dx_spine_MeshAttachment_getRegionOriginalWidth));
cls->defineFunction("getWidth", _SE(js_cocos2dx_spine_MeshAttachment_getWidth));
@ -6697,6 +6773,8 @@ bool js_register_cocos2dx_spine_MeshAttachment(se::Object* obj)
cls->defineFunction("getTriangles", _SE(js_cocos2dx_spine_MeshAttachment_getTriangles));
cls->defineFunction("getRegionOffsetY", _SE(js_cocos2dx_spine_MeshAttachment_getRegionOffsetY));
cls->defineFunction("getRegionOffsetX", _SE(js_cocos2dx_spine_MeshAttachment_getRegionOffsetX));
cls->defineFunction("getRegionY", _SE(js_cocos2dx_spine_MeshAttachment_getRegionY));
cls->defineFunction("getRegionX", _SE(js_cocos2dx_spine_MeshAttachment_getRegionX));
cls->defineFunction("getRegionV", _SE(js_cocos2dx_spine_MeshAttachment_getRegionV));
cls->defineFunction("getRegionRotate", _SE(js_cocos2dx_spine_MeshAttachment_getRegionRotate));
cls->defineFunction("getParentMesh", _SE(js_cocos2dx_spine_MeshAttachment_getParentMesh));
@ -7905,6 +7983,43 @@ static bool js_cocos2dx_spine_RegionAttachment_setRegionOriginalHeight(se::State
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOriginalHeight)
static bool js_cocos2dx_spine_RegionAttachment_setRegionDegrees(se::State& s)
{
spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_setRegionDegrees : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
int arg0 = 0;
do { int32_t tmp = 0; ok &= seval_to_int32(args[0], &tmp); arg0 = (int)tmp; } while(false);
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionDegrees : Error processing arguments");
cobj->setRegionDegrees(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionDegrees)
static bool js_cocos2dx_spine_RegionAttachment_getRegionDegrees(se::State& s)
{
spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_getRegionDegrees : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
int result = cobj->getRegionDegrees();
ok &= int32_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_getRegionDegrees : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionDegrees)
static bool js_cocos2dx_spine_RegionAttachment_setRegionOffsetY(se::State& s)
{
spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject();
@ -7943,6 +8058,44 @@ static bool js_cocos2dx_spine_RegionAttachment_setRegionOffsetX(se::State& s)
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOffsetX)
static bool js_cocos2dx_spine_RegionAttachment_setRegionY(se::State& s)
{
spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_setRegionY : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
float arg0 = 0;
ok &= seval_to_float(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionY : Error processing arguments");
cobj->setRegionY(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionY)
static bool js_cocos2dx_spine_RegionAttachment_setRegionX(se::State& s)
{
spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_setRegionX : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
float arg0 = 0;
ok &= seval_to_float(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionX : Error processing arguments");
cobj->setRegionX(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionX)
static bool js_cocos2dx_spine_RegionAttachment_getRegionOriginalWidth(se::State& s)
{
spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject();
@ -7973,12 +8126,12 @@ static bool js_cocos2dx_spine_RegionAttachment_setUVs(se::State& s)
float arg1 = 0;
float arg2 = 0;
float arg3 = 0;
bool arg4;
float arg4 = 0;
ok &= seval_to_float(args[0], &arg0);
ok &= seval_to_float(args[1], &arg1);
ok &= seval_to_float(args[2], &arg2);
ok &= seval_to_float(args[3], &arg3);
ok &= seval_to_boolean(args[4], &arg4);
ok &= seval_to_float(args[4], &arg4);
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_setUVs : Error processing arguments");
cobj->setUVs(arg0, arg1, arg2, arg3, arg4);
return true;
@ -8518,6 +8671,41 @@ static bool js_cocos2dx_spine_RegionAttachment_getRegionOffsetX(se::State& s)
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOffsetX)
static bool js_cocos2dx_spine_RegionAttachment_getRegionY(se::State& s)
{
spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_getRegionY : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
float result = cobj->getRegionY();
ok &= float_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_getRegionY : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionY)
static bool js_cocos2dx_spine_RegionAttachment_getRegionX(se::State& s)
{
spine::RegionAttachment* cobj = (spine::RegionAttachment*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_RegionAttachment_getRegionX : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
float result = cobj->getRegionX();
ok &= float_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_RegionAttachment_getRegionX : Error processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionX)
extern se::Object* __jsb_spine_Attachment_proto;
@ -8529,6 +8717,8 @@ bool js_register_cocos2dx_spine_RegionAttachment(se::Object* obj)
cls->defineFunction("setRegionOriginalHeight", _SE(js_cocos2dx_spine_RegionAttachment_setRegionOriginalHeight));
cls->defineFunction("setRegionOffsetY", _SE(js_cocos2dx_spine_RegionAttachment_setRegionOffsetY));
cls->defineFunction("setRegionOffsetX", _SE(js_cocos2dx_spine_RegionAttachment_setRegionOffsetX));
cls->defineFunction("setRegionY", _SE(js_cocos2dx_spine_RegionAttachment_setRegionY));
cls->defineFunction("setRegionX", _SE(js_cocos2dx_spine_RegionAttachment_setRegionX));
cls->defineFunction("getRegionOriginalWidth", _SE(js_cocos2dx_spine_RegionAttachment_getRegionOriginalWidth));
cls->defineFunction("setUVs", _SE(js_cocos2dx_spine_RegionAttachment_setUVs));
cls->defineFunction("getWidth", _SE(js_cocos2dx_spine_RegionAttachment_getWidth));
@ -8560,6 +8750,10 @@ bool js_register_cocos2dx_spine_RegionAttachment(se::Object* obj)
cls->defineFunction("getRegionOriginalHeight", _SE(js_cocos2dx_spine_RegionAttachment_getRegionOriginalHeight));
cls->defineFunction("getRegionOffsetY", _SE(js_cocos2dx_spine_RegionAttachment_getRegionOffsetY));
cls->defineFunction("getRegionOffsetX", _SE(js_cocos2dx_spine_RegionAttachment_getRegionOffsetX));
cls->defineFunction("getRegionY", _SE(js_cocos2dx_spine_RegionAttachment_getRegionY));
cls->defineFunction("getRegionX", _SE(js_cocos2dx_spine_RegionAttachment_getRegionX));
cls->defineFunction("setRegionDegrees", _SE(js_cocos2dx_spine_RegionAttachment_setRegionDegrees));
cls->defineFunction("getRegionDegrees", _SE(js_cocos2dx_spine_RegionAttachment_getRegionDegrees));
cls->install();
JSBClassType::registerClass<spine::RegionAttachment>(cls);
@ -12876,6 +13070,25 @@ static bool js_cocos2dx_spine_SkeletonRenderer_setUseTint(se::State& s)
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonRenderer_setUseTint)
static bool js_cocos2dx_spine_SkeletonRenderer_setUseMulti(se::State& s)
{
spine::SkeletonRenderer* cobj = (spine::SkeletonRenderer*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_SkeletonRenderer_setUseMulti : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
bool arg0;
ok &= seval_to_boolean(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_SkeletonRenderer_setUseMulti : Error processing arguments");
cobj->setUseMulti(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonRenderer_setUseMulti)
static bool js_cocos2dx_spine_SkeletonRenderer_setTimeScale(se::State& s)
{
spine::SkeletonRenderer* cobj = (spine::SkeletonRenderer*)s.nativeThisObject();
@ -13913,6 +14126,7 @@ bool js_register_cocos2dx_spine_SkeletonRenderer(se::Object* obj)
auto cls = se::Class::create("Skeleton", obj, nullptr, _SE(js_cocos2dx_spine_SkeletonRenderer_constructor));
cls->defineFunction("setUseTint", _SE(js_cocos2dx_spine_SkeletonRenderer_setUseTint));
cls->defineFunction("setUseMulti", _SE(js_cocos2dx_spine_SkeletonRenderer_setUseMulti));
cls->defineFunction("setTimeScale", _SE(js_cocos2dx_spine_SkeletonRenderer_setTimeScale));
cls->defineFunction("render", _SE(js_cocos2dx_spine_SkeletonRenderer_render));
cls->defineFunction("initWithUUID", _SE(js_cocos2dx_spine_SkeletonRenderer_initWithUUID));
@ -15341,6 +15555,25 @@ static bool js_cocos2dx_spine_SkeletonCacheAnimation_setUseTint(se::State& s)
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setUseTint)
static bool js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti(se::State& s)
{
spine::SkeletonCacheAnimation* cobj = (spine::SkeletonCacheAnimation*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 1) {
bool arg0;
ok &= seval_to_boolean(args[0], &arg0);
SE_PRECONDITION2(ok, false, "js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti : Error processing arguments");
cobj->setUseMulti(arg0);
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti)
static bool js_cocos2dx_spine_SkeletonCacheAnimation_setTimeScale(se::State& s)
{
spine::SkeletonCacheAnimation* cobj = (spine::SkeletonCacheAnimation*)s.nativeThisObject();
@ -16096,6 +16329,7 @@ bool js_register_cocos2dx_spine_SkeletonCacheAnimation(se::Object* obj)
auto cls = se::Class::create("SkeletonCacheAnimation", obj, nullptr, _SE(js_cocos2dx_spine_SkeletonCacheAnimation_constructor));
cls->defineFunction("setUseTint", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setUseTint));
cls->defineFunction("setUseMulti", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti));
cls->defineFunction("setTimeScale", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setTimeScale));
cls->defineFunction("findAnimation", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_findAnimation));
cls->defineFunction("setAttachUtil", _SE(js_cocos2dx_spine_SkeletonCacheAnimation_setAttachUtil));

View File

@ -420,6 +420,8 @@ bool register_all_cocos2dx_spine(se::Object* obj);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionOriginalHeight);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionOffsetY);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionOffsetX);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionY);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionX);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_copy);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionOriginalWidth);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getWidth);
@ -455,6 +457,8 @@ SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionHeight);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getTriangles);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionOffsetY);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionOffsetX);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionY);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionX);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionV);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getRegionRotate);
SE_DECLARE_FUNC(js_cocos2dx_spine_MeshAttachment_getParentMesh);
@ -563,11 +567,15 @@ bool register_all_cocos2dx_spine(se::Object* obj);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOriginalHeight);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOffsetY);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionOffsetX);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionY);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionX);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOriginalWidth);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setUVs);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getWidth);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getY);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRotation);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionDegrees);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionDegrees);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setWidth);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionWidth);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getUVs);
@ -594,6 +602,8 @@ SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_updateOffset);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOriginalHeight);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOffsetY);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionOffsetX);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionY);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getRegionX);
extern se::Object* __jsb_spine_RotateTimeline_proto;
extern se::Class* __jsb_spine_RotateTimeline_class;
@ -906,6 +916,7 @@ extern se::Class* __jsb_spine_SkeletonRenderer_class;
bool js_register_spine_SkeletonRenderer(se::Object* obj);
bool register_all_cocos2dx_spine(se::Object* obj);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setUseTint);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setUseMulti);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_setTimeScale);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_render);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonRenderer_initWithUUID);
@ -1006,6 +1017,7 @@ extern se::Class* __jsb_spine_SkeletonCacheAnimation_class;
bool js_register_spine_SkeletonCacheAnimation(se::Object* obj);
bool register_all_cocos2dx_spine(se::Object* obj);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setUseTint);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setUseMulti);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setTimeScale);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_findAnimation);
SE_DECLARE_FUNC(js_cocos2dx_spine_SkeletonCacheAnimation_setAttachUtil);

View File

@ -672,6 +672,32 @@ bool seval_to_spine_Vector_T_ptr(const se::Value& v, spine::Vector<T*>* ret)
return true;
}
bool spine_skin_attachments_to_seval(std::vector<std::map<std::string, spine::Attachment*>>& v, se::Value* ret) {
assert(ret != nullptr);
bool ok = true;
se::HandleObject arr(se::Object::createArrayObject(v.size()));
int i = 0;
for (const auto &vv : v)
{
se::HandleObject obj(se::Object::createPlainObject());
se::Value tmp;
for (const auto& e : vv) {
native_ptr_to_rooted_seval<spine::Attachment>(e.second, &tmp);
obj->setProperty(e.first.c_str(), tmp);
}
arr->setArrayElement(i, se::Value(obj));
i++;
}
ret->setObject(arr, true);
return ok;
}
bool seval_to_spine_Vector_String(const se::Value& v, spine::Vector<spine::String>* ret);
bool spine_Vector_String_to_seval(const spine::Vector<spine::String>& v, se::Value* ret);
#endif

View File

@ -51,6 +51,8 @@
#include "cocos/editor-support/spine/spine.h"
#include "cocos/editor-support/spine-creator-support/spine-cocos2dx.h"
#include "cocos/editor-support/spine-creator-support/AttachmentVertices.h"
using namespace cocos2d;
static spine::Cocos2dTextureLoader textureLoader;
@ -233,6 +235,252 @@ static bool js_register_spine_retainSkeletonData(se::State& s)
}
SE_BIND_FUNC(js_register_spine_retainSkeletonData)
static bool js_cocos2dx_spine_Skin_getAttachmentsForJSB(se::State& s) {
spine::Skin* cobj = (spine::Skin*)s.nativeThisObject();
SE_PRECONDITION2(
cobj, false,
"js_cocos2dx_spine_Skin_getAttachmentsForJSB : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
std::vector<std::map<std::string, spine::Attachment*>> result =
cobj->getAttachmentsForJSB();
ok &= spine_skin_attachments_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false,
"js_cocos2dx_spine_Skin_getAttachmentsForJSB : Error "
"processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d",
(int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_Skin_getAttachmentsForJSB)
static bool js_cocos2dx_spine_RegionAttachment_getTextureForJSB(se::State& s) {
spine::RegionAttachment* cobj =
(spine::RegionAttachment*)s.nativeThisObject();
SE_PRECONDITION2(
cobj, false,
"js_cocos2dx_spine_RegionAttachment_getTextureForJSB : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
spine::AttachmentVertices* attachmentVertices = (spine::AttachmentVertices*)cobj->getRendererObject();
ok &= native_ptr_to_seval<cocos2d::middleware::Texture2D>((cocos2d::middleware::Texture2D*)attachmentVertices->_texture, &s.rval());
SE_PRECONDITION2(ok, false,
"js_cocos2dx_spine_RegionAttachment_getTextureForJSB : Error "
"processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d",
(int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_getTextureForJSB)
static bool js_cocos2dx_spine_RegionAttachment_setRegionForJSB(se::State& s) {
spine::RegionAttachment* attachment =
(spine::RegionAttachment*)s.nativeThisObject();
SE_PRECONDITION2(
attachment, false,
"js_cocos2dx_spine_RegionAttachment_setRegionForJSB : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
if (argc != 5) {
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 5);
return false;
}
bool ok = false;
if (attachment == nullptr) return false;
cocos2d::middleware::Texture2D* texture = nullptr;
ok = seval_to_native_ptr(args[0], &texture);
SE_PRECONDITION2(
ok, false,
"js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Middleware Texture2D failed!");
cocos2d::renderer::Rect rect;
ok = seval_to_Rect(args[1], &rect);
SE_PRECONDITION2(
ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Invalid Rect failed!");
cocos2d::Size originalSize;
ok = seval_to_Size(args[2], &originalSize);
SE_PRECONDITION2(
ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Invalid OriginalSize failed!");
cocos2d::Vec2 offset;
ok = seval_to_Vec2(args[3], &offset);
SE_PRECONDITION2(
ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Invalid Offset failed!");
float degrees;
ok = seval_to_float(args[4], &degrees);
SE_PRECONDITION2(
ok, false, "js_cocos2dx_spine_RegionAttachment_setRegionForJSB: Converting Invalid Degrees failed!");
spine::AttachmentVertices* attachmentVertices = (spine::AttachmentVertices*)attachment->getRendererObject();
CC_SAFE_RELEASE(attachmentVertices->_texture);
attachmentVertices->_texture = texture;
CC_SAFE_RETAIN(texture);
float u, v, u2, v2;
float w = texture->getNativeTexture()->getWidth();
float h = texture->getNativeTexture()->getHeight();
if (degrees != 0) {
u = rect.x / w;
v = rect.y / h;
u2 = (rect.x + rect.h) / w;
v2 = (rect.y + rect.w) / h;
} else {
u = rect.x / w;
v = rect.y / h;
u2 = (rect.x + rect.w) / w;
v2 = (rect.y + rect.h) / h;
}
attachment->setRegionX(rect.x);
attachment->setRegionY(rect.y);
attachment->setRegionWidth(rect.w);
attachment->setRegionHeight(rect.h);
attachment->setRegionOriginalWidth(originalSize.width);
attachment->setRegionOriginalHeight(originalSize.height);
attachment->setRegionOffsetX(offset.x);
attachment->setRegionOffsetY(offset.y);
attachment->setRegionDegrees(degrees);
attachment->setUVs(u, v, u2, v2, degrees);
attachment->updateOffset();
cocos2d::middleware::V2F_T2F_C4B* vertices = attachmentVertices->_triangles->verts;
for (int i = 0, ii = 0; i < 4; ++i, ii += 2) {
vertices[i].texCoord.u = attachment->getUVs()[ii];
vertices[i].texCoord.v = attachment->getUVs()[ii + 1];
}
return true;
}
SE_BIND_FUNC(js_cocos2dx_spine_RegionAttachment_setRegionForJSB)
static bool js_cocos2dx_spine_MeshAttachment_getTextureForJSB(se::State& s) {
spine::MeshAttachment* cobj =
(spine::MeshAttachment*)s.nativeThisObject();
SE_PRECONDITION2(
cobj, false,
"js_cocos2dx_spine_MeshAttachment_getTextureForJSB : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
CC_UNUSED bool ok = true;
if (argc == 0) {
spine::AttachmentVertices* attachmentVertices = (spine::AttachmentVertices*)cobj->getRendererObject();
ok &= native_ptr_to_seval<cocos2d::middleware::Texture2D>((cocos2d::middleware::Texture2D*)attachmentVertices->_texture, &s.rval());
SE_PRECONDITION2(ok, false,
"js_cocos2dx_spine_MeshAttachment_getTextureForJSB : Error "
"processing arguments");
return true;
}
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d",
(int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_getTextureForJSB)
static bool js_cocos2dx_spine_MeshAttachment_setRegionForJSB(se::State& s) {
spine::MeshAttachment* attachment =
(spine::MeshAttachment*)s.nativeThisObject();
SE_PRECONDITION2(
attachment, false,
"js_cocos2dx_spine_MeshAttachment_setRegionForJSB : Invalid Native Object");
const auto& args = s.args();
size_t argc = args.size();
if (argc != 5) {
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 5);
return false;
}
bool ok = false;
if (attachment == nullptr) return false;
cocos2d::middleware::Texture2D* texture = nullptr;
ok = seval_to_native_ptr(args[0], &texture);
SE_PRECONDITION2(
ok, false,
"js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Middleware Texture2D failed!");
cocos2d::renderer::Rect rect;
ok = seval_to_Rect(args[1], &rect);
SE_PRECONDITION2(
ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Invalid Rect failed!");
cocos2d::Size originalSize;
ok = seval_to_Size(args[2], &originalSize);
SE_PRECONDITION2(
ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Invalid OriginalSize failed!");
cocos2d::Vec2 offset;
ok = seval_to_Vec2(args[3], &offset);
SE_PRECONDITION2(
ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Invalid Offset failed!");
float degrees;
ok = seval_to_float(args[4], &degrees);
SE_PRECONDITION2(
ok, false, "js_cocos2dx_spine_MeshAttachment_setRegionForJSB: Converting Invalid Degrees failed!");
spine::AttachmentVertices* attachmentVertices = (spine::AttachmentVertices*)attachment->getRendererObject();
CC_SAFE_RELEASE(attachmentVertices->_texture);
attachmentVertices->_texture = texture;
CC_SAFE_RETAIN(texture);
float u, v, u2, v2;
float w = texture->getNativeTexture()->getWidth();
float h = texture->getNativeTexture()->getHeight();
if (degrees != 0) {
u = rect.x / w;
v = rect.y / h;
u2 = (rect.x + rect.h) / w;
v2 = (rect.y + rect.w) / h;
} else {
u = rect.x / w;
v = rect.y / h;
u2 = (rect.x + rect.w) / w;
v2 = (rect.y + rect.h) / h;
}
attachment->setRegionU(u);
attachment->setRegionV(v);
attachment->setRegionU2(u2);
attachment->setRegionV2(v2);
attachment->setRegionRotate(degrees != 0);
attachment->setRegionDegrees(degrees);
attachment->setRegionX(rect.x);
attachment->setRegionY(rect.y);
attachment->setRegionWidth(rect.w);
attachment->setRegionHeight(rect.h);
attachment->setRegionOriginalWidth(originalSize.width);
attachment->setRegionOriginalHeight(originalSize.height);
attachment->setRegionOffsetX(offset.x);
attachment->setRegionOffsetY(offset.y);
attachment->updateUVs();
cocos2d::middleware::V2F_T2F_C4B* vertices = attachmentVertices->_triangles->verts;
for (size_t i = 0, ii = 0, nn = attachment->getWorldVerticesLength(); ii < nn; ++i, ii += 2) {
vertices[i].texCoord.u = attachment->getUVs()[ii];
vertices[i].texCoord.v = attachment->getUVs()[ii + 1];
}
return true;
}
SE_BIND_FUNC(js_cocos2dx_spine_MeshAttachment_setRegionForJSB)
bool register_all_spine_manual(se::Object* obj)
{
// Get the ns
@ -250,6 +498,14 @@ bool register_all_spine_manual(se::Object* obj)
ns->defineFunction("retainSkeletonData", _SE(js_register_spine_retainSkeletonData));
ns->defineFunction("disposeSkeletonData", _SE(js_register_spine_disposeSkeletonData));
__jsb_spine_Skin_proto->defineFunction("getAttachments", _SE(js_cocos2dx_spine_Skin_getAttachmentsForJSB));
__jsb_spine_RegionAttachment_proto->defineFunction("getTextureForJSB",_SE(js_cocos2dx_spine_RegionAttachment_getTextureForJSB));
__jsb_spine_RegionAttachment_proto->defineFunction("setRegionForJSB",_SE(js_cocos2dx_spine_RegionAttachment_setRegionForJSB));
__jsb_spine_MeshAttachment_proto->defineFunction("getTextureForJSB",_SE(js_cocos2dx_spine_MeshAttachment_getTextureForJSB));
__jsb_spine_MeshAttachment_proto->defineFunction("setRegionForJSB",_SE(js_cocos2dx_spine_MeshAttachment_setRegionForJSB));
spine::setSpineObjectDisposeCallback([](void* spineObj){
se::Object* seObj = nullptr;

View File

@ -30,4 +30,7 @@ namespace se {
class Object;
}
SE_DECLARE_FUNC(js_cocos2dx_spine_Skin_getAttachmentsForJSB);
SE_DECLARE_FUNC(js_cocos2dx_spine_RegionAttachment_getTextureForJSB);
bool register_all_spine_manual(se::Object* obj);