Jump to content
  • Advertisement
Sign in to follow this  
Hurp

Momentary impulse through some sort of force

This topic is 3003 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In the simulation I am creating I have a very basic "Update Position, Calculate Acceleration, Update Velocity" update going. However, this only ideal if the object never takes some sort of momentary impulse force. By "momentary impulse" I mean like when you press forward and a character moves one unit for that time slice and the force is not permanently added to the velocity, like in a driving simulation.

My question is, how can I have a momentary impulse added to my current physics update? I want to be able to add a force like (2.0f, 0.0f, 0.0f) to my object and have it be their for ONLY the one time the update gets called.

Here is how my code is right now:


position += velocity * deltaTime;
D3DXVECTOR3 acceleration = gravity / mass;
velocity += acceleration * deltaTime;

Share this post


Link to post
Share on other sites
Advertisement
It's not exactly clear how you want to apply the "impulse."

Perhaps you default the impulse to (0,0,0) and set it to some temporary value when it's to be applied.

// ... set the impulse if desired, else leave as (0,0,0)
D3DXVECTOR3 imp_accel = impulse/mass;
D3DXVECTOR3 tmp_vel = imp_accel * deltaTime;

position += ( velocity +tmp_vel ) * deltaTime; // leaves velocity independent of impulse
impulse = D3DXVECTOR3(0,0,0);
// followed by your acceleration & velocity calcs

Share this post


Link to post
Share on other sites
By "impulse" I mean a temporary value that gets added for one time slices.

I do not want to add it directly to my position and nothing else because then that would rude my collision detection.

Share this post


Link to post
Share on other sites
Quote:
when you press forward and a character moves one unit for that time slice
Quote:
I do not want to add it directly to my position and nothing else

That's a bit confusing, I'm afraid. Do you want the position to change as a result of the impulse? Your first post says "yes," the second post "no."

Share this post


Link to post
Share on other sites
Sorry about that, I can see how what I said can be confusing.

I want to apply a force that would directly affect my players position over one time slice. However, if I directly add a force to just the players position, than it will move him in a direction that could move him through an object if I did not properly account for that in some how.

I was under the impression that only velocity should be directly added to a players position, is this correct?

Share this post


Link to post
Share on other sites
Quote:
Original post by Hurp
Sorry about that, I can see how what I said can be confusing.

I want to apply a force that would directly affect my players position over one time slice. However, if I directly add a force to just the players position, than it will move him in a direction that could move him through an object if I did not properly account for that in some how.

I was under the impression that only velocity should be directly added to a players position, is this correct?

A force applied to the center of mass of a rigid body modifies the accelerarion. The acceleration modifies the velocity and the velocity modifies the position, if of course, the acceleration and the velocity are not equal to zero. The effect is direct if in your ODE solver the position at time t+dt is computed with the velocity at time t+dt.

This is the case in the following two examples

acceleration = force / mass;
velocity += acceleration * dt;
position += velocity * dt;



acceleration = force / mass;
old_velocity = velocity;
velocity = old_velocity + acceleration * dt;
position += ( velocity + old_velocity ) * dt / 2;


The last example is more accurate.

Now, you should understand that when dealing with collision detection you have to make a choice:
- you can try to detect collisions before they happen. If a collision is predicted, the state of the simulation is updated to the time of collision and the collision response is computed.
- you could let them happen and resolve them later.

The first option is the most difficult to implement. Because, generally you don't have a closed form solution of the system of equations you want to solve. You can use iterative methods for determining the "exact" time of collision, for non-obvious cases, but it is computationally expensive, when dealing with non simple geometries.

The second option is the easiest one: you make the assumption that at the beginning of the update routine, you have no collision. You update the simulation. Then, you test if a (many) collision(s) occurred: if a (many) collision(s) occurred, you correct the position and velocity of the colliding bodies.

For the second option, there's no need to know the velocity of a rigid body at the start of a frame for collision detection. The velocity at the end of the frame is definitely needed, to adequately correct the position and velocity of colliding bodies.

