Ability to set constant velocity?

Official forum for the Chipmunk2D Physics Library.
Post Reply
iisystems
Posts: 16
Joined: Tue Apr 14, 2009 2:42 pm
Contact:

Ability to set constant velocity?

Post by iisystems »

Hi,

I've scoured the board for an answer to what seems to be a basic question, but to no avail. Is there a simple way in Chipmunk to set a body to a constant velocity? Imagine my cpSpace as a top-down flowing river with a current (of constant velocity)-- I simply want to add bodies to "float" down the river. By using gravity, I get an acceleration, understandably. However, I expected that using cpBodyApplyForce, I would get my constant velocity PLUS when the body collidated with other static bodies, it would bounce, but generally continue movement in the same direction. What I'm seeing is that this is acting just like gravity. I get the general movement in the same direction after collisions, but absent of collisions, I get acceleration, just like gravity.

cpBodyApplyForce(body, gCurrent, cpBodyLocal2World(body, cpvzero)); // Set body to flow with current

Does velocity need to be managed manually in order to get a constant velocity? If so, I would greatly appreciate an example or pointer of how to do this.

This is a similar question to (unanswered): http://www.slembcke.net/forums/viewtopi ... 395&p=1796

Thanks very much!

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

Re: Ability to set constant velocity?

Post by slembcke »

Well, the reason why they look very similar is because gravity is a force. The gravity parameter of a space is setting the acceleration due to gravity, and the force of gravity is calculated automatically for each object.

To answer your question, yes, you will have to manage the velocity by yourself to get the behavior that you want. The simple solution is to set the velocity of the body directly every frame, (or you could do this in a velocity integration function too). Making large changes to the velocity of a body every frame can do some odd things though. A better solution is to slowly apply the change in velocity over a few frames.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
iisystems
Posts: 16
Joined: Tue Apr 14, 2009 2:42 pm
Contact:

Re: Ability to set constant velocity?

Post by iisystems »

Makes perfect sense! Thanks very much for clarifying this for me...
iisystems
Posts: 16
Joined: Tue Apr 14, 2009 2:42 pm
Contact:

Re: Ability to set constant velocity?

Post by iisystems »

I have a follow-up question on this. I am trying to manually manage position and velocity. It seems I have to use cpBodySlew(), as when I set the position directly it has repercussions (possibly because of collision with other bodies at the position I try to set it to). cpBodySlew() works great, but my problem is that I don't understand how to get back to my constant velocity as cpBodySlew changes the velocity in order to update the position. It seems like a Catch-22. I have a body at a certain velocity. I want to reposition that body slightly and then continue at the same velocity once the body is repositioned.

I was writing a position integration function (where I would reset the velocity), but I can't figure out how to tell when I've reached the destination point. A velocity integration function doesn't seem right because it seems I need to use cpBodySlew().

Am I looking at this the wrong way?

