use crate::csg::{Real, Vec2, Vec3};
#[derive(Clone, Copy, Debug)]
pub struct BBox {
pub id: Option<usize>,
pub min: Vec3,
pub max: Vec3,
}
#[derive(Clone, Debug)]
pub struct BPos {
pub id: Option<usize>,
pub pos: Vec2,
}
impl BBox {
pub fn default() -> Self {
BBox {
id: None,
min: Vec3::MAX,
max: Vec3::MIN,
}
}
pub fn new(id: Option<usize>, pts: &[Vec3]) -> Self {
let mut b = BBox {
id,
min: Vec3::MAX,
max: Vec3::MIN,
};
for pt in pts {
b.union(pt);
}
b
}
pub fn size(&self) -> Vec3 {
self.max - self.min
}
pub fn scale(&self) -> Real {
let s = self.size();
s.x.abs().max(s.y.abs()).max(s.z.abs())
}
pub fn union(&mut self, p: &Vec3) {
if p.x.is_nan() {
return;
}
self.min = self.min.min(*p);
self.max = self.max.max(*p);
}
pub fn longest_dim(&self) -> usize {
let s = self.size();
if s.x > s.y && s.x > s.z {
0
} else if s.y > s.z {
1
} else {
2
}
}
}
pub fn union_bbs(b0: &Aabb, b1: &Aabb) -> Aabb {
Aabb {
min: b0.min.min(b1.min),
max: b0.max.max(b1.max),
}
}
#[derive(Clone, Copy, Debug)]
pub struct Aabb {
pub min: Vec3,
pub max: Vec3,
}
impl Aabb {
pub fn empty() -> Self {
Aabb {
min: Vec3::MAX,
max: Vec3::MIN,
}
}
}
impl From<&BBox> for Aabb {
fn from(b: &BBox) -> Self {
Aabb {
min: b.min,
max: b.max,
}
}
}
pub trait QueryShape {
fn overlaps_node(&self, bb: &Aabb) -> bool;
fn id(&self) -> Option<usize>;
}
impl QueryShape for BBox {
#[inline]
fn overlaps_node(&self, bb: &Aabb) -> bool {
bb.min.cmple(self.max).all() && bb.max.cmpge(self.min).all()
}
#[inline]
fn id(&self) -> Option<usize> {
self.id
}
}
impl QueryShape for BPos {
#[inline]
fn overlaps_node(&self, bb: &Aabb) -> bool {
bb.min.x <= self.pos.x
&& bb.min.y <= self.pos.y
&& bb.max.x >= self.pos.x
&& bb.max.y >= self.pos.y
}
#[inline]
fn id(&self) -> Option<usize> {
self.id
}
}