roctree/src/utilities/intersection_checks.rs
Alex Selimov 209f483992 [WIP] start critical data structures, NEED TESTS*
- Add missing primitives file
- Begin bounding volume hierarchy code
- Add some untested base functions for octree and morton encoding
- Add interesection tests for box and triangle
2025-03-05 09:14:58 -05:00

51 lines
1.5 KiB
Rust

use core::f64;
use vecmath::{vec3_cross, vec3_dot, vec3_sub};
use crate::primitives::{Box3, Triangle};
/// Determine whether two shapes interesect using the separating axis theorem
pub fn tri_aabb_intersect(bx: &Box3, tri: &Triangle) -> bool {
// Get edge vectors for triangle
let e1 = vec3_sub(tri.v2, tri.v1);
let e2 = vec3_sub(tri.v3, tri.v2);
let e3 = vec3_sub(tri.v1, tri.v3);
// Get face and edge normals
let tri_face = vec3_cross(e1, e2);
let n1 = vec3_cross(e1, e1);
let n2 = vec3_cross(e2, e1);
let n3 = vec3_cross(e3, e1);
// Face normals AABB
let u0 = [1.0, 0.0, 0.0];
let u1 = [0.0, 1.0, 0.0];
let u2 = [0.0, 0.0, 1.0];
// Now check all of the axes
let box_vertices = bx.get_vertices();
for axis in [u0, u1, u2, tri_face, n1, n2, n3] {
let box_projection = project_pnts(&box_vertices, axis);
let tri_projection = project_pnts(&[tri.v1, tri.v2, tri.v3], axis);
let start = f64::max(box_projection.0, tri_projection.0);
let end = f64::min(box_projection.1, tri_projection.1);
if start < end {
return false;
}
}
return true;
}
/// Project points unto an Axis and return the max and min
fn project_pnts(pnts: &[[f64; 3]], axis: [f64; 3]) -> (f64, f64) {
let mut min_proj = f64::INFINITY;
let mut max_proj = f64::NEG_INFINITY;
for pnt in pnts {
let projection = vec3_dot(axis, *pnt);
min_proj = min_proj.min(projection);
max_proj = max_proj.max(projection);
}
(min_proj, max_proj)
}