Hi,
Does anyone know if it's somehow possible to change the texture coordinates / rectangles of attachments programmatically? Something like the textureRect property of CCSprites?
Thanks!
Edit: Here is a SkeletonRenderer extension to modify the texture rect, position, rotation and scale of an spRegionAttachment:
Header file:
@interface SkeletonRenderer (Extended)
-(CGRect)getTextureRectOfRegionAttachment:(spRegionAttachment *)attachment contentScale:(float)scale;
-(void)setTextureRect:(CGRect)rect regionAttachment:(spRegionAttachment *)attachment contentScale:(float)scale;
-(CGPoint)getPositionOfRegionAttachment:(spRegionAttachment *)attachment skeletonScale:(float)scale;
-(void)setPosition:(CGPoint)pos regionAttachment:(spRegionAttachment *)attachment skeletonScale:(float)scale;
-(float)getRotationOfRegionAttachment:(spRegionAttachment *)attachment;
-(void)setRotation:(float)rotation regionAttachment:(spRegionAttachment *)attachment;
-(float)getScaleXOfRegionAttachment:(spRegionAttachment *)attachment;
-(float)getScaleYOfRegionAttachment:(spRegionAttachment *)attachment;
-(void)setScaleX:(float)scaleX regionAttachment:(spRegionAttachment *)attachment;
-(void)setScaleY:(float)scaleY regionAttachment:(spRegionAttachment *)attachment;
-(void)updateRegionAttachment:(spRegionAttachment *)attachment;
@end
Main file:
@implementation SkeletonRenderer (Extended)
-(CGRect)getTextureRectOfRegionAttachment:(spRegionAttachment *)attachment contentScale:(float)scale
{
spAtlasRegion *region = (spAtlasRegion *)attachment->rendererObject;
return CGRectMake(region->x / scale, region->y / scale, region->width / scale, region->height / scale);
}
-(void)setTextureRect:(CGRect)rect regionAttachment:(spRegionAttachment *)attachment contentScale:(float)scale
{
spAtlasRegion *region = (spAtlasRegion *)attachment->rendererObject;
region->x = rect.origin.x * scale;
region->y = rect.origin.y * scale;
region->width = rect.size.width * scale;
region->height = rect.size.height * scale;
[self updateRegionAttachment:attachment];
}
-(CGPoint)getPositionOfRegionAttachment:(spRegionAttachment *)attachment skeletonScale:(float)scale
{
return CGPointMake(attachment->x / scale, attachment->y / scale);
}
-(void)setPosition:(CGPoint)pos regionAttachment:(spRegionAttachment *)attachment skeletonScale:(float)scale
{
attachment->x = pos.x * scale;
attachment->y = pos.y * scale;
[self updateRegionAttachment:attachment];
}
-(float)getRotationOfRegionAttachment:(spRegionAttachment *)attachment
{
return attachment->rotation;
}
-(void)setRotation:(float)rotation regionAttachment:(spRegionAttachment *)attachment
{
attachment->rotation = rotation;
[self updateRegionAttachment:attachment];
}
-(float)getScaleXOfRegionAttachment:(spRegionAttachment *)attachment
{
return attachment->scaleX;
}
-(float)getScaleYOfRegionAttachment:(spRegionAttachment *)attachment
{
return attachment->scaleY;
}
-(void)setScaleX:(float)scaleX regionAttachment:(spRegionAttachment *)attachment
{
attachment->scaleX = scaleX;
[self updateRegionAttachment:attachment];
}
-(void)setScaleY:(float)scaleY regionAttachment:(spRegionAttachment *)attachment
{
attachment->scaleY = scaleY;
[self updateRegionAttachment:attachment];
}
-(void)updateRegionAttachment:(spRegionAttachment *)attachment
{
spAtlasRegion *region = (spAtlasRegion *)attachment->rendererObject;
region->u = region->x / (float)region->page->width;
region->v = region->y / (float)region->page->height;
if (region->rotate) {
region->u2 = (region->x + region->height) / (float)region->page->width;
region->v2 = (region->y + region->width) / (float)region->page->height;
} else {
region->u2 = (region->x + region->width) / (float)region->page->width;
region->v2 = (region->y + region->height) / (float)region->page->height;
}
spRegionAttachment_setUVs(attachment, region->u, region->v, region->u2, region->v2, region->rotate);
attachment->regionOffsetX = region->offsetX;
attachment->regionOffsetY = region->offsetY;
attachment->regionWidth = region->width;
attachment->regionHeight = region->height;
attachment->regionOriginalWidth = region->originalWidth;
attachment->regionOriginalHeight = region->originalHeight;
spRegionAttachment_updateOffset(attachment);
}
@end
How to use:
//Get the attachment
spRegionAttachment *attachment = (spRegionAttachment *)[skeleton getAttachment:@"slotName" attachmentName:@"attachmentName"];
//Get the texture rect
CGRect rect = [skeleton getTextureRectOfRegionAttachment:attachment contentScale:CC_CONTENT_SCALE_FACTOR()];
//Set a new texture rect
CGRect newRect = CGRectMake(10, 20, 30, 40);
[skeleton setTextureRect:newRect regionAttachment:attachment contentScale:CC_CONTENT_SCALE_FACTOR()];
//Get the position (use the same scale here that was used when creating the skeleton)
CGPoint pos = [skeleton getPositionOfRegionAttachment:attachment skeletonScale:1.0];
//Set a new position
CGPoint newPos = ccp(10, 20);
[skeleton setPosition:newPos regionAttachment:attachment skeletonScale:1.0];
//Get the scale
float scaleX = [skeleton getScaleXOfRegionAttachment:attachment];
//Set a new scale
float newScaleX = 2;
[skeleton setScaleX:newScaleX regionAttachment:attachment];