You can't try detecting collisions before their occurrence, and at the same time, move the bodies arbitrarily.

P.S: a force can't be added to a position or a velocity. As I already told you, you need to read a book or a course on basic physics. You can't try implementing a collision detection routine, if you don't grasp what a force and an impulse are. Some papers would be very hard to even read, if I didn't have a background in Mathematics and Physics. So take the time to read about linear momentum and impulse: you won't lose your time.

[Edited by - johnstanp on July 6, 2010 8:51:03 AM]

Share this post


Link to post
Share on other sites
What I've just written is still valid but after reading you again, and reminiscing our previous discussions, I better understand your problem. So I hope that now, it will perfectly be addressed.

Quote:
Original post by Hurp
Sorry about that, I can see how what I said can be confusing.

I want to apply a force that would directly affect my players position over one time slice. However, if I directly add a force to just the players position, than it will move him in a direction that could move him through an object if I did not properly account for that in some how.

I was under the impression that only velocity should be directly added to a players position, is this correct?


Well, if my assumption is right, you're still using the "algorithm" and the initial updayte function I provided in a previous topic...
What you want to do is not adding a "force" to a player's position, but incrementing the player's position with a certain quantity (of course a vector).
This is what you want:

position += delta_position;



between t and t+dt.

Now, the equations I provided earlier don't take into account the velocity at time t+dt to compute the position at time t+dt, but the velocity at time t.
So as you've well guessed, affecting the velocity doesn't directly affect the position. It will at t+2*dt. But you want to directly affect position by affecting the velocity. It's simple: use another integration scheme.

This one offers a better accuracy than the one I proposed earlier (in another topic):

acceleration = force / mass;
position += velocity * dt + 0.5 * acceleration * dt * dt;
velocity += acceleration * dt;



This is equivalent to:

acceleration = force / mass;
Vector3 old_velocity = velocity;
velocity += acceleration * dt;
position += 0.5 * ( velocity + old_velocity ) * dt;


You should be able to demonstrate it.

If you chose that integration scheme, then if you want the player's position to be incremented by dx after the next update, apply the following force(*):

Vector3 force = mass * ( 2 * dx / dt - 2 * velocity ) / dt;



Then call the function that update the player's state, with that value:

void update( Rigid_body & body, Vector3 const & force, float dt )
{
Vector3 old_velocity = body.velocity;
body.velocity += force / body.mass * dt;
body.position += 0.5 * ( old_velocity + body.velocity ) * dt;
}

int main( int argc, char ** argv )
{
...
//dx is what you incorrectly call "impulse"
Vector3 force = body.mass * ( 2 * dx / dt - 2 * body.velocity ) / dt;
update( body, force, dt );
}



This way you can continue using what you're using right now.

P.S:
(*) is derived this way:
x - xo = dx = ( vo + v )dt/2
<=>v = 2dx/dt - vo (1)

dv = v - vo
=>dv = 2dx/dt - 2vo (2)

v = vo + adt
<=>a = ( v - vo )/dt
<=>a = dv/dt (3)

(2) in (3)=>
a = ( 2dx/dt - 2vo )/dt (4)

F = Ma (5)
(4) in (5)=>
F = M( 2dx/dt - 2vo )/dt (6)

v = velocity at time t+dt
vo = velocity at time t
x = position at time t+dt
xo = position at time t
a = acceleration in time interval[t,t+dt]
dt = timestep of the simulation

[Edited by - johnstanp on July 6, 2010 8:56:51 AM]

Share this post


Link to post
Share on other sites
And at last:
your collision detection routine (the one I provided earlier) doesn't know exactly the position of the bodies at the end of the frame. It just knows current positions and velocities and "predict" with this data, eventual collisions. The collision routine assumes that the velocity of the bodies are constant between t and t+dt, which is obviously not the case. This is why I told you that you can't prevent inter-penetrations: you just know that impulses will be computed if a collision appears. That doesn't mean bodies won't inter-penetrate.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!