diff --git a/spine-cocos2dx/src/spine/SkeletonRenderer.cpp b/spine-cocos2dx/src/spine/SkeletonRenderer.cpp index cde7ce45e..df80160a1 100644 --- a/spine-cocos2dx/src/spine/SkeletonRenderer.cpp +++ b/spine-cocos2dx/src/spine/SkeletonRenderer.cpp @@ -36,12 +36,35 @@ #include #include +#define INITIAL_WORLD_VERTICES_LENGTH 1000 +// Used for transforming attachments for bounding boxes & debug rendering +static float* worldVertices = nullptr; +static size_t worldVerticesLength = 0; + +void ensureWorldVerticesCapacity(size_t capacity) { + if (worldVerticesLength < capacity) { + float* newWorldVertices = new float[capacity]; + memcpy(newWorldVertices, worldVertices, capacity * sizeof(float)); + delete[] worldVertices; + worldVertices = newWorldVertices; + worldVerticesLength = capacity; + } +} + USING_NS_CC; using std::min; using std::max; namespace spine { +void SkeletonRenderer::destroyScratchBuffers() { + if (worldVertices) { + delete[] worldVertices; + worldVertices = nullptr; + worldVerticesLength = 0; + } +} + SkeletonRenderer* SkeletonRenderer::createWithData (spSkeletonData* skeletonData, bool ownsSkeletonData) { SkeletonRenderer* node = new SkeletonRenderer(skeletonData, ownsSkeletonData); node->autorelease(); @@ -61,7 +84,10 @@ SkeletonRenderer* SkeletonRenderer::createWithFile (const std::string& skeletonD } void SkeletonRenderer::initialize () { - _worldVertices = new float[1000]; // Max number of vertices per mesh. + if (!worldVertices) { + worldVertices = new float[INITIAL_WORLD_VERTICES_LENGTH]; + worldVerticesLength = INITIAL_WORLD_VERTICES_LENGTH; + } _clipper = spSkeletonClipping_create(); @@ -131,8 +157,7 @@ SkeletonRenderer::~SkeletonRenderer () { if (_ownsSkeletonData) spSkeletonData_dispose(_skeleton->data); spSkeleton_dispose(_skeleton); if (_atlas) spAtlas_dispose(_atlas); - if (_attachmentLoader) spAttachmentLoader_dispose(_attachmentLoader); - delete [] _worldVertices; + if (_attachmentLoader) spAttachmentLoader_dispose(_attachmentLoader); spSkeletonClipping_dispose(_clipper); } @@ -613,11 +638,11 @@ void SkeletonRenderer::drawDebug (Renderer* renderer, const Mat4 &transform, uin spSlot* slot = _skeleton->drawOrder[i]; if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_REGION) continue; spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment; - spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices, 0, 2); - points[0] = Vec2(_worldVertices[0], _worldVertices[1]); - points[1] = Vec2(_worldVertices[2], _worldVertices[3]); - points[2] = Vec2(_worldVertices[4], _worldVertices[5]); - points[3] = Vec2(_worldVertices[6], _worldVertices[7]); + spRegionAttachment_computeWorldVertices(attachment, slot->bone, worldVertices, 0, 2); + points[0] = Vec2(worldVertices[0], worldVertices[1]); + points[1] = Vec2(worldVertices[2], worldVertices[3]); + points[2] = Vec2(worldVertices[4], worldVertices[5]); + points[3] = Vec2(worldVertices[6], worldVertices[7]); drawNode->drawPoly(points, 4, true, Color4F::BLUE); } } @@ -645,12 +670,13 @@ void SkeletonRenderer::drawDebug (Renderer* renderer, const Mat4 &transform, uin for (int i = 0, n = _skeleton->slotsCount; i < n; ++i) { spSlot* slot = _skeleton->drawOrder[i]; if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_MESH) continue; - spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment; - spVertexAttachment_computeWorldVertices(SUPER(attachment), slot, 0, attachment->super.worldVerticesLength, _worldVertices, 0, 2); + spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment; + ensureWorldVerticesCapacity(attachment->super.worldVerticesLength); + spVertexAttachment_computeWorldVertices(SUPER(attachment), slot, 0, attachment->super.worldVerticesLength, worldVertices, 0, 2); for (int ii = 0; ii < attachment->trianglesCount;) { - Vec2 v1(_worldVertices + (attachment->triangles[ii++] * 2)); - Vec2 v2(_worldVertices + (attachment->triangles[ii++] * 2)); - Vec2 v3(_worldVertices + (attachment->triangles[ii++] * 2)); + Vec2 v1(worldVertices + (attachment->triangles[ii++] * 2)); + Vec2 v2(worldVertices + (attachment->triangles[ii++] * 2)); + Vec2 v3(worldVertices + (attachment->triangles[ii++] * 2)); drawNode->drawLine(v1, v2, Color4F::YELLOW); drawNode->drawLine(v2, v3, Color4F::YELLOW); drawNode->drawLine(v3, v1, Color4F::YELLOW); @@ -680,16 +706,17 @@ Rect SkeletonRenderer::getBoundingBox () const { int verticesCount; if (slot->attachment->type == SP_ATTACHMENT_REGION) { spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment; - spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices, 0, 2); + spRegionAttachment_computeWorldVertices(attachment, slot->bone, worldVertices, 0, 2); verticesCount = 8; } else if (slot->attachment->type == SP_ATTACHMENT_MESH) { spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment; - spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, _worldVertices, 0, 2); + ensureWorldVerticesCapacity(mesh->super.worldVerticesLength); + spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, worldVertices, 0, 2); verticesCount = mesh->super.worldVerticesLength; } else continue; for (int ii = 0; ii < verticesCount; ii += 2) { - float x = _worldVertices[ii] * scaleX, y = _worldVertices[ii + 1] * scaleY; + float x = worldVertices[ii] * scaleX, y = worldVertices[ii + 1] * scaleY; minX = min(minX, x); minY = min(minY, y); maxX = max(maxX, x); diff --git a/spine-cocos2dx/src/spine/SkeletonRenderer.h b/spine-cocos2dx/src/spine/SkeletonRenderer.h index 8ac8f9a62..426cba1aa 100644 --- a/spine-cocos2dx/src/spine/SkeletonRenderer.h +++ b/spine-cocos2dx/src/spine/SkeletonRenderer.h @@ -108,6 +108,9 @@ public: virtual const cocos2d::BlendFunc& getBlendFunc () const override; virtual void setOpacityModifyRGB (bool value) override; virtual bool isOpacityModifyRGB () const override; + + // Frees global memory used for temporay vertex transformations. + static void destroyScratchBuffers(); CC_CONSTRUCTOR_ACCESS: SkeletonRenderer (); @@ -136,7 +139,6 @@ protected: spAttachmentLoader* _attachmentLoader; cocos2d::CustomCommand _debugCommand; cocos2d::BlendFunc _blendFunc; - float* _worldVertices; bool _premultipliedAlpha; spSkeleton* _skeleton; float _timeScale;