This article provides an introduction to the different bounding volume techniques used to implement collision detection in 3D environments. Followup articles will cover implementations in specific 3D libraries.
Axis-aligned bounding boxes
As with 2D collision detection, axis-aligned bounding boxes (AABB) are the quickest algorithm to determine whether the two game entities are overlapping or not. This consists of wrapping game entities in a non-rotated (thus axis-aligned) box and checking the positions of these boxes in the 3D coordinate space to see if they are overlapping.
The axis-aligned constraint is there because of performance reasons. The overlapping area between two non-rotated boxes can be checked with logical comparisons alone, whereas rotated boxes require additional trigonometric operations, which are slower to calculate. If you have entities that will be rotating, you can either modify the dimensions of the bounding box so it still wraps the object, or opt to use another bounding geometry type, such as spheres (which are invariant to rotation.) The animated GIF below shows a graphic example of an AABB that adapts its size to fit the rotating entity. The box constantly changes dimensions to snugly fit the entity contained inside.
Note: Check out the Bounding Volumes with Three.js article to see a practical implementation of this technique.
Point vs. AABB
Checking if a point is inside an AABB is pretty simple — we just need to check whether the point's coordinates fall inside the AABB; considering each axis separately. If we assume that Px, Py and Pz are the point's coordinates, and BminX–BmaxX, BminY–BmaxY, and BminZ–BmaxZ are the ranges of each axis of the AABB, we can calculate whether a collision has occurred between the two using the following formula:
x >= B{minX} \wedge Px <= B{maxX}) \wedge (Py >= B{minY} \wedge Py <= B{maxY}) \wedge (Pz >= B{minZ} \wedge Pz <= B{maxZ})
Or in JavaScript:
function isPointInsideAABB(point, box) { return (point.x >= box.minX && point.x <= box.maxX) && (point.y >= box.minY && point.y <= box.maxY) && (point.z >= box.minZ && point.z <= box.maxZ);}
AABB vs. AABB
Checking whether an AABB intersects another AABB is similar to the point test. We just need to do one test per axis, using the boxes' boundaries. The diagram below shows the test we'd perform over the X-axis — basically, do the ranges AminX–AmaxX and BminX–BmaxX overlap?
Mathematically this would look like so:
And in JavaScript, we'd use this:
function intersect(a, b) { return (a.minX <= b.maxX && a.maxX >= b.minX) && (a.minY <= b.maxY && a.maxY >= b.minY) && (a.minZ <= b.maxZ && a.maxZ >= b.minZ);}
Bounding spheres
Using bounding spheres to detect collisions is a bit more complex than AABB, but still fairly quick to test. The main advantage of spheres is that they are invariant to rotation, so if the wrapped entity rotates, the bounding sphere would still be the same. Their main disadvantage is that unless the entity they are wrapping is actually spherical, the wrapping is usually not a good fit (i.e. wrapping a person with a bounding sphere will cause a lot of false positives, whereas an AABB would be a better match).
Point vs. sphere
To check whether a sphere contains a point we need to calculate the distance between the point and the sphere's center. If this distance is smaller than or equal to the radius of the sphere, the point is inside the sphere.
Taking into account that the Euclidean distance between two points A and B is , our formula for point vs. sphere collision detection would work out like so:
Or in JavaScript:
function isPointInsideSphere(point, sphere) { var distance = Math.sqrt((point.x - sphere.x) * (point.x - sphere.x) + (point.y - sphere.y) * (point.y - sphere.y) + (point.z - sphere.z) * (point.z - sphere.z)); return distance < sphere.radius;}
Note: The code above features a square root, which can be expensive to calculate. An easy optimization to avoid it consists of comparing the squared distance with the squared radius, so the optimized equation would instead involve distanceSqr < sphere.radius * sphere.radius
.
Sphere vs. sphere
The sphere vs sphere test is similar to the point vs sphere test. What we need to test here is that the distance between the sphere's centers is less than or equal to the sum of their radii.
Mathematically, this looks like:
x - B_x)^2 + (A_y - B_y)^2 + (A_z - B_z)^2} <= A{radius} + B_{radius}
Or in JavaScript:
function intersect(sphere, other) { var distance = Math.sqrt((sphere.x - other.x) * (sphere.x - other.x) + (sphere.y - other.y) * (sphere.y - other.y) + (sphere.z - other.z) * (sphere.z - other.z)); return distance < (sphere.radius + other.radius);}
Sphere vs. AABB
Testing whether a sphere and an AABB are colliding is slightly more complicated, but still simple and fast. A logical approach would be to check every vertex of the AABB, doing a point vs sphere test for each one. This is overkill, however — testing all the vertices is unnecessary, as we can get away with just calculating the distance between the AABB's closest point (not necessarily a vertex) and the sphere's center, seeing if it is less than or equal to the sphere's radius. We can get this value by clamping the sphere's center to the AABB's limits.
In JavaScript, we'd do this test like so:
function intersect(sphere, box) { var x = Math.max(box.minX, Math.min(sphere.x, box.maxX)); var y = Math.max(box.minY, Math.min(sphere.y, box.maxY)); var z = Math.max(box.minZ, Math.min(sphere.z, box.maxZ)); var distance = Math.sqrt((x - sphere.x) * (x - sphere.x) + (y - sphere.y) * (y - sphere.y) + (z - sphere.z) * (z - sphere.z)); return distance < sphere.radius;}
Using a physics engine
3D physics engines provide collision detection algorithms, most of them based on bounding volumes as well. The way a physics engine works is by creating a physical body, usually attached to a visual representation of it. This body has properties such as velocity, position, rotation, torque, etc., and also a physical shape. This shape is the one that is considered in the collision detection calculations.
We have prepared a live collision detection demo (with source code) that you can take a look at to see such techniques in action — this uses the open-source 3D physics engine cannon.js.
See also
Related articles on MDN:
- Bounding volumes collision detection with Three.js
- 2D collision detection
External resources:
- Simple intersection tests for games on Gamasutra
- Bounding volume on Wikipedia
FAQs
How is 3D collision detection implemented?
How to do Basic 3D Collision Detection in C++ - YouTube
How do games do collision detection?
Continuous collision detection techniques attempt to find when two bodies collided between the previous and the current step of the simulation. They compute the time of impact, so we can then go back in time and process the collision at that point.
What is a collision detection in programming?
How to Code: Collision Detection — Part I - YouTube
What is AABB algorithm?
AABB stands for Axis-Aligned Bounding Box, it is an algorithm to detect collision between a rectangle's edges, in this case, those edges are parallel with coordinate axes. Basically, we will check two rectangles overlap with each other or not.
How do you implement physics in game?
How Do Developers Implement Physics In Video Games? ( Part 1)
How is collision done in 2D games?
The most basic way to approach this type of 2d collision detection is to utilize a concept known as Axis-aligned bounding box. Axis-aligned bounding box, or AABB, detects if two non-rotational polygons are overlapping each other.
What type of algorithm is often used in the creation of 3D terrain in gaming and special effects?
In computing, procedural generation is a method of creating data algorithmically as opposed to manually, typically through a combination of human-generated assets and algorithms coupled with computer-generated randomness and processing power. In computer graphics, it is commonly used to create textures and 3D models.
How does CSMA CD detect collisions?
The collision detection technology detects collisions by sensing transmissions from other stations. On detection of a collision, the station stops transmitting, sends a jam signal, and then waits for a random time interval before retransmission.
How do you program a collision in scratch?
Scratch Wall Collision | How to Make Sprites Not Go Through Walls
What does collision mean in video games?
Collision detection concerns the detection of collisions between objects in the virtual environment. Primarily employed to stop objects moving through each other and the environment. Collision Detection is everywhere in computer games: between characters and characters, between characters and terrain, etc.
Where is collision detection used?
Collision detection is a classic issue of computational geometry and has applications in various computing fields, primarily in computer graphics, computer games, computer simulations, robotics and computational physics.
What is collision geometry 3D Modelling?
From Valve Developer Community. A collision mesh is a cheap 3D mesh used by VPhysics. It is sometimes called a collision model, after the C++ object that loads it into the engine, but as far as creating models is concerned, it is a vertex mesh more or less like any other.
What is Broadphase?
Typically, a broadphase keeps track of bounding volumes, usually AABBs, of all colliders. The broadphase produces a list of collider pairs whose AABBs are colliding. These collider pairs are then passed on to the collision detection algorithm to decide whether they actually collide.
How do you use a Quadtree?
- Insert an object into the quadtree: Check if the object intersects the current node. ...
- Delete an object from the quadtree: ...
- Test if an object intersects any object inside the quadtree: ...
- Test for all collisions between all objects inside the quadtree: ...
- Update the quadtree:
How do you find collision in Unity 3D?
Steps to detect collision in Unity 3D
Make sure Is Kinematic check box is unchecked. Step 2: Attach Collider components to the other game objects. Here we have added Box Collider to Ground and Enemy Game Objects.