Game Development Community

Collision detection

by Gerald Fishel · in Torque Game Engine · 04/01/2004 (5:42 pm) · 7 replies

Hi,

Well I got my new interiors working pretty good now, as far as the rendering goes. Portal-based with polygon soup cells, and radiosity baked lightmaps from 3D Studio Max, lookin pretty sweet. Also has a decent auto-generation of a navigation grid for AI purposes. Now I just need to get the collision detection.

I've got some nice, fast routines for detection/response that are ready to use with the data format of my interiors, I'm looking for some thoughts on where to insert the check in the Torque engine. I'm guessing I will probably have to create more than one set of collision routines, at first my main concern will be the player objects. What I basically need from each Player object is current position, a bounding elipsoid or a bounding box to calculate a rough bounding elipsoid of the model, a velocity/direction vector and perhaps some sort of gravity vector. And an interface to update the player's position.

I think when I am outside of the interior I should do the collision after the terrain, and if I am inside of the interior I can probably ignore the terrain.

Eventually I will most likely need seperate routines for client and server to keep the game consistent in a multiplayer environment, but for now either/or will suffice.

Any thoughts on where to begin with this mission would be really appreciated. I have a feeling this is going to be more difficult than it sounds. lol

Once I get this working good I will release it to the community, perhaps some others will find it useful. I find it much nicer to model in Max than in those CSG editors. Perhaps a little bit slower rendering, but doesnt seem too bad so far.

Thanks

#2
04/01/2004 (7:54 pm)
Thanks Matthew,

Browsed it quickly, looks like it shall be informative. I'll try to put it to use tomorrow. Sleep beckons :p

Peace
#3
04/09/2004 (7:48 am)
Okay, well I got the player collision detection working great with my new interiors, and after implementing a tree structure to limit the poly tests, it has not resulted in any decrease in performance from the torque interiors. Of course, there are some niceties missing like the dynamic shadow casting, but I will get into that later.

The next step is getting the projectile collision working.

Im going to try to get it working with the current Torque 'castRay' method. However, the example in the tutorial only shows ray/plane collisions which are not very accurate; a plane can cut in front of the player without the polygon being in the line of fire and you end up with collisions far away from any objects as long as the bounding box of the object is intersected by the ray. I imagine this would be less of a problem with slow projectiles, but most of my projectiles are fast; bullets and such.

Anyway, I have tried some of my own ray/triangle collision routines, but I am not having a lot of success, I think it is due to a lack of understanding of what is expected in the RayInfo structure that is returned, and possibly how to convert the object's vertices from local space to world space before detection.

Does anybody have an example of a simple castRay function that works on triangles? If not, is there some documentation that has a clear, verbose description of the RayInfo structure and what the fields are expected to contain on collision? I looked in the Torque class reference, and it didnt say anything meaningful at all about it.


Thanks a lot
#4
04/09/2004 (8:40 am)
Which of RayInfo's fields are you having trouble with? Point and normal are self-explanatory. The material info isn't really important till after you get raw collision working. t is a scalar from 0 to 1 indicating how far from the start point to the end point you are.

As for ray tri intersection, have you tried google?

www.cfxweb.net/modules.php?name=News&file=article&sid=1308
www.acm.org/jgt/papers/MollerTrumbore97/
www.ce.chalmers.se/staff/tomasm/code/

And this one might be best to get started with:

www.lighthouse3d.com/opengl/maths/index.php?raytriint

This is the full structure for RayInfo:

struct Collision
{
   SceneObject* object;
   Point3F point;
   VectorF normal;
   U32 material;

   // Face and Face dot are currently only set by the extrudedPolyList
   // clipper.  Values are otherwise undefined.
   U32 face;                  // Which face was hit
   F32 faceDot;               // -Dot of face with poly normal
   F32 distance;
};

struct RayInfo: public Collision {
   // The collision struct has object, point, normal & material.
   F32 t;
};


object is the object you hit with the ray. Point and normal are the point and normal you hit. material is a U32 indicating which material you hit; disregard that for now, it only becomes meaningful once you have collision working and leaving it null does no harm.

The last three things are to be ignored in this context.

And t is a scalar representing the point along the line at which collision occured, with 0 being the start point and 1 being the end point.

Points are transformed into object space before the individual castRays are called.

Does that answer all your questions?
#5
04/09/2004 (8:52 am)
Hi Ben,

Thanks for the quick response.

I think I might know where my malfunction is now. My ray/tri tests take an origin and a direction vector rather than a start and end point, thus they return t as the actual distance in units rather than a clamped scalar. I think I tried reducing it to a scalar, and it didnt work out that great, but I was also trying some different angles with converting object space to world space at the same time and that might have done it. Now that I have a better description of the required fields, I should be in better shape.

I'm going to go back to it after lunch.

Thanks again for your help, you guys are great ;)

Peace
#6
04/09/2004 (8:58 am)
Oh, and just to make sure I am clear on one thing, the 'point' field of RayInfo is supposed to be in object space, not world space, correct?

Thanks
#7
04/09/2004 (10:24 am)
I got it to work. I just had to grab the absolute value of my t and divide it by the ray length, and it works perfectly.

Thanks again, Ben and Matthew.

Peace