use std::ops::*;
use serde::{Serialize, Deserialize};
use crate::traits::*;
use crate::Vec3;
#[repr(C)]
#[derive(Copy, Clone, PartialEq, Debug, Default)]
#[derive(Serialize, Deserialize)]
pub struct Vec4<S> {
pub x: S,
pub y: S,
pub z: S,
pub w: S,
}
impl<S> Vec4<S> {
pub const fn new(x: S, y: S, z: S, w: S) -> Self {
Self { x, y, z, w }
}
}
impl<S: Scalar> Vec4<S> {
#[inline(always)]
pub fn of(v: S) -> Self {
Self { x: v, y: v, z: v, w: v }
}
#[inline(always)]
pub fn min(self, other: Self) -> Self {
Self {
x: if self.x < other.x { self.x } else { other.x },
y: if self.y < other.y { self.y } else { other.y },
z: if self.z < other.z { self.z } else { other.z },
w: if self.w < other.w { self.w } else { other.w },
}
}
#[inline(always)]
pub fn max(self, other: Self) -> Self {
Self {
x: if self.x > other.x { self.x } else { other.x },
y: if self.y > other.y { self.y } else { other.y },
z: if self.z > other.z { self.z } else { other.z },
w: if self.w > other.w { self.w } else { other.w },
}
}
#[inline(always)]
pub fn min_component(self) -> S {
if self.x < self.y {
Vec3::new(self.x, self.z, self.w).min_component()
} else {
Vec3::new(self.y, self.z, self.w).min_component()
}
}
#[inline(always)]
pub fn max_component(self) -> S {
if self.x > self.y {
Vec3::new(self.x, self.z, self.w).max_component()
} else {
Vec3::new(self.y, self.z, self.w).max_component()
}
}
}
impl<S: Number> Vec4<S> {
pub const ZERO: Self = Self::new(S::ZERO, S::ZERO, S::ZERO, S::ZERO);
pub const X: Self = Self::new(S::ONE, S::ZERO, S::ZERO, S::ZERO);
pub const Y: Self = Self::new(S::ZERO, S::ONE, S::ZERO, S::ZERO);
pub const Z: Self = Self::new(S::ZERO, S::ZERO, S::ONE, S::ZERO);
pub const W: Self = Self::new(S::ZERO, S::ZERO, S::ZERO, S::ONE);
#[inline(always)]
pub fn dot(self, other: Self) -> S {
self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
}
#[inline(always)]
pub fn len2(self) -> S {
self.dot(self)
}
#[inline(always)]
pub fn distance2(self, other: Self) -> S {
(self - other).len2()
}
#[inline(always)]
pub fn reflect(self, other: Self) -> Self {
self - other * S::TWO * self.dot(other)
}
}
impl<S: Signed> Vec4<S> {
#[inline(always)]
pub fn abs(self) -> Self {
Self {
x: self.x.abs(),
y: self.y.abs(),
z: self.z.abs(),
w: self.w.abs(),
}
}
}
impl<S: Float> Vec4<S> {
#[inline(always)]
pub fn len(self) -> S {
self.len2().sqrt()
}
#[inline(always)]
pub fn normalized(self) -> Self {
self * (S::ONE / self.len())
}
}
impl<S: Number> Add for Vec4<S> {
type Output = Self;
#[inline(always)]
fn add(self, other: Self) -> Self::Output {
Self {
x: self.x + other.x,
y: self.y + other.y,
z: self.z + other.z,
w: self.w + other.w,
}
}
}
impl<S: Number> AddAssign for Vec4<S> {
#[inline(always)]
fn add_assign(&mut self, other: Self) {
self.x += other.x;
self.y += other.y;
self.z += other.z;
self.w += other.w;
}
}
impl<S: Number> Sub for Vec4<S> {
type Output = Self;
#[inline(always)]
fn sub(self, other: Self) -> Self::Output {
Self {
x: self.x - other.x,
y: self.y - other.y,
z: self.z - other.z,
w: self.w - other.w,
}
}
}
impl<S: Number> SubAssign for Vec4<S> {
#[inline(always)]
fn sub_assign(&mut self, other: Self) {
self.x -= other.x;
self.y -= other.y;
self.z -= other.z;
self.w -= other.w;
}
}
impl<S: Number> Mul for Vec4<S> {
type Output = Self;
#[inline(always)]
fn mul(self, other: Self) -> Self::Output {
Self {
x: self.x * other.x,
y: self.y * other.y,
z: self.z * other.z,
w: self.w * other.w,
}
}
}
impl<S: Number> MulAssign for Vec4<S> {
fn mul_assign(&mut self, other: Self) {
self.x *= other.x;
self.y *= other.y;
self.z *= other.z;
self.w *= other.w;
}
}
impl<S: Number> Mul<S> for Vec4<S> {
type Output = Self;
#[inline(always)]
fn mul(self, other: S) -> Self::Output {
Self {
x: self.x * other,
y: self.y * other,
z: self.z * other,
w: self.w * other,
}
}
}
impl<S: Number> MulAssign<S> for Vec4<S> {
#[inline(always)]
fn mul_assign(&mut self, other: S) {
self.x *= other;
self.y *= other;
self.z *= other;
self.w *= other;
}
}
impl<S: Number> Div for Vec4<S> {
type Output = Self;
#[inline(always)]
fn div(self, other: Self) -> Self {
Self {
x: self.x / other.x,
y: self.y / other.y,
z: self.z / other.z,
w: self.w / other.w,
}
}
}
impl<S: Number> DivAssign for Vec4<S> {
#[inline(always)]
fn div_assign(&mut self, other: Self) {
self.x /= other.x;
self.y /= other.y;
self.z /= other.z;
self.w /= other.w;
}
}
impl<S: Number> Div<S> for Vec4<S> {
type Output = Self;
#[inline(always)]
fn div(self, other: S) -> Self {
Self {
x: self.x / other,
y: self.y / other,
z: self.z / other,
w: self.w / other,
}
}
}
impl<S: Number> DivAssign<S> for Vec4<S> {
#[inline(always)]
fn div_assign(&mut self, other: S) {
self.x /= other;
self.y /= other;
self.z /= other;
self.w /= other;
}
}
impl<S: Signed> Neg for Vec4<S> {
type Output = Self;
#[inline(always)]
fn neg(self) -> Self::Output {
Self {
x: -self.x,
y: -self.y,
z: -self.z,
w: -self.w,
}
}
}
pub type Vec4B = Vec4<bool>;
pub type Vec4I = Vec4<i32>;
pub type Vec4U = Vec4<u32>;
pub type Vec4F = Vec4<f32>;
pub type Vec4D = Vec4<f64>;