Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Agemaniac

Colision Response Problem

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

Hello..i''m working in a game and i have some problems with collision response. I already have the point of collision (i''m using Coldet to find it) and the objects that are colliding. how should i update the values of position, velocity, angular momentum etc, etc... I''m using the following piece of code, but it not seen to work. Can someone tell me what i''m doing wrong? cVETOR3D position = colision_point; cVETOR3D r1 = position - obj1.position; cVETOR3D r2 = position - obj2.position; //should i normalize position here??? //r1.Normalize(); //r2.Normalize(); cVETOR3D vel1= source1.velocity+ Cross (source1.velocidade_angular, r1); cVETOR3D vel2= source2.velocity+ Cross(source1.velocidade_angular, r2); float impulse_numerator1 = -(1.0f + obj1.restitution_coefic) * Dot(vel1, normal_colision); float impulse_numerator2 = -(1.0f + obj2.restitution_coefic) * Dot(vel1, normal_colision); float impulse_denominator1 = pac_colisao.obj1.OneOverMass + Dot(vcross_aux.Cross(source1.invw_inertia_tensor * Cross(r1, normal_colision), r1), normal_colision); float impulse_denominator2 = obj2.OneOverMass + Dot(Cross(obj2.invw_inertia_tensor * Cross(r2, normal_colision), r2), normal_colision); if (impulse_denominator1 == 0) impulse_denominator1 = 1; if (impulse_denominator2 == 0) impulse_denominator2 = 1; cVETOR3D impulse1 = normal_colision * (impulse_numerator1/impulse_denominator1) ; cVETOR3D impulse2 = normal_colision * (impulse_numerator2/impulse_denominator2); //apply impulse to primary quantities obj1.velocidade = impulse1 * obj1.OneOverMass; obj2.velocidade = impulse2 * obj2.OneOverMass; obj1.angular_momentum = Cross(r1, impulse1); obj2.angular_momentum = Cross(r2, impulse2); //compute affected auxiliary quantities obj1.angular_velocity = obj1.invw_inertia_tensor * obj1.angular_momentum; obj2.angular_velocity = obj2.invw_inertia_tensor * obj2.angular_momentum; if you know plz..post the correct form to calculate each of them when you already now the collision point

Share this post


Link to post
Share on other sites
Advertisement
Hi,

The r1,r2 are correct. You shouldn''t normalize them.

The problem is, there is only one impulse to be calculated. Minus of this impulse is applied to the other object.

>>float impulse_numerator1 = -(1.0f + obj1.restitution_coefic) * >>Dot(vel1, normal_colision);

You must calculate relative velocity instead of vel1. Let vrel=vel1-vel2

the expression must be (we have only one impulse numerator)
>>float impulse_numerator = -(1.0f + obj1.restitution_coefic) * >>Dot(vrel, normal_colision);

I didnot check the denominator side but actual denominator is
the total of the denomitors you used.

So

impulse= impulse_numerator / (impulse_denominator1+impulse_denominator2);
I am assuming you calculated the denominators correctly.



Share this post


Link to post
Share on other sites
hi.thanks for the post..
ok...here is my problem with what you said

>>float impulse_numerator1 = -(1.0f + obj1.restitution_coefic) * >>Dot(vel1, normal_colision);

You must calculate relative velocity instead of vel1. Let vrel=vel1-vel2

ok..with this code i dont need to calculate vel1 and vel2...note that its not obj1.vel1...its
cVETOR3D vel1= source1.velocity+ Cross (source1.velocidade_angular, r1);

is it really wrong??

Share this post


Link to post
Share on other sites
Hi,

I assumed that vel1 and vel2 are the velocities at the contact point not objects'' linear velocities.

vrel = v1+ w1 x r1 - ( v2 + w2 x r2 )
is the relative contact point velocity. ( v1 ,v2 are linear velocities and w1,w2 are angular velocities)

