Shape and body in wrong position, Objective Chipmunk

Discuss any Chipmunk bugs here.
Post Reply
EndreOlah
Posts: 4
Joined: Sat Feb 04, 2012 3:09 pm
Contact:

Shape and body in wrong position, Objective Chipmunk

Post by EndreOlah »

Hi,

I have a very simple code for setting up a sprite and its body. It works fine on a regular display, but when I change to retina display, the sprite is at its normal place (off course Cocos is showing the double sized sprite), but the shape and body of the sprite is just half sized and its place is also at the half coordinates. I could fix the size of the shape, but I do not know how to adjust the position of the shape to get them at the double coordinate values. As the synchronization of the body and the sprite is done somewhere in Chipmunk, I guess there is a possibility to tell to Chipmunk that it has to double the coordinates for the shape and body, but to keep the sprite coordinates.

Here is my code:

sprite =[CCSprite spriteWithSpriteFrameName:@"Gino_Front_Jump 1.png"];
standFrame =[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"Gino_Front_Jump 1.png"];

CGRect Rect2=sprite.boundingBox;
cpFloat mass = Rect2.size.width*Rect2.size.height/4096.0f;
body = [ChipmunkCocosBody bodyWithMass:mass andMoment:cpMomentForBox(mass, Rect2.size.width, Rect2.size.height)];
body.pos = cpv(pos.x*GameScale,pos.y*GameScale);

int num = 12;
CGPoint verts[] = {
cpv(-7.5f*GameScale, -27.5f*GameScale),
cpv(-15.0f*GameScale, -14.0f*GameScale),
cpv(-14.0f*GameScale, 13.5f*GameScale),
cpv(-13.5f*GameScale, 14.4f*GameScale),
cpv(-11.0f*GameScale, 17.0f*GameScale),
cpv(-1.5f*GameScale, 22.5f*GameScale),
cpv(0.5f*GameScale, 22.5f*GameScale),
cpv(10.0f*GameScale, 17.0f*GameScale),
cpv(12.5f*GameScale, 14.5f*GameScale),
cpv(13.0f*GameScale, 13.5f*GameScale),
cpv(14.0f*GameScale, -14.0f*GameScale),
cpv(6.5f*GameScale, -27.5f*GameScale)
};

ChipmunkShape * shape = [ChipmunkPolyShape polyWithBody:body count:num verts:verts offset:cpv(0,0)];

shape.elasticity = 0.0f;
shape.friction = 1.0f;
shape.layers = 1;
// The collision type controls what collision callbacks will be triggered when this shape touches other shapes.
// See more in GameWorld about how.
shape.collisionType = type;
shape.data = self;

// Now the rest of the lines finish initializing the game object.

// Create a set with all the physics objects in it. This fullfils the ChipmunkObject protocol.
chipmunkObjects = [[NSArray alloc] initWithObjects:body, shape, nil];

// Create an array of sprites
sprites = [[NSArray alloc] initWithObjects:sprite, nil];

body.syncedNodes = sprites;

I appreciate any help.
EndreOlah
Posts: 4
Joined: Sat Feb 04, 2012 3:09 pm
Contact:

Re: Shape and body in wrong position, Objective Chipmunk

Post by EndreOlah »

Finally, I had an idea to search for the use of the syncednodes variable and I have found that the ChipmunkCocosBody.m is updated the nodes, but the display scale is not considered at all, so I have changed a line from

node.position = body->p

to

node.position = ccp(body->p.x/CC_CONTENT_SCALE_FACTOR(),body->p.y/CC_CONTENT_SCALE_FACTOR());

as this line is now changing the sprite position to the body location in points and not in pixels, I have to upscale the body and shape coordinates to the pixel coordinates. But this is quote easy, so my problem is solved. I just can hope that nothing else is effected by this in the physics engine. :)))
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Shape and body in wrong position, Objective Chipmunk

Post by slembcke »

Older versions of the ChipmunkDebugNode code weren't retina compatible. (It looks like the one bundled with the AngryChipmunks is outdated) The draw method should look like this (note the glScalef()):

Code: Select all

-(void) draw;
{
	glDisableClientState(GL_COLOR_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisable(GL_TEXTURE_2D);
	
	glPushMatrix(); {
		glScalef(CC_CONTENT_SCALE_FACTOR(), CC_CONTENT_SCALE_FACTOR(), 1.0);
		glLineWidth(1.0f);
		cpSpaceEachShape(space.space, drawShape, NULL);
		
		glColor4f(0.5f, 1.0f, 0.5f, 1.0f);
		cpSpaceEachConstraint(space.space, drawConstraint, NULL);
	} glPopMatrix();
	
	glEnableClientState(GL_COLOR_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glEnable(GL_TEXTURE_2D);
}
I'm not really sure why it was implemented in Cocos2D that OpenGL rendering operates in pixels instead of points (like it was actually harder to make it be that way), but that's the way it is.

You do *NOT* want to be dividing the position of the object and rescaling the shapes and body properties based on CC_CONTENT_SCALE. That will mess up a lot of your physics unless you are really careful and understand how the scale affects all the different units. Keep it all in points.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
EndreOlah
Posts: 4
Joined: Sat Feb 04, 2012 3:09 pm
Contact:

Re: Shape and body in wrong position, Objective Chipmunk

Post by EndreOlah »

Hi Slembecke,

the problem is that Cocos2D sprites are still operated in points and not in pixels, so whatever I use for locations on touches for example I get in points instead of pixels, but everything which is related to bodies or shapes have to be upscaled by 2 to get it working on retina displays.

So when I address a body.pos than the vector coordinates need to be double to retina display. The same for the body.vel properties. If I do not double this vectors, than everything is messed up.

Also I as I have mentioned the shapes have to be upscaled too.

So my code became a little bit messy as when I talk to Cocos2D then I have to use simple coordinates, but when I work with Chipmunk I need to add *CC_CONTENT_SCALE_FACTOR() all the times.

Regards

Endre
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Shape and body in wrong position, Objective Chipmunk

Post by slembcke »

No no. Chipmunk is not operating in points or even pixels. It has no idea what either are. It simply works in whatever scale you want. If you are giving coordinates to Chipmunk measured in points, then it will be simulating them in points. If you send it coordinates in kilometers, then it will be simulating them in kilometers.

I think the issue that you were having is that you were assuming that things were half as big as they really were because of the ChipmunkDebugNode. Cocos2D sets up rendering to happen in pixels and you have to manually scale things to match points, so the debug node was rendering pixels instead of points. The fix I showed above will fix that. The simulation itself was still happening in points.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
EndreOlah
Posts: 4
Joined: Sat Feb 04, 2012 3:09 pm
Contact:

Re: Shape and body in wrong position, Objective Chipmunk

Post by EndreOlah »

Hi Slembecke,

thanks for the correction. It!s working well. Honestly I did not expect that the problem is coming only from the debug draw, as bodies were working according to the drawn shapes and not according to the sprite positions. But it shows that I need to be more familiar with the Chipmunk background.

Thanks again and regards

Endre
rlesko
Posts: 1
Joined: Sun Apr 22, 2012 9:22 am
Contact:

Re: Shape and body in wrong position, Objective Chipmunk

Post by rlesko »

Im a little confused about this. Which draw method is replaced with the one you have posted?
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests