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
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) |
|
} |
|
}
|
|
|