Just before going into how to do it in details, let me summarize what you need to do:
- Calculate Bounding Volume for your mesh (pre-process).
- Calculate distance between your camera and the bounding volume.
- Check if the camera position is less than a specific distance from
- Trigger your collision response.
Calculate a bounding volume for your mesh
This is useful because a bounding volume is usually much simpler than your actual mesh, which makes your intersection test much simpler and much faster. As a simple example, in order to calculate an axis aligned bounding box:
//Axis aligned bounding box, cannot be rotated in a direct way.
// Loop through vertices and get
Vec3 max( MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
Vec3 min(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT);
for (int i=0; i< m_vertices.size(); ++i )
if( m_vertices[i].x > max.x)
//Do this for Y,Z
if( m_vertices[i].x < min.x)
//Do this for Y,Z
return AABB( min, max );
What about the camera?
Unlike, the mesh, the camera can be considered as a single vertex. This gives us two simple options when dealing with the camera:
- Consider the camera a single vertex.
- Consider the camera a single vertex with a radius. In other words give your camera a sphere.
I will go with the first option because it's simpler.
This is as simple as calculating the distance between the camera position and the bounding volume, if the distance is less than some distance stop the camera from entering the volume (do collision response).
// Calculates the square distance between point and an AABB
float SquaredDistPointAABB(Point p, AABB b)
float sqDist = 0.0f;
for (int i = 0; i < 3; i++)
// For each axis, count any excess distance outside box extents
float v = p[i];
if (v < b.min[i]) sqDist += (b.min[i] - v) * (b.min[i] - v);
if (v > b.max[i]) sqDist += (v - b.max[i]) * (v - b.max[i]);
Here we calculate the distance squared, to avoid square root calculation, because it's faster, but you can simply take the square root.
What this solution doesn't do
This is a simple solution that can be enough for a simple game. But in the following scenarios it will clearly fell short.
What if I want trignle level collision detection?
In this solution we only checked for collision with the bounding volume, this good enough in case of the camera, but if you want more accurate collision detection, like for example Shooting a ray (bullet) in an FPS game, you need to check collision with the mesh triangles, there are other techniques can be used like using a proxy mesh which could be much simpler than the actual one, also check the next point.
What if I have N objects?
Well, for example if you have million objects it doesn't make sense to check for every intersection with those objects, what people do, is they do spatial partitioning to reduce checks to only those objects that are near (most likely will hit each other).
What about if my camera/object is moving at 1 bazillion km/h ?
Well, I doubt any collision engine can solve this (because of floating point accuracy). But (lame) jokes aside, moving objects (especially at high speeds) suffer from what is called Tunneling, in order to solve this you need to predict when the two objects will intersect, this will add the time variable to the static equation, so you need to calculate the possible time that two objects will collide. Which makes things a little bit more complicated.