Created
September 12, 2011 21:38
-
-
Save slembcke/1212534 to your computer and use it in GitHub Desktop.
Chipmunk Pro deformable terrain: DeformableBitmapDemo.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "DeformableBitmapDemo.h" | |
@implementation DeformableBitmapDemo | |
@synthesize space; | |
#define PIXEL_SIZE 4 | |
#define TILE_SIZE 128 | |
- (id) init | |
{ | |
if((self = [super init])){ | |
space = [[ChipmunkSpace alloc] init]; | |
space.gravity = cpv(0, -500); | |
int width = 640; | |
int height = 480; | |
// Subsample the data from a small context for efficiency. | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); | |
sampler = [[ChipmunkCGContextSampler alloc] initWithWidth:width/PIXEL_SIZE height:height/PIXEL_SIZE colorSpace:colorSpace bitmapInfo:kCGImageAlphaNone component:0]; | |
CGColorSpaceRelease(colorSpace); | |
[sampler setBorderValue:1.0]; | |
// The output rectangle should be inset slightly so that we sample pixel centers, not edges. | |
// This along with the tileOffset below will make sure the pixels line up with the geometry perfectly. | |
sampler.outputRect = cpBBNew(0.5*PIXEL_SIZE, 0.5*PIXEL_SIZE, width - 0.5*PIXEL_SIZE, height - 0.5*PIXEL_SIZE); | |
// Samples are spread out over the entire tile size starting at the edges. | |
// You must sample 1 point more than you'd think to line up with the pixels. | |
tiles = [[ChipmunkBasicTileCache alloc] initWithSampler:sampler space:space tileSize:TILE_SIZE samplesPerTile:TILE_SIZE/PIXEL_SIZE + 1]; | |
tiles.tileOffset = cpv(-0.5*PIXEL_SIZE, -0.5*PIXEL_SIZE); // See above | |
tiles.segmentRadius = 1; | |
tiles.simplifyThreshold = 2; | |
// Set the CGContext's transform to match it's Chipmunk coords. | |
CGContextConcatCTM(sampler.context, CGAffineTransformMake(1.0/PIXEL_SIZE, 0.0, 0.0, 1.0/PIXEL_SIZE, 0.0, 0.0)); | |
// Clear it to white. | |
CGContextSetGrayFillColor(sampler.context, 1.0, 1.0); | |
CGContextFillRect(sampler.context, CGRectMake(0, 0, width, height)); | |
// Draw a block in the middle of the screen. | |
CGContextSetGrayFillColor(sampler.context, 0.0, 1.0); | |
CGContextFillRect(sampler.context, CGRectMake(100, 100, width - 200, height - 200)); | |
} | |
return self; | |
} | |
-(void)dealloc | |
{ | |
self.space = nil; | |
[sampler release]; | |
[tiles release]; | |
[super dealloc]; | |
} | |
static cpBB | |
CGRect2cpBB(CGRect r) | |
{ | |
cpFloat l = r.origin.x; | |
cpFloat b = r.origin.y; | |
return cpBBNew(l, b, l + r.size.width, b + r.size.height); | |
} | |
//static cpBB | |
//cpBBDilate(cpBB bb, cpFloat d) | |
//{ | |
// return cpBBNew(bb.l - d, bb.b - d, bb.r + d, bb.t + d); | |
//} | |
-(void)drawEllipseAt:(cpVect)pos | |
{ | |
cpFloat radius = 16; | |
CGRect rect = CGRectMake(pos.x - radius, pos.y - radius, radius*2.0, radius*2.0); | |
CGContextFillEllipseInRect(sampler.context, rect); | |
// CGContextFillRect(sampler.context, rect); | |
[tiles markDirtyRect:CGRect2cpBB(rect)]; | |
} | |
-(void)leftMouse:(cpVect)pos; | |
{ | |
CGContextSetGrayFillColor(sampler.context, 1.0, 1.0); | |
[self drawEllipseAt:pos]; | |
} | |
-(void)drag:(cpVect)pos { | |
[self drawEllipseAt:pos]; | |
} | |
-(void)rightMouse:(cpVect)pos; | |
{ | |
CGContextSetGrayFillColor(sampler.context, 2.0, 1.0); | |
[self drawEllipseAt:pos]; | |
} | |
-(void)step:(cpFloat)dt; | |
{ | |
// Ensure that the geometry for the current screen rect is ready. | |
[tiles ensureRect:cpBBNew(0.0, 0.0, 640.0, 480.0)]; | |
[space step:dt]; | |
} | |
-(void)drawUnderlay | |
{ | |
glPixelZoom(PIXEL_SIZE, -PIXEL_SIZE); | |
glWindowPos2f(0, 480); | |
glDrawPixels(sampler.width, sampler.height, GL_LUMINANCE, GL_UNSIGNED_BYTE, [sampler.pixelData bytes]); | |
} | |
extern void ChipmunkDemoDrawString(int x, int y, const char *str); | |
-(void)drawOverlay | |
{ | |
ChipmunkDemoDrawString(20, 460, | |
"Controls:\n" | |
"Left click to cut holes in the block.\n" | |
"Right click to add to it.\n" | |
"Return to restart the demo.\n" | |
); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment