Moving Platforms, Liquid, All the Funky stuff

Official forum for the Chipmunk2D Physics Library.
X-0ut
Posts: 28
Joined: Tue Oct 02, 2007 5:02 am
Contact:

Moving Platforms, Liquid, All the Funky stuff

Post by X-0ut »

I'm looking for some good solutions to some problems I encountered in a previous project using Chipmunk.
For moving platforms, I adjusted a static bodies position each step. Which worked great for moving the platform. Unfortunately any objects that came into contact with the platform would not move along with it. I hacked that in using collision pair callbacks, but it was fugly and didnt work very well.
An allternative method would be great, ideally I want platforms to follow splines. Maybe it can be accomplished using a joint, but note the platform must not be effected by gravity and must not rotate.

Liquid, another little hack I made was to simply damp the gravity of a body in contact with a water body. It worked ok for that project but I'd really like something with a bit more realistic behaviour. For instance, I'd like objects to float on water surface, or sink if they are too heavy etc.

And finally, a problem I encountered and could not solve. Stopping a body from rotating but still moving with a joint such as pivot.

If anyone has solved these problems or even has any ideas that could help me on my way, they would be very appreciated.

TIA
darwinian
Posts: 3
Joined: Tue Nov 20, 2007 10:15 am
Contact:

Re: Moving Platforms, Liquid, All the Funky stuff

Post by darwinian »

I implemented very basic moving platforms by simply adjusting the velocity of a dynamic body. The dynamic body is set up with infinite moment of inertia to prevent rotation, and a large mass so as not to be affected by, for example, the player jumping on it. It won't be affected by gravity as you are calculating the new velocity each frame yourself (then calling cpBodyUpdatePosition).

While this does work, it can be improved. I too was considering some path based movement for platforms. I thought it might be possible to represent the path as a spline and update the velocity based on the tangent at a specific point on the curve. A fully untested idea as of yet.

As for the problem of preventing a body from rotating but still moving with a joint, if I understand you correctly, shouldn't it just be a case of setting an infinite moment of inertia?

As for water, well I would love to hear of a good way of implementing it. I haven't tried yet, but it is on my feature list.
X-0ut
Posts: 28
Joined: Tue Oct 02, 2007 5:02 am
Contact:

Re: Moving Platforms, Liquid, All the Funky stuff

Post by X-0ut »

Ah I see, maybe thats where I was going wrong with the platforms. Instead of adjusting the position each step, I should alter the velocity. That is probably why nothing would sit ontop of them.
About the rotation I'll have to give that a try.

Liquids.. I've been thinking maybe I could attach a slide joint to a body that enters water etc. One end of the joint attaches to the objects center, and the other to the water surface.
The min/max would be based on the objects weight and the viscousity of the liquid. Its completely untested and I can see some cases in which it would break. Hoping for a better solution really.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Moving Platforms, Liquid, All the Funky stuff

Post by slembcke »

Yeah, as has already been said, if you are changing the position of the object, you must also change the velocity to match. Chipmunk uses Euler integration, so make sure that you are calculating the velocity from the delta of the positions. Using the derivative of the position (if you are doing something fancy like splines) won't work 100% right.

As far as liquids. I would keep it simple. Start by trying to apply a buoyant and damping force if the center of the object is in the liquid. For roughly symmetric shapes, I would think that would work pretty well. If the shape is more complicated, try using point sampling to estimate how much of the object is submerged and apply the buoyant and damping forces to the average of the submerged points.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
X-0ut
Posts: 28
Joined: Tue Oct 02, 2007 5:02 am
Contact:

Re: Moving Platforms, Liquid, All the Funky stuff

Post by X-0ut »

Ok thanks for all the answers, I think I got enough to be getting on with now.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Moving Platforms, Liquid, All the Funky stuff

Post by slembcke »

Aha! I knew I had added a function that would help in this situation. (Apparently forgot to doc it. Sigh)

Code: Select all

void cpBodySlew(cpBody *body, cpVect pos, cpFloat dt)
Sets the velocity of the object for you so that next time cpBodyUpdatePosition() is called (with the same timestep) it will move to the position you specified. That will handle keeping the position and velocity in sync so that objects won't slide around on surface of your platform.

Also, I think I'm going to add callbacks for updating the body positions/velocities. That way you don't have to worry about adding a lot of logic outside of the cpSpaceStep() call for handling all the custom physics behavior (such as moving platforms).
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Moving Platforms, Liquid, All the Funky stuff

Post by slembcke »

So I played around with buoyancy a bit. I basically did a uniform grid sampling over a box to estimate how much of the area is below the water level. To each point I applied an upward force and a damping force.

Code: Select all

static void
apply_bouyancy(){
	int numx = 20;
	int numy = 4;
	
	float stepx = (float)WIDTH/(float)numx;
	float stepy = (float)HEIGHT/(float)numy;
	
	glBegin(GL_POINTS);
	for(int x=0; x<numx; x++){
		for(int y=0; y<numy; y++){
			cpVect r = cpv((x + 0.5)*stepx - WIDTH/2, (y + 0.5)*stepy - HEIGHT/2);
			cpVect p = cpBodyLocal2World(box_body, r);
			
			if(p.y < 0){
				cpVect v = cpvadd(box_body->v, cpvmult(cpvperp(r), box_body->w));
				cpVect f_damp = cpvmult(v, -0.0005*cpvlength(v));
				cpVect f = cpvadd(cpv(0, 2), f_damp);
				cpBodyApplyForce(box_body, f, r);

				glVertex2f(p.x, p.y);
			}
		}
	}
	glEnd();
}
I was uncertain how well the damping would work as it should be based more on how the surface is interacting with the fluid. Damping the entire submerged area actually works pretty well though.

The next step would be to build a poisson disc distribution and discard points that lie outside of a shape. (uniform sampling produces jitter when the grid is aligned with the water level) For this very reason, I've added point queries for shapes for this very reason. I'm going to try and clean this code up and release another incremental upgrade.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Moving Platforms, Liquid, All the Funky stuff

Post by slembcke »

Slight bug in the code I posted before. I was calculating r incorrectly. This is correct.

Code: Select all

			cpVect p_sample = cpv((x + 0.5)*stepx - WIDTH/2, (y + 0.5)*stepy - HEIGHT/2);
			cpVect p = cpBodyLocal2World(body, p_sample);
			cpVect r = cpvsub(p, body->p);
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
X-0ut
Posts: 28
Joined: Tue Oct 02, 2007 5:02 am
Contact:

Re: Moving Platforms, Liquid, All the Funky stuff

Post by X-0ut »

Excellent! :)
joshcryer
Posts: 18
Joined: Wed Sep 26, 2007 8:19 pm
Contact:

Re: Moving Platforms, Liquid, All the Funky stuff

Post by joshcryer »

Sick! (As in cool.)
Post Reply

Who is online

Users browsing this forum: No registered users and 23 guests