use core::marker::PhantomData;
use glam::DVec3;
use uom::si::{Dimension, Quantity, SI};
use crate::frame::Frame;
#[repr(C)]
pub struct Qty3<D: ?Sized + Dimension, F: Frame> {
pub x: Quantity<D, SI<f64>, f64>,
pub y: Quantity<D, SI<f64>, f64>,
pub z: Quantity<D, SI<f64>, f64>,
_f: PhantomData<F>,
}
impl<D: ?Sized + Dimension, F: Frame> Qty3<D, F> {
#[inline]
pub const fn new(
x: Quantity<D, SI<f64>, f64>,
y: Quantity<D, SI<f64>, f64>,
z: Quantity<D, SI<f64>, f64>,
) -> Self {
Self {
x,
y,
z,
_f: PhantomData,
}
}
#[inline(always)]
pub fn raw_si(&self) -> DVec3 {
DVec3::new(self.x.value, self.y.value, self.z.value)
}
#[inline(always)]
pub fn from_raw_si(v: DVec3) -> Self {
Self {
x: Quantity {
dimension: PhantomData,
units: PhantomData,
value: v.x,
},
y: Quantity {
dimension: PhantomData,
units: PhantomData,
value: v.y,
},
z: Quantity {
dimension: PhantomData,
units: PhantomData,
value: v.z,
},
_f: PhantomData,
}
}
#[inline]
pub fn zero() -> Self {
Self::from_raw_si(DVec3::ZERO)
}
#[inline(always)]
pub fn relabel_to<F2: Frame>(self) -> Qty3<D, F2> {
Qty3 {
x: self.x,
y: self.y,
z: self.z,
_f: PhantomData,
}
}
}
impl<D: ?Sized + Dimension, F: Frame> Copy for Qty3<D, F> {}
impl<D: ?Sized + Dimension, F: Frame> Clone for Qty3<D, F> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<D: ?Sized + Dimension, F: Frame> core::fmt::Debug for Qty3<D, F> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"Qty3<{}>({}, {}, {})",
core::any::type_name::<F>(),
self.x.value,
self.y.value,
self.z.value
)
}
}
impl<D: ?Sized + Dimension, F: Frame> PartialEq for Qty3<D, F> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.x.value == other.x.value
&& self.y.value == other.y.value
&& self.z.value == other.z.value
}
}
impl<D: ?Sized + Dimension, F: Frame> Default for Qty3<D, F> {
#[inline]
fn default() -> Self {
Self::zero()
}
}