use bytes::BufMut; use std::ops::{Add, AddAssign, Div, Mul, Sub}; use num_traits::{Float, Num}; use super::vector2::Vector2; #[derive(Clone, Copy, Debug, PartialEq, Hash, Eq, Default)] pub struct Vector3 { pub x: T, pub y: T, pub z: T, } impl Vector3 { pub const fn new(x: T, y: T, z: T) -> Self { Vector3 { x, y, z } } pub fn length_squared(&self) -> T { self.x * self.x + self.y * self.y + self.z * self.z } pub fn horizontal_length_squared(&self) -> T { self.x * self.x + self.z * self.z } pub fn add(&self, other: &Vector3) -> Self { Vector3 { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z, } } pub fn add_raw(&self, x: T, y: T, z: T) -> Self { Vector3 { x: self.x + x, y: self.y + y, z: self.z + z, } } pub fn sub(&self, other: &Vector3) -> Self { Vector3 { x: self.x - other.x, y: self.y - other.y, z: self.z - other.z, } } pub fn multiply(self, x: T, y: T, z: T) -> Self { Self { x: self.x * x, y: self.y * y, z: self.z * z, } } pub fn lerp(&self, other: &Vector3, t: T) -> Self { Vector3 { x: self.x + (other.x - self.x) * t, y: self.y + (other.y - self.y) * t, z: self.z + (other.z - self.z) * t, } } pub fn sign(&self) -> Vector3 where T: Num + PartialOrd + Copy, { Vector3 { x: if self.x > T::zero() { 1 } else if self.x < T::zero() { -1 } else { 0 }, y: if self.y > T::zero() { 1 } else if self.y < T::zero() { -1 } else { 0 }, z: if self.z > T::zero() { 1 } else if self.z < T::zero() { -1 } else { 0 }, } } pub fn squared_distance_to_vec(&self, other: Self) -> T { self.squared_distance_to(other.x, other.y, other.z) } pub fn squared_distance_to(&self, x: T, y: T, z: T) -> T { let delta_x = self.x - x; let delta_y = self.y - y; let delta_z = self.z - z; delta_x * delta_x + delta_y * delta_y + delta_z * delta_z } } impl Vector3 { pub fn length(&self) -> T { self.length_squared().sqrt() } pub fn horizontal_length(&self) -> T { self.horizontal_length_squared().sqrt() } pub fn normalize(&self) -> Self { let length = self.length(); Vector3 { x: self.x / length, y: self.y / length, z: self.z / length, } } } impl Mul for Vector3 { type Output = Self; fn mul(self, scalar: T) -> Self { Self { x: self.x * scalar, y: self.y * scalar, z: self.z * scalar, } } } impl Add for Vector3 { type Output = Vector3; fn add(self, rhs: Self) -> Self::Output { Self { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z, } } } impl AddAssign for Vector3 { fn add_assign(&mut self, other: Self) { self.x += other.x; self.y += other.y; self.z += other.z; } } /* impl Neg for Vector3 { type Output = Self; fn neg(self) -> Self { Vector3 { x: -self.x, y: -self.y, z: -self.z, } } } */ impl From<(T, T, T)> for Vector3 { #[inline(always)] fn from((x, y, z): (T, T, T)) -> Self { Vector3 { x, y, z } } } impl From> for (T, T, T) { #[inline(always)] fn from(vector: Vector3) -> Self { (vector.x, vector.y, vector.z) } } impl Vector3 where T: Into, { pub fn to_f64(&self) -> Vector3 { Vector3 { x: self.x.into(), y: self.y.into(), z: self.z.into(), } } } impl Vector3 where T: Into, { pub fn to_i32(&self) -> Vector3 { let x: f64 = self.x.into(); let y: f64 = self.y.into(); let z: f64 = self.z.into(); Vector3 { x: x.round() as i32, y: y.round() as i32, z: z.round() as i32, } } pub fn to_vec2_i32(&self) -> Vector2 { let x: f64 = self.x.into(); let z: f64 = self.z.into(); Vector2 { x: x.round() as i32, z: z.round() as i32, } } } pub trait Math: Mul //+ Neg + Add + AddAssign<> + Div + Sub + Sized { } impl Math for i16 {} impl Math for f64 {} impl Math for f32 {} impl Math for i32 {} impl Math for i64 {} impl Math for u8 {} impl<'de> serde::Deserialize<'de> for Vector3 { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct Vector3Visitor; impl<'de> serde::de::Visitor<'de> for Vector3Visitor { type Value = Vector3; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a valid Vector<32>") } fn visit_seq(self, mut seq: A) -> Result where A: serde::de::SeqAccess<'de>, { if let Some(x) = seq.next_element::()? { if let Some(y) = seq.next_element::()? { if let Some(z) = seq.next_element::()? { return Ok(Vector3::new(x, y, z)); } } } Err(serde::de::Error::custom("Failed to read Vector")) } } deserializer.deserialize_seq(Vector3Visitor) } } impl<'de> serde::Deserialize<'de> for Vector3 { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct Vector3Visitor; impl<'de> serde::de::Visitor<'de> for Vector3Visitor { type Value = Vector3; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a valid Vector") } fn visit_seq(self, mut seq: A) -> Result where A: serde::de::SeqAccess<'de>, { if let Some(x) = seq.next_element::()? { if let Some(y) = seq.next_element::()? { if let Some(z) = seq.next_element::()? { return Ok(Vector3::new(x, y, z)); } } } Err(serde::de::Error::custom("Failed to read Vector")) } } deserializer.deserialize_seq(Vector3Visitor) } } impl serde::Serialize for Vector3 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let mut buf = Vec::new(); buf.put_f32(self.x); buf.put_f32(self.y); buf.put_f32(self.z); serializer.serialize_bytes(&buf) } } impl serde::Serialize for Vector3 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let mut buf = Vec::new(); buf.put_f64(self.x); buf.put_f64(self.y); buf.put_f64(self.z); serializer.serialize_bytes(&buf) } } impl serde::Serialize for Vector3 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let mut buf = Vec::new(); buf.put_i16(self.x); buf.put_i16(self.y); buf.put_i16(self.z); serializer.serialize_bytes(&buf) } } impl serde::Serialize for Vector3 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let mut buf = Vec::new(); buf.put_i32(self.x); buf.put_i32(self.y); buf.put_i32(self.z); serializer.serialize_bytes(&buf) } } #[inline] pub const fn packed_chunk_pos(vec: &Vector3) -> i64 { let mut result = 0i64; // Need to go to i64 first to conserve sign result |= (vec.x as i64 & 0x3FFFFF) << 42; result |= (vec.z as i64 & 0x3FFFFF) << 20; result |= vec.y as i64 & 0xFFFFF; result } #[inline] pub const fn packed_local(vec: &Vector3) -> i16 { let x = vec.x as i16; let y = vec.y as i16; let z = vec.z as i16; (x << 8) | (z << 4) | y }