Skip to content

Instantly share code, notes, and snippets.

@seanh
Created September 15, 2011 14:44
Show Gist options
  • Save seanh/1219425 to your computer and use it in GitHub Desktop.
Save seanh/1219425 to your computer and use it in GitHub Desktop.
Computing the "full bounding box" of a CCNode in Cocos2D. (Put this code in a CCNode subclass.)
/*!
Return the -boundingBox of another node, converted into this node's local
coordinate space.
*/
-(CGRect) boundingBoxConvertedToNodeSpace:(CCNode *)other
{
// Get the bottomLeft and topRight corners of the other node's bounding box
// in the other node's coordinate space.
CGRect boundingBox = [other boundingBox];
CGPoint bottomLeft = CGPointMake(boundingBox.origin.x, boundingBox.origin.y);
CGPoint topRight = CGPointMake(boundingBox.origin.x + boundingBox.size.width, boundingBox.origin.y + boundingBox.size.height);
// Convert bottomLeft and topRight to the global coordinate space.
CGPoint worldSpaceBottomLeft = [other.parent convertToWorldSpace:bottomLeft];
CGPoint worldSpaceTopRight = [other.parent convertToWorldSpace:topRight];
// Convert worldSpaceBottomLeft and worldSpaceTopRight into this node's
// local coordinate space.
CGPoint nodeSpaceBottomLeft = [self.parent convertToNodeSpace:worldSpaceBottomLeft];
CGPoint nodeSpaceTopRight = [self.parent convertToNodeSpace:worldSpaceTopRight];
// Finally, construct the bounding box in this node's local coordinate space
// and return it.
float width = nodeSpaceTopRight.x - nodeSpaceBottomLeft.x;
float height = nodeSpaceTopRight.y - nodeSpaceBottomLeft.y;
return CGRectMake(nodeSpaceBottomLeft.x, nodeSpaceBottomLeft.y, width, height);
}
/*!
Return a CGRect computed as the union of this node's -boundingBox and those of
this node's descendant nodes.
*/
-(CGRect) fullBoundingBox
{
NSMutableArray *stack = [[NSMutableArray new] autorelease];
float leftmost = [self boundingBox].origin.x;
float rightmost = leftmost + [self boundingBox].size.width;
float lowest = [self boundingBox].origin.y;
float highest = lowest + [self boundingBox].size.height;
for (CCNode *child in self.children) { [stack addObject:child]; }
while ([stack count] > 0)
{
CCNode *node = [[stack lastObject] retain];
[stack removeLastObject];
CGRect bb = [self boundingBoxConvertedToNodeSpace:node];
float nodeleftmost = bb.origin.x;
float noderightmost = bb.origin.x + bb.size.width;
float nodelowest = bb.origin.y;
float nodehighest = bb.origin.y + bb.size.height;
leftmost = fmin(leftmost,nodeleftmost);
rightmost = fmax(rightmost,noderightmost);
lowest = fmin(lowest,nodelowest);
highest = fmax(highest,nodehighest);
for (CCNode *child in node.children)
{
[stack addObject:child];
}
[node release];
}
float width = rightmost - leftmost;
float height = highest - lowest;
return CGRectMake(leftmost,lowest,width,height);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment