diff --git a/spine-cocos2d-objc/example/CoinExample.h b/spine-cocos2d-objc/example/CoinExample.h new file mode 100644 index 000000000..a4c20cfc7 --- /dev/null +++ b/spine-cocos2d-objc/example/CoinExample.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable, and + * non-transferable license to use, install, execute, and perform the Spine + * Runtimes software and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#import "cocos2d.h" +#import + +@interface CoinExample : CCNode { + SkeletonAnimation* skeletonNode; +} + ++ (CCScene*) scene; + +@end diff --git a/spine-cocos2d-objc/example/CoinExample.m b/spine-cocos2d-objc/example/CoinExample.m new file mode 100644 index 000000000..3ad713fb7 --- /dev/null +++ b/spine-cocos2d-objc/example/CoinExample.m @@ -0,0 +1,74 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable, and + * non-transferable license to use, install, execute, and perform the Spine + * Runtimes software and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#import "CoinExample.h" +#import "SpineBoyExample.h" + +@implementation CoinExample + ++ (CCScene*) scene { + CCScene *scene = [CCScene node]; + [scene addChild:[CoinExample node]]; + return scene; +} + +-(id) init { + self = [super init]; + if (!self) return nil; + + skeletonNode = [SkeletonAnimation skeletonWithFile:@"coin.json" atlasFile:@"coin.atlas" scale:0.5]; + + __weak SkeletonAnimation* node = skeletonNode; + skeletonNode.twoColorTint = false; + + [skeletonNode setAnimationForTrack:0 name:@"rotate" loop:YES]; + + CGSize windowSize = [[CCDirector sharedDirector] viewSize]; + [skeletonNode setPosition:ccp(windowSize.width / 2, windowSize.height / 2 - 100)]; + [self addChild:skeletonNode]; + + self.userInteractionEnabled = YES; + self.contentSize = windowSize; + + return self; +} + +#if ( TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR ) +- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event { + if (!skeletonNode.debugBones) + skeletonNode.debugBones = true; + else if (skeletonNode.timeScale == 1) + skeletonNode.timeScale = 0.3f; + else + [[CCDirector sharedDirector] replaceScene:[SpineboyExample scene]]; +} +#endif + +@end diff --git a/spine-cocos2d-objc/example/TankExample.m b/spine-cocos2d-objc/example/TankExample.m index 116e2b478..4521936da 100644 --- a/spine-cocos2d-objc/example/TankExample.m +++ b/spine-cocos2d-objc/example/TankExample.m @@ -29,7 +29,7 @@ *****************************************************************************/ #import "TankExample.h" -#import "SpineboyExample.h" +#import "CoinExample.h" @implementation TankExample @@ -63,7 +63,7 @@ else if (skeletonNode.timeScale == 1) skeletonNode.timeScale = 0.3f; else - [[CCDirector sharedDirector] replaceScene:[SpineboyExample scene]]; + [[CCDirector sharedDirector] replaceScene:[CoinExample scene]]; } #endif diff --git a/spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj b/spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj index 66c7a676e..675f0431e 100644 --- a/spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj +++ b/spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj @@ -34,6 +34,14 @@ 765A2EF61D7D7A08003FB779 /* goblins.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF41D7D7A08003FB779 /* goblins.atlas */; }; 765A2EF71D7D7A08003FB779 /* goblins.png in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF51D7D7A08003FB779 /* goblins.png */; }; 76BF7E071E66ED9C00485998 /* GLUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 76BF7E051E66ED9C00485998 /* GLUtils.c */; }; + 76EE4E461EB36DE6000254F4 /* Array.c in Sources */ = {isa = PBXBuildFile; fileRef = 76EE4E421EB36DE6000254F4 /* Array.c */; }; + 76EE4E471EB36DE6000254F4 /* ClippingAttachment.c in Sources */ = {isa = PBXBuildFile; fileRef = 76EE4E431EB36DE6000254F4 /* ClippingAttachment.c */; }; + 76EE4E481EB36DE6000254F4 /* SkeletonClipping.c in Sources */ = {isa = PBXBuildFile; fileRef = 76EE4E441EB36DE6000254F4 /* SkeletonClipping.c */; }; + 76EE4E491EB36DE6000254F4 /* Triangulator.c in Sources */ = {isa = PBXBuildFile; fileRef = 76EE4E451EB36DE6000254F4 /* Triangulator.c */; }; + 76EE4E511EB36E53000254F4 /* coin.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 76EE4E4E1EB36E53000254F4 /* coin.atlas */; }; + 76EE4E521EB36E53000254F4 /* coin.json in Resources */ = {isa = PBXBuildFile; fileRef = 76EE4E4F1EB36E53000254F4 /* coin.json */; }; + 76EE4E531EB36E53000254F4 /* coin.png in Resources */ = {isa = PBXBuildFile; fileRef = 76EE4E501EB36E53000254F4 /* coin.png */; }; + 76EE4E561EB36E94000254F4 /* CoinExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EE4E551EB36E94000254F4 /* CoinExample.m */; }; 76F28D161DEC810300CDE54D /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF41DEC810200CDE54D /* Animation.c */; }; 76F28D171DEC810300CDE54D /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF51DEC810300CDE54D /* AnimationState.c */; }; 76F28D181DEC810300CDE54D /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF61DEC810300CDE54D /* AnimationStateData.c */; }; @@ -162,6 +170,15 @@ 765A2EF51D7D7A08003FB779 /* goblins.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = goblins.png; path = Resources/goblins.png; sourceTree = ""; }; 76BF7E051E66ED9C00485998 /* GLUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GLUtils.c; path = src/spine/GLUtils.c; sourceTree = ""; }; 76BF7E061E66ED9C00485998 /* GLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GLUtils.h; path = src/spine/GLUtils.h; sourceTree = ""; }; + 76EE4E421EB36DE6000254F4 /* Array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Array.c; path = "../spine-c/spine-c/src/spine/Array.c"; sourceTree = ""; }; + 76EE4E431EB36DE6000254F4 /* ClippingAttachment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ClippingAttachment.c; path = "../spine-c/spine-c/src/spine/ClippingAttachment.c"; sourceTree = ""; }; + 76EE4E441EB36DE6000254F4 /* SkeletonClipping.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SkeletonClipping.c; path = "../spine-c/spine-c/src/spine/SkeletonClipping.c"; sourceTree = ""; }; + 76EE4E451EB36DE6000254F4 /* Triangulator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Triangulator.c; path = "../spine-c/spine-c/src/spine/Triangulator.c"; sourceTree = ""; }; + 76EE4E4E1EB36E53000254F4 /* coin.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = coin.atlas; path = Resources/coin.atlas; sourceTree = ""; }; + 76EE4E4F1EB36E53000254F4 /* coin.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = coin.json; path = Resources/coin.json; sourceTree = ""; }; + 76EE4E501EB36E53000254F4 /* coin.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = coin.png; path = Resources/coin.png; sourceTree = ""; }; + 76EE4E541EB36E94000254F4 /* CoinExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoinExample.h; path = example/CoinExample.h; sourceTree = ""; }; + 76EE4E551EB36E94000254F4 /* CoinExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CoinExample.m; path = example/CoinExample.m; sourceTree = ""; }; 76F28CF41DEC810200CDE54D /* Animation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Animation.c; path = "../spine-c/spine-c/src/spine/Animation.c"; sourceTree = ""; }; 76F28CF51DEC810300CDE54D /* AnimationState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationState.c; path = "../spine-c/spine-c/src/spine/AnimationState.c"; sourceTree = ""; }; 76F28CF61DEC810300CDE54D /* AnimationStateData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationStateData.c; path = "../spine-c/spine-c/src/spine/AnimationStateData.c"; sourceTree = ""; }; @@ -269,6 +286,8 @@ 76F5BDA91D2BDE67005917E5 /* RaptorExample.m */, 76F5BDAB1D2BDFA2005917E5 /* TankExample.h */, 76F5BDAC1D2BDFA2005917E5 /* TankExample.m */, + 76EE4E541EB36E94000254F4 /* CoinExample.h */, + 76EE4E551EB36E94000254F4 /* CoinExample.m */, 43C32A07170B10FF004A9460 /* AppDelegate.h */, 43C32A08170B10FF004A9460 /* AppDelegate.m */, 43C32A05170B0F93004A9460 /* main.m */, @@ -280,6 +299,10 @@ 43C32822170B0BC2004A9460 /* spine-c */ = { isa = PBXGroup; children = ( + 76EE4E421EB36DE6000254F4 /* Array.c */, + 76EE4E431EB36DE6000254F4 /* ClippingAttachment.c */, + 76EE4E441EB36DE6000254F4 /* SkeletonClipping.c */, + 76EE4E451EB36DE6000254F4 /* Triangulator.c */, 76FAC1941E3FA15E001CCC8C /* Color.c */, 76FAC1951E3FA15E001CCC8C /* PointAttachment.c */, 76F28CF41DEC810200CDE54D /* Animation.c */, @@ -338,6 +361,9 @@ 43C32867170B0C7F004A9460 /* Resources */ = { isa = PBXGroup; children = ( + 76EE4E4E1EB36E53000254F4 /* coin.atlas */, + 76EE4E4F1EB36E53000254F4 /* coin.json */, + 76EE4E501EB36E53000254F4 /* coin.png */, 765A2EF41D7D7A08003FB779 /* goblins.atlas */, 765A2EF51D7D7A08003FB779 /* goblins.png */, 76F5BD9C1D2BDE1C005917E5 /* raptor.atlas */, @@ -515,14 +541,17 @@ 43C3286E170B0DA6004A9460 /* spineboy.atlas in Resources */, 43C3286F170B0DA6004A9460 /* spineboy.png in Resources */, 43C3287D170B0DBE004A9460 /* Default-568h@2x.png in Resources */, + 76EE4E521EB36E53000254F4 /* coin.json in Resources */, 43C3287E170B0DBE004A9460 /* Default-Landscape~ipad.png in Resources */, 43C3287F170B0DBE004A9460 /* Default.png in Resources */, 76F5BDA31D2BDE1C005917E5 /* raptor.json in Resources */, + 76EE4E531EB36E53000254F4 /* coin.png in Resources */, 43C32880170B0DBE004A9460 /* Default@2x.png in Resources */, 765A2EF71D7D7A08003FB779 /* goblins.png in Resources */, 43C32881170B0DBE004A9460 /* Icon-72.png in Resources */, 76F5BDA41D2BDE1C005917E5 /* raptor.png in Resources */, 43C32882170B0DBE004A9460 /* Icon-Small-50.png in Resources */, + 76EE4E511EB36E53000254F4 /* coin.atlas in Resources */, 76F5BDA21D2BDE1C005917E5 /* raptor.atlas in Resources */, 43C32883170B0DBE004A9460 /* Icon-Small.png in Resources */, 43C32884170B0DBE004A9460 /* Icon-Small@2x.png in Resources */, @@ -553,16 +582,20 @@ 76F5BDAA1D2BDE67005917E5 /* RaptorExample.m in Sources */, 76F28D301DEC810300CDE54D /* Skin.c in Sources */, 76F28D251DEC810300CDE54D /* Json.c in Sources */, + 76EE4E491EB36DE6000254F4 /* Triangulator.c in Sources */, 76F28D1C1DEC810300CDE54D /* AttachmentLoader.c in Sources */, + 76EE4E461EB36DE6000254F4 /* Array.c in Sources */, 76F28D241DEC810300CDE54D /* IkConstraintData.c in Sources */, 76F28D1E1DEC810300CDE54D /* BoneData.c in Sources */, 76F28D2A1DEC810300CDE54D /* RegionAttachment.c in Sources */, + 76EE4E471EB36DE6000254F4 /* ClippingAttachment.c in Sources */, 76F28D2C1DEC810300CDE54D /* SkeletonBinary.c in Sources */, 76F5BDAD1D2BDFA2005917E5 /* TankExample.m in Sources */, 76F28D171DEC810300CDE54D /* AnimationState.c in Sources */, 76F28D221DEC810300CDE54D /* extension.c in Sources */, 76F28D231DEC810300CDE54D /* IkConstraint.c in Sources */, 76BF7E071E66ED9C00485998 /* GLUtils.c in Sources */, + 76EE4E481EB36DE6000254F4 /* SkeletonClipping.c in Sources */, 43C3282F170B0C19004A9460 /* spine-cocos2d-objc.m in Sources */, 76F28D1F1DEC810300CDE54D /* BoundingBoxAttachment.c in Sources */, 76F28D281DEC810300CDE54D /* PathConstraint.c in Sources */, @@ -580,6 +613,7 @@ 76F28D1B1DEC810300CDE54D /* Attachment.c in Sources */, 76F28D261DEC810300CDE54D /* MeshAttachment.c in Sources */, 76F28D1A1DEC810300CDE54D /* AtlasAttachmentLoader.c in Sources */, + 76EE4E561EB36E94000254F4 /* CoinExample.m in Sources */, 76F28D211DEC810300CDE54D /* EventData.c in Sources */, 76F28D181DEC810300CDE54D /* AnimationStateData.c in Sources */, 43F7FF891927F94800CA4038 /* SkeletonRenderer.m in Sources */, diff --git a/spine-cocos2d-objc/src/spine/SkeletonRenderer.h b/spine-cocos2d-objc/src/spine/SkeletonRenderer.h index 097062a50..ce4f6217d 100644 --- a/spine-cocos2d-objc/src/spine/SkeletonRenderer.h +++ b/spine-cocos2d-objc/src/spine/SkeletonRenderer.h @@ -46,6 +46,7 @@ spAtlas* _atlas; float* _worldVertices; CCBlendMode* screenMode; + spSkeletonClipping* _clipper; } + (id) skeletonWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData; diff --git a/spine-cocos2d-objc/src/spine/SkeletonRenderer.m b/spine-cocos2d-objc/src/spine/SkeletonRenderer.m index bcd3c8d66..9bf404dad 100644 --- a/spine-cocos2d-objc/src/spine/SkeletonRenderer.m +++ b/spine-cocos2d-objc/src/spine/SkeletonRenderer.m @@ -34,7 +34,7 @@ #import #import "CCDrawNode.h" -static const unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0}; +static unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0}; static spTwoColorBatcher* batcher = 0; static spMesh* mesh = 0; static bool handlerQueued = false; @@ -89,6 +89,8 @@ static bool handlerQueued = false; CCBlendFuncSrcColor: @(GL_ONE), CCBlendFuncDstColor: @(GL_ONE_MINUS_SRC_COLOR)} ]; + + _clipper = spSkeletonClipping_create(); } - (id) initWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData { @@ -153,6 +155,7 @@ static bool handlerQueued = false; if (_atlas) spAtlas_dispose(_atlas); spSkeleton_dispose(_skeleton); FREE(_worldVertices); + spSkeletonClipping_dispose(_clipper); [super dealloc]; } @@ -179,9 +182,10 @@ static bool handlerQueued = false; int blendMode = -1; uint32_t srcBlend = GL_SRC_ALPHA; uint32_t dstBlend = GL_ONE_MINUS_SRC_ALPHA; - const float* uvs = 0; + float* uvs = 0; + float* vertices = _worldVertices; int verticesCount = 0; - const unsigned short* triangles = 0; + unsigned short* triangles = 0; int trianglesCount = 0; float r = 0, g = 0, b = 0, a = 0; float dr = 0, dg = 0, db = 0; @@ -192,7 +196,7 @@ static bool handlerQueued = false; switch (slot->attachment->type) { case SP_ATTACHMENT_REGION: { spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment; - spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices, 0, 2); + spRegionAttachment_computeWorldVertices(attachment, slot->bone, vertices, 0, 2); texture = [self getTextureForRegion:attachment]; uvs = attachment->uvs; verticesCount = 8; @@ -206,7 +210,7 @@ static bool handlerQueued = false; } case SP_ATTACHMENT_MESH: { spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment; - spVertexAttachment_computeWorldVertices(SUPER(attachment), slot, 0, attachment->super.worldVerticesLength, _worldVertices, 0, 2); + spVertexAttachment_computeWorldVertices(SUPER(attachment), slot, 0, attachment->super.worldVerticesLength, vertices, 0, 2); texture = [self getTextureForMesh:attachment]; uvs = attachment->uvs; verticesCount = attachment->super.worldVerticesLength; @@ -218,8 +222,13 @@ static bool handlerQueued = false; a = attachment->color.a; break; } + case SP_ATTACHMENT_CLIPPING: { + spClippingAttachment* clip = (spClippingAttachment*)slot->attachment; + spSkeletonClipping_clipStart(_clipper, slot, clip); + } default: ; } + if (texture) { if (slot->data->blendMode != blendMode) { blendMode = slot->data->blendMode; @@ -261,58 +270,72 @@ static bool handlerQueued = false; GLKVector2 center = GLKVector2Make(size.width / 2.0, size.height / 2.0); GLKVector2 extents = GLKVector2Make(size.width / 2.0, size.height / 2.0); if (_skipVisibilityCheck || CCRenderCheckVisbility(transform, center, extents)) { - if (!self.twoColorTint) { - CCRenderBuffer buffer = [renderer enqueueTriangles:(trianglesCount / 3) andVertexes:verticesCount withState:self.renderState globalSortOrder:0]; - for (int i = 0; i * 2 < verticesCount; ++i) { - CCVertex vertex; - vertex.position = GLKVector4Make(_worldVertices[i * 2], _worldVertices[i * 2 + 1], 0.0, 1.0); - vertex.color = GLKVector4Make(r, g, b, a); - vertex.texCoord1 = GLKVector2Make(uvs[i * 2], 1 - uvs[i * 2 + 1]); - CCRenderBufferSetVertex(buffer, i, CCVertexApplyTransform(vertex, transform)); - } - for (int j = 0; j * 3 < trianglesCount; ++j) { - CCRenderBufferSetTriangle(buffer, j, triangles[j * 3], triangles[j * 3 + 1], triangles[j * 3 + 2]); - } - } else { - if (slot->darkColor) { - dr = slot->darkColor->r; - dg = slot->darkColor->g; - db = slot->darkColor->b; + + if (spSkeletonClipping_isClipping(_clipper)) { + spSkeletonClipping_clipTriangles(_clipper, vertices, verticesCount, triangles, trianglesCount, uvs); + vertices = _clipper->clippedVertices->items; + verticesCount = _clipper->clippedVertices->size; + uvs = _clipper->clippedUVs->items; + triangles = _clipper->clippedTriangles->items; + trianglesCount = _clipper->clippedTriangles->size; + } + + if (trianglesCount > 0) { + if (!self.twoColorTint) { + CCRenderBuffer buffer = [renderer enqueueTriangles:(trianglesCount / 3) andVertexes:verticesCount withState:self.renderState globalSortOrder:0]; + for (int i = 0; i * 2 < verticesCount; ++i) { + CCVertex vertex; + vertex.position = GLKVector4Make(vertices[i * 2], vertices[i * 2 + 1], 0.0, 1.0); + vertex.color = GLKVector4Make(r, g, b, a); + vertex.texCoord1 = GLKVector2Make(uvs[i * 2], 1 - uvs[i * 2 + 1]); + CCRenderBufferSetVertex(buffer, i, CCVertexApplyTransform(vertex, transform)); + } + for (int j = 0; j * 3 < trianglesCount; ++j) { + CCRenderBufferSetTriangle(buffer, j, triangles[j * 3], triangles[j * 3 + 1], triangles[j * 3 + 2]); + } } else { - dr = dg = db = 0; + if (slot->darkColor) { + dr = slot->darkColor->r; + dg = slot->darkColor->g; + db = slot->darkColor->b; + } else { + dr = dg = db = 0; + } + + spMeshPart meshPart; + spMesh_allocatePart(mesh, &meshPart, verticesCount / 2, trianglesCount, self.texture.name, srcBlend, dstBlend); + + spVertex* verts = &meshPart.mesh->vertices[meshPart.startVertex]; + unsigned short* indices = &meshPart.mesh->indices[meshPart.startIndex]; + + for (int i = 0; i * 2 < verticesCount; i++, vertices++) { + CCVertex vertex; + vertex.position = GLKVector4Make(vertices[i * 2], vertices[i * 2 + 1], 0.0, 1.0); + vertex = CCVertexApplyTransform(vertex, transform); + verts->x = vertex.position.x; + verts->y = vertex.position.y; + verts->z = vertex.position.z; + verts->w = vertex.position.w; + verts->color = ((unsigned short)(r * 255))| ((unsigned short)(g * 255)) << 8 | ((unsigned short)(b * 255)) <<16 | ((unsigned short)(a * 255)) << 24; + verts->color2 = ((unsigned short)(dr * 255)) | ((unsigned short)(dg * 255)) << 8 | ((unsigned short)(db * 255)) << 16 | ((unsigned short)(255)) << 24; + verts->u = uvs[i * 2]; + verts->v = 1 - uvs[i * 2 + 1]; + } + + for (int j = 0; j < trianglesCount; j++, indices++) { + *indices = triangles[j]; + } + + [renderer enqueueBlock:^{ + spTwoColorBatcher_add(batcher, meshPart); + } globalSortOrder:0 debugLabel: nil threadSafe: false]; } - - spMeshPart meshPart; - spMesh_allocatePart(mesh, &meshPart, verticesCount / 2, trianglesCount, self.texture.name, srcBlend, dstBlend); - - spVertex* vertices = &meshPart.mesh->vertices[meshPart.startVertex]; - unsigned short* indices = &meshPart.mesh->indices[meshPart.startIndex]; - - for (int i = 0; i * 2 < verticesCount; i++, vertices++) { - CCVertex vertex; - vertex.position = GLKVector4Make(_worldVertices[i * 2], _worldVertices[i * 2 + 1], 0.0, 1.0); - vertex = CCVertexApplyTransform(vertex, transform); - vertices->x = vertex.position.x; - vertices->y = vertex.position.y; - vertices->z = vertex.position.z; - vertices->w = vertex.position.w; - vertices->color = ((unsigned short)(r * 255))| ((unsigned short)(g * 255)) << 8 | ((unsigned short)(b * 255)) <<16 | ((unsigned short)(a * 255)) << 24; - vertices->color2 = ((unsigned short)(dr * 255)) | ((unsigned short)(dg * 255)) << 8 | ((unsigned short)(db * 255)) << 16 | ((unsigned short)(255)) << 24; - vertices->u = uvs[i * 2]; - vertices->v = 1 - uvs[i * 2 + 1]; - } - - for (int j = 0; j < trianglesCount; j++, indices++) { - *indices = triangles[j]; - } - - [renderer enqueueBlock:^{ - spTwoColorBatcher_add(batcher, meshPart); - } globalSortOrder:0 debugLabel: nil threadSafe: false]; } } } + spSkeletonClipping_clipEnd(_clipper, slot); } + spSkeletonClipping_clipEnd2(_clipper); if (self.twoColorTint) { [renderer enqueueBlock:^{