abitofcode

Building a depth map for cocos2d in Photoshop

After the Create data with Photoshop and Irregular touch detection, when CGRect is not enough – part 1 articles last July I started to write a follow up showing another use of the raw data format. I’ve just found the source code and notes I’d put together so I figured I’d throw it up in it’s rough form (the youtube video’s been linking to an unpublished article for about a year :S )

The result

The approach uses a greyscale image saved out in raw format to provide us with height information based on pixel position. In the example project (download link at bottom of page) I use this to affect the scale of a sprite, this can be seen in the video. Each pixel has 256 possible values, I’ve used 0 to represent the highest points and 255 the lowest.

I’ve thrown all the code into the HelloWorld layer and this example uses 1 pixel in the depth map to represent 1 pixel in the hill image, if you don’t need this level of accuracy you could make your depth map smaller and adjust your calculation for the offset. The depth map itself was created in photoshop using the gradient tool.

The resources

The resource link contains the Photoshop document and a copy of the depth map and the ‘hill’ images.

Fig 1.The visible map and the depth data

The depth map image above contains ‘ff’ values as it approaches the end of the file as the bottom right of the depth map is white (see above). We can check this in the terminal.

>hexdump depth.raw | tail
0075250 dc db dc dd dd de dd dd df df df df e0 e0 e1 e2
0075260 e2 e2 e3 e2 e3 e4 e5 e5 e4 e5 e6 e6 e7 e7 e6 e8
0075270 e8 e8 e9 ea e9 ea eb ea eb eb ec ec ed ed ed ed
0075280 ee ef ee ef ef f0 f1 f1 f0 f1 f2 f1 f2 f2 f3 f3
0075290 f4 f4 f3 f4 f4 f5 f6 f5 f6 f6 f7 f7 f7 f8 f7 f8
00752a0 f9 f9 f9 f9 fa fa fa fa fb fb fb fc fb fc fc fc
00752b0 fc fe fe fd fd fe ff fd fe ff ff ff ff ff ff ff
00752c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
*
0075300

>printf “%d\n” 0×0075300
480000

The work is done here;

-(int)getHeightAtPoint:(CGPoint)pt
{
  // set the value to -1, a default no data at point
  int retValue = -1;
 
  // if the image lookup data is present and the value is within the bounds of the image
  if(self.depthData && CGRectContainsPoint(CGRectMake(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT), pt)) 
  {
    // The raw data assumes a top left origin
    pt.y = (IMAGE_HEIGHT - pt.y) - 1;       
 
    // calculate an offset
    int offset = pt.y * IMAGE_WIDTH + pt.x;
 
    // get the data at the offset
    NSRange range = {offset,sizeof(Byte)};
    NSData *pixelValue = [depthData subdataWithRange:range];  
 
    retValue = *(int*)[pixelValue bytes];
 
    // We want 255 to be the lowest value
    retValue = 255 - retValue;
  }
  return retValue;
}

[Download not found]
[Download not found]

2 Comments

  1. Reminds me of collision mapping from “back in the day”, except this is easier to implement. Cheers!

  2. Pingback: List of Open Source Cocos2d Projects, Extensions and Code Snippets | iUridium

%d bloggers like this: