#[repr(C)]
#[derive(Clone, Copy, Debug, bytemuck::Pod, bytemuck::Zeroable)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Size(pub f32);
impl Size {
pub const AUTO: Self = Self(f32::MAX);
pub const AUTO_LARGE: Self = Self(f32::MIN);
#[inline]
pub fn new_scene(size: f32) -> Self {
debug_assert!((0.0..f32::MAX).contains(&size), "Bad size: {size}");
Self(size)
}
#[inline]
pub fn new_points(size: f32) -> Self {
debug_assert!((0.0..f32::MAX).contains(&size), "Bad size: {size}");
Self(-size)
}
#[inline]
pub fn is_auto(&self) -> bool {
self.0 <= f32::MIN || self.0 >= f32::MAX
}
#[inline]
pub fn scene(&self) -> Option<f32> {
(0.0..f32::MAX).contains(&self.0).then_some(self.0)
}
#[inline]
pub fn points(&self) -> Option<f32> {
(self.0 > f32::MIN && self.0 <= 0.0).then_some(-self.0)
}
}
impl PartialEq for Size {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.0.is_nan() && other.0.is_nan() || self.0 == other.0
}
}
impl std::ops::Mul<f32> for Size {
type Output = Size;
#[inline]
fn mul(self, rhs: f32) -> Self::Output {
debug_assert!(rhs.is_finite() && rhs >= 0.0);
debug_assert!((self.0 * rhs).is_finite());
Self(self.0 * rhs)
}
}
impl std::ops::MulAssign<f32> for Size {
#[inline]
fn mul_assign(&mut self, rhs: f32) {
debug_assert!(rhs.is_finite() && rhs >= 0.0);
debug_assert!((self.0 * rhs).is_finite());
self.0 *= rhs;
}
}
#[repr(C)]
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
pub struct SizeHalf(half::f16);
impl From<Size> for SizeHalf {
#[inline]
fn from(size: Size) -> Self {
SizeHalf(half::f16::from_f32(size.0))
}
}