#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone, Copy)]
pub struct BboxNode {
pub min: [f32; 3],
pub max: [f32; 3],
pub face_index: usize,
pub left: usize,
pub right: usize,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct BboxTree {
pub nodes: Vec<BboxNode>,
pub root: usize,
}
#[allow(dead_code)]
pub fn triangle_bbox(v0: [f32; 3], v1: [f32; 3], v2: [f32; 3]) -> ([f32; 3], [f32; 3]) {
let min = [
v0[0].min(v1[0]).min(v2[0]),
v0[1].min(v1[1]).min(v2[1]),
v0[2].min(v1[2]).min(v2[2]),
];
let max = [
v0[0].max(v1[0]).max(v2[0]),
v0[1].max(v1[1]).max(v2[1]),
v0[2].max(v1[2]).max(v2[2]),
];
(min, max)
}
#[allow(dead_code)]
pub fn merge_bbox(a: ([f32; 3], [f32; 3]), b: ([f32; 3], [f32; 3])) -> ([f32; 3], [f32; 3]) {
let min = [a.0[0].min(b.0[0]), a.0[1].min(b.0[1]), a.0[2].min(b.0[2])];
let max = [a.1[0].max(b.1[0]), a.1[1].max(b.1[1]), a.1[2].max(b.1[2])];
(min, max)
}
#[allow(dead_code)]
pub fn build_bbox_tree(positions: &[[f32; 3]], indices: &[u32]) -> BboxTree {
let tri_count = indices.len() / 3;
let mut nodes = Vec::with_capacity(tri_count);
for t in 0..tri_count {
let i0 = indices[t * 3] as usize;
let i1 = indices[t * 3 + 1] as usize;
let i2 = indices[t * 3 + 2] as usize;
let (min, max) = triangle_bbox(positions[i0], positions[i1], positions[i2]);
nodes.push(BboxNode {
min,
max,
face_index: t,
left: usize::MAX,
right: usize::MAX,
});
}
let root = if nodes.is_empty() { usize::MAX } else { 0 };
BboxTree { nodes, root }
}
#[allow(dead_code)]
pub fn point_in_bbox(p: [f32; 3], min: [f32; 3], max: [f32; 3]) -> bool {
p[0] >= min[0]
&& p[0] <= max[0]
&& p[1] >= min[1]
&& p[1] <= max[1]
&& p[2] >= min[2]
&& p[2] <= max[2]
}
#[allow(dead_code)]
pub fn bbox_overlap(a_min: [f32; 3], a_max: [f32; 3], b_min: [f32; 3], b_max: [f32; 3]) -> bool {
a_min[0] <= b_max[0]
&& a_max[0] >= b_min[0]
&& a_min[1] <= b_max[1]
&& a_max[1] >= b_min[1]
&& a_min[2] <= b_max[2]
&& a_max[2] >= b_min[2]
}
#[allow(dead_code)]
pub fn node_count(tree: &BboxTree) -> usize {
tree.nodes.len()
}
#[allow(dead_code)]
pub fn bbox_volume(min: [f32; 3], max: [f32; 3]) -> f32 {
(max[0] - min[0]) * (max[1] - min[1]) * (max[2] - min[2])
}
#[allow(dead_code)]
pub fn bbox_tree_to_json(tree: &BboxTree) -> String {
format!("{{\"node_count\":{}}}", tree.nodes.len())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_triangle_bbox() {
let (min, max) = triangle_bbox([0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]);
assert!((min[0]).abs() < 1e-9);
assert!((max[0] - 1.0).abs() < 1e-6);
}
#[test]
fn test_merge_bbox() {
let a = ([0.0, 0.0, 0.0], [1.0, 1.0, 1.0]);
let b = ([-1.0, -1.0, -1.0], [0.5, 0.5, 0.5]);
let (min, max) = merge_bbox(a, b);
assert!((min[0] - (-1.0)).abs() < 1e-6);
assert!((max[0] - 1.0).abs() < 1e-6);
}
#[test]
fn test_build_tree() {
let pos = vec![[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let idx = vec![0, 1, 2];
let tree = build_bbox_tree(&pos, &idx);
assert_eq!(node_count(&tree), 1);
}
#[test]
fn test_build_empty() {
let tree = build_bbox_tree(&[], &[]);
assert_eq!(node_count(&tree), 0);
assert_eq!(tree.root, usize::MAX);
}
#[test]
fn test_point_in_bbox() {
assert!(point_in_bbox(
[0.5, 0.5, 0.5],
[0.0, 0.0, 0.0],
[1.0, 1.0, 1.0]
));
assert!(!point_in_bbox(
[1.5, 0.5, 0.5],
[0.0, 0.0, 0.0],
[1.0, 1.0, 1.0]
));
}
#[test]
fn test_bbox_overlap() {
assert!(bbox_overlap(
[0.0, 0.0, 0.0],
[1.0, 1.0, 1.0],
[0.5, 0.5, 0.5],
[1.5, 1.5, 1.5]
));
assert!(!bbox_overlap(
[0.0, 0.0, 0.0],
[1.0, 1.0, 1.0],
[2.0, 2.0, 2.0],
[3.0, 3.0, 3.0]
));
}
#[test]
fn test_bbox_volume() {
let v = bbox_volume([0.0, 0.0, 0.0], [2.0, 3.0, 4.0]);
assert!((v - 24.0).abs() < 1e-6);
}
#[test]
fn test_node_face_index() {
let pos = vec![[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let idx = vec![0, 1, 2];
let tree = build_bbox_tree(&pos, &idx);
assert_eq!(tree.nodes[0].face_index, 0);
}
#[test]
fn test_bbox_tree_to_json() {
let tree = BboxTree {
nodes: vec![],
root: usize::MAX,
};
let j = bbox_tree_to_json(&tree);
assert!(j.contains("\"node_count\":0"));
}
#[test]
fn test_multi_triangle_tree() {
let pos = vec![
[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[1.0, 1.0, 0.0],
];
let idx = vec![0, 1, 2, 1, 3, 2];
let tree = build_bbox_tree(&pos, &idx);
assert_eq!(node_count(&tree), 2);
}
}