Permalink
Browse files

Skew: Serveral fixes

BatchNode + Skew: works as expected
Manual transform + Skew: works as expected
SpriteTest: added 4 new skew tests
  • Loading branch information...
1 parent fcd90cc commit 60a974486ee1b92f9cccaef8a255c77b5367d772 @ricardoquesada ricardoquesada committed May 22, 2011
View
1 CHANGELOG
@@ -2,6 +2,7 @@ version 1.0 - XX-Jun-2011
. [NEW] Actions: Added SkewTo and SkewBy actions
. [NEW] LabelTTF: Added support for LineBreakMode. Mac only supports Word-Break.
. [NEW] Node / Sprite: Added support for SkewX and SkewY properties
+. [NEW] Tests: Added skewX, skewY tests for sprites and actions. Added linebreak tests for LabelTTF.
. [NEW] TextureCache: Added dumpCachedTextureInfo method. Shows the RAM used by the cached textures (issue #1154)
. [FIX] cocosLive: Fixed memory leaks in NSURLConnection
. [FIX] Sprites: DisplayedFrame returns the correct frame (issue #1182)
View
5 cocos2d-ios.xcodeproj/xcshareddata/xcdebugger/Breakpoints.xcbkptlist
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Bucket
+ type = "4"
+ version = "1.0">
+</Bucket>
View
6 cocos2d/CCNode.m
@@ -638,8 +638,10 @@ -(void) transform
// skew
if ( (skewX_ != 0.0f) || (skewY_ != 0.0f) ) {
- GLfloat m[6] = { 1.0f, tanf(CC_DEGREES_TO_RADIANS(skewY_), tanf(CC_DEGREES_TO_RADIANS(skewX_), 1.0f, 0.0f, 0.0f };
- glMultMatrixf(m);
+ CGAffineTransform skewMatrix = CGAffineTransformMake( 1.0f, tanf(CC_DEGREES_TO_RADIANS(skewY_)), tanf(CC_DEGREES_TO_RADIANS(skewX_)), 1.0f, 0.0f, 0.0f );
+ GLfloat glMatrix[16];
+ CGAffineToGL(&skewMatrix, glMatrix);
+ glMultMatrixf(glMatrix);
}
// scale
View
28 cocos2d/CCSprite.m
@@ -473,26 +473,16 @@ -(void)updateTransform
float radians = -CC_DEGREES_TO_RADIANS(rotation_);
float c = cosf(radians);
float s = sinf(radians);
-
- float matrixB = s * scaleX_;
- if ( skewY_ != 0 )
- {
- // only apply skew if it is non-zero, to avoid
- // cancelling the rotation component
- matrixB *= tanf(CC_DEGREES_TO_RADIANS(skewY_));
- }
-
- float matrixC = -s * scaleY_;
- if ( skewX_ != 0 )
- {
- // only apply skew if it is non-zero to avoid
- // cancelling the rotation component
- matrixC *= tanf(CC_DEGREES_TO_RADIANS(skewX_));
- }
-
- matrix = CGAffineTransformMake( c * scaleX_, matrixB,
- matrixC, c * scaleY_,
+
+ matrix = CGAffineTransformMake( c * scaleX_, s * scaleX_,
+ -s * scaleY_, c * scaleY_,
positionInPixels_.x, positionInPixels_.y);
+ if( skewX_ || skewY_ ) {
+ CGAffineTransform skewMatrix = CGAffineTransformMake(1.0f, tanf(CC_DEGREES_TO_RADIANS(skewY_)),
+ tanf(CC_DEGREES_TO_RADIANS(skewX_)), 1.0f,
+ 0.0f, 0.0f);
+ matrix = CGAffineTransformConcat(skewMatrix, matrix);
+ }
matrix = CGAffineTransformTranslate(matrix, -anchorPointInPixels_.x, -anchorPointInPixels_.y);
View
17 tests/SpriteTest.h
@@ -174,6 +174,23 @@
{}
@end
+@interface SpriteOffsetAnchorSkew : SpriteDemo
+{}
+@end
+
+@interface SpriteBatchNodeOffsetAnchorSkew : SpriteDemo
+{}
+@end
+
+@interface SpriteOffsetAnchorSkewScale : SpriteDemo
+{}
+@end
+
+@interface SpriteBatchNodeOffsetAnchorSkewScale : SpriteDemo
+{}
+@end
+
+
@interface SpriteOffsetAnchorFlip : SpriteDemo
{}
@end
View
341 tests/SpriteTest.m
@@ -23,6 +23,10 @@
@"SpriteBatchNodeOffsetAnchorRotation",
@"SpriteOffsetAnchorScale",
@"SpriteBatchNodeOffsetAnchorScale",
+ @"SpriteOffsetAnchorSkew",
+ @"SpriteBatchNodeOffsetAnchorSkew",
+ @"SpriteOffsetAnchorSkewScale",
+ @"SpriteBatchNodeOffsetAnchorSkewScale",
@"SpriteOffsetAnchorFlip",
@"SpriteBatchNodeOffsetAnchorFlip",
@"SpriteAnimationSplit",
@@ -2135,6 +2139,343 @@ -(NSString *) title
@end
#pragma mark -
+#pragma mark Example SpriteOffsetAnchorSkew
+
+@implementation SpriteOffsetAnchorSkew
+
+-(id) init
+{
+ if( (self=[super init]) ) {
+
+ CGSize s = [[CCDirector sharedDirector] winSize];
+
+ for(int i=0;i<3;i++) {
+ CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
+ [cache addSpriteFramesWithFile:@"animations/grossini.plist"];
+ [cache addSpriteFramesWithFile:@"animations/grossini_gray.plist" textureFile:@"animations/grossini_gray.png"];
+
+ //
+ // Animation using Sprite batch
+ //
+ CCSprite *sprite = [CCSprite spriteWithSpriteFrameName:@"grossini_dance_01.png"];
+ sprite.position = ccp( s.width/4*(i+1), s.height/2);
+
+ CCSprite *point = [CCSprite spriteWithFile:@"r1.png"];
+ point.scale = 0.25f;
+ point.position = sprite.position;
+ [self addChild:point z:1];
+
+ switch(i) {
+ case 0:
+ sprite.anchorPoint = CGPointZero;
+ break;
+ case 1:
+ sprite.anchorPoint = ccp(0.5f, 0.5f);
+ break;
+ case 2:
+ sprite.anchorPoint = ccp(1,1);
+ break;
+ }
+
+ point.position = sprite.position;
+
+ NSMutableArray *animFrames = [NSMutableArray array];
+ for(int i = 0; i < 14; i++) {
+
+ CCSpriteFrame *frame = [cache spriteFrameByName:[NSString stringWithFormat:@"grossini_dance_%02d.png",(i+1)]];
+ [animFrames addObject:frame];
+ }
+ CCAnimation *animation = [CCAnimation animationWithFrames:animFrames];
+ [sprite runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithDuration:2.8f animation:animation restoreOriginalFrame:NO] ]];
+
+ id skewX = [CCSkewBy actionWithDuration:2 skewX:45 skewY:0];
+ id skewX_back = [skewX reverse];
+ id skewY = [CCSkewBy actionWithDuration:2 skewX:0 skewY:45];
+ id skewY_back = [skewY reverse];
+
+ id seq_skew = [CCSequence actions:skewX, skewX_back, skewY, skewY_back, nil];
+ [sprite runAction:[CCRepeatForever actionWithAction:seq_skew]];
+
+ [self addChild:sprite z:0];
+ }
+ }
+ return self;
+}
+
+
+- (void) dealloc
+{
+ CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
+ [cache removeSpriteFramesFromFile:@"animations/grossini.plist"];
+ [cache removeSpriteFramesFromFile:@"animations/grossini_gray.plist"];
+ [super dealloc];
+}
+
+-(NSString *) title
+{
+ return @"Sprite offset + anchor + scale";
+}
+@end
+
+#pragma mark -
+#pragma mark Example SpriteBatchNodeOffsetAnchorSkew
+
+@implementation SpriteBatchNodeOffsetAnchorSkew
+
+-(id) init
+{
+ if( (self=[super init]) ) {
+
+ CGSize s = [[CCDirector sharedDirector] winSize];
+
+ for(int i=0;i<3;i++) {
+ CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
+ [cache addSpriteFramesWithFile:@"animations/grossini.plist"];
+ [cache addSpriteFramesWithFile:@"animations/grossini_gray.plist" textureFile:@"animations/grossini_gray.png"];
+
+ //
+ // Animation using Sprite batch
+ //
+ CCSprite *sprite = [CCSprite spriteWithSpriteFrameName:@"grossini_dance_01.png"];
+ sprite.position = ccp( s.width/4*(i+1), s.height/2);
+
+ CCSprite *point = [CCSprite spriteWithFile:@"r1.png"];
+ point.scale = 0.25f;
+ point.position = sprite.position;
+ [self addChild:point z:200];
+
+ switch(i) {
+ case 0:
+ sprite.anchorPoint = CGPointZero;
+ break;
+ case 1:
+ sprite.anchorPoint = ccp(0.5f, 0.5f);
+ break;
+ case 2:
+ sprite.anchorPoint = ccp(1,1);
+ break;
+ }
+
+ point.position = sprite.position;
+
+ CCSpriteBatchNode *spritebatch = [CCSpriteBatchNode batchNodeWithFile:@"animations/grossini.pvr.gz"];
+ [self addChild:spritebatch];
+
+ NSMutableArray *animFrames = [NSMutableArray array];
+ for(int i = 0; i < 14; i++) {
+
+ CCSpriteFrame *frame = [cache spriteFrameByName:[NSString stringWithFormat:@"grossini_dance_%02d.png",(i+1)]];
+ [animFrames addObject:frame];
+ }
+ CCAnimation *animation = [CCAnimation animationWithFrames:animFrames];
+ [sprite runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithDuration:2.8f animation:animation restoreOriginalFrame:NO] ]];
+
+ id skewX = [CCSkewBy actionWithDuration:2 skewX:45 skewY:0];
+ id skewX_back = [skewX reverse];
+ id skewY = [CCSkewBy actionWithDuration:2 skewX:0 skewY:45];
+ id skewY_back = [skewY reverse];
+
+ id seq_skew = [CCSequence actions:skewX, skewX_back, skewY, skewY_back, nil];
+ [sprite runAction:[CCRepeatForever actionWithAction:seq_skew]];
+
+ [spritebatch addChild:sprite z:i];
+ }
+ }
+ return self;
+}
+
+
+- (void) dealloc
+{
+ CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
+ [cache removeSpriteFramesFromFile:@"animations/grossini.plist"];
+ [cache removeSpriteFramesFromFile:@"animations/grossini_gray.plist"];
+ [super dealloc];
+}
+
+-(NSString *) title
+{
+ return @"SpriteBatchNode offset + anchor + skew";
+}
+@end
+
+#pragma mark -
+#pragma mark Example SpriteOffsetAnchorSkewScale
+
+@implementation SpriteOffsetAnchorSkewScale
+
+-(id) init
+{
+ if( (self=[super init]) ) {
+
+ CGSize s = [[CCDirector sharedDirector] winSize];
+
+ for(int i=0;i<3;i++) {
+ CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
+ [cache addSpriteFramesWithFile:@"animations/grossini.plist"];
+ [cache addSpriteFramesWithFile:@"animations/grossini_gray.plist" textureFile:@"animations/grossini_gray.png"];
+
+ //
+ // Animation using Sprite batch
+ //
+ CCSprite *sprite = [CCSprite spriteWithSpriteFrameName:@"grossini_dance_01.png"];
+ sprite.position = ccp( s.width/4*(i+1), s.height/2);
+
+ CCSprite *point = [CCSprite spriteWithFile:@"r1.png"];
+ point.scale = 0.25f;
+ point.position = sprite.position;
+ [self addChild:point z:1];
+
+ switch(i) {
+ case 0:
+ sprite.anchorPoint = CGPointZero;
+ break;
+ case 1:
+ sprite.anchorPoint = ccp(0.5f, 0.5f);
+ break;
+ case 2:
+ sprite.anchorPoint = ccp(1,1);
+ break;
+ }
+
+ point.position = sprite.position;
+
+ NSMutableArray *animFrames = [NSMutableArray array];
+ for(int i = 0; i < 14; i++) {
+
+ CCSpriteFrame *frame = [cache spriteFrameByName:[NSString stringWithFormat:@"grossini_dance_%02d.png",(i+1)]];
+ [animFrames addObject:frame];
+ }
+ CCAnimation *animation = [CCAnimation animationWithFrames:animFrames];
+ [sprite runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithDuration:2.8f animation:animation restoreOriginalFrame:NO] ]];
+
+ // Skew
+ id skewX = [CCSkewBy actionWithDuration:2 skewX:45 skewY:0];
+ id skewX_back = [skewX reverse];
+ id skewY = [CCSkewBy actionWithDuration:2 skewX:0 skewY:45];
+ id skewY_back = [skewY reverse];
+
+ id seq_skew = [CCSequence actions:skewX, skewX_back, skewY, skewY_back, nil];
+ [sprite runAction:[CCRepeatForever actionWithAction:seq_skew]];
+
+ // Scale
+ id scale = [CCScaleBy actionWithDuration:2 scale:2];
+ id scale_back = [scale reverse];
+ id seq_scale = [CCSequence actions:scale, scale_back, nil];
+ [sprite runAction:[CCRepeatForever actionWithAction:seq_scale]];
+
+
+ [self addChild:sprite z:0];
+ }
+ }
+ return self;
+}
+
+
+- (void) dealloc
+{
+ CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
+ [cache removeSpriteFramesFromFile:@"animations/grossini.plist"];
+ [cache removeSpriteFramesFromFile:@"animations/grossini_gray.plist"];
+ [super dealloc];
+}
+
+-(NSString *) title
+{
+ return @"Sprite anchor + skew + scale";
+}
+@end
+
+#pragma mark -
+#pragma mark Example SpriteBatchNodeOffsetAnchorSkewScale
+
+@implementation SpriteBatchNodeOffsetAnchorSkewScale
+
+-(id) init
+{
+ if( (self=[super init]) ) {
+
+ CGSize s = [[CCDirector sharedDirector] winSize];
+
+ for(int i=0;i<3;i++) {
+ CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
+ [cache addSpriteFramesWithFile:@"animations/grossini.plist"];
+ [cache addSpriteFramesWithFile:@"animations/grossini_gray.plist" textureFile:@"animations/grossini_gray.png"];
+
+ //
+ // Animation using Sprite batch
+ //
+ CCSprite *sprite = [CCSprite spriteWithSpriteFrameName:@"grossini_dance_01.png"];
+ sprite.position = ccp( s.width/4*(i+1), s.height/2);
+
+ CCSprite *point = [CCSprite spriteWithFile:@"r1.png"];
+ point.scale = 0.25f;
+ point.position = sprite.position;
+ [self addChild:point z:200];
+
+ switch(i) {
+ case 0:
+ sprite.anchorPoint = CGPointZero;
+ break;
+ case 1:
+ sprite.anchorPoint = ccp(0.5f, 0.5f);
+ break;
+ case 2:
+ sprite.anchorPoint = ccp(1,1);
+ break;
+ }
+
+ point.position = sprite.position;
+
+ CCSpriteBatchNode *spritebatch = [CCSpriteBatchNode batchNodeWithFile:@"animations/grossini.pvr.gz"];
+ [self addChild:spritebatch];
+
+ NSMutableArray *animFrames = [NSMutableArray array];
+ for(int i = 0; i < 14; i++) {
+
+ CCSpriteFrame *frame = [cache spriteFrameByName:[NSString stringWithFormat:@"grossini_dance_%02d.png",(i+1)]];
+ [animFrames addObject:frame];
+ }
+ CCAnimation *animation = [CCAnimation animationWithFrames:animFrames];
+ [sprite runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithDuration:2.8f animation:animation restoreOriginalFrame:NO] ]];
+
+ // Skew
+ id skewX = [CCSkewBy actionWithDuration:2 skewX:45 skewY:0];
+ id skewX_back = [skewX reverse];
+ id skewY = [CCSkewBy actionWithDuration:2 skewX:0 skewY:45];
+ id skewY_back = [skewY reverse];
+
+ id seq_skew = [CCSequence actions:skewX, skewX_back, skewY, skewY_back, nil];
+ [sprite runAction:[CCRepeatForever actionWithAction:seq_skew]];
+
+ // Scale
+ id scale = [CCScaleBy actionWithDuration:2 scale:2];
+ id scale_back = [scale reverse];
+ id seq_scale = [CCSequence actions:scale, scale_back, nil];
+ [sprite runAction:[CCRepeatForever actionWithAction:seq_scale]];
+
+ [spritebatch addChild:sprite z:i];
+ }
+ }
+ return self;
+}
+
+
+- (void) dealloc
+{
+ CCSpriteFrameCache *cache = [CCSpriteFrameCache sharedSpriteFrameCache];
+ [cache removeSpriteFramesFromFile:@"animations/grossini.plist"];
+ [cache removeSpriteFramesFromFile:@"animations/grossini_gray.plist"];
+ [super dealloc];
+}
+
+-(NSString *) title
+{
+ return @"SpriteBatchNode anchor + skew + scale";
+}
+@end
+
+#pragma mark -
#pragma mark Example SpriteOffsetAnchorFlip
@implementation SpriteOffsetAnchorFlip

0 comments on commit 60a9744

Please sign in to comment.