Jump to content
  • Advertisement
Sign in to follow this  

3D Collision Response

This topic is 5423 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

Having figured out 2D collision detection and response, I've recently moved into the 3rd dimension. However, it's a little more complicated then I had anticipated, particular when dealing with angular velocities. What I'm basically looking for is an equation (or a set of equations) that can tell me the resultant angular and linear velocities of two 3D objects that just collided (we're talking about perfectly elastic collisions here). I was also wandering if I could get an equation (or a set of equations) that can tell me the resultant angular and linear velocities when a force (represented by a vector) is applied on a particular point on a 3D object. Please help

Share this post

Link to post
Share on other sites
Ok, firstly I'm wandering how to represent angular velocities of objects in 3D space. Initially I thought it could just be a vector to indicate about which axis the rotation applies and a scalar to indicate the extent of the rotation, but of course it could be rotating around 2 axii simultaneously or 3, or 4, in fact there really is no limit. So how do I represent this velocity in a finite manner? The thought of a matrix comes to mind, which could store an infinite combination of rotations, but when we get a collision, how do I exactly modify this matrix in response to the collision.

In a collision I have the following information available to me:

- The normal of the collision (currently I treat all collisions as point-face collisions)
- Each object's point of collision
- Each object's linear velocity
- Each object's centre of mass
- Each object's mass

I need this information as I'm currently writing the physics for a Space Combat game (with space ships and missiles flying around and a terrain below to crash into)

Share this post

Link to post
Share on other sites
Thanks, I've just read through the first of these links and I just want to make sure I'm interpreting it correctly:

it says:

delta L = (p - x(t)) X J

where La(t) is the angular momentum of object A, similarly for Lb, and J = jn (n is the unit normal of the contact and j is the impulse)

(we'll use the ' symbol to denote a property's value just after the collision)

So La'(t) = La(t) + (p - x(t)) x J
-> I(t)wa'(t) = I(t)wa(t) + (p - x(t)) x J
-> wa'(t) = wa(t) + I-1(t)((p - x(t)) x J)

So the above gives the resultant angular velocity from a collision (for object a. Object b sim), right?

But this doc seems to represent angular velocity with a single vector, but can't an object be spinning, say around the z-axis and around the x-axis at the same time, which would require two angular velocity vectors?

My next question is that does the size of w(t) represent how many radians we rotate around the vector of w(t), or something else?

Lastly I just want to make sure I've got the post collision linear velocities sorted:

Let va' be the postcollision vel of object a at its centre of mass
Let va be the precollision vel of object a at its centre of mass
Let n be the normal of the collision
Let Ma be the mass of object A

Then va' = va + (j/Ma)n

Similarly for object b

Am I right with this?

And god, I've yet to see how forces effect linear and angular velocites (so much work!). I'm presuming that will be in the second of the links you gave me. I may come back with some more questions on that once I've read it...

Share this post

Link to post
Share on other sites
yes, it's a little bit more compliacted in 3D.

The collision impulse will generate angular and linear momentum.

delta_vel = (J * inv_mass) * N
delta_w = (J * inv_inertia) * ((P - CG) ^ N);
vel += delta_vel;
w += delta_w;

w is indeed a vector. apparently, |w| is the angular velocity amount, while w normalised is the axis of rotation.

However, I never tried it that way, instead, I do

Qw = Quaternion(w.x, w.y, w.z, 0) * Qang * 0.5f;
Qang += Qw * dt;

inv_inertia = Mang * local_inv_inertia * Mang.Inverse();

Qang is the orientation of the body, as a quaternion.
Mang is the orientation in matrix form.
local_inv_inertia is the inertia of the body in local space, which never changes.

Share this post

Link to post
Share on other sites
Hi there. First of all don't panic, I had a hard time understanding all this stuff first time round as well. All the notation makes its difficult and there's a lot to take in before you get the full picture. The good news though is that once its clicked it'll seem fairly straight forward. I'm not familiar with their notation (everyone seems to use their own) so it might be easier for me to give you a run down in my own words. I get the feeling your trying to jump to collision responce before you've got a rigib body simulator going so I'll start there. I just want to stress though that this is just one way of doing this (the easiest I can think to explain) and people might use slight differences. Here goes:

Heres an imaginary class that will fully represent the state of a rigid body at any instance in time:

class RBState
float Mass; // mass
mat33 InvIT; // inverse of the local space inertia tensor -> a 3x3 matrix decribing the way the mass is distributed throughout the body
mat33 InvWorldIT // world space version of above
vec3 Pos; // position
mat33 Rot; // orientation matrix
vec3 LVel; // linear velocity
vec3 AVel; // angular velocity
vec3 AMom; // angular momentum

vec3 Force; // total force being applied this frame
vec3 Torque; // total torque acting in the body this frame

The angular velocity can be described as a 3D vector were each component simply describes the angular velocity around that axis. For example AVel(6, 3, 1) might represent an object spinning at 6 m/s around the x axis, 3 m/s around the y axis, and 1 m/s around the z axis, the combination of which fully descibes the objects spin in 3D.

The force and torque vectors describe those quantities acting on the bodies centre of mass (CoM). Any external force can be split into a force-torque pair and summed up in these vectors before updating the rigid bodies state for that frame. When a force is applied at any point on the body, the same linear force will also be felt by the bodies CoM. However if the applied force does not act towards the bodies CoM it will also add torque to the body causing it to spin. The force-torque pair for a force applied at any point in world space is calculated as follows:

RBState::ApplyForce(vec3 F, vec3 pt)
Force += F;
Torque += (pt - Pos).CrossProduct(F);

Once all your forces have been applied to the body you then want to uptade its state over a given time span (eg: time to end of frame, time to first collision etc.) This is done like so:

RBState::Update(float dt)
Pos += LVel*dt;
LVel += Force*dt/Mass;
AMom += Torque*dt;

temp = (AVel.CrossProduct(AMom) + Torque)*dt;
AVel += temp*InvWorldIT;

Rot += (Rot*(AVel.SkewSymmetricMatrix()))*dt;

InvWorldIT = ((Rot.Transpose())*InvBodyIT)*Rot;

// dont forget to reset your force and torque accumulators

Hopefully this should give you enough to go off to put together a rigid body simulator which you can use to push objects around by applying forces. This is the first step to a physics/collision engine and only once you've got this running fairly stable should you start thinking about including collision responce. Just a few things, objects may spin the opposite way to what you expect depending on what handed coordinate system you use. If this happens reverse the order of matrix and vector multiplications. Secondly you may need to apply damping to things like the momentums and velocities to stop the system exploding under large forces. Sorry for the code dump but its the easiest way I could think to show you.

PS: I've just re-read what i wrote and you might want to double check the way I've said to update AVel there if you copy paste these code chunks cause I'm not sure it looks quite right. Sorry for not double checking myself but I'm experiencing a serious case of brain drain today, hence all the time pratting on the internet rather than working.

PPS: Ignore what I said about handed coordinate systems, its actually whether your maths library is set up for pre or post multiplication that'll make the difference. Come on brain.....you can do it :)

[Edited by - Motorherp on September 16, 2004 6:14:04 AM]

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!