Sign in to follow this  
domok

What to do on collision?! [solved]

Recommended Posts

First I'm going to explain what I have: I have a map (3D..) and a player who moves around. The map is subdivided for collision detection using an octree. Until now I just checked if the bounding circle of the player collides with the map and if so I undid the last movement of the player. But that obviously doesn't work well enough but I can't think of a good way how to do it. It doesn't have to be very precise, bounding circle is good enough. Hope you can tell me how one usually does this! [Edited by - domok on September 11, 2009 4:50:53 PM]

Share this post


Link to post
Share on other sites
well, well...

In its simplest form, you go through the nearby triangles, find the point on triangles the closest to the sphere, and push the sphere away from that point.

In the collision response example, you do the same, however you reflect the velocity of the ball using two positions of the ball.

1) the position if there was no collision detected.
2) the position of the ball after collisions are resolved (by pushing the ball around).

that gives you a collision plane normal, and you bounce the ball against that plane.

I'm working on a third method, that uses a swept test for more accuracy (especially when the ball travels fast).

alternatively, you can look at that.

Share this post


Link to post
Share on other sites
Thanks that helped alot!

It's almost perfect now but I would really like to use an ellipse instead of the circle. In the article it is described but I can't find out how to do it because I do the whole collision stuff a bit different than it is described in the article. I do it like this:

- I calculate the closest point of all the triangles that come into consideration.
- If the triangle collides with the sphere, I find out how much the sphere intersects it and use this to move the player/center away from the triangle (orthogonally).

What do I have to do to make this work with an ellipse?

Share this post


Link to post
Share on other sites
Detecting the collision of an ellipsoid with a triangle is a bit more difficult and will involve quite a bit of math.

One alternative is:

1. look for the intersection points of your ellipsoid with the infinite plane of the triangle. This link has a pretty thorough explanation of the math.

2. check if any of the intersection points in that plane fall within the triangle. You can use Barycentric coordinates for that.

Another alternative, which may involve a bit less math, is to simulate your ellipsoid with a capsule, a cylinder capped with spheres at either end. That's what's used in a lot of collision engines. The collision of a cylinder with a plane is a little easier (but not a lot), and the collision of the spheres you know about.

Share this post


Link to post
Share on other sites
I'll throw another one.

Assume your ellipsoid is a sphere with a different radius along the x, y and z axis. To turn the test into a sphere-triangle test, you'll need to transform the vertices of the triangle into the ellipsoid space, that is :



Vector Vector::scale(const Vector& s) { return Vector(x*s.x, y*s.y, z*s.z); }
Vector Vector::inverseScale(const Vector& s) { return Vector(x/s.x, y/s.y, z/s.z); }

Vector ellipsoidCentre;
Vector ellipsoidRadius;
Vector triangle[3];
Vector mtd;
Vector closest;

Vector localTriangle[3] =
{
(triangle[0] - ellipsoidCentre).inverseScale(ellipsoidRadius)),
(triangle[1] - ellipsoidCentre).inverseScale(ellipsoidRadius)),
(triangle[2] - ellipsoidCentre).inverseScale(ellipsoidRadius)),
};

Vector localClosest;
float localdist_squared = findClosestPoint(Vector(0, 0, 0), localTriangle[0], localTriangle[1], localTriangle[2], localClosest);

if(localdist_squared > 1.0f) return false;

float localdist = sqrt(localdist_squared);
Vector localMtd = -(localClosest * (1.0f - localdist) / localdist);

closest = localClosest.scale(ellipsoidRadius) + ellipsoidCentre;
mtd = localMtd.scale(ellipsoidRadius);



you basically transform the triangle into the ellipsoid space, find out the closest point and mtd (the vector you need to use to push the sphere), and transform the results back into world space.

*code untested*

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this