Main Site Links Resources Tutorials
News VB Gaming Code Downloads DirectX 7
Contact Webmaster VB Programming Product Reviews DirectX 8
  General Multimedia Articles DirectX 9

DirectXGraphics: 3D Collision Detection
Author: Jack Hoxley
Written: 23rd August 2001
Contact: [EMail]
Download: GR_Coll3D.Zip (103kb)

Contents of this lesson
1. Introduction
2. About the algorithm
3. Application of the algorithm

1. Introduction

welcome back for another extended graphics tutorial. This article should hopefully help out a lot of people - I quite often get asked "How do i stop my characters walking through walls?", technically this article doesn't directly address this, but it will provide you with the required tools with which to solve the problem.

2. About the algorithm

The algorithm used is entirely based upon the article written by Kevin Kaiser entitled "3D Collision Detection" - which I found in an excellent book called "Game Programming Gems" (Deloura, Mark). Basically, I take no credit for the actual alogrithm or process here - all I've done is adapt it into a few more useful functions and rewrite it in another language (the original is in C). I've tried not to directly copy his code, but obviously there are going to be a few similiarities...

Anyway, there are two functions presented in the downloadable code - point-triangle collision and triangle-triangle collision. Both make use of the standard equation for a plane - aX+bY+cZ+d=0; the actual maths behind this isn't too important right now and it's beyond this article to explain it - search around the net for further info if you need it. The first step in all of the functions is to generate a plane for the source triangle, we then get the a,b,c and d coefficients for the above plane equation.

Then in the case of point-Triangle collision we just run the equation - if aX+bY+cZ+d=0 the point is touching the triangle, thus we judge it as colliding. Simple really...

Triangle-Triangle collision is a bit more complicated, but the maths really doesn't matter a huge amount (again, look it up if you want). For triangle-triangle collision we use a line-plane intersection test, basically we check the 3 lines that define the 2nd triangle and see if any of them intersect the plane for the 1st triangle - if they do then we have a positive collision. The line-plane intersection test is based on parametric equations and calculus, thus the resulting value ('t' in the code) will allow you to linearly interpolate along the given line to find the actual coordinate at which the triangle intersects the other triangle.

3. Application of the algorithm

okay, now that I've presented the type of algorithm, there are a few things that need to be pointed out - with respect to actually using it in a game environment...

- Data format
The data format used by all the functions is a standard pre-lit, untransformed 3D vertex; the actual algorithm only uses the coordinates for the triangle so the other data is a little irrelevent, but you may need to customise it's function prototypes and definitions should you want to use un-lit untransformed vertices (for example).
- Triangle-Triangle coordinates
The triangles are described in the parameters for the functions in clockwise order, this is important. The function must generate a normal for the triangle, so if it's presented in the wrong order you'll possibly get an incorrect plane being generated and thus bogus collisions will be reported.
- Certain cases where it wont generate a collision.
If the two triangles being tested are on the same plane already the function will return no collision as it is impossible for this algorithm to detect a collision in such a case (you get divide by 0 errors). Also, as you may have already realised, a triangle-triangle collision cannot be detected unless the edge of a (secondary) triangle intersects the plane of the primary triangle. This can easily be solved by checking primary against secondary and then secondary against primary, but that requires a whole-lot-of extra work to be done...
- Result
The result of this function is just a boolean true/false indicating if there was a collision - no other physics is calculated or applied, should you want the resulting coordinate you'll need to extend the function according to what I said earlier, or apply a second algorithm that works out physics-type-stuff...
- Array version in DLL.
As much for my own practise as for your convenience I've written a 2nd version of this library in a C/C++ DLL. Naturally this version of the function is considerably faster than VB's version. But due to the overhead of calling a DLL function I've included an array version of the function so that you can pass 1000's of triangles to be tested in one call, which cuts the time (compared with 1000's of calls) by 10 fold.
- Using the functions for game objects.
Now this is a big one. How do you use this function in your game world? there is no set answer, as it depends on how you've structured your world and it's characters. one option is to test a bounding box(s) for the chararacter/objects and if that results in a collision you can then narrow it down to where abouts on the model - an individual vertex (triangle-point detection) or a point in space (triangle-triangle detection). Just bare in mind that scanning 1000 triangles against 10,000 points each frame is going to kill your frame rate straight away - so try to reduce the potential set early on.

You can download the source code from the top of the page, or from the downloads page. enjoy...

any feedback or improvements can be emailed to me - I'm always interested...

DirectX 4 VB 2000 Jack Hoxley. All rights reserved.
Reproduction of this site and it's contents, in whole or in part, is prohibited,
except where explicitly stated otherwise.
Design by Mateo
Contact Webmaster