Recommendation: Use the NSDT scene editor to quickly build a 3D application scene
axis-aligned bounding box
Like 2D collision detection, Axis Aligned Bounding Box (AABB) is the fastest algorithm for determining whether two game entities overlap. This involves wrapping the game entity in a non-rotated (and thus axis-aligned) box, and checking the position of those boxes in 3D coordinate space to see if they overlap.
There are axis alignment constraints for performance reasons . The overlapping area between two non-rotated boxes can be checked only by logical comparison, while rotated boxes require additional trigonometric operations, which are computationally slow. If you have entities that will be rotated, you can either modify the dimensions of the bounding box so that it still wraps around the object, or choose to use a different bounding geometry type, such as a sphere (invariant to rotation). The animated GIF below shows an example of a graphic of an AABB resizing to fit a rotating entity. The box is constantly changing dimensions to fit snugly to the entities contained within.
Note: Check out the article Bounding volume collision detection with THREE.js for a practical implementation of this technique.
Point vs. AABB
Checking whether a point is within the AABB is very simple - we just need to check if the point's coordinates are within the AABB; consider each axis separately. If we assume that P x , P y and P z are the coordinates of the points, and B minX–B maxX , B minY–B maxY and B minZ – B maxZ are the ranges for each axis of the AABB, we can calculate the difference between the two using Whether there is a collision between:
or in JavaScript:
.JS copied to clipboard
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 one AABB intersects another AABB is similar to a point test. We only need to do one test per axis using the bounds of the box. The image below shows the test we will perform on the X axis - basically, do the ranges A minX–A maxX and B minX–B maxX overlap?
Mathematically, this looks like this:
In JavaScript, we would use this:
.JS copied to clipboard
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 sphere
Using a bounding sphere to detect collisions is slightly more complicated than AABB's, but still fairly quick to test. The main advantage of spheres is that they are invariant to rotation, so if the wrapped entity is rotated, the bounding sphere will still be the same. Their main downside is that unless the entity they're wrapping is actually spherical, wrapping is usually not a good fit (i.e. wrapping a person with a bounding sphere would result in a lot of false positives, whereas AABB would be a better match) .
point and sphere
To check if a sphere contains a point, we need to calculate the distance between the point and the center of the sphere. If this distance is less than or equal to the radius of the sphere, the point is inside the sphere.
Considering the Euclidean distance between two points A and B is
Our point to sphere collision detection formula will look like this:
or in JavaScript:
.JS copied to clipboard
function isPointInsideSphere(point, sphere) {
// we are using multiplications because is faster than calling Math.pow
const 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 has square roots which can be expensive to compute. A simple optimization to avoid this involves comparing the squared distance to the squared radius, so the optimization equation would 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 centers of the spheres is less than or equal to the sum of their radii.
Mathematically, this looks like:
or in JavaScript:
.JS copied to clipboard
function intersect(sphere, other) {
// we are using multiplications because it's faster than calling Math.pow
const 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 collide is slightly more complicated, but still quick and easy. A logical approach would be to examine each vertex of the AABB, doing a point versus sphere test for each vertex. However, this is overkill - testing all vertices is unnecessary, since we just need to calculate the distance between the closest point of the AABB (not necessarily a vertex) and the center of the sphere to see if it is less than or equal to the radius of the sphere. We can get this value by clamping the center of the sphere to the limits of the AABB.
In JavaScript, we would do this test like this:
.JS copied to clipboard
function intersect(sphere, box) {
// get box closest point to sphere center by clamping
const x = Math.max(box.minX, Math.min(sphere.x, box.maxX));
const y = Math.max(box.minY, Math.min(sphere.y, box.maxY));
const z = Math.max(box.minZ, Math.min(sphere.z, box.maxZ));
// this is the same as isPointInsideSphere
const 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;
}
use physics engine
3D physics engines provide collision detection algorithms, most of which are also based on bounding volumes. The way a physics engine works is to create a physical body , usually attached to its visual representation. This body has properties such as velocity, position, rotation, torque, etc., as well as a physical shape . This shape is what is considered in collision detection calculations.
Original Link: 3D Collision Detection (mvrlink.com)