You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.1 KiB

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<usize> {
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<USize3> for (NonZeroU32, NonZeroU32, NonZeroU32) {
fn from(size: USize3) -> Self {
(size.width, size.depth, size.height)
}
}
impl From<USize3> for (u32, u32, u32) {
fn from(size: USize3) -> Self {
(size.width.get(), size.depth.get(), size.height.get())
}
}
impl TryFrom<UVec3> for USize3 {
type Error = TryFromIntError;
fn try_from(UVec3 { x, y, z }: UVec3) -> Result<Self, Self::Error> {
Ok(Self::new(x.try_into()?, y.try_into()?, z.try_into()?))
}
}
impl From<USize3> 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)
}
}