Page 1 of 1

seesaw platform problem

Posted: Mon Jul 02, 2012 5:15 pm
by JohnL
I have a bar completely across the screen and it moves in a seesaw fashion 10 degrees either way moving in 0.1 degree steps. The bar is a rogue body and I change the angle.

The center point of the bar is in the middle of the screen.

A ball sits on top of this bar and will roll from left to right and vice versa when it tilts the other way.

It is all working apart from the ball will looks a little off the line by about 2-4 pixels in the air when it tilt downward like it not able to catch up the falling momentum of the see-saw.

// m_floor_angle value ranges from -10.0f to 10.0f

Code: Select all

 cpFloat floorAngle = m_floor_angle < 0 ? 360 + m_floor_angle : m_floor_angle;
    cpFloat a = fmod(floorAngle * M_PI / 180.0f, 360);    
    m_moveableFloorBody->w = 0.0f;
    cpBodySetAngle(m_moveableFloorBody, a);
    cpSpaceReindexShapesForBody(m_space, m_moveableFloorBody);
I've tried setting m_moveableFloorBody->w to a value other than 0.0f and it makes it worst depending on which side of the seesaw the ball currently sits on.

I've tried various other things such as setting the ball velocity to make it catch up the falling see-saw but it doesn't seem to work well.

Is there a solution to this?

Re: seesaw platform problem

Posted: Mon Jul 02, 2012 6:03 pm
by slembcke
The issue is that by setting the angle (or position) explicitly you are effectively teleporting the seesaw to the new angle each step. The angular velocity (w) is never set, so objects colliding with it will act as though it wasn't actually moving. So when the platform moves away from the ball, the ball is suddenly sitting on nothing and will start falling. Eventually it may catch up seesaw and collide with it, but because it has an angular velocity of 0 it will collide as if it hit a solid non moving object and stop. Then the seesaw will teleport out from underneath it again and the process will repeat.

So yes, you do need to set the angular velocity, but it sounds like you were setting it to a constant. That won't really work. It's really easy to calculate the actual angular velocity assuming you know your timestep:

Code: Select all

newAngle = ...;
cpBodySetAngVel(body, (newAngle/cpBodyGetAngVel(body))/dt);
cpBodySetAngle(body, newAngle);
Alternatively, you can control the tilt of the seesaw using an animated constraint. Basically you'd create a gear joint with a ratio 1.0 and make it soft by setting the maxForce property something finite. Then animate the phase property to make the seesaw rock back and forth. This isn't a very obvious way to control objects, but it works extremely well if you want the physics to respect finite force limits. See the Crane or Tank demos for examples of using joints this way.

Re: seesaw platform problem

Posted: Thu Jul 05, 2012 5:15 pm
by JohnL
Thank you for such quick reply.

I've only just manage to find time to get back onto this problem.

Your first solution didn't work because the I got 0 from cpBodyGetAngVel(body) which would have been division by zero and chipmunk threw an exception error soon after.

Anyway, my problem was that I was rendering the scene from the variable m_floorAngle and not from the physics engine floor->body->angle which has moved since then. Face palm! This explains why it was a frame out. Your explanation has helped me a lot anyway and so I've changed the way it works by accelerating/de-accelerating the angle velocity and then called cpBodyUpdatePosition(); I'll be moving sideways eventually so updatePosition() will serve both purpose.

Re: seesaw platform problem

Posted: Thu Jul 05, 2012 11:36 pm
by slembcke
Ooops. Crap that code snippet was supposed to be subtraction, not division. Like this:

Code: Select all

newAngle = ...;
cpBodySetAngVel(body, (newAngle - cpBodyGetAngVel(body))/dt);
cpBodySetAngle(body, newAngle);