@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
97 lines (80 loc) • 2.87 kB
JavaScript
import { assert } from "../../../assert.js";
import { computeTriangleRayIntersectionBarycentricEdge } from "./computeTriangleRayIntersectionBarycentricEdge.js";
/**
* Compute barycentric coordinates for triangle intersection
* NOTE: most of the code is inlined for speed to avoid allocation and function calls
* @see https://github.com/erich666/jgt-code/blob/master/Volume_02/Number_1/Moller1997a/raytri.c
* @source https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm (Möller and Trumbore, « Fast, Minimum Storage Ray-Triangle Intersection », Journal of Graphics Tools, vol. 2, 1997, p. 21–28)
* @param {number[]} result [t,u,v, normal_x, normal_y, normal_z] will be written here
* @param {number} origin_x
* @param {number} origin_y
* @param {number} origin_z
* @param {number} direction_x
* @param {number} direction_y
* @param {number} direction_z
* @param {number} ax
* @param {number} ay
* @param {number} az
* @param {number} bx
* @param {number} by
* @param {number} bz
* @param {number} cx
* @param {number} cy
* @param {number} cz
* @returns {boolean}
*/
export function computeTriangleRayIntersectionBarycentric(
result,
origin_x, origin_y, origin_z,
direction_x, direction_y, direction_z,
ax, ay, az,
bx, by, bz,
cx, cy, cz
) {
assert.isNumber(ax, 'ax');
assert.isNumber(ay, 'ay');
assert.isNumber(az, 'az');
assert.isNumber(bx, 'bx');
assert.isNumber(by, 'by');
assert.isNumber(bz, 'bz');
assert.isNumber(cx, 'cx');
assert.isNumber(cy, 'cy');
assert.isNumber(cz, 'cz');
// nan checks
assert.notNaN(ax, 'ax');
assert.notNaN(ay, 'ay');
assert.notNaN(az, 'az');
assert.notNaN(bx, 'bx');
assert.notNaN(by, 'by');
assert.notNaN(bz, 'bz');
assert.notNaN(cx, 'cx');
assert.notNaN(cy, 'cy');
assert.notNaN(cz, 'cz');
// finate number check
assert.isFiniteNumber(ax, 'ax');
assert.isFiniteNumber(ay, 'ay');
assert.isFiniteNumber(az, 'az');
assert.isFiniteNumber(bx, 'bx');
assert.isFiniteNumber(by, 'by');
assert.isFiniteNumber(bz, 'bz');
assert.isFiniteNumber(cx, 'cx');
assert.isFiniteNumber(cy, 'cy');
assert.isFiniteNumber(cz, 'cz');
// find vectors for two edges sharing vert
// edge1 = a - b
const edge1_x = bx - ax;
const edge1_y = by - ay;
const edge1_z = bz - az;
// edge2 = c - a
const edge2_x = cx - ax;
const edge2_y = cy - ay;
const edge2_z = cz - az;
return computeTriangleRayIntersectionBarycentricEdge(
result,
origin_x, origin_y, origin_z,
direction_x, direction_y, direction_z,
ax, ay, az,
edge1_x, edge1_y, edge1_z,
edge2_x, edge2_y, edge2_z
);
}