use core::iter::Sum;
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
#[derive(Copy, Clone, PartialEq)]
pub struct Vec3 {
x: f32,
y: f32,
z: f32,
}
impl Vec3 {
pub fn new(x: f32, y: f32, z: f32) -> Self {
Self { x, y, z }
}
pub fn x(&self) -> f32 {
self.x
}
pub fn y(&self) -> f32 {
self.y
}
pub fn z(&self) -> f32 {
self.z
}
pub fn dot(&self, other: &Vec3) -> f32 {
self.x * other.x + self.y * other.y + self.z * other.z
}
pub fn length2(&self) -> f32 {
self.x * self.x + self.y * self.y + self.z * self.z
}
pub fn max(&self, other: Vec3) -> Vec3 {
Vec3::new(
self.x.max(other.x),
self.y.max(other.y),
self.z.max(other.z),
)
}
pub fn min(&self, other: Vec3) -> Vec3 {
Vec3::new(
self.x.min(other.x),
self.y.min(other.y),
self.z.min(other.z),
)
}
pub fn truncate(&self) -> Vec3 {
Vec3::new(self.x.trunc(), self.y.trunc(), self.z.trunc())
}
}
impl<'a> Add for &'a Vec3 {
type Output = Vec3;
fn add(self, other: &'a Vec3) -> Vec3 {
Vec3::new(self.x + other.x, self.y + other.y, self.z + other.z)
}
}
impl Add for Vec3 {
type Output = Vec3;
fn add(self, other: Vec3) -> Vec3 {
Vec3::new(self.x + other.x, self.y + other.y, self.z + other.z)
}
}
impl AddAssign<Vec3> for Vec3 {
fn add_assign(&mut self, other: Vec3) {
self.x += other.x;
self.y += other.y;
self.z += other.z;
}
}
impl<'a> Add<&'a Vec3> for Vec3 {
type Output = Vec3;
fn add(self, other: &'a Vec3) -> Vec3 {
Vec3::new(self.x + other.x, self.y + other.y, self.z + other.z)
}
}
impl<'a> AddAssign<&'a Vec3> for Vec3 {
fn add_assign(&mut self, other: &'a Vec3) {
self.x += other.x;
self.y += other.y;
self.z += other.z;
}
}
impl Add<f32> for Vec3 {
type Output = Vec3;
fn add(self, other: f32) -> Vec3 {
Vec3::new(self.x + other, self.y + other, self.z + other)
}
}
impl<'a> Add<f32> for &'a Vec3 {
type Output = Vec3;
fn add(self, other: f32) -> Vec3 {
Vec3::new(self.x + other, self.y + other, self.z + other)
}
}
impl AddAssign<f32> for Vec3 {
fn add_assign(&mut self, other: f32) {
self.x += other;
self.y += other;
self.z += other;
}
}
impl Sub for Vec3 {
type Output = Vec3;
fn sub(self, other: Vec3) -> Vec3 {
Vec3::new(self.x - other.x, self.y - other.y, self.z - other.z)
}
}
impl SubAssign<Vec3> for Vec3 {
fn sub_assign(&mut self, other: Vec3) {
self.x -= other.x;
self.y -= other.y;
self.z -= other.z;
}
}
impl<'a> Sub<&'a Vec3> for Vec3 {
type Output = Vec3;
fn sub(self, other: &'a Vec3) -> Vec3 {
Vec3::new(self.x - other.x, self.y - other.y, self.z - other.z)
}
}
impl<'a> Sub for &'a Vec3 {
type Output = Vec3;
fn sub(self, other: &'a Vec3) -> Vec3 {
Vec3::new(self.x - other.x, self.y - other.y, self.z - other.z)
}
}
impl<'a> SubAssign<&'a Vec3> for Vec3 {
fn sub_assign(&mut self, other: &'a Vec3) {
self.x -= other.x;
self.y -= other.y;
self.z -= other.z;
}
}
impl Sub<f32> for Vec3 {
type Output = Vec3;
fn sub(self, other: f32) -> Vec3 {
Vec3::new(self.x - other, self.y - other, self.z - other)
}
}
impl<'a> Sub<f32> for &'a Vec3 {
type Output = Vec3;
fn sub(self, other: f32) -> Vec3 {
Vec3::new(self.x - other, self.y - other, self.z - other)
}
}
impl SubAssign<f32> for Vec3 {
fn sub_assign(&mut self, other: f32) {
self.x -= other;
self.y -= other;
self.z -= other;
}
}
impl<'a> Mul for &'a Vec3 {
type Output = Vec3;
fn mul(self, other: &'a Vec3) -> Vec3 {
Vec3::new(self.x * other.x, self.y * other.y, self.z * other.z)
}
}
impl Mul for Vec3 {
type Output = Vec3;
fn mul(self, other: Vec3) -> Vec3 {
Vec3::new(self.x * other.x, self.y * other.y, self.z * other.z)
}
}
impl MulAssign for Vec3 {
fn mul_assign(&mut self, other: Vec3) {
self.x *= other.x;
self.y *= other.y;
self.z *= other.z;
}
}
impl<'a> Mul<&'a Vec3> for Vec3 {
type Output = Vec3;
fn mul(self, other: &'a Vec3) -> Vec3 {
Vec3::new(self.x * other.x, self.y * other.y, self.z * other.z)
}
}
impl<'a> MulAssign<&'a Vec3> for Vec3 {
fn mul_assign(&mut self, other: &'a Vec3) {
self.x *= other.x;
self.y *= other.y;
self.z *= other.z;
}
}
impl Mul<f32> for Vec3 {
type Output = Vec3;
fn mul(self, other: f32) -> Vec3 {
Vec3::new(self.x * other, self.y * other, self.z * other)
}
}
impl<'a> Mul<f32> for &'a Vec3 {
type Output = Vec3;
fn mul(self, other: f32) -> Vec3 {
Vec3::new(self.x * other, self.y * other, self.z * other)
}
}
impl MulAssign<f32> for Vec3 {
fn mul_assign(&mut self, other: f32) {
self.x *= other;
self.y *= other;
self.z *= other;
}
}
impl Div for Vec3 {
type Output = Vec3;
fn div(self, other: Vec3) -> Vec3 {
Vec3::new(self.x / other.x, self.y / other.y, self.z / other.z)
}
}
impl DivAssign for Vec3 {
fn div_assign(&mut self, other: Vec3) {
self.x /= other.x;
self.y /= other.y;
self.z /= other.z;
}
}
impl<'a> Div<&'a Vec3> for Vec3 {
type Output = Vec3;
fn div(self, other: &'a Vec3) -> Vec3 {
Vec3::new(self.x / other.x, self.y / other.y, self.z / other.z)
}
}
impl<'a> Div for &'a Vec3 {
type Output = Vec3;
fn div(self, other: &'a Vec3) -> Vec3 {
Vec3::new(self.x / other.x, self.y / other.y, self.z / other.z)
}
}
impl<'a> DivAssign<&'a Vec3> for Vec3 {
fn div_assign(&mut self, other: &'a Vec3) {
self.x /= other.x;
self.y /= other.y;
self.z /= other.z;
}
}
impl Div<f32> for Vec3 {
type Output = Vec3;
fn div(self, other: f32) -> Vec3 {
Vec3::new(self.x / other, self.y / other, self.z / other)
}
}
impl<'a> Div<f32> for &'a Vec3 {
type Output = Vec3;
fn div(self, other: f32) -> Vec3 {
Vec3::new(self.x / other, self.y / other, self.z / other)
}
}
impl DivAssign<f32> for Vec3 {
fn div_assign(&mut self, other: f32) {
let t = 1.0 / other;
self.x *= t;
self.y *= t;
self.z *= t;
}
}
impl Sum<Vec3> for Vec3 {
fn sum<I: Iterator<Item = Vec3>>(iter: I) -> Self {
iter.fold(Vec3::new(0.0, 0.0, 0.0), |a, b| a + b)
}
}