use std::convert::{TryFrom, TryInto};
use std::ops::*;
pub trait MulAdd<A = Self, B = Self> {
type Output;
fn mul_add(self, a: A, b: B) -> Self::Output;
}
impl MulAdd<u32, u32> for u32 {
type Output = u32;
fn mul_add(self, a: u32, b: u32) -> Self::Output {
(self * a) + b
}
}
impl MulAdd<i32, i32> for i32 {
type Output = i32;
fn mul_add(self, a: i32, b: i32) -> Self::Output {
(self * a) + b
}
}
macro_rules! vec2i {
($(($n:ident, $v3t:ident, $v4t:ident) => $t:ident),+) => {
$(
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct $n {
pub x: $t,
pub y: $t,
}
impl $n {
#[inline]
pub fn new(x: $t, y: $t) -> Self {
$n { x, y }
}
#[inline]
pub fn broadcast(val: $t) -> Self {
Self::new(val, val)
}
#[inline]
pub fn unit_x() -> Self {
$n{ x: 1, y: 0 }
}
#[inline]
pub fn unit_y() -> Self {
$n{ x: 0, y: 1 }
}
#[inline]
pub fn into_homogeneous_point(self) -> $v3t {
$v3t { x: self.x, y: self.y, z: 1 }
}
#[inline]
pub fn into_homogeneous_vector(self) -> $v3t {
$v3t { x: self.x, y: self.y, z: 0 }
}
#[inline]
pub fn from_homogeneous_point(v: $v3t) -> Self {
Self { x: v.x / v.z, y: v.y / v.z }
}
#[inline]
pub fn from_homogeneous_vector(v: $v3t) -> Self {
v.into()
}
#[inline]
pub fn dot(&self, other: $n) -> $t {
self.x.mul_add(other.x, self.y * other.y)
}
#[inline]
pub fn reflected(&self, normal: $n) -> Self {
*self - (2 * self.dot(normal) * normal)
}
#[inline]
pub fn mag(&self) -> $t {
(self.mag_sq() as f64).sqrt() as $t
}
#[inline]
pub fn mag_sq(&self) -> $t {
self.x.mul_add(self.x, self.y * self.y)
}
#[inline]
pub fn mul_add(&self, mul: $n, add: $n) -> Self {
$n::new(
self.x.mul_add(mul.x, add.x),
self.y.mul_add(mul.y, add.y),
)
}
#[inline]
pub fn abs(&self) -> Self {
Self::new(self.x, self.y)
}
#[inline]
pub fn clamp(&mut self, min: Self, max: Self) {
self.x = self.x.max(min.x).min(max.x);
self.y = self.y.max(min.y).min(max.y);
}
#[inline]
pub fn clamped(mut self, min: Self, max: Self) -> Self {
self.clamp(min, max);
self
}
#[inline]
pub fn map<F>(&self, f: F) -> Self
where F: Fn($t) -> $t
{
$n::new(
f(self.x),
f(self.y),
)
}
#[inline]
pub fn apply<F>(&mut self, f: F)
where F: Fn($t) -> $t
{
self.x = f(self.x);
self.y = f(self.y);
}
#[inline]
pub fn max_by_component(mut self, other: Self) -> Self {
self.x = self.x.max(other.x);
self.y = self.y.max(other.y);
self
}
#[inline]
pub fn min_by_component(mut self, other: Self) -> Self {
self.x = self.x.min(other.x);
self.y = self.y.min(other.y);
self
}
#[inline]
pub fn component_max(&self) -> $t {
self.x.max(self.y)
}
#[inline]
pub fn component_min(&self) -> $t {
self.x.min(self.y)
}
#[inline]
pub fn zero() -> Self {
Self::broadcast(0)
}
#[inline]
pub fn one() -> Self {
Self::broadcast(1)
}
#[inline]
pub fn xyz(&self) -> $v3t {
$v3t::new(self.x, self.y, 0)
}
#[inline]
pub fn xyzw(&self) -> $v4t {
$v4t::new(self.x, self.y, 0, 0)
}
#[inline]
pub fn layout() -> alloc::alloc::Layout {
alloc::alloc::Layout::from_size_align(std::mem::size_of::<Self>(), std::mem::align_of::<$t>()).unwrap()
}
#[inline]
pub fn as_slice(&self) -> &[$t] {
unsafe {
std::slice::from_raw_parts(self as *const $n as *const $t, 2)
}
}
#[inline]
pub fn as_array(&self) -> [$t; 2] {
use std::convert::TryInto;
self.as_slice().try_into().unwrap()
}
#[inline]
pub fn as_byte_slice(&self) -> &[u8] {
unsafe {
std::slice::from_raw_parts(self as *const $n as *const u8, 2 * std::mem::size_of::<$t>())
}
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [$t] {
unsafe {
std::slice::from_raw_parts_mut(self as *mut $n as *mut $t, 2)
}
}
#[inline]
pub fn as_mut_byte_slice(&mut self) -> &mut [u8] {
unsafe {
std::slice::from_raw_parts_mut(self as *mut $n as *mut u8, 2 * std::mem::size_of::<$t>())
}
}
#[inline]
pub fn as_ptr(&self) -> *const $t {
self as *const $n as *const $t
}
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut $t {
self as *mut $n as *mut $t
}
}
impl From<[$t; 2]> for $n {
#[inline]
fn from(comps: [$t; 2]) -> Self {
Self::new(comps[0], comps[1])
}
}
impl Into<[$t; 2]> for $n {
#[inline]
fn into(self) -> [$t; 2] {
[self.x, self.y]
}
}
impl From<&[$t; 2]> for $n {
#[inline]
fn from(comps: &[$t; 2]) -> Self {
Self::from(*comps)
}
}
impl From<&mut [$t; 2]> for $n {
#[inline]
fn from(comps: &mut [$t; 2]) -> Self {
Self::from(*comps)
}
}
impl From<($t, $t)> for $n {
#[inline]
fn from(comps: ($t, $t)) -> Self {
Self::new(comps.0, comps.1)
}
}
impl From<&($t, $t)> for $n {
#[inline]
fn from(comps: &($t, $t)) -> Self {
Self::from(*comps)
}
}
impl From<$n> for ($t, $t) {
#[inline]
fn from(v: $n) -> Self {
(v.x, v.y)
}
}
impl Add for $n {
type Output = Self;
#[inline]
fn add(self, rhs: $n) -> Self {
$n::new(self.x + rhs.x, self.y + rhs.y)
}
}
impl AddAssign for $n {
#[inline]
fn add_assign(&mut self, rhs: $n) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl Sub for $n {
type Output = Self;
#[inline]
fn sub(self, rhs: $n) -> Self {
$n::new(self.x - rhs.x, self.y - rhs.y)
}
}
impl SubAssign for $n {
#[inline]
fn sub_assign(&mut self, rhs: $n) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}
impl Mul for $n {
type Output = Self;
#[inline]
fn mul(self, rhs: $n) -> Self {
$n::new(self.x * rhs.x, self.y * rhs.y)
}
}
impl Mul<$n> for $t {
type Output = $n;
#[inline]
fn mul(self, rhs: $n) -> $n {
$n::new(self * rhs.x, self * rhs.y)
}
}
impl Mul<$t> for $n {
type Output = $n;
#[inline]
fn mul(self, rhs: $t) -> $n {
$n::new(self.x * rhs, self.y * rhs)
}
}
impl MulAssign for $n {
#[inline]
fn mul_assign(&mut self, rhs: $n) {
self.x *= rhs.x;
self.y *= rhs.y;
}
}
impl MulAssign<$t> for $n {
#[inline]
fn mul_assign(&mut self, rhs: $t) {
self.x *= rhs;
self.y *= rhs;
}
}
impl Div for $n {
type Output = Self;
#[inline]
fn div(self, rhs: $n) -> Self {
$n::new(self.x / rhs.x, self.y / rhs.y)
}
}
impl Div<$t> for $n {
type Output = $n;
#[inline]
fn div(self, rhs: $t) -> $n {
$n::new(self.x / rhs, self.y / rhs)
}
}
impl DivAssign for $n {
#[inline]
fn div_assign(&mut self, rhs: $n) {
self.x /= rhs.x;
self.y /= rhs.y;
}
}
impl DivAssign<$t> for $n {
#[inline]
fn div_assign(&mut self, rhs: $t) {
self.x /= rhs;
self.y /= rhs;
}
}
impl Index<usize> for $n {
type Output = $t;
fn index(&self, index: usize) -> &Self::Output {
match index {
0 => &self.x,
1 => &self.y,
_ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
}
}
}
impl IndexMut<usize> for $n {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
match index {
0 => &mut self.x,
1 => &mut self.y,
_ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
}
}
}
)+
};
}
vec2i!((Vec2u, Vec3u, Vec4u) => u32);
vec2i!((Vec2i, Vec3i, Vec4i) => i32);
macro_rules! vec3i {
($(($v2t:ident, $n:ident, $v4t:ident) => $t:ident),+) => {
$(#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct $n {
pub x: $t,
pub y: $t,
pub z: $t,
}
impl $n {
#[inline]
pub fn new(x: $t, y: $t, z: $t) -> Self {
$n { x, y, z }
}
#[inline]
pub fn broadcast(val: $t) -> Self {
Self::new(val, val, val)
}
#[inline]
pub fn unit_x() -> Self {
$n{ x: 1, y: 0, z: 0 }
}
#[inline]
pub fn unit_y() -> Self {
$n{ x: 0, y: 1, z: 0 }
}
#[inline]
pub fn unit_z() -> Self {
$n{ x: 0, y: 0, z: 1 }
}
#[inline]
pub fn cross(&self, other: $n) -> Self {
$n::new(
self.y.mul_add(other.z, -(self.z as i32) as $t * other.y),
self.z.mul_add(other.x, -(self.x as i32) as $t * other.z),
self.x.mul_add(other.y, -(self.y as i32) as $t * other.x),
)
}
#[inline]
pub fn into_homogeneous_point(self) -> $v4t {
$v4t { x: self.x, y: self.y, z: self.z, w: 1 }
}
#[inline]
pub fn into_homogeneous_vector(self) -> $v4t {
$v4t { x: self.x, y: self.y, z: self.z, w: 0 }
}
#[inline]
pub fn from_homogeneous_point(v: $v4t) -> Self {
Self { x: v.x / v.w, y: v.y / v.w, z: v.z / v.w }
}
#[inline]
pub fn from_homogeneous_vector(v: $v4t) -> Self {
v.into()
}
#[inline]
pub fn dot(&self, other: $n) -> $t {
self.x.mul_add(other.x, self.y.mul_add(other.y, self.z * other.z))
}
#[inline]
pub fn reflect(&mut self, normal: $n) {
*self -= 2 * self.dot(normal) * normal;
}
#[inline]
pub fn reflected(&self, normal: $n) -> Self {
let mut a = *self;
a.reflect(normal);
a
}
#[inline]
pub fn mag(&self) -> $t {
(self.mag_sq() as f64).sqrt() as $t
}
#[inline]
pub fn mag_sq(&self) -> $t {
self.x.mul_add(self.x, self.y.mul_add(self.y, self.z * self.z))
}
#[inline]
pub fn mul_add(&self, mul: $n, add: $n) -> Self {
$n::new(
self.x.mul_add(mul.x, add.x),
self.y.mul_add(mul.y, add.y),
self.z.mul_add(mul.z, add.z),
)
}
#[inline]
pub fn abs(&self) -> Self {
Self::new(self.x, self.y, self.z)
}
#[inline]
pub fn clamp(&mut self, min: Self, max: Self) {
self.x = self.x.max(min.x).min(max.x);
self.y = self.y.max(min.y).min(max.y);
self.z = self.z.max(min.z).min(max.z);
}
#[inline]
pub fn clamped(mut self, min: Self, max: Self) -> Self {
self.clamp(min, max);
self
}
#[inline]
pub fn map<F>(&self, f: F) -> Self
where F: Fn($t) -> $t
{
$n::new(
f(self.x),
f(self.y),
f(self.z)
)
}
#[inline]
pub fn apply<F>(&mut self, f: F)
where F: Fn($t) -> $t
{
self.x = f(self.x);
self.y = f(self.y);
self.z = f(self.z);
}
#[inline]
pub fn max_by_component(mut self, other: Self) -> Self {
self.x = self.x.max(other.x);
self.y = self.y.max(other.y);
self.z = self.z.max(other.z);
self
}
#[inline]
pub fn min_by_component(mut self, other: Self) -> Self {
self.x = self.x.min(other.x);
self.y = self.y.min(other.y);
self.z = self.z.min(other.z);
self
}
#[inline]
pub fn component_max(&self) -> $t {
self.x.max(self.y).max(self.z)
}
#[inline]
pub fn component_min(&self) -> $t {
self.x.min(self.y).min(self.z)
}
#[inline]
pub fn zero() -> Self {
Self::broadcast(0)
}
#[inline]
pub fn one() -> Self {
Self::broadcast(1)
}
#[inline]
pub fn xy(&self) -> $v2t {
$v2t::new(self.x, self.y)
}
#[inline]
pub fn xyzw(&self) -> $v4t {
$v4t::new(self.x, self.y, self.z, 0)
}
#[inline]
pub fn layout() -> alloc::alloc::Layout {
alloc::alloc::Layout::from_size_align(std::mem::size_of::<Self>(), std::mem::align_of::<$t>()).unwrap()
}
#[inline]
pub fn as_slice(&self) -> &[$t] {
unsafe {
std::slice::from_raw_parts(self as *const $n as *const $t, 3)
}
}
#[inline]
pub fn as_array(&self) -> [$t; 3] {
use std::convert::TryInto;
self.as_slice().try_into().unwrap()
}
#[inline]
pub fn as_byte_slice(&self) -> &[u8] {
unsafe {
std::slice::from_raw_parts(self as *const $n as *const u8, 3 * std::mem::size_of::<$t>())
}
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [$t] {
unsafe {
std::slice::from_raw_parts_mut(self as *mut $n as *mut $t, 3)
}
}
#[inline]
pub fn as_mut_byte_slice(&mut self) -> &mut [u8] {
unsafe {
std::slice::from_raw_parts_mut(self as *mut $n as *mut u8, 3 * std::mem::size_of::<$t>())
}
}
#[inline]
pub fn as_ptr(&self) -> *const $t {
self as *const $n as *const $t
}
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut $t {
self as *mut $n as *mut $t
}
}
impl From<[$t; 3]> for $n {
#[inline]
fn from(comps: [$t; 3]) -> Self {
Self::new(comps[0], comps[1], comps[2])
}
}
impl Into<[$t; 3]> for $n {
#[inline]
fn into(self) -> [$t; 3] {
[self.x, self.y, self.z]
}
}
impl From<&[$t; 3]> for $n {
#[inline]
fn from(comps: &[$t; 3]) -> Self {
Self::from(*comps)
}
}
impl From<&mut [$t; 3]> for $n {
#[inline]
fn from(comps: &mut [$t; 3]) -> Self {
Self::from(*comps)
}
}
impl From<($t, $t, $t)> for $n {
#[inline]
fn from(comps: ($t, $t, $t)) -> Self {
Self::new(comps.0, comps.1, comps.2)
}
}
impl From<&($t, $t, $t)> for $n {
#[inline]
fn from(comps: &($t, $t, $t)) -> Self {
Self::from(*comps)
}
}
impl From<$n> for ($t, $t, $t) {
#[inline]
fn from(v: $n) -> Self {
(v.x, v.y, v.z)
}
}
impl Add for $n {
type Output = Self;
#[inline]
fn add(self, rhs: $n) -> Self {
$n::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
}
}
impl AddAssign for $n {
#[inline]
fn add_assign(&mut self, rhs: $n) {
self.x += rhs.x;
self.y += rhs.y;
self.z += rhs.z;
}
}
impl Sub for $n {
type Output = Self;
#[inline]
fn sub(self, rhs: $n) -> Self {
$n::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
}
}
impl SubAssign for $n {
#[inline]
fn sub_assign(&mut self, rhs: $n) {
self.x -= rhs.x;
self.y -= rhs.y;
self.z -= rhs.z;
}
}
impl Mul for $n {
type Output = Self;
#[inline]
fn mul(self, rhs: $n) -> Self {
$n::new(self.x * rhs.x, self.y * rhs.y, self.z * rhs.z)
}
}
impl Mul<$n> for $t {
type Output = $n;
#[inline]
fn mul(self, rhs: $n) -> $n {
$n::new(self * rhs.x, self * rhs.y, self * rhs.z)
}
}
impl Mul<$t> for $n {
type Output = $n;
#[inline]
fn mul(self, rhs: $t) -> $n {
$n::new(self.x * rhs, self.y * rhs, self.z * rhs)
}
}
impl MulAssign for $n {
#[inline]
fn mul_assign(&mut self, rhs: $n) {
self.x *= rhs.x;
self.y *= rhs.y;
self.z *= rhs.z;
}
}
impl MulAssign<$t> for $n {
#[inline]
fn mul_assign(&mut self, rhs: $t) {
self.x *= rhs;
self.y *= rhs;
self.z *= rhs;
}
}
impl Div for $n {
type Output = Self;
#[inline]
fn div(self, rhs: $n) -> Self {
$n::new(self.x / rhs.x, self.y / rhs.y, self.z / rhs.z)
}
}
impl Div<$t> for $n {
type Output = $n;
#[inline]
fn div(self, rhs: $t) -> $n {
$n::new(self.x / rhs, self.y / rhs, self.z / rhs)
}
}
impl DivAssign for $n {
#[inline]
fn div_assign(&mut self, rhs: $n) {
self.x /= rhs.x;
self.y /= rhs.y;
self.z /= rhs.z;
}
}
impl DivAssign<$t> for $n {
#[inline]
fn div_assign(&mut self, rhs: $t) {
self.x /= rhs;
self.y /= rhs;
self.z /= rhs;
}
}
impl Index<usize> for $n {
type Output = $t;
fn index(&self, index: usize) -> &Self::Output {
match index {
0 => &self.x,
1 => &self.y,
2 => &self.z,
_ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
}
}
}
impl IndexMut<usize> for $n {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
match index {
0 => &mut self.x,
1 => &mut self.y,
2 => &mut self.z,
_ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
}
}
}
)+
}
}
vec3i!((Vec2u, Vec3u, Vec4u) => u32);
vec3i!((Vec2i, Vec3i, Vec4i) => i32);
macro_rules! vec4i {
($($n:ident, $v2t:ident, $v3t:ident => $t:ident),+) => {
$(#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct $n {
pub x: $t,
pub y: $t,
pub z: $t,
pub w: $t,
}
impl $n {
#[inline]
pub fn new<T: Into<$t>>(x: T, y: T, z: T, w: T) -> Self {
$n { x: x.into(), y: y.into(), z: z.into(), w: w.into() }
}
#[inline]
pub fn broadcast<T: Into<$t> + Copy>(val: T) -> Self {
Self::new(val, val, val, val)
}
#[inline]
pub fn unit_x() -> Self {
$n{ x: 1, y: 0, z: 0, w: 0 }
}
#[inline]
pub fn unit_y() -> Self {
$n{ x: 0, y: 1, z: 0, w: 0 }
}
#[inline]
pub fn unit_z() -> Self {
$n{ x: 0, y: 0, z: 1, w: 0 }
}
#[inline]
pub fn unit_w() -> Self {
$n{ x: 0, y: 0, z: 0, w: 1 }
}
#[inline]
pub fn dot(&self, other: $n) -> $t {
self.x.mul_add(other.x, self.y.mul_add(other.y, self.z.mul_add(other.z, self.w * other.w)))
}
#[inline]
pub fn reflect(&mut self, normal: $n) {
*self -= 2 * self.dot(normal) * normal;
}
#[inline]
pub fn reflected(&self, normal: $n) -> Self {
let mut a = *self;
a.reflect(normal);
a
}
#[inline]
pub fn mag(&self) -> $t {
(self.mag_sq() as f64).sqrt() as $t
}
#[inline]
pub fn mag_sq(&self) -> $t {
self.x.mul_add(self.x, self.y.mul_add(self.y, self.z.mul_add(self.z, self.w * self.w)))
}
#[inline]
pub fn mul_add(&self, mul: $n, add: $n) -> Self {
$n::new(
self.x.mul_add(mul.x, add.x),
self.y.mul_add(mul.y, add.y),
self.z.mul_add(mul.z, add.z),
self.w.mul_add(mul.w, add.w),
)
}
#[inline]
pub fn clamp(&mut self, min: Self, max: Self) {
self.x = self.x.max(min.x).min(max.x);
self.y = self.y.max(min.y).min(max.y);
self.z = self.z.max(min.z).min(max.z);
self.w = self.w.max(min.w).min(max.w);
}
#[inline]
pub fn clamped(mut self, min: Self, max: Self) -> Self {
self.clamp(min, max);
self
}
#[inline]
pub fn map<F>(&self, f: F) -> Self
where F: Fn($t) -> $t
{
$n::new(
f(self.x),
f(self.y),
f(self.z),
f(self.w),
)
}
#[inline]
pub fn apply<F>(&mut self, f: F)
where F: Fn($t) -> $t
{
self.x = f(self.x);
self.y = f(self.y);
self.z = f(self.z);
self.w = f(self.w);
}
#[inline]
pub fn max_by_component(mut self, other: Self) -> Self {
self.x = self.x.max(other.x);
self.y = self.y.max(other.y);
self.z = self.z.max(other.z);
self.w = self.w.max(other.w);
self
}
#[inline]
pub fn min_by_component(mut self, other: Self) -> Self {
self.x = self.x.min(other.x);
self.y = self.y.min(other.y);
self.z = self.z.min(other.z);
self.w = self.w.min(other.w);
self
}
#[inline]
pub fn component_max(&self) -> $t {
self.x.max(self.y).max(self.z).max(self.w)
}
#[inline]
pub fn component_min(&self) -> $t {
self.x.min(self.y).min(self.z).min(self.w)
}
#[inline]
pub fn zero() -> Self {
Self::broadcast(0 as $t)
}
#[inline]
pub fn one() -> Self {
Self::broadcast(1 as $t)
}
#[inline]
pub fn xy(&self) -> $v2t {
$v2t::new(self.x, self.y)
}
#[inline]
pub fn xyz(&self) -> $v3t {
$v3t::new(self.x, self.y, self.z)
}
#[inline]
pub fn layout() -> alloc::alloc::Layout {
alloc::alloc::Layout::from_size_align(std::mem::size_of::<Self>(), std::mem::align_of::<$t>()).unwrap()
}
#[inline]
pub fn as_slice(&self) -> &[$t] {
unsafe {
std::slice::from_raw_parts(self as *const $n as *const $t, 4)
}
}
#[inline]
pub fn as_array(&self) -> [$t; 4] {
use std::convert::TryInto;
self.as_slice().try_into().unwrap()
}
#[inline]
pub fn as_byte_slice(&self) -> &[u8] {
unsafe {
std::slice::from_raw_parts(self as *const $n as *const u8, 4 * std::mem::size_of::<$t>())
}
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [$t] {
unsafe {
std::slice::from_raw_parts_mut(self as *mut $n as *mut $t, 4)
}
}
#[inline]
pub fn as_mut_byte_slice(&mut self) -> &mut [u8] {
unsafe {
std::slice::from_raw_parts_mut(self as *mut $n as *mut u8, 4 * std::mem::size_of::<$t>())
}
}
#[inline]
pub fn as_ptr(&self) -> *const $t {
self as *const $n as *const $t
}
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut $t {
self as *mut $n as *mut $t
}
}
impl From<[$t; 4]> for $n {
#[inline]
fn from(comps: [$t; 4]) -> Self {
Self::new(comps[0], comps[1], comps[2], comps[3])
}
}
impl Into<[$t; 4]> for $n {
#[inline]
fn into(self) -> [$t; 4] {
[self.x, self.y, self.z, self.w]
}
}
impl From<&[$t; 4]> for $n {
#[inline]
fn from(comps: &[$t; 4]) -> Self {
Self::from(*comps)
}
}
impl From<&mut [$t; 4]> for $n {
#[inline]
fn from(comps: &mut [$t; 4]) -> Self {
Self::from(*comps)
}
}
impl From<($t, $t, $t, $t)> for $n {
#[inline]
fn from(comps: ($t, $t, $t, $t)) -> Self {
Self::new(comps.0, comps.1, comps.2, comps.3)
}
}
impl From<&($t, $t, $t, $t)> for $n {
#[inline]
fn from(comps: &($t, $t, $t, $t)) -> Self {
Self::from(*comps)
}
}
impl From<$n> for ($t, $t, $t, $t) {
#[inline]
fn from(v: $n) -> Self {
(v.x, v.y, v.z, v.w)
}
}
impl Add for $n {
type Output = Self;
#[inline]
fn add(self, rhs: $n) -> Self {
$n::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z, self.w + rhs.w)
}
}
impl AddAssign for $n {
#[inline]
fn add_assign(&mut self, rhs: $n) {
self.x += rhs.x;
self.y += rhs.y;
self.z += rhs.z;
self.w += rhs.w;
}
}
impl Sub for $n {
type Output = Self;
#[inline]
fn sub(self, rhs: $n) -> Self {
$n::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z, self.w - rhs.w)
}
}
impl SubAssign for $n {
#[inline]
fn sub_assign(&mut self, rhs: $n) {
self.x -= rhs.x;
self.y -= rhs.y;
self.z -= rhs.z;
self.w -= rhs.w;
}
}
impl Mul for $n {
type Output = Self;
#[inline]
fn mul(self, rhs: $n) -> Self {
$n::new(self.x * rhs.x, self.y * rhs.y, self.z * rhs.z, self.w * rhs. w)
}
}
impl Mul<$n> for $t {
type Output = $n;
#[inline]
fn mul(self, rhs: $n) -> $n {
$n::new(self * rhs.x, self * rhs.y, self * rhs.z, self * rhs.w)
}
}
impl Mul<$t> for $n {
type Output = $n;
#[inline]
fn mul(self, rhs: $t) -> $n {
$n::new(self.x * rhs, self.y * rhs, self.z * rhs, self.w * rhs)
}
}
impl MulAssign for $n {
#[inline]
fn mul_assign(&mut self, rhs: $n) {
self.x *= rhs.x;
self.y *= rhs.y;
self.z *= rhs.z;
self.w *= rhs.w;
}
}
impl MulAssign<$t> for $n {
#[inline]
fn mul_assign(&mut self, rhs: $t) {
self.x *= rhs;
self.y *= rhs;
self.z *= rhs;
self.w *= rhs;
}
}
impl Div for $n {
type Output = Self;
#[inline]
fn div(self, rhs: $n) -> Self {
$n::new(self.x / rhs.x, self.y / rhs.y, self.z / rhs.z, self.w / rhs.w)
}
}
impl Div<$t> for $n {
type Output = $n;
#[inline]
fn div(self, rhs: $t) -> $n {
$n::new(self.x / rhs, self.y / rhs, self.z / rhs, self.w / rhs)
}
}
impl DivAssign for $n {
#[inline]
fn div_assign(&mut self, rhs: $n) {
self.x /= rhs.x;
self.y /= rhs.y;
self.z /= rhs.z;
self.w /= rhs.w;
}
}
impl DivAssign<$t> for $n {
#[inline]
fn div_assign(&mut self, rhs: $t) {
self.x /= rhs;
self.y /= rhs;
self.z /= rhs;
self.w /= rhs;
}
}
impl Index<usize> for $n {
type Output = $t;
fn index(&self, index: usize) -> &Self::Output {
match index {
0 => &self.x,
1 => &self.y,
2 => &self.z,
3 => &self.w,
_ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
}
}
}
impl IndexMut<usize> for $n {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
match index {
0 => &mut self.x,
1 => &mut self.y,
2 => &mut self.z,
3 => &mut self.w,
_ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
}
}
}
)+
}
}
vec4i!(Vec4u, Vec2u, Vec3u => u32);
vec4i!(Vec4i, Vec2i, Vec3i => i32);
impl From<Vec3u> for Vec2u {
#[inline]
fn from(vec: Vec3u) -> Self {
Self { x: vec.x, y: vec.y }
}
}
impl From<Vec3u> for Vec4u {
#[inline]
fn from(vec: Vec3u) -> Self {
Self {
x: vec.x,
y: vec.y,
z: vec.z,
w: 0,
}
}
}
impl From<Vec4u> for Vec3u {
#[inline]
fn from(vec: Vec4u) -> Self {
Self {
x: vec.x,
y: vec.y,
z: vec.z,
}
}
}
impl From<Vec3i> for Vec2i {
#[inline]
fn from(vec: Vec3i) -> Self {
Self { x: vec.x, y: vec.y }
}
}
impl From<Vec3i> for Vec4i {
#[inline]
fn from(vec: Vec3i) -> Self {
Self {
x: vec.x,
y: vec.y,
z: vec.z,
w: 0,
}
}
}
impl From<Vec4i> for Vec3i {
#[inline]
fn from(vec: Vec4i) -> Self {
Self {
x: vec.x,
y: vec.y,
z: vec.z,
}
}
}
impl TryFrom<Vec3u> for Vec3i {
type Error = <i32 as TryFrom<u32>>::Error;
fn try_from(rhv: Vec3u) -> Result<Self, Self::Error> {
Ok(Self {
x: rhv.x.try_into()?,
y: rhv.y.try_into()?,
z: rhv.z.try_into()?,
})
}
}
impl TryFrom<Vec3i> for Vec3u {
type Error = <u32 as TryFrom<i32>>::Error;
fn try_from(rhv: Vec3i) -> Result<Self, Self::Error> {
Ok(Self {
x: rhv.x.try_into()?,
y: rhv.y.try_into()?,
z: rhv.z.try_into()?,
})
}
}