@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
88 lines (62 loc) • 2.23 kB
JavaScript
const abs = Math.abs;
/**
* NOTES:
* https://web.archive.org/web/20090803054252/http://tog.acm.org/resources/GraphicsGems/gems/RayBox.c
* https://tavianator.com/fast-branchless-raybounding-box-intersections/
* https://gamedev.stackexchange.com/questions/18436/most-efficient-aabb-vs-ray-collision-algorithms
*
* @param {number} x0
* @param {number} y0
* @param {number} z0
* @param {number} x1
* @param {number} y1
* @param {number} z1
* @param {number} origin_x
* @param {number} origin_y
* @param {number} origin_z
* @param {number} direction_x
* @param {number} direction_y
* @param {number} direction_z
* @returns {boolean}
*/
export function aabb3_intersects_ray(
x0, y0, z0,
x1, y1, z1,
origin_x, origin_y, origin_z,
direction_x, direction_y, direction_z
) {
// Z Projection
const extents_x = (x1 - x0) * 0.5;
const center_x = x0 + extents_x;
const diff_x = origin_x - center_x;
if (diff_x * direction_x >= 0 && abs(diff_x) > extents_x) {
return false;
}
// Y projection
const extents_y = (y1 - y0) * 0.5;
const center_y = y0 + extents_y;
const diff_y = origin_y - center_y;
if (diff_y * direction_y >= 0 && abs(diff_y) > extents_y) {
return false;
}
// Z projection
const extents_z = (z1 - z0) * 0.5;
const center_z = z0 + extents_z;
const diff_z = origin_z - center_z;
if (diff_z * direction_z >= 0 && abs(diff_z) > extents_z) {
return false;
}
const abs_direction_y = abs(direction_y);
const abs_direction_z = abs(direction_z);
const f0 = abs(direction_y * diff_z - direction_z * diff_y);
if (f0 > extents_y * abs_direction_z + extents_z * abs_direction_y) {
return false;
}
const abs_direction_x = abs(direction_x);
const f1 = abs(direction_z * diff_x - direction_x * diff_z);
if (f1 > extents_x * abs_direction_z + extents_z * abs_direction_x) {
return false;
}
const f2 = abs(direction_x * diff_y - direction_y * diff_x);
return f2 <= extents_x * abs_direction_y + extents_y * abs_direction_x;
}