#[derive(Debug, Clone, PartialEq)]
pub struct Aabb {
pub min: [f32; 3],
pub max: [f32; 3],
}
impl Aabb {
pub fn new(min: [f32; 3], max: [f32; 3]) -> Self {
Self { min, max }
}
pub fn point(p: [f32; 3]) -> Self {
Self { min: p, max: p }
}
pub fn merge(a: &Aabb, b: &Aabb) -> Aabb {
Aabb {
min: [
a.min[0].min(b.min[0]),
a.min[1].min(b.min[1]),
a.min[2].min(b.min[2]),
],
max: [
a.max[0].max(b.max[0]),
a.max[1].max(b.max[1]),
a.max[2].max(b.max[2]),
],
}
}
pub fn intersects(&self, other: &Aabb) -> bool {
self.min[0] <= other.max[0]
&& self.max[0] >= other.min[0]
&& self.min[1] <= other.max[1]
&& self.max[1] >= other.min[1]
&& self.min[2] <= other.max[2]
&& self.max[2] >= other.min[2]
}
pub fn contains(&self, p: [f32; 3]) -> bool {
p[0] >= self.min[0]
&& p[0] <= self.max[0]
&& p[1] >= self.min[1]
&& p[1] <= self.max[1]
&& p[2] >= self.min[2]
&& p[2] <= self.max[2]
}
pub fn surface_area(&self) -> f32 {
let dx = self.max[0] - self.min[0];
let dy = self.max[1] - self.min[1];
let dz = self.max[2] - self.min[2];
2.0 * (dx * dy + dy * dz + dz * dx)
}
pub fn center(&self) -> [f32; 3] {
[
0.5 * (self.min[0] + self.max[0]),
0.5 * (self.min[1] + self.max[1]),
0.5 * (self.min[2] + self.max[2]),
]
}
pub fn expand(&self, margin: f32) -> Aabb {
Aabb {
min: [
self.min[0] - margin,
self.min[1] - margin,
self.min[2] - margin,
],
max: [
self.max[0] + margin,
self.max[1] + margin,
self.max[2] + margin,
],
}
}
}
#[derive(Debug, Clone)]
pub struct BvhPrimitive {
pub aabb: Aabb,
pub object_id: usize,
}
impl BvhPrimitive {
pub fn new(aabb: Aabb, object_id: usize) -> Self {
Self { aabb, object_id }
}
}
#[derive(Debug)]
pub struct BvhNode {
pub aabb: Aabb,
pub left: Option<Box<BvhNode>>,
pub right: Option<Box<BvhNode>>,
pub primitives: Vec<usize>,
}
impl BvhNode {
pub fn is_leaf(&self) -> bool {
self.left.is_none() && self.right.is_none()
}
}
#[derive(Debug, Clone)]
pub struct FlatBvhNode {
pub aabb: Aabb,
pub left_first: u32,
pub count: u32,
}
#[derive(Debug, Clone)]
pub struct RayHit {
pub object_id: usize,
pub t: f32,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct GpuRay {
pub origin: [f32; 3],
pub direction: [f32; 3],
pub max_t: f32,
}
impl GpuRay {
pub fn new(origin: [f32; 3], direction: [f32; 3], max_t: f32) -> Self {
Self {
origin,
direction,
max_t,
}
}
}
#[derive(Debug, Clone)]
pub struct BvhStats {
pub node_count: usize,
pub leaf_count: usize,
pub internal_count: usize,
pub max_depth: usize,
pub total_primitives: usize,
pub avg_primitives_per_leaf: f32,
}
#[derive(Debug, Clone)]
pub struct BvhTreeStatistics {
pub node_count: usize,
pub leaf_count: usize,
pub internal_count: usize,
pub max_depth: usize,
pub total_primitives: usize,
pub avg_fanout: f32,
pub total_leaf_surface_area: f32,
}
#[derive(Debug, Clone)]
pub struct LbvhPrimitive {
pub aabb: Aabb,
pub object_id: usize,
pub morton: u32,
}
#[derive(Debug, Clone)]
pub struct MortonCluster {
pub indices: Vec<usize>,
pub aabb: Aabb,
pub radius: f32,
}