Rotating a static shape

Official forum for the Chipmunk2D Physics Library.
Post Reply
rcutshaw
Posts: 6
Joined: Fri Jan 27, 2012 2:00 am
Contact:

Rotating a static shape

Post by rcutshaw »

I've looked through all the articles I can find and still am unable to rotate a static shape before putting it on screen the first time. I have some custom debug draw code enabled, so I see the outline of the shape onscreen. Here's the code I'm using to create the objects and rotate the body and sprite:

Code: Select all

cpBody* finishLineBody = cpBodyNew(INFINITY, INFINITY);

finishLineBody->p = position;  // created the position and passed it in to this method

cpShape* fLineShape = cpPolyShapeNew(finishLineBody, 8, verts, cpvzero);  // verts already created
    
fLineShape->e = 0.3f;
fLineShape->u = 0.7f;
    
CCSprite *finishLineSprite = [CCSprite spriteWithFile:@"finish_line.png"];

finishLineSprite.position = finishLineBody->p;
fLineShape->data = (__bridge void*)finishLineSprite;

// The rotation code
fLineShape->body->a = CC_DEGREES_TO_RADIANS(90.0);
finishLineSprite.rotation = CC_RADIANS_TO_DEGREES(fLineShape->body->a) * -1;
    
cpSpaceAddStaticShape(self.space, fLineShape);
[self addChild:finishLineSprite z:0];

The sprite is rotated 90º as desired, but the shape doesn't get rotated so my collisions don't match the sprite.

My real question is this:  Where, when and how does a shape attached to a body get rotated?  I can see from the debugger output that the tVerts array usually gets updated after a rotation takes place (but I can't find where).

I have another static shape/body/sprite object that I manually rotate when a touch happens and it DOES get rotated correctly.  I'm using the same way of rotating that object and it works there.  That object's tVerts have been updated properly when I break in the debug draw code.

When looking at the tVerts for the finishLineShape/body above in the debug draw code, I notice that the tVerts haven't been updated to reflect the fLineShape->body->a = CC_DEGREES_TO_RADIANS(90.0); call made before adding the shape to the space.

My update method updates the sprite.position, body->a and sprite.rotation as normal:

-(void) update:(ccTime)delta
{
	float timeStep = 0.03f;
	cpSpaceStep(self.space, timeStep);

	// call forEachShape C method to update sprite positions
	cpSpaceEachShape(self.space, &forEachShape, nil);
}

static void forEachShape(cpShape* shape, void* data)
{
	CCSprite* sprite = (__bridge CCSprite*)shape->data;
	if (sprite != nil)
	{
		cpBody* body = shape->body;
		sprite.position = body->p;
		sprite.rotation = CC_RADIANS_TO_DEGREES(body->a) * -1;
	}
}
I've also tried using a mass and momentum of a value other than INFINITY when creating the body. No luck. If I change the mass and momentum AND add the shape as a dynamic shape AND add the body to the space, the rotation works (but this is now a dynamic body/shape/sprite which reacts to gravity - which I don't want).

I'd like to understand the detailed mechanism of rotation of a static shape created with a body and associated with a sprite (also, an understanding of dynamic (non-static) shape rotation).

I assume that a shape created with a body is locked to that body position and rotation angle and so gets rotated when the body gets rotated - is this correct?

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

Re: Rotating a static shape

Post by slembcke »

You can't set the angle of a body directly without causing problems:

Code: Select all

	/// Rotation of the body around it's center of gravity in radians.
	/// Must agree with cpBody.rot! Use cpBodySetAngle() when changing the angle for this reason.
	cpFloat a;
The angle, mass and moment of inertia must be set using the setter functions, and as of Chipmunk 6 it's highly recommended to always use the accessor functions.

