diff --git a/spine-cocos2d-iphone/example/ExampleLayer.m b/spine-cocos2d-iphone/example/ExampleLayer.m index ffb509c59..5153a54ff 100644 --- a/spine-cocos2d-iphone/example/ExampleLayer.m +++ b/spine-cocos2d-iphone/example/ExampleLayer.m @@ -26,6 +26,10 @@ [self scheduleUpdate]; +#if __CC_PLATFORM_MAC + [self setMouseEnabled:YES]; +#endif + return self; } @@ -37,4 +41,17 @@ } } +#if __CC_PLATFORM_MAC +- (BOOL) ccMouseDown:(NSEvent*)event { + CCDirector* director = [CCDirector sharedDirector]; + NSPoint location = [director convertEventToGL:event]; + location.x -= [[director runningScene]position].x; + location.y -= [[director runningScene]position].y; + location.x -= skeletonNode.position.x; + location.y -= skeletonNode.position.y; + if (CGRectContainsPoint(skeletonNode.boundingBox, location)) NSLog(@"Clicked!"); + return YES; +} +#endif + @end diff --git a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.h b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.h index 345c49e03..08242a050 100644 --- a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.h +++ b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.h @@ -34,6 +34,7 @@ namespace spine { extern "C" { #endif +ccV3F_C4B_T2F_Quad* RegionAttachment_updateQuad (Attachment* self, Slot* slot); ccV3F_C4B_T2F_Quad* RegionAttachment_getQuad (RegionAttachment* self); #ifdef __cplusplus diff --git a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m index 70d12e381..abc2fefca 100644 --- a/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m +++ b/spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m @@ -94,7 +94,7 @@ void _Cocos2dRegionAttachment_dispose (Attachment* self) { FREE(self); } -void _Cocos2dRegionAttachment_draw (Attachment* attachment, Slot* slot) { +ccV3F_C4B_T2F_Quad* RegionAttachment_updateQuad (Attachment* attachment, Slot* slot) { Cocos2dRegionAttachment* self = SUB_CAST(Cocos2dRegionAttachment, attachment); Cocos2dSkeleton* skeleton = SUB_CAST(Cocos2dSkeleton, slot->skeleton); @@ -130,12 +130,21 @@ void _Cocos2dRegionAttachment_draw (Attachment* attachment, Slot* slot) { quad->br.vertices.x = offset[6] * slot->bone->m00 + offset[7] * slot->bone->m01 + slot->bone->worldX; quad->br.vertices.y = offset[6] * slot->bone->m10 + offset[7] * slot->bone->m11 + slot->bone->worldY; + return quad; +} + +void _Cocos2dRegionAttachment_draw (Attachment* attachment, Slot* slot) { + RegionAttachment_updateQuad(attachment, slot); + + Cocos2dRegionAttachment* self = SUB_CAST(Cocos2dRegionAttachment, attachment); + Cocos2dSkeleton* skeleton = SUB_CAST(Cocos2dSkeleton, slot->skeleton); + // Cocos2d doesn't handle batching for us, so we'll just force a single texture per skeleton. skeleton->node->textureAtlas = self->textureAtlas; while (self->textureAtlas.capacity <= skeleton->node->quadCount) { if (![self->textureAtlas resizeCapacity:self->textureAtlas.capacity * 2]) return; } - [self->textureAtlas updateQuad:quad atIndex:skeleton->node->quadCount++]; + [self->textureAtlas updateQuad:&self->quad atIndex:skeleton->node->quadCount++]; } RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) { @@ -304,7 +313,7 @@ char* _Util_readFile (const char* path, int* length) { skeleton->a = self.opacity / (float)255; quadCount = 0; - for (int i = 0, n = skeleton->slotCount; i < n; i++) + for (int i = 0, n = skeleton->slotCount; i < n; ++i) if (skeleton->slots[i]->attachment) Attachment_draw(skeleton->slots[i]->attachment, skeleton->slots[i]); if (textureAtlas) [textureAtlas drawNumberOfQuads:quadCount]; @@ -313,7 +322,7 @@ char* _Util_readFile (const char* path, int* length) { ccDrawColor4B(0, 0, 255, 255); glLineWidth(1); CGPoint points[4]; - for (int i = 0, n = skeleton->slotCount; i < n; i++) { + for (int i = 0, n = skeleton->slotCount; i < n; ++i) { if (!skeleton->slots[i]->attachment) continue; ccV3F_C4B_T2F_Quad* quad = &((Cocos2dRegionAttachment*)skeleton->slots[i]->attachment)->quad; points[0] = ccp(quad->bl.vertices.x, quad->bl.vertices.y); @@ -327,7 +336,7 @@ char* _Util_readFile (const char* path, int* length) { // Bone lengths. glLineWidth(2); ccDrawColor4B(255, 0, 0, 255); - for (int i = 0, n = skeleton->boneCount; i < n; i++) { + for (int i = 0, n = skeleton->boneCount; i < n; ++i) { Bone *bone = skeleton->bones[i]; float x = bone->data->length * bone->m00 + bone->worldX; float y = bone->data->length * bone->m10 + bone->worldY; @@ -336,7 +345,7 @@ char* _Util_readFile (const char* path, int* length) { // Bone origins. ccPointSize(4); ccDrawColor4B(0, 0, 255, 255); // Root bone is blue. - for (int i = 0, n = skeleton->boneCount; i < n; i++) { + for (int i = 0, n = skeleton->boneCount; i < n; ++i) { Bone *bone = skeleton->bones[i]; ccDrawPoint(ccp(bone->worldX, bone->worldY)); if (i == 0) ccDrawColor4B(0, 255, 0, 255); @@ -344,6 +353,33 @@ char* _Util_readFile (const char* path, int* length) { } } +- (CGRect) boundingBox { + float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN; + for (int i = 0; i < skeleton->slotCount; ++i) { + Slot* slot = skeleton->slots[i]; + Attachment* attachment = slot->attachment; + if (attachment->type != ATTACHMENT_REGION) continue; + Cocos2dRegionAttachment* regionAttachment = SUB_CAST(Cocos2dRegionAttachment, attachment); + minX = fmin(minX, regionAttachment->quad.bl.vertices.x); + minY = fmin(minY, regionAttachment->quad.bl.vertices.y); + maxX = fmax(maxX, regionAttachment->quad.bl.vertices.x); + maxY = fmax(maxY, regionAttachment->quad.bl.vertices.y); + minX = fmin(minX, regionAttachment->quad.br.vertices.x); + minY = fmin(minY, regionAttachment->quad.br.vertices.y); + maxX = fmax(maxX, regionAttachment->quad.br.vertices.x); + maxY = fmax(maxY, regionAttachment->quad.br.vertices.y); + minX = fmin(minX, regionAttachment->quad.tl.vertices.x); + minY = fmin(minY, regionAttachment->quad.tl.vertices.y); + maxX = fmax(maxX, regionAttachment->quad.tl.vertices.x); + maxY = fmax(maxY, regionAttachment->quad.tl.vertices.y); + minX = fmin(minX, regionAttachment->quad.tr.vertices.x); + minY = fmin(minY, regionAttachment->quad.tr.vertices.y); + maxX = fmax(maxX, regionAttachment->quad.tr.vertices.x); + maxY = fmax(maxY, regionAttachment->quad.tr.vertices.y); + } + return CGRectMake(minX, minY, maxX - minX, maxY - minY); +} + // Convenience methods: - (void) setMix:(NSString*)fromName to:(NSString*)toName duration:(float)duration { diff --git a/spine-cocos2dx/src/spine/spine-cocos2dx.cpp b/spine-cocos2dx/src/spine/spine-cocos2dx.cpp index 62e22f602..579ae15d3 100644 --- a/spine-cocos2dx/src/spine/spine-cocos2dx.cpp +++ b/spine-cocos2dx/src/spine/spine-cocos2dx.cpp @@ -27,6 +27,8 @@ #include USING_NS_CC; +using std::min; +using std::max; namespace spine { void _Cocos2dxAtlasPage_dispose (AtlasPage* page) { @@ -186,6 +188,33 @@ void CCSkeleton::draw () { } } +CCRect CCSkeleton::boundingBox () { + float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN; + for (int i = 0; i < skeleton->slotCount; ++i) { + Slot* slot = skeleton->slots[i]; + Attachment* attachment = slot->attachment; + if (attachment->type != ATTACHMENT_REGION) continue; + Cocos2dxRegionAttachment* regionAttachment = SUB_CAST(Cocos2dxRegionAttachment, attachment); + minX = min(minX, regionAttachment->quad.bl.vertices.x); + minY = min(minY, regionAttachment->quad.bl.vertices.y); + maxX = max(maxX, regionAttachment->quad.bl.vertices.x); + maxY = max(maxY, regionAttachment->quad.bl.vertices.y); + minX = min(minX, regionAttachment->quad.br.vertices.x); + minY = min(minY, regionAttachment->quad.br.vertices.y); + maxX = max(maxX, regionAttachment->quad.br.vertices.x); + maxY = max(maxY, regionAttachment->quad.br.vertices.y); + minX = min(minX, regionAttachment->quad.tl.vertices.x); + minY = min(minY, regionAttachment->quad.tl.vertices.y); + maxX = max(maxX, regionAttachment->quad.tl.vertices.x); + maxY = max(maxY, regionAttachment->quad.tl.vertices.y); + minX = min(minX, regionAttachment->quad.tr.vertices.x); + minY = min(minY, regionAttachment->quad.tr.vertices.y); + maxX = max(maxX, regionAttachment->quad.tr.vertices.x); + maxY = max(maxY, regionAttachment->quad.tr.vertices.y); + } + return CCRectMake(minX, minY, maxX - minX, maxY - minY); +} + // Convenience methods: void CCSkeleton::setMix (const char* fromName, const char* toName, float duration) { @@ -255,7 +284,7 @@ void _Cocos2dxRegionAttachment_dispose (Attachment* self) { FREE(self); } -void _Cocos2dxRegionAttachment_draw (Attachment* attachment, Slot* slot) { +ccV3F_C4B_T2F_Quad* RegionAttachment_updateQuad (Attachment* attachment, Slot* slot) { Cocos2dxRegionAttachment* self = SUB_CAST(Cocos2dxRegionAttachment, attachment); Cocos2dxSkeleton* skeleton = SUB_CAST(Cocos2dxSkeleton, slot->skeleton); @@ -291,12 +320,21 @@ void _Cocos2dxRegionAttachment_draw (Attachment* attachment, Slot* slot) { quad->br.vertices.x = offset[6] * slot->bone->m00 + offset[7] * slot->bone->m01 + slot->bone->worldX; quad->br.vertices.y = offset[6] * slot->bone->m10 + offset[7] * slot->bone->m11 + slot->bone->worldY; - // cocos2dx doesn't handle batching for us, so we'll just force a single texture per skeleton. + return quad; +} + +void _Cocos2dxRegionAttachment_draw (Attachment* attachment, Slot* slot) { + RegionAttachment_updateQuad(attachment, slot); + + Cocos2dxRegionAttachment* self = SUB_CAST(Cocos2dxRegionAttachment, attachment); + Cocos2dxSkeleton* skeleton = SUB_CAST(Cocos2dxSkeleton, slot->skeleton); + + // cocos2dx doesn't handle batching for us, so we force a single texture per skeleton. skeleton->node->textureAtlas = self->textureAtlas; while (self->textureAtlas->getCapacity() <= skeleton->node->quadCount) { if (!self->textureAtlas->resizeCapacity(self->textureAtlas->getCapacity() * 2)) return; } - self->textureAtlas->updateQuad(quad, skeleton->node->quadCount++); + self->textureAtlas->updateQuad(&self->quad, skeleton->node->quadCount++); } RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) { diff --git a/spine-cocos2dx/src/spine/spine-cocos2dx.h b/spine-cocos2dx/src/spine/spine-cocos2dx.h index 764d71e26..167c4aa1f 100644 --- a/spine-cocos2dx/src/spine/spine-cocos2dx.h +++ b/spine-cocos2dx/src/spine/spine-cocos2dx.h @@ -102,6 +102,7 @@ public: virtual void update (float deltaTime); virtual void draw (); + virtual cocos2d::CCRect boundingBox (); // CCBlendProtocol CC_PROPERTY(cocos2d::ccBlendFunc, blendFunc, BlendFunc); @@ -115,6 +116,8 @@ typedef struct { cocos2d::CCTextureAtlas* textureAtlas; } Cocos2dxRegionAttachment; +cocos2d::ccV3F_C4B_T2F_Quad* RegionAttachment_updateQuad (Attachment* self, Slot* slot); + } #endif /* SPINE_COCOS2DX_H_ */