sufficient object displacement after collision

Started by
3 comments, last by oliii 20 years, 11 months ago
in my collision system, objects are moved away from eachother when it is determined that they intersect .. ex: sphere1 is moved to a distance (sphere1.radius + sphere2.radius) away from sphere2 .. however, the system sometimes registers collisions between the objects after this displacement takes place ex: sphere1 intersects sphere2 sphere1 moved away from sphere2 sphere1 intersects sphere2 sphere1 moved away from sphere2 sphere1 intersects sphere2 .. and so on .. even though neither one of the objects moves after the initial collision/displacement, they still "intersect", and are "moved" away from eachother, but they don't seem to move enough to avoid future collisions my collision functions check that the distance between the two objects is strictly less than the two objects' bounds combined .. i don't get it! what would be a good method to avoid this? i thought of perhaps adding some constant SEPERATOR variable to all displacements .. but then stuff would jitter around corners, right? minimizing collisions is important in this case because i calculate a new world matrix for all objects that have collided during a frame [edited by - aphydx on April 30, 2003 6:52:15 PM]
Advertisement
My previous build had my avatars creating the same problems, one collision would have the avatar shoved into another collision. The only solution I can present is the one I'm currently using. The character is at point x,y we make a temporary duplicate of x and y called x1,y1 and we move those coordinates in the direction we would like to go.
We then test for collisions with x1,y1. The distance between x1,y1 and the test case should be the bounding radius of the two avatars added together.
If all the tests are successful, then pass x,y the validated values of x1,y1.

This will solve your collisions. Note: Wall sliding will be removed unless you adapt a solution.

- Valles (brain dagamed)

[edited by - valles on April 30, 2003 7:18:01 PM]
It''s a natural and well-known problem that resolving collisions (ie. relaxing constraints sequentially) can cause new ones (ie. alter the state of other constraints).

One idea would be to simply stop iterating after few (eg. eight) iterations. If your objects are large and can''t move too much in a single time step, this shouldn''t cause problems.

Ideally, resolving the collisions should be done in parallel, so that all possible collisions "take in account" other possible collision. This wouldn''t however be simple and kewl game programming, but a science of itself.

Robust Treatment of Collision, Contact and Friction for Cloth Animation (Bridson, Fedkiw, Anderson, SIGGRAPH 2002) addresses this for cloth animation by switching to a fail-safe method after a few iterations. Here a fail-safe method (method of impact zones) means that when two objects won''t stop colliding after a little number of iterations, they are combined into a collision a group that is handled as a rigid body. If this group collides with other groups, these are combined again, and so on. This is still much more complex than simple and nice iterative resolving, though.

- Mikko Kauppila
Both the other posters seem to have missed your point. Your problem is that even after the spheres have been displaced so that they SHOULDNT be colliding any more, they still are, correct? This is most likely caused by inaccuracies in floating point calculations. Perhaps try adding a small value to the amount that the two spheres are displaced by, like 0.0001. This may resolve your problem.
what I would do, is to displace the objects with a damping factor. They might still intersect over a few frames, but they won't jerk around if they got multiple collisions. They will slowly push apart from each other.


  bool IntersectAndSeparate(CSphere& Sphere1, CSphere& Sphere2){    float  r = Sphere1.Radius + Sphere2.Radius;    Vector D = Sphere1.Position - Sphere2.Position;    float  d = D.GetLength();    float depth = r - d;    // spheres do not intersect    if (depth < 0.0f) return false;    // normal of contact, to push the spheres apart    Vector Normal1 = D.UnitVector();    Vector Normal2 = -Normal1;    // smoothly separate the spheres. 1.0f will make the spheres     // just contact. set from 0.0f to 1.01f.    const float damping = 0.3f;     // this will make the largest sphere move less than the     // smallest sphere, wich will reduce further problems when     // the spheres are pushed apart.    float ratio1 = (Sphere.Radius2) / R;    float Ratio2 = 1.0f - R;    float disp1 = depth * damping * ratio1;    float disp2 = depth * damping * ratio2;    Sphere1.Position += disp1 * Normal1;    Sphere2.Position += disp2 * Normal2;    return true; }  



you can tweak the damping factor, like make it a funciton of the depth. If the depth is very large, increase the damping factor.


[edited by - oliii on May 1, 2003 6:49:17 PM]

Everything is better with Metal.

This topic is closed to new replies.

Advertisement