Archived

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

aphydx

sufficient object displacement after collision

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites