use parry3d::bounding_volume::AABB;
use crate::Octant;
use super::{error::Error, WorldPoint};
impl Octant {
pub fn from_center(c: &WorldPoint, p: &WorldPoint) -> Self {
Self::new(p.x > c.x, p.y > c.y, p.z > c.z)
}
pub fn from_aabb<'err>(bb: &AABB, p: &'err WorldPoint) -> Result<Self, Error<'err>> {
if !bb.contains_local_point(p) {
return Err(Error::PointOutOfBounds(p));
}
Ok(Self::from_center(&bb.center(), p))
}
pub fn sup_aabb(self, bb: &AABB) -> AABB {
use parry3d::math::Point as P;
let n = &bb.mins;
let x = &bb.maxs;
let v = x - n;
match self.0 {
0 => AABB {
mins: *n,
maxs: x + v,
},
1 => AABB {
mins: P::new(n.x, n.y, n.z - v.z),
maxs: P::new(x.x + v.x, x.y + v.y, x.z),
},
2 => AABB {
mins: P::new(n.x, n.y - v.y, n.z),
maxs: P::new(x.x + v.x, x.y, x.z + v.z),
},
3 => AABB {
mins: P::new(n.x, n.y - v.y, n.z - v.z),
maxs: P::new(x.x + v.x, x.y, x.z),
},
4 => AABB {
mins: P::new(n.x - v.x, n.y, n.z),
maxs: P::new(x.x, x.y + v.y, x.z + v.z),
},
5 => AABB {
mins: P::new(n.x - v.x, n.y, n.z - v.z),
maxs: P::new(x.x, x.y + v.y, x.z),
},
6 => AABB {
mins: P::new(n.x - v.x, n.y - v.y, n.z),
maxs: P::new(x.x, x.y, x.z + v.z),
},
7 => AABB {
mins: n - v,
maxs: *x,
},
_ => unreachable!(),
}
}
pub fn sub_aabb(self, bb: &AABB) -> AABB {
use parry3d::math::Point as P;
let c = bb.center();
let n = &bb.mins;
let x = &bb.maxs;
match self.0 {
0 => AABB {
mins: *n, maxs: c,
},
1 => AABB {
mins: P::new(n.x, n.y, c.z), maxs: P::new(c.x, c.y, x.z),
},
2 => AABB {
mins: P::new(n.x, c.y, n.z), maxs: P::new(c.x, x.y, c.z),
},
3 => AABB {
mins: P::new(n.x, c.y, c.z), maxs: P::new(c.x, x.y, x.z),
},
4 => AABB {
mins: P::new(c.x, n.y, n.z), maxs: P::new(x.x, c.y, c.z),
},
5 => AABB {
mins: P::new(c.x, n.y, c.z), maxs: P::new(x.x, c.y, x.z),
},
6 => AABB {
mins: P::new(c.x, c.y, n.z), maxs: P::new(x.x, x.y, c.z),
},
7 => AABB {
mins: c, maxs: *x,
},
_ => unreachable!(),
}
}
}