use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; use crate::color::Color; #[derive(Debug, Default, Clone)] pub struct Vec2 { pub x: Value, pub y: Value, } impl Vec2 { pub const ZERO: Self = Self { x: 0, y: 0 }; } impl Add for Vec2 where Value: Add + Clone, { type Output = Self; fn add(self, rhs: Value) -> Self::Output { Self { x: self.x + rhs.clone(), y: self.y + rhs, } } } impl Sub for Vec2 where Value: Sub + Clone, { type Output = Self; fn sub(self, rhs: Value) -> Self::Output { Self { x: self.x - rhs.clone(), y: self.y - rhs, } } } impl Mul for Vec2 where Value: Mul + Clone, { type Output = Self; fn mul(self, rhs: Value) -> Self::Output { Self { x: self.x * rhs.clone(), y: self.y * rhs, } } } impl Div for Vec2 where Value: Div + Clone, { type Output = Self; fn div(self, rhs: Value) -> Self::Output { Self { x: self.x / rhs.clone(), y: self.y / rhs, } } } #[derive(Debug, Default, Clone)] #[repr(C)] pub struct Vec3 { pub x: Value, pub y: Value, pub z: Value, } impl Vec3 { pub const UP: Self = Self { x: 0.0, y: 1.0, z: 0.0 }; /// Returns the length of the vector. #[must_use] pub fn length(&self) -> f32 { (self.x.powi(2) + self.y.powi(2) + self.z.powi(2)).sqrt() } /// Normalizes the vector, returning a unit vector. #[must_use] pub fn normalize(&self) -> Self { let length = self.length(); Self { x: self.x / length, y: self.y / length, z: self.z / length, } } /// Returns the cross product of this and another vector. #[must_use] pub fn cross(&self, rhs: &Self) -> Self { Self { x: (self.y * rhs.z) - (self.z * rhs.y), y: (self.z * rhs.x) - (self.x * rhs.z), z: (self.x * rhs.y) - (self.y * rhs.x), } } /// Returns the dot product of this and another vector. #[must_use] pub fn dot(&self, rhs: &Self) -> f32 { (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z) } /// Returns a direction vector from the specified angle (in degrees). #[must_use] pub fn direction_from_angle(pitch_degs: f32, yaw_degs: f32) -> Self { Self { x: yaw_degs.to_radians().cos() * pitch_degs.to_radians().cos(), y: pitch_degs.to_radians().sin(), z: yaw_degs.to_radians().sin() * pitch_degs.to_radians().cos(), } } } impl Vec3 { pub fn as_ptr(&self) -> *const Value { &self.x } } impl Sub for Vec3 where Value: Sub, { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { Self::Output { x: self.x - rhs.x, y: self.y - rhs.y, z: self.z - rhs.z, } } } impl Sub for &Vec3 where for<'a, 'b> &'a Value: Sub<&'b Value, Output = Value>, { type Output = Vec3; fn sub(self, rhs: Self) -> Self::Output { Self::Output { x: &self.x - &rhs.x, y: &self.y - &rhs.y, z: &self.z - &rhs.z, } } } impl Add for Vec3 where Value: Add, { type Output = Self; fn add(self, rhs: Self) -> Self::Output { Self::Output { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z, } } } impl Add for &Vec3 where for<'a, 'b> &'a Value: Add<&'b Value, Output = Value>, { type Output = Vec3; fn add(self, rhs: Self) -> Self::Output { Self::Output { x: &self.x + &rhs.x, y: &self.y + &rhs.y, z: &self.z + &rhs.z, } } } impl Neg for Vec3 where Value: Neg, { type Output = Self; fn neg(mut self) -> Self::Output { self.x = -self.x; self.y = -self.y; self.z = -self.z; self } } impl Add for Vec3 where Value: Add + Clone, { type Output = Self; fn add(mut self, rhs: Value) -> Self::Output { self.x = self.x + rhs.clone(); self.y = self.y + rhs.clone(); self.z = self.z + rhs.clone(); self } } impl Sub for Vec3 where Value: Sub + Clone, { type Output = Self; fn sub(mut self, rhs: Value) -> Self::Output { self.x = self.x - rhs.clone(); self.y = self.y - rhs.clone(); self.z = self.z - rhs.clone(); self } } impl Mul for Vec3 where Value: Mul + Clone, { type Output = Self; fn mul(mut self, rhs: Value) -> Self::Output { self.x = self.x * rhs.clone(); self.y = self.y * rhs.clone(); self.z = self.z * rhs.clone(); self } } impl AddAssign for Vec3 where Value: AddAssign, { fn add_assign(&mut self, rhs: Self) { self.x += rhs.x; self.y += rhs.y; self.z += rhs.z; } } impl SubAssign for Vec3 where Value: SubAssign, { fn sub_assign(&mut self, rhs: Self) { self.x -= rhs.x; self.y -= rhs.y; self.z -= rhs.z; } } impl From for Vec3 where Value: Clone, { fn from(value: Value) -> Self { Self { x: value.clone(), y: value.clone(), z: value, } } } impl From> for Vec3 { fn from(color: Color) -> Self { Self { x: color.red, y: color.green, z: color.blue, } } }