From b204e97ad2ea5f63d285201c2ac076b86b1cc359 Mon Sep 17 00:00:00 2001 From: folecr Date: Mon, 11 Feb 2013 13:26:40 -0800 Subject: [PATCH] Simpler, correct handling of spritesheet sources * bounds of insets are calculated relative to sprite * transformations are then applied to get the texture coordinates * handle sprites stored rotated in a spritesheet correctly --- .../GUI/CCControlExtension/CCScale9Sprite.cpp | 338 ++++++++---------- 1 file changed, 159 insertions(+), 179 deletions(-) diff --git a/extensions/GUI/CCControlExtension/CCScale9Sprite.cpp b/extensions/GUI/CCControlExtension/CCScale9Sprite.cpp index 7f6f879903..b005f32a6f 100644 --- a/extensions/GUI/CCControlExtension/CCScale9Sprite.cpp +++ b/extensions/GUI/CCControlExtension/CCScale9Sprite.cpp @@ -128,11 +128,11 @@ bool CCScale9Sprite::updateWithBatchNode(CCSpriteBatchNode* batchnode, CCRect re if(this->scale9Image != batchnode) - { - CC_SAFE_RELEASE(this->scale9Image); - scale9Image = batchnode; - CC_SAFE_RETAIN(scale9Image); - } + { + CC_SAFE_RELEASE(this->scale9Image); + scale9Image = batchnode; + CC_SAFE_RETAIN(scale9Image); + } scale9Image->removeAllChildrenWithCleanup(true); @@ -140,12 +140,12 @@ bool CCScale9Sprite::updateWithBatchNode(CCSpriteBatchNode* batchnode, CCRect re // If there is no given rect if ( rect.equals(CCRectZero) ) - { - // Get the texture size as original - CCSize textureSize = scale9Image->getTextureAtlas()->getTexture()->getContentSize(); + { + // Get the texture size as original + CCSize textureSize = scale9Image->getTextureAtlas()->getTexture()->getContentSize(); - rect = CCRectMake(0, 0, textureSize.width, textureSize.height); - } + rect = CCRectMake(0, 0, textureSize.width, textureSize.height); + } // Set the given rect's size as original size m_spriteRect = rect; @@ -153,191 +153,98 @@ bool CCScale9Sprite::updateWithBatchNode(CCSpriteBatchNode* batchnode, CCRect re m_preferredSize = m_originalSize; m_capInsetsInternal = capInsets; - // Get the image edges - float l = rect.origin.x; - float t = rect.origin.y; - float h = rect.size.height; float w = rect.size.width; + float h = rect.size.height; // If there is no specified center region if ( m_capInsetsInternal.equals(CCRectZero) ) - { - // Apply the 3x3 grid format - if (rotated) - { - m_capInsetsInternal = CCRectMake(h/3, w/3, h/3, w/3); - } - else { + // CCLog("... cap insets not specified : using default cap insets ..."); m_capInsetsInternal = CCRectMake(w/3, h/3, w/3, h/3); } - } - // - // Set up the image - // - if (rotated) - { - // Sprite frame is rotated + float left_w = m_capInsetsInternal.origin.x; + float center_w = m_capInsetsInternal.size.width; + float right_w = rect.size.width - (left_w + center_w); - // Centre - centre = new CCSprite(); - centre->initWithTexture(scale9Image->getTexture(), m_capInsetsInternal, true); - scale9Image->addChild(centre, 0, pCentre); + float top_h = m_capInsetsInternal.origin.y; + float center_h = m_capInsetsInternal.size.height; + float bottom_h = rect.size.height - (top_h + center_h); - // Bottom - bottom = new CCSprite(); - bottom->initWithTexture(scale9Image->getTexture(), CCRectMake(l, - m_capInsetsInternal.origin.y, - m_capInsetsInternal.size.width, - m_capInsetsInternal.origin.x - l), - rotated - ); - scale9Image->addChild(bottom, 1, pBottom); + // calculate rects - // Top - top = new CCSprite(); - top->initWithTexture(scale9Image->getTexture(),CCRectMake(m_capInsetsInternal.origin.x + m_capInsetsInternal.size.height, - m_capInsetsInternal.origin.y, - m_capInsetsInternal.size.width, - h - m_capInsetsInternal.size.height - (m_capInsetsInternal.origin.x - l)), - rotated - ); - scale9Image->addChild(top, 1, pTop); + // ... top row + float x = 0.0; + float y = 0.0; - // Right - right = new CCSprite(); - right->initWithTexture(scale9Image->getTexture(), CCRectMake(m_capInsetsInternal.origin.x, - m_capInsetsInternal.origin.y+m_capInsetsInternal.size.width, - w - (m_capInsetsInternal.origin.y-t)-m_capInsetsInternal.size.width, - m_capInsetsInternal.size.height), - rotated - ); - scale9Image->addChild(right, 1, pRight); + // top left + CCRect lefttopbounds = CCRectMake(x, y, + left_w, top_h); - // Left - left = new CCSprite(); - left->initWithTexture(scale9Image->getTexture(), CCRectMake(m_capInsetsInternal.origin.x, - t, - m_capInsetsInternal.origin.y - t, - m_capInsetsInternal.size.height), - rotated - ); - scale9Image->addChild(left ,1, pLeft); - - // Top right - topRight = new CCSprite(); - topRight->initWithTexture(scale9Image->getTexture(), CCRectMake(m_capInsetsInternal.origin.x + m_capInsetsInternal.size.height, - m_capInsetsInternal.origin.y + m_capInsetsInternal.size.width, - w - (m_capInsetsInternal.origin.y-t)-m_capInsetsInternal.size.width, - h - m_capInsetsInternal.size.height - (m_capInsetsInternal.origin.x - l)), - rotated - ); - scale9Image->addChild(topRight ,2 ,pTopRight); - - // Top left - topLeft = new CCSprite(); - topLeft->initWithTexture(scale9Image->getTexture(), CCRectMake(m_capInsetsInternal.origin.x + m_capInsetsInternal.size.height, - t, - m_capInsetsInternal.origin.y - t, - h - m_capInsetsInternal.size.height - (m_capInsetsInternal.origin.x - l)), - rotated - ); - scale9Image->addChild(topLeft, 2, pTopLeft); - - // Bottom right - bottomRight = new CCSprite(); - bottomRight->initWithTexture(scale9Image->getTexture(),CCRectMake(l, - m_capInsetsInternal.origin.y + m_capInsetsInternal.size.width, - w - (m_capInsetsInternal.origin.y-t)-m_capInsetsInternal.size.width, - m_capInsetsInternal.origin.x - l), - rotated - ); - scale9Image->addChild(bottomRight, 2, pBottomRight); - - // Bottom left - bottomLeft = new CCSprite(); - bottomLeft->initWithTexture(scale9Image->getTexture(), CCRectMake(l, - t, - m_capInsetsInternal.origin.y - t, - m_capInsetsInternal.origin.x - l), - rotated - ); - scale9Image->addChild(bottomLeft, 2, pBottomLeft); - } - else - { - // Sprite frame is not rotated - - float origin_x = rect.origin.x; - float origin_y = rect.origin.y; - - float left_w = m_capInsetsInternal.origin.x; - float center_w = m_capInsetsInternal.size.width; - float right_w = rect.size.width - (left_w + center_w); - - float top_h = m_capInsetsInternal.origin.y; - float center_h = m_capInsetsInternal.size.height; - float bottom_h = rect.size.height - (top_h + center_h); - - // calculate rects - - // ... top row - float x = origin_x; - float y = origin_y; - - // top left - CCRect lefttopbounds = CCRectMake(x, y, - left_w, top_h); - - // top center - TRANSLATE_X(x, y, left_w); - CCRect centertopbounds = CCRectMake(x, y, - center_w, top_h); + // top center + TRANSLATE_X(x, y, left_w); + CCRect centertopbounds = CCRectMake(x, y, + center_w, top_h); - // top right - TRANSLATE_X(x, y, center_w); - CCRect righttopbounds = CCRectMake(x, y, - right_w, top_h); + // top right + TRANSLATE_X(x, y, center_w); + CCRect righttopbounds = CCRectMake(x, y, + right_w, top_h); - // ... center row - x = origin_x; - y = origin_y; - TRANSLATE_Y(x, y, top_h); + // ... center row + x = 0.0; + y = 0.0; + TRANSLATE_Y(x, y, top_h); - // center left - CCRect leftcenterbounds = CCRectMake(x, y, - left_w, center_h); + // center left + CCRect leftcenterbounds = CCRectMake(x, y, + left_w, center_h); - // center center - TRANSLATE_X(x, y, left_w); - CCRect centerbounds = CCRectMake(x, y, - center_w, center_h); + // center center + TRANSLATE_X(x, y, left_w); + CCRect centerbounds = CCRectMake(x, y, + center_w, center_h); - // center right - TRANSLATE_X(x, y, center_w); - CCRect rightcenterbounds = CCRectMake(x, y, - right_w, center_h); + // center right + TRANSLATE_X(x, y, center_w); + CCRect rightcenterbounds = CCRectMake(x, y, + right_w, center_h); - // ... bottom row - x = origin_x; - y = origin_y; - TRANSLATE_Y(x, y, top_h); - TRANSLATE_Y(x, y, center_h); + // ... bottom row + x = 0.0; + y = 0.0; + TRANSLATE_Y(x, y, top_h); + TRANSLATE_Y(x, y, center_h); - // bottom left - CCRect leftbottombounds = CCRectMake(x, y, - left_w, bottom_h); + // bottom left + CCRect leftbottombounds = CCRectMake(x, y, + left_w, bottom_h); - // bottom center - TRANSLATE_X(x, y, left_w); - CCRect centerbottombounds = CCRectMake(x, y, - center_w, bottom_h); + // bottom center + TRANSLATE_X(x, y, left_w); + CCRect centerbottombounds = CCRectMake(x, y, + center_w, bottom_h); - // bottom right - TRANSLATE_X(x, y, center_w); - CCRect rightbottombounds = CCRectMake(x, y, - right_w, bottom_h); + // bottom right + TRANSLATE_X(x, y, center_w); + CCRect rightbottombounds = CCRectMake(x, y, + right_w, bottom_h); + + if (!rotated) { + // CCLog("!rotated"); + + CCAffineTransform t = CCAffineTransformMakeIdentity(); + t = CCAffineTransformTranslate(t, rect.origin.x, rect.origin.y); + + centerbounds = CCRectApplyAffineTransform(centerbounds, t); + rightbottombounds = CCRectApplyAffineTransform(rightbottombounds, t); + leftbottombounds = CCRectApplyAffineTransform(leftbottombounds, t); + righttopbounds = CCRectApplyAffineTransform(righttopbounds, t); + lefttopbounds = CCRectApplyAffineTransform(lefttopbounds, t); + rightcenterbounds = CCRectApplyAffineTransform(rightcenterbounds, t); + leftcenterbounds = CCRectApplyAffineTransform(leftcenterbounds, t); + centerbottombounds = CCRectApplyAffineTransform(centerbottombounds, t); + centertopbounds = CCRectApplyAffineTransform(centertopbounds, t); // Centre centre = new CCSprite(); @@ -383,17 +290,90 @@ bool CCScale9Sprite::updateWithBatchNode(CCSpriteBatchNode* batchnode, CCRect re bottomRight = new CCSprite(); bottomRight->initWithTexture(scale9Image->getTexture(), rightbottombounds); scale9Image->addChild(bottomRight, 2, pBottomRight); + } else { + // set up transformation of coordinates + // to handle the case where the sprite is stored rotated + // in the spritesheet + // CCLog("rotated"); + + float midpointx = rect.origin.x + (rect.size.width/2); + float midpointy = rect.origin.y + (rect.size.height/2); + + CCAffineTransform t = CCAffineTransformMakeIdentity(); + + // RIGHT TO LEFT! + t = CCAffineTransformTranslate(t, midpointx, midpointy); + t = CCAffineTransformScale(t, -1.0, -1.0); + t = CCAffineTransformRotate(t, -1.57079633); + t = CCAffineTransformTranslate(t, -midpointx, -midpointy); + + t = CCAffineTransformTranslate(t, rect.origin.x, rect.origin.y); + + centerbounds = CCRectApplyAffineTransform(centerbounds, t); + rightbottombounds = CCRectApplyAffineTransform(rightbottombounds, t); + leftbottombounds = CCRectApplyAffineTransform(leftbottombounds, t); + righttopbounds = CCRectApplyAffineTransform(righttopbounds, t); + lefttopbounds = CCRectApplyAffineTransform(lefttopbounds, t); + rightcenterbounds = CCRectApplyAffineTransform(rightcenterbounds, t); + leftcenterbounds = CCRectApplyAffineTransform(leftcenterbounds, t); + centerbottombounds = CCRectApplyAffineTransform(centerbottombounds, t); + centertopbounds = CCRectApplyAffineTransform(centertopbounds, t); + + // Centre + centre = new CCSprite(); + centre->initWithTexture(scale9Image->getTexture(), centerbounds, true); + scale9Image->addChild(centre, 0, pCentre); + + // Top + top = new CCSprite(); + top->initWithTexture(scale9Image->getTexture(), centertopbounds, true); + scale9Image->addChild(top, 1, pTop); + + // Bottom + bottom = new CCSprite(); + bottom->initWithTexture(scale9Image->getTexture(), centerbottombounds, true); + scale9Image->addChild(bottom, 1, pBottom); + + // Left + left = new CCSprite(); + left->initWithTexture(scale9Image->getTexture(), leftcenterbounds, true); + scale9Image->addChild(left, 1, pLeft); + + // Right + right = new CCSprite(); + right->initWithTexture(scale9Image->getTexture(), rightcenterbounds, true); + scale9Image->addChild(right, 1, pRight); + + // Top left + topLeft = new CCSprite(); + topLeft->initWithTexture(scale9Image->getTexture(), lefttopbounds, true); + scale9Image->addChild(topLeft, 2, pTopLeft); + + // Top right + topRight = new CCSprite(); + topRight->initWithTexture(scale9Image->getTexture(), righttopbounds, true); + scale9Image->addChild(topRight, 2, pTopRight); + + // Bottom left + bottomLeft = new CCSprite(); + bottomLeft->initWithTexture(scale9Image->getTexture(), leftbottombounds, true); + scale9Image->addChild(bottomLeft, 2, pBottomLeft); + + // Bottom right + bottomRight = new CCSprite(); + bottomRight->initWithTexture(scale9Image->getTexture(), rightbottombounds, true); + scale9Image->addChild(bottomRight, 2, pBottomRight); } - + this->setContentSize(rect.size); this->addChild(scale9Image); if (m_bSpritesGenerated) - { - // Restore color and opacity - this->setOpacity(opacity); - this->setColor(color); - } + { + // Restore color and opacity + this->setOpacity(opacity); + this->setColor(color); + } m_bSpritesGenerated = true; return true;