Also, you should create a static body using cpBodyNewStatic() instead of an infinite mass rogue body if you really want it to be static and you want to use the sleeping feature. (http://chipmunk-physics.net/release/Chi ... ougeStatic)
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
rcutshaw
Posts: 6
Joined: Fri Jan 27, 2012 2:00 am
Contact:

Re: Rotating a static shape

Post by rcutshaw »

Hi Scott,

Thanks for that information. It corrected my problems. I appreciate all your work and making yourself available to answer these questions. I'm still trying to understand the process of shape updates after rotation. How (and where) do tVerts & tAxes get updated after a call to cpBodySetAngle()?

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

Re: Rotating a static shape

Post by slembcke »

They are updated when the shape is added to the space, right before it inserts it into the spatial index:
https://github.com/slembcke/Chipmunk-Ph ... ace.c#L280
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
rcutshaw
Posts: 6
Joined: Fri Jan 27, 2012 2:00 am
Contact:

Re: Rotating a static shape

Post by rcutshaw »

But let's say you already added the shape to the space and then subsequently rotate the body. What is the method and line number where the tVerts and tAxes are specifically modified? Thanks
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Rotating a static shape

Post by slembcke »

You aren't supposed to modify static shapes after adding them to the space (you told Chipmunk it was static after all).

If you want to modify a static shape, you have to specifically tell Chipmunk to update it by calling one of the cpSpaceReindex*() functions to let it know about the change.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
rcutshaw
Posts: 6
Joined: Fri Jan 27, 2012 2:00 am
Contact:

Re: Rotating a static shape

Post by rcutshaw »

OK, I guess I need to explain more about my application. It's an iOS/Mac game similar to "Bubble Ball" with both static and dynamic shapes which are arranged on the screen BEFORE physics simulation is started with a START button. The static shapes are added to the space AFTER they have been relocated and rotated if necessary by the user in ccTouchMoved. So that is why I want to know as much as possible about the mechanism of both static and dynamic shape movement and rotation on screen. When the START button is pressed, the static shapes are added to the space and the simulation is started. The ball obeys gravity and is deflected by the objects in order to arrive at the goal location. I always use getters and setters but a lot of the code out there in examples seem to mutate the structures directly and when I use code from examples to get started, I sometimes get things working before going through to clean up the code (replace direct access by getters/setters etc.). In the case of the rotation of static shapes, the reason I asked about where and when the tVerts/tAxes get mutated is that I wanted a deeper understanding of the mechanism of these rotations in Chipmunk, something which is not documented (or if it is, I couldn't find it). It's NOT so that I could mutate these structures outside the normal method calls.

I'm asking you to please shed some light on the inner workings of Chipmunk so that I might increase my knowledge of this nice framework and be able to better utilize it in my apps. I'm using Kobold2d with Cocos2D and Chipmunk and this is my first game (although I've been programming Macs and iOS devices for over twenty years, mainly on scientific applications), so I'm still on the steep slope of the gaming learning curve.

Thank you again for all your help. I have a great deal of respect for you for creating a great framework and supporting it so openly. I purchased Objective Chipmunk and plan on incorporating it into my Kobold2D apps after I learn the ropes of basic physics programming. I'm hoping that game programming will be a major part of my efforts in the future.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Rotating a static shape

Post by slembcke »

So regular shapes have their collision data updated each frame during the cpSpaceStep() call right after it updates the positions of all the bodies. Static shapes on the other hand only have their collision detection data updated when first added to the space.

The collision detection data is sort of stored in two places. The shapes store information on their geometry (updated by calling cpShapeUpdate), and the space has spatial indexes that efficiently track which shapes are overlapping (updated by calling one of several of the cpSpatial in functions). Both need to be updated when a shape moves, and the cpSpaceReindex*() functions do exactly that. http://chipmunk-physics.net/release/Chi ... alIndexing

So! As it says in the documentation there, you'd want to call the cpSpaceReindex*() functions in two cases. When you move a static shape, you need to do it as it's the only way it's collision data will get updated. The other case is when you move a regular shape and then need to perform queries against it. Because Chipmunk normally only updates them when you call cpSpaceStep(), the query will only work against the previous position.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Post Reply

Who is online

Users browsing this forum: Metager [Bot] and 5 guests