use std::ops::*;
use super::real::Real;
macro_rules! impl_vec {
($type: ident, $count: tt, $($field: tt),*) => {
#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Serialize, Deserialize)]
pub struct $type<R: Real = f32> {
$(pub $field: R),*
}
impl<R: Real> $type<R> {
pub fn new($($field: R),*) -> Self {
Self { $($field),* }
}
}
impl<R: Real> Add<Self> for $type<R> {
type Output = Self;
fn add(self, other: Self) -> Self::Output {
$type::new($(self.$field + other.$field),*)
}
}
impl<R: Real> AddAssign<Self> for $type<R> {
fn add_assign(&mut self, other: Self) {
$(self.$field += other.$field);*
}
}
impl<R: Real> Sub<Self> for $type<R> {
type Output = Self;
fn sub(self, other: Self) -> Self::Output {
$type::new($(self.$field - other.$field),*)
}
}
impl<R: Real> SubAssign<Self> for $type<R> {
fn sub_assign(&mut self, other: Self) {
$(self.$field -= other.$field);*
}
}
impl<R: Real> Mul<R> for $type<R> {
type Output = Self;
fn mul(self, other: R) -> Self::Output {
$type::new($(self.$field * other),*)
}
}
impl Mul<$type<f32>> for f32 {
type Output = $type<f32>;
fn mul(self, other: $type<f32>) -> Self::Output {
$type::new($(self * other.$field),*)
}
}
impl Mul<$type<f64>> for f64 {
type Output = $type<f64>;
fn mul(self, other: $type<f64>) -> Self::Output {
$type::new($(self * other.$field),*)
}
}
impl<R: Real> Into<[R; $count]> for $type<R> {
fn into(self) -> [R; $count] {
[$(self.$field),*]
}
}
}
}
impl_vec!(Vec2, 2, x, y);
impl_vec!(Vec3, 3, x, y, z);
impl_vec!(Vec4, 4, x, y, z, w);
impl<R: Real> Vec2<R> {
pub fn zero() -> Self {
Self::new(R::zero(), R::zero())
}
}
impl<R: Real> Vec3<R> {
pub fn zero() -> Self {
Self::new(R::zero(), R::zero(), R::zero())
}
}
impl<R: Real> From<Vec2<R>> for Vec3<R> {
fn from(vec2: Vec2<R>) -> Self {
Self::new(vec2.x, vec2.y, R::zero())
}
}