You can check Chris Hecker web page (http://www.d6.com/users/checker)
for more information.
Also from Brian Mirtich papers you can find collision responses with friction.

Share this post


Link to post
Share on other sites
Hello!! Now i figure out that i was using the incorrect formula.
now i''m trying to do the following thing found in the paper that you told me

impulse_numerator = -(1+e)vab . n

impulse_denominator = n . n(1/massA + 1/massB)
+ [(Ia(Rap x n))xRap + (Ib(Rbp x n)) x Rbp] . n;

obs: Ia and Ib = inverse world inertia tensor

I thougth impulse_numerator is right.
but looking to the impulse_denominator formula i can''t understand what is n . n (1/massA + 1/massB).
should i do n . n first? I don''t think so ..because dot product between them will be equal zero, then...should i do n . ( n(1/massA+1/massB)?
i try use this kind of thing but the impulse_denominator seen to have a too "big" value.

ok.other problem...
after calculate impulse, what can i do?
i''m using the following piece of code...

impulse = impulse_numerator/impulse_denominator * normal_collision
obj1.velocity += Cross(impulse, collision_normal);
obj2.velocity - = Cross(impulse, collision_normal);
.....

how can i know if i have to do this or:
obj1.velocity -= Cross(impulse, collision_normal);
obj2.velocity + = Cross(impulse, collision_normal);
.....

i know that i have to aply the impulse in one object and minus impulse in the other..but i don''t know in which aply each impulse....sorry ..my english is poor..hope that someone can help me....thanks.

Share this post


Link to post
Share on other sites
n.n is not equal to zero. It is equal to magnitude of n. If n is normalized ,it is one.

Did you understand the difference between dot product and cross product. They are wholly differnt.

Ok here is velocities after collision

obj1.velocity+=impulse*obj1.oneovermass
obj2.velocity-=impulse*obj2.oneovermass

obj1.angularvelocity+=obj1.invw_inertia_tensor * cross(r1,impulse)

obj2.angularvelocity-=obj2.invw_inertia_tensor * cross(r2,impulse)

Share this post


Link to post
Share on other sites
the same, innit?

(n.n)*k will get you there faster than n . (n * k)

only one dot product and a mul, instead of a vector mul and a dot product

and a small typo

"n.n is not equal to zero. It is equal to magnitude of n"

it''s actually the square magnitude of n.

magnitude(n) = sqrt(n.n)

Share this post


Link to post
Share on other sites
yep...now i found the correct formulas and everything looks fine...just one thing is incorrect(i thought)
when i use two spheres to test the algorithm i found out that it works well when i''m using colisions normals like (1,0,0)
(0,1,0), Normalize (1,1,1) and so on....when the colision normal change just a bit, (0.99954, 0.000332, 0.0099) the impulse seens to be wrong. The two spheres with initial velocities (20,20,20)
(-20, -20, -20) dont change velocities...the final velocities are like (18,18,18), (-17,-17,-17).."just an example...not real values"........i''m sure that the velocities when the impulse is aplied should change at last their signs...otherwise the spheres are going to collide forever.

does anyone know what is wrong?? i''m using coldet to find the colision normal..and since my spheres are made of triangles the collison normal can be like i said.

i''m using the following:



cVETOR3D position = colision_point;
cVETOR3D r1 = position - obj1.position;
cVETOR3D r2 = position - obj2.position;
cVETOR3D vel1= source1.velocity+ Cross (source1.velocidade_angular, r1);
cVETOR3D vel2= source2.velocity+ Cross(source1.velocidade_angular, r2);
cVETOR3D velr= vel1 - vel2;

float impulse_numerator = -(1.0f + obj1.restitution_coefic) * Dot(velr, normal_colision);

float impulse_numerator1 = -(1.0f + obj1.coeficiente_de_restituicao) * Dot(velr, normal_tri_1);

cVETOR3D impulse_denominator1 = vcross_aux.Cross(source1.invw_inertia_tensor * vcross_aux.Cross(r1, pac_colisao.normal_tri_1), r1);

cVETOR3D impulse_denominator2 = vcross_aux.Cross(source2.invw_inertia_tensor * vcross_aux.Cross(r2, pac_colisao.normal_tri_1), r2);

cVETOR3D impulse_denominator_parcial = impulse_denominator1 + impulse_denominator2;

float impulse_denominator_parcial2 = obj1.OneOverMass + obj2.OneOverMass + Dot(impulse_denominator_parcial, normal_tri_1);

cVETOR3D impulse = pac_colisao.normal_tri_1 * (impulse_numerator1/impulse_denominator_parcial2);

//apply impulse to primary quantities
obj1.velocity += impulse * obj1.OneOverMass;
obj2.velocity -= impulse * obj1.OneOverMass;
obj1.angular_momentum = Cross(r1, impulse);
obj2.angular_momentum = Cross(r2, impulse);

//compute affected auxiliary quantities
obj1.angular_velocity = obj1.invw_inertia_tensor * obj1.angular_momentum;

obj2.angular_velocity = obj2.invw_inertia_tensor * obj2.angular_momentum;




when i use it impulse_denominator_parcial2 seens to change like 0.2 to 2.0 when using normal colision (1,0,0) and (0.999, 0.0007, 0.0007)...(provided by coldet)...it changes a lot the impulse result and the velocity is not update properly...can someone figure out what is wrong???

Share this post


Link to post
Share on other sites
I don''t understand...

What''s normal_tri_1?

you only need to use normal_colision

and you had a ''='' instead of a ''+='' when computing the angular velocity.




cVETOR3D position = colision_point;
cVETOR3D r1 = position - obj1.position;
cVETOR3D r2 = position - obj2.position;
cVETOR3D vel1 = source1.velocity+ Cross(source1.velocidade_angular, r1);
cVETOR3D vel2 = source2.velocity+ Cross(source1.velocidade_angular, r2);
cVETOR3D velr = vel1 - vel2;

float impulse_numerator = -(1.0f + obj1.restitution_coefic) * Dot(velr, normal_colision);


cVETOR3D impulse_denominator1 = vcross_aux.Cross(source1.invw_inertia_tensor * vcross_aux.Cross(r1, normal_colision), r1);

cVETOR3D impulse_denominator2 = vcross_aux.Cross(source2.invw_inertia_tensor * vcross_aux.Cross(r2, normal_colision), r2);

cVETOR3D impulse_denominator_parcial = impulse_denominator1 + impulse_denominator2;

float impulse_denominator_parcial2 = obj1.OneOverMass + obj2.OneOverMass + Dot(impulse_denominator_parcial, normal_colision);

cVETOR3D impulse = normal_colision * (impulse_numerator1/impulse_denominator_parcial2);

//apply impulse to primary quantities
obj1.velocity += impulse * obj1.OneOverMass;
obj2.velocity -= impulse * obj1.OneOverMass;
obj1.angular_momentum = Cross(r1, impulse);
obj2.angular_momentum = Cross(r2, impulse);

//compute affected auxiliary quantities
obj1.angular_velocity += obj1.invw_inertia_tensor * obj1.angular_momentum;

obj2.angular_velocity += obj2.invw_inertia_tensor * obj2.angular_momentum;

Share this post


Link to post
Share on other sites

  • 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!