Just so you know what I'm trying to do, I'm attempting to keep constant distance between several bodies. The bodies collide and I pick the new position based upon fixed spacing for the trailing object away from the leading object. Essentially "stick" discrete bodies together without actually touching (because I don't want any more collisions at this point).

Here's what I have and I'd really appreciate your input to let me know if I'm approaching this wrong or if you have other ideas:

int collFuncOilOil(cpShape *a, cpShape *b, cpContact *contacts, int numContacts, cpFloat normal_coef, void *data)
{
// Average the two bodies' force so they will travel together:
cpBody *aBody = a->body;
cpBody *bBody = b->body;
cpVect aForce = aBody->f;
cpVect bForce = bBody->f;
cpBodyResetForces(aBody);
cpBodyResetForces(bBody);
cpVect resultantForce = cpv((aForce.x + bForce.x)/2, (aForce.y + bForce.y)/2);
cpBodyApplyForce(aBody, resultantForce, cpvzero);
cpBodyApplyForce(bBody, resultantForce, cpvzero);

// Determine which shape to position (take the trailing one and "tack it on")
cpBody *bodyToMove, *referenceBody;
if ((abs(resultantForce.y) > abs(resultantForce.x)) && (resultantForce.y != 0))
{
// Y-coordinate is dominant
if (resultantForce.y > 0)
{
if (aBody->p.y > bBody->p.y)
{
referenceBody = aBody;
bodyToMove = bBody;
}
else
{
referenceBody = bBody;
bodyToMove = aBody;
}
}
}
else
{
// X-coordinate is dominant
if (resultantForce.x > 0)
{
if (aBody->p.x > bBody->p.x)
{
referenceBody = aBody;
bodyToMove = bBody;
}
else
{
referenceBody = bBody;
bodyToMove = aBody;
}
}
}

float angle = (float)(sqrt(pow(abs(aBody->p.x - bBody->p.x), 2) + pow(abs(aBody->p.y - bBody->p.y), 2)));
float xDelta = (float)sin(angle) * SPRITE_BUFFER_SPACE;
float yDelta = (float)cos(angle) * SPRITE_BUFFER_SPACE;
float origX = bodyToMove->p.x;
float origY = bodyToMove->p.y;
cpVect newPos;
newPos.x = referenceBody->p.x + ((referenceBody->p.x < bodyToMove->p.x) ? xDelta : 0 - xDelta);
newPos.y = referenceBody->p.y + ((referenceBody->p.y < bodyToMove->p.y) ? yDelta : 0 - yDelta);
cpBodySlew(bodyToMove, newPos, 1.0f);
// bodyToMove->p = newPos; // Replaced by cpBodySlew

return 0; // processed
}

Thank you again!!!
PeskyJ
Posts: 19
Joined: Fri Apr 24, 2009 4:24 pm
Location: Reading, UK
Contact:

Re: Ability to set constant velocity?

Post by PeskyJ »

I would say that setting the velocity manually is not very elegant. There are two ways you can do it with chipmunk physics.

1) Have a low value for damping in the space. This is a dubiously named field because it's actually the inverse of damping, the lower it is, the more damping you get. So setting a low value (0.05) and perhaps a higher gravity (to get the speed you want) will give a nice terminal velocity effect and also dull the effects of objects bouncing off each other which to me sounds ideal for objects in water.

2) Another way would be to apply a force relative to the velocity. So the faster it gets, the bigger the force in the opposite direction. This is how real wind resistance works, which is why objects in free-fall in the Earth's atmosphere have a terminal velocity. As they get faster, wind resistance gets higher, until the force from wind resistance is equal to that of gravity, once that happens the body continues at the same speed, it is still falling but not falling faster. i.e. it has reached its terminal velocity.
Games games games... I love games. Check out my games: [url]http://www.tinyplay.com/games.html[/url]
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Ability to set constant velocity?

Post by slembcke »

Trying to keep a mostly constant velocity using the method I mentioned above works pretty good. However, when you start saying that you need to manually control the position and the velocity (and from the sounds of it, the collision response too), I need to start asking if you really want to be using a physics engine. I'm not sure if I understood what you were describing or what your code was trying to do exactly, but I suspect that using a full rigid body physics engine is not really what you want, and might be making it harder to do what you want to do.

A physics engine is supposed to help you out managing the physical state of objects (their position and velocity), but most importantly, the task of collision response which is difficult if you need stable stacking, friction, elasticity, etc. The fact that it also provides collision detection is sort of an implementation detail. It needs to do it so that it can implement the collision response. It sounds like all you want from Chipmunk is the collision detection, which honestly is not Chipmunk's greatest strength. What I mean by that is that you can't easily just use Chipmunk's collision detection. Some parts like the spatial hash could be usable separately if I provided adequate documentation for it, but the collision detection is very tightly coupled with the fact that all collision detection shapes are connected to rigid body objects.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
iisystems
Posts: 16
Joined: Tue Apr 14, 2009 2:42 pm
Contact:

Re: Ability to set constant velocity?

Post by iisystems »

PeskyJ, thanks for the pointers, I will try out both these ideas and see what works better. This may very well solve my constant velocity problem. And I did misunderstand the damping parameter-- I was playing around with low values like a week ago and got frustrated that no matter how low it was, my objects would stop moving!

Slembcke, you're touching on my bigger problem though-- Is Chipmunk really the right tool for me? For this particular aspect of the game I'm writing, I'm beginning to fear you might be right. However, I do need it for everything else and don't want to give up hope yet. I'm trying to do a half-decent job of simulating fluid using small particles, but these particles also hit other objects and need to move around them accordingly, which of course Chipmunk handles great. I've seen the pseudo-fluid simulations on YouTube and these appear to be much more complicated than what I'm doing as my game is simple top-down perspective (like a puddle of water moving on a leaning tabletop) . Anyway, seeing those simulations is what originally convinced me I could do this with cocos2d and chipmunk.

They key to my algorithm is to find a way to couple these particles once they collide-- like a weak magnetic force attracting only their own type-- and then I adjust the position so they are 0.5 or 1.0f away from each other after they collide-- also syncing their velocities so to avoid tons of ongoing collisions once they are coupled. The attached sprite is oversized so you don't see the gaps between the bodies. Beginning to sound like a hack, I know. However, it is working to an extent and under-the-covers each particle is aware of which group it is attached to so even if it does collide, I am able to ignore. Anyway, I end up with lots of groups of 2-3 particles perfectly spaced and flowing with synchronized (and soon pseudo-constant) velocity, but the groups refuse to play together and merge correctly when particles from different groups collide and end up kicking each other away. You have a great engine here and I feel like I am close to making it work at this point. If I can't get it to work however, I will have to completely change my game to handle discrete particles-- make them into balls or something with a totally different concept, but this pretty much negates the purpose/uniqueness of the game and the other actors I already have working (like a sponge which soaks up the fluid and then can be squeezed to release it in a controlled manner)...

So anyway, I do need the collision response for this object class with other objects-- you're right that I don't really want it for self-collisions among these particles, but obviously can't have it both ways.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Ability to set constant velocity?

Post by slembcke »

Do you have the means to record a video of what you have? I'm still not quite sure I follow what it is that you are trying to accomplish. It's possible that it might be easier to use Chipmunk than not. Other people have made games that use Chipmunk in ways that make me cringe because they heavily rely on behaviors of Chipmunk that I don't consider ideal. For instance, using how Chipmunk solves overlapping objects as part of the gameplay. In the end the game is usually just fine, and ultimately it does what they want. It might even be hypocritical now to tell people to avoid such things as we did the same thing for the injection gameplay mode in ScribBall 2. So don't necessarily let me discourage you.

On the other hand, I've tried to optimize Chipmunk for what I consider it's strengths. Doing some hackery to make something fancy work with the physics is likely to be inefficient. Something to consider especially when you are talking about an iPhone game that uses lots of particles.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
iisystems
Posts: 16
Joined: Tue Apr 14, 2009 2:42 pm
Contact:

Re: Ability to set constant velocity?

Post by iisystems »

Slembke,

Sorry it's taken me so long to get back here. I actually ended up ripping out tons of code where I was trying to avoid Chipmunk collisions and instead just let them happen. In the end, I have a ridiculously simple velocity integration function which gives me constant velocity proportional to the applied force.

// myVelocityFunc - overrides Chipmunk's setVelocity function
void myVelocityFunc(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
body->v = cpvmult(body->f, body->m_inv); // Set constant velocity based on force
}

I still have issues I need to solve with joints related to this as my particles hit a net where I reduce the force on them so the net doesn't stretch ridiculously, but I will do some more homework before posting on this as I see you've added some new joint parameters...

Thanks very much!

Scott
Post Reply

Who is online

Users browsing this forum: No registered users and 36 guests