#![allow(dead_code)] use std::convert::{AsMut, AsRef}; use std::fmt::{Debug, Formatter, Result as FmtResult}; use std::ops::{Add, Deref, DerefMut, Mul, Sub}; #[cfg(feature = "serde")] use serde::{ de::{Deserialize, Deserializer, Error}, ser::{Serialize, Serializer}, }; pub use super::{ angle::Angle, numeric::{Float, Numeric}, }; macro_rules! first_ptr { ($this:ident, $first:ident $(, $other:ident)*) => { unsafe { &$this.$first } }; } macro_rules! define_vec { ($Name:ident, $size:tt, $($T:ident => $i:tt => $f:ident),*) => { #[repr(C, packed)] pub struct $Name { $(pub $f: T,)+ } impl $Name { #[inline] pub const fn new($($f: T,)+) -> Self { Self { $($f,)+ } } #[inline] pub fn as_ptr(&self) -> * const T { first_ptr!(self $(, $f)+) } } impl Default for $Name where T: Default { #[inline] fn default() -> Self { Self { $($f: T::default(),)+ } } } impl Debug for $Name where T: Debug { fn fmt(&self, fmt: &mut Formatter<'_>) -> FmtResult { fmt.debug_list().entries(self.as_ref().iter()).finish() } } impl PartialEq<$Name> for $Name where S: PartialEq, { fn eq(&self, other: &$Name) -> bool { unsafe { true $(&& other.$f.eq(&self.$f))+ } } } impl Eq for $Name where T: Eq { } impl Deref for $Name { type Target = [T; $size]; #[inline] fn deref(&self) -> &Self::Target { self.as_ref() } } impl DerefMut for $Name { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut() } } impl AsRef<[T; $size]> for $Name { #[inline] fn as_ref(&self) -> &[T; $size] { unsafe { let raw: * const _ = self; let raw = raw as * const [T; $size]; &*raw } } } impl AsMut<[T; $size]> for $Name { #[inline] fn as_mut(&mut self) -> &mut [T; $size] { unsafe { let raw: * mut _ = self; let raw = raw as * mut [T; $size]; &mut *raw } } } impl Clone for $Name where T: Clone { #[inline] fn clone(&self) -> Self { unsafe { Self { $($f: self.$f.clone(),)+ } } } } impl Copy for $Name where T: Copy { } impl From<[T; $size]> for $Name where T: Copy, { #[inline] fn from(arr: [T; $size]) -> Self { Self { $($f: arr[$i],)+ } } } impl From for $Name where T: Copy, { #[inline] fn from(value: T) -> Self { Self { $($f: value,)+ } } } impl From<($($T,)+)> for $Name { #[inline] fn from(($($f,)+): ($($T,)+)) -> Self { Self { $($f,)+ } } } #[cfg(feature = "serde")] impl Serialize for $Name where T: Serialize, { fn serialize(&self, serializer: S) -> Result where S: Serializer { unsafe { vec![$(&self.$f,)+].serialize(serializer) } } } #[cfg(feature = "serde")] impl<'de, T> Deserialize<'de> for $Name where T: Deserialize<'de>, { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { let mut data = Vec::::deserialize(deserializer)?.into_iter(); Ok(Self { $($f: data.next().ok_or_else(|| D::Error::custom("Vector is missing some elements!"))?,)+ }) } } }; } define_vec!(Vector2, 2, T => 0 => x, T => 1 => y); define_vec!(Vector3, 3, T => 0 => x, T => 1 => y, T => 2 => z); define_vec!(Vector4, 4, T => 0 => x, T => 1 => y, T => 2 => z, T => 3 => w); pub type Vector2f = Vector2; pub type Vector3f = Vector3; pub type Vector4f = Vector4; pub type Vector2d = Vector2; pub type Vector3d = Vector3; pub type Vector4d = Vector4; pub type Vector2i = Vector2; pub type Vector3i = Vector3; pub type Vector4i = Vector4; /* Vector2 */ impl Vector2 where T: Numeric, { #[inline] pub fn multiply(mut self, v: T) -> Self { self.x = self.x * v; self.y = self.y * v; self } #[inline] pub fn length_sqr(&self) -> T { self.x * self.x + self.y * self.y } #[inline] pub fn length(&self) -> T { Numeric::sqrt(self.length_sqr()) } #[inline] pub fn normalize(mut self) -> Self { let len = self.length(); self.x = self.x / len; self.y = self.y / len; self } #[inline] pub fn scalar(&self, other: &Self) -> T { self.x * other.x + self.y * other.y } } impl Vector2 where T: Float, { #[inline] pub fn angle(&self, other: &Self) -> Angle { let s = self.scalar(other); let l1 = self.length(); let l2 = self.length(); Angle::Rad(T::acos(s / (l1 + l2))) } #[inline] pub fn angle2(&self, other: &Self) -> Angle { Angle::Rad(T::atan2( other.x * self.y - other.y * self.x, other.x * self.x + other.y * self.y, )) } } impl Add for Vector2 where T: Numeric, { type Output = Self; #[inline] fn add(mut self, other: Self) -> Self::Output { self.x = self.x + other.x; self.y = self.y + other.y; self } } impl Sub for Vector2 where T: Numeric, { type Output = Self; #[inline] fn sub(mut self, other: Self) -> Self::Output { self.x = self.x - other.x; self.y = self.y - other.y; self } } impl Mul for Vector2 where T: Numeric, { type Output = T; #[inline] fn mul(self, rhs: Self) -> Self::Output { self.scalar(&rhs) } } impl Mul for Vector2 where T: Numeric, { type Output = Self; #[inline] fn mul(self, rhs: T) -> Self::Output { self.multiply(rhs) } } /* Vector3 */ impl Vector3 where T: Numeric, { #[inline] pub fn multiply(mut self, v: T) -> Self { self.x = self.x * v; self.y = self.y * v; self.z = self.z * v; self } #[inline] pub fn length_sqr(&self) -> T { self.x * self.x + self.y * self.y + self.z * self.z } #[inline] pub fn length(&self) -> T { Numeric::sqrt(self.length_sqr()) } #[inline] pub fn normalize(mut self) -> Self { let len = self.length(); self.x = self.x / len; self.y = self.y / len; self.z = self.z / len; self } #[inline] pub fn scalar(&self, other: &Self) -> T { self.x * other.x + self.y * other.y + self.z * other.z } #[inline] pub fn cross(&self, other: &Self) -> Self { Self { x: self.y * other.z - self.z * other.y, y: self.z * other.x - self.x * other.z, z: self.x * other.y - self.y * other.x, } } } impl Vector3 where T: Float, { #[inline] pub fn angle(&self, other: &Self) -> Angle { let s = self.scalar(other); let l1 = self.length(); let l2 = self.length(); Angle::Rad(T::acos(s / (l1 + l2))) } } impl Add for Vector3 where T: Numeric, { type Output = Self; #[inline] fn add(mut self, other: Self) -> Self::Output { self.x = self.x + other.x; self.y = self.y + other.y; self.z = self.z + other.z; self } } impl Sub for Vector3 where T: Numeric, { type Output = Self; #[inline] fn sub(mut self, other: Self) -> Self::Output { self.x = self.x - other.x; self.y = self.y - other.y; self.z = self.z - other.z; self } } impl Mul for Vector3 where T: Numeric, { type Output = T; #[inline] fn mul(self, rhs: Self) -> Self::Output { self.scalar(&rhs) } } impl Mul for Vector3 where T: Numeric, { type Output = Self; #[inline] fn mul(self, rhs: T) -> Self::Output { self.multiply(rhs) } } /* Vector4 */ impl Vector4 where T: Numeric, { #[inline] pub fn multiply(mut self, v: T) -> Self { self.x = self.x * v; self.y = self.y * v; self.z = self.z * v; self } #[inline] pub fn length_sqr(self) -> T { self.xyz().length_sqr() } #[inline] pub fn length(self) -> T { self.xyz().length() } #[inline] pub fn normalize(mut self) -> Self { let len = self.length(); if unsafe { !Numeric::is_zero(&self.w) } { self.x = self.x / self.w; self.y = self.y / self.w; self.z = self.z / self.w; } else { self.x = Numeric::zero(); self.y = Numeric::zero(); self.z = Numeric::zero(); } self.x = self.x / len; self.y = self.y / len; self.z = self.z / len; self.w = Numeric::one(); self } #[inline] pub fn scalar(&self, other: &Self) -> T { self.xyz().scalar(&other.xyz()) } #[inline] pub fn cross(&self, other: &Self) -> Self { (self.xyz().cross(&other.xyz()), Numeric::one()).into() } #[inline] pub fn xyz(self) -> Vector3 { if unsafe { Numeric::is_zero(&self.w) } { Vector3 { x: Numeric::zero(), y: Numeric::zero(), z: Numeric::zero(), } } else { Vector3 { x: self.x / self.w, y: self.y / self.w, z: self.z / self.w, } } } } impl Vector4 where T: Float, { #[inline] pub fn angle(&self, other: &Self) -> Angle { self.xyz().angle(&other.xyz()) } } impl Add for Vector4 where T: Numeric, { type Output = Self; #[inline] fn add(self, other: Self) -> Self::Output { (self.xyz() + other.xyz(), T::one()).into() } } impl Sub for Vector4 where T: Numeric, { type Output = Self; #[inline] fn sub(self, other: Self) -> Self::Output { (self.xyz() - other.xyz(), T::one()).into() } } impl Mul for Vector4 where T: Numeric, { type Output = T; fn mul(self, rhs: Self) -> Self::Output { self.scalar(&rhs) } } impl Mul for Vector4 where T: Numeric, { type Output = Self; #[inline] fn mul(self, rhs: T) -> Self::Output { self.multiply(rhs) } } impl From<(Vector3, T)> for Vector4 { fn from((vec3, w): (Vector3, T)) -> Self { Self { x: vec3.x, y: vec3.y, z: vec3.z, w, } } } #[cfg(test)] mod tests { use super::*; #[test] fn add() { let v1 = Vector2f::from((1.0, 0.0)); let v2 = Vector2f::from((0.0, 1.0)); let ex = Vector2f::from((1.0, 1.0)); assert_eq!(ex, v1 + v2); let v1 = Vector3f::from((1.0, 0.0, 1.8)); let v2 = Vector3f::from((0.0, 2.0, 1.2)); let ex = Vector3f::from((1.0, 2.0, 3.0)); assert_eq!(ex, v1 + v2); let v1 = Vector4f::from((1.0, 0.0, 1.8, 0.5)); let v2 = Vector4f::from((0.0, 2.0, 1.2, 1.0)); let ex = Vector4f::from((2.0, 2.0, 4.8, 1.0)); assert_eq!(ex, v1 + v2); } #[test] fn sub() { let v1 = Vector2f::from((1.0, 0.0)); let v2 = Vector2f::from((0.0, 1.0)); let ex = Vector2f::from((1.0, -1.0)); assert_eq!(ex, v1 - v2); let v1 = Vector3d::from((1.0, 0.0, 1.75)); let v2 = Vector3d::from((0.0, 2.0, 1.0)); let ex = Vector3d::from((1.0, -2.0, 0.75)); assert_eq!(ex, v1 - v2); let v1 = Vector4d::from((1.0, 0.0, 1.0, 0.5)); let v2 = Vector4d::from((0.0, 2.0, -2.0, 1.0)); let ex = Vector4d::from((2.0, -2.0, 4.0, 1.0)); assert_eq!(ex, v1 - v2); } #[test] fn multiply() { let v1 = Vector2f::from((1.0, 0.0)).multiply(2.0); let ex = Vector2f::from((2.0, 0.0)); assert_eq!(ex, v1); let v1 = Vector3d::from((1.0, 0.0, 1.75)).multiply(2.0); let ex = Vector3d::from((2.0, 0.0, 3.5)); assert_eq!(ex, v1); let v1 = Vector4d::from((1.0, 0.0, 0.5, 0.5)).multiply(3.0); let ex = Vector4d::from((3.0, 0.0, 1.5, 0.5)); assert_eq!(ex, v1); } #[test] fn scalar() { let v1 = Vector2f::from((1.0, 0.0)); let v2 = Vector2f::from((0.0, 1.0)); assert_eq!(0.0, v1.scalar(&v2)); let v1 = Vector3f::from((1.0, 0.0, 0.0)); let v2 = Vector3f::from((0.0, 1.0, 0.0)); assert_eq!(0.0, v1.scalar(&v2)); let v1 = Vector4f::from((3.0, 0.0, 0.0, 1.0)); let v2 = Vector4f::from((0.0, 2.0, 0.0, 0.8)); assert_eq!(0.0, v1.scalar(&v2)); } #[test] fn normalize() { let v1 = Vector2f::from((1.0, 0.0)).normalize(); let ex = Vector2f::from((1.0, 0.0)); assert_eq!(ex, v1); let v1 = Vector3d::from((1.0, 0.0, 1.75)).normalize(); let ex = Vector3d::from((0.49613893835683387, 0.0, 0.8682431421244593)); assert_eq!(ex, v1); let v1 = Vector4d::from((1.0, 0.0, 0.5, 0.5)).normalize(); let ex = Vector4d::from((0.8944271909999159, 0.0, 0.4472135954999579, 1.0)); assert_eq!(ex, v1); } #[test] fn cross() { let v1 = Vector3d::from((1.0, 0.0, 0.0)); let v2 = Vector3d::from((0.0, 1.0, 0.0)); let ex = Vector3d::from((0.0, 0.0, 1.0)); assert_eq!(ex, v1.cross(&v2)); let v1 = Vector4d::from((1.0, 0.0, 0.0, 0.5)); let v2 = Vector4d::from((0.0, 3.0, 0.0, 1.0)); let ex = Vector4d::from((0.0, 0.0, 6.0, 1.0)); assert_eq!(ex, v1.cross(&v2)); } }