use std::num::{NonZeroU32, TryFromIntError}; use bevy::math::{IVec3, UVec3}; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub struct USize3 { pub width: NonZeroU32, pub height: NonZeroU32, pub depth: NonZeroU32, } impl USize3 { pub fn new(width: NonZeroU32, height: NonZeroU32, depth: NonZeroU32) -> Self { Self { width, height, depth, } } pub fn splat(length: NonZeroU32) -> Self { Self::new(length, length, length) } pub fn contains(&self, pos: IVec3) -> bool { (0..self.width.get() as i32).contains(&pos.x) && (0..self.height.get() as i32).contains(&pos.y) && (0..self.depth.get() as i32).contains(&pos.z) } pub fn ivec3_to_index(&self, pos: IVec3) -> Option { self.contains(pos).then(|| { let w = self.width.get() as i32; let h = self.height.get() as i32; (pos.x + (pos.y * w) + (pos.z * w * h)) as usize }) } pub fn index_to_ivec3(&self, index: usize) -> IVec3 { let i = index as i32; let w = self.width.get() as i32; let h = self.height.get() as i32; IVec3::new(i % w, i / w % h, i / w / h) } } impl From for (NonZeroU32, NonZeroU32, NonZeroU32) { fn from(size: USize3) -> Self { (size.width, size.depth, size.height) } } impl From for (u32, u32, u32) { fn from(size: USize3) -> Self { (size.width.get(), size.depth.get(), size.height.get()) } } impl TryFrom for USize3 { type Error = TryFromIntError; fn try_from(UVec3 { x, y, z }: UVec3) -> Result { Ok(Self::new(x.try_into()?, y.try_into()?, z.try_into()?)) } } impl From for UVec3 { fn from(size: USize3) -> Self { Self::new(size.width.get(), size.height.get(), size.depth.get()) } } impl ndarray::IntoDimension for USize3 { type Dim = ndarray::Ix3; fn into_dimension(self) -> Self::Dim { let w = self.width.get() as usize; let h = self.height.get() as usize; let d = self.depth.get() as usize; ndarray::Ix3(w, h, d) } }