use crate::{BranchShape, ChildIndex, Level, Tree, VectorKey};
use glam::{IVec2, IVec3, UVec2, UVec3};
use ndshape::{
ConstPow2Shape2i32, ConstPow2Shape2u32, ConstPow2Shape3i32, ConstPow2Shape3u32, ConstShape,
};
pub type QuadtreeShapeI32 = ConstPow2Shape2i32<1, 1>;
pub type QuadtreeShapeU32 = ConstPow2Shape2u32<1, 1>;
pub type OctreeShapeI32 = ConstPow2Shape3i32<1, 1, 1>;
pub type OctreeShapeU32 = ConstPow2Shape3u32<1, 1, 1>;
pub type QuadtreeI32<T> = Tree<IVec2, QuadtreeShapeI32, T, 4>;
pub type QuadtreeU32<T> = Tree<UVec2, QuadtreeShapeU32, T, 4>;
pub type OctreeI32<T> = Tree<IVec3, OctreeShapeI32, T, 8>;
pub type OctreeU32<T> = Tree<UVec3, OctreeShapeU32, T, 8>;
impl<T> QuadtreeI32<T> {
pub fn new(height: Level) -> Self {
unsafe { Self::new_generic(height) }
}
}
impl<T> QuadtreeU32<T> {
pub fn new(height: Level) -> Self {
unsafe { Self::new_generic(height) }
}
}
impl<T> OctreeI32<T> {
pub fn new(height: Level) -> Self {
unsafe { Self::new_generic(height) }
}
}
impl<T> OctreeU32<T> {
pub fn new(height: Level) -> Self {
unsafe { Self::new_generic(height) }
}
}
macro_rules! impl_signed_branch_shape {
($name:ty, $vector:ty, $shifter:expr) => {
impl BranchShape<$vector> for $name {
const SHAPE_SHIFTER: $vector = $shifter;
#[inline]
fn linearize_child(v: $vector) -> ChildIndex {
<$name>::linearize(v.into()) as ChildIndex
}
#[inline]
fn delinearize_child(i: ChildIndex) -> $vector {
<$name>::delinearize(i as i32).into()
}
}
};
}
macro_rules! impl_unsigned_branch_shape {
($name:ty, $vector:ty, $shifter:expr) => {
impl BranchShape<$vector> for $name {
const SHAPE_SHIFTER: $vector = $shifter;
#[inline]
fn linearize_child(v: $vector) -> ChildIndex {
<$name>::linearize(v.into()) as ChildIndex
}
#[inline]
fn delinearize_child(i: ChildIndex) -> $vector {
<$name>::delinearize(i as u32).into()
}
}
};
}
impl_unsigned_branch_shape!(QuadtreeShapeU32, UVec2, UVec2::from_array([1; 2]));
impl_unsigned_branch_shape!(OctreeShapeU32, UVec3, UVec3::from_array([1; 3]));
impl_signed_branch_shape!(QuadtreeShapeI32, IVec2, IVec2::from_array([1; 2]));
impl_signed_branch_shape!(OctreeShapeI32, IVec3, IVec3::from_array([1; 3]));
impl VectorKey for IVec2 {
#[inline]
fn mul_u32(self, rhs: u32) -> Self {
self * rhs as i32
}
}
impl VectorKey for IVec3 {
#[inline]
fn mul_u32(self, rhs: u32) -> Self {
self * rhs as i32
}
}
impl VectorKey for UVec2 {
#[inline]
fn mul_u32(self, rhs: u32) -> Self {
self * rhs
}
}
impl VectorKey for UVec3 {
#[inline]
fn mul_u32(self, rhs: u32) -> Self {
self * rhs
}
}