mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38:50 +00:00
1293 lines
28 KiB
Rust
1293 lines
28 KiB
Rust
use crate::point::{p2, p3};
|
|
use crate::quaternion::Quat;
|
|
use crate::Point;
|
|
use std::ops::*;
|
|
|
|
pub trait InnerSpace:
|
|
std::fmt::Debug
|
|
+ Copy
|
|
+ Clone
|
|
+ Neg<Output = Self>
|
|
+ Mul<f32, Output = Self>
|
|
+ Div<f32, Output = Self>
|
|
+ Add<Self, Output = Self>
|
|
+ Sub<Self, Output = Self>
|
|
{
|
|
fn dot(&self, other: &Self) -> f32;
|
|
fn dist(&self, other: &Self) -> f32;
|
|
fn angle(&self, other: &Self) -> f32;
|
|
fn length(&self) -> f32;
|
|
fn normalize(&self) -> Self;
|
|
fn normalize_mut(&mut self);
|
|
fn project_onto(&self, other: &Self) -> Self;
|
|
fn reflect(&self, normal: &Self) -> Self;
|
|
fn lerp(&self, other: &Self, t: f32) -> Self;
|
|
fn to_point(&self) -> impl Point;
|
|
}
|
|
|
|
// ##################################################
|
|
// # VECTOR 2D #
|
|
// ##################################################
|
|
|
|
/// Representation of a 2D vector
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
#[allow(non_camel_case_types)]
|
|
pub struct v2 {
|
|
x: f32,
|
|
y: f32,
|
|
}
|
|
|
|
impl v2 {
|
|
/// The unit vector along the x-axis.
|
|
pub const X: v2 = v2 { x: 1.0, y: 0.0 };
|
|
/// The unit vector along the y-axis.
|
|
pub const Y: v2 = v2 { x: 0.0, y: 1.0 };
|
|
/// The zero vector.
|
|
pub const ZERO: v2 = v2 { x: 0.0, y: 0.0 };
|
|
|
|
/// Creates a new vector with the given components.
|
|
pub const fn new(x: f32, y: f32) -> Self {
|
|
v2 { x, y }
|
|
}
|
|
|
|
/// Creates a new vector from a point.
|
|
pub fn from_point(p: p2) -> Self {
|
|
Self { x: p.x(), y: p.y() }
|
|
}
|
|
|
|
/// Gets the x-component of the vector.
|
|
pub fn x(&self) -> f32 {
|
|
self.x
|
|
}
|
|
|
|
/// Gets the y-component of the vector.
|
|
pub fn y(&self) -> f32 {
|
|
self.y
|
|
}
|
|
|
|
/// Sets the x-component of the vector.
|
|
pub fn set_x(&mut self, new_x: f32) {
|
|
self.x = new_x;
|
|
}
|
|
|
|
/// Sets the y-component of the vector.
|
|
pub fn set_y(&mut self, new_y: f32) {
|
|
self.y = new_y;
|
|
}
|
|
}
|
|
|
|
impl Add<v2> for v2 {
|
|
type Output = v2;
|
|
|
|
fn add(self, other: v2) -> v2 {
|
|
v2 {
|
|
x: self.x + other.x,
|
|
y: self.y + other.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AddAssign for v2 {
|
|
fn add_assign(&mut self, other: v2) {
|
|
self.x += other.x;
|
|
self.y += other.y;
|
|
}
|
|
}
|
|
|
|
impl Sub<v2> for v2 {
|
|
type Output = v2;
|
|
|
|
fn sub(self, other: v2) -> v2 {
|
|
v2 {
|
|
x: self.x - other.x,
|
|
y: self.y - other.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SubAssign for v2 {
|
|
fn sub_assign(&mut self, other: v2) {
|
|
self.x -= other.x;
|
|
self.y -= other.y;
|
|
}
|
|
}
|
|
|
|
impl Neg for v2 {
|
|
type Output = Self;
|
|
|
|
fn neg(self) -> Self::Output {
|
|
Self {
|
|
x: -self.x,
|
|
y: -self.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Mul<f32> for v2 {
|
|
type Output = v2;
|
|
|
|
fn mul(self, other: f32) -> v2 {
|
|
v2 {
|
|
x: self.x * other,
|
|
y: self.y * other,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Mul<v2> for f32 {
|
|
type Output = v2;
|
|
|
|
fn mul(self, other: v2) -> v2 {
|
|
v2 {
|
|
x: self * other.x,
|
|
y: self * other.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Div<f32> for v2 {
|
|
type Output = v2;
|
|
|
|
fn div(self, other: f32) -> v2 {
|
|
v2 {
|
|
x: self.x / other,
|
|
y: self.y / other,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Into<[f32; 2]> for v2 {
|
|
fn into(self) -> [f32; 2] {
|
|
[self.x, self.y]
|
|
}
|
|
}
|
|
|
|
impl Into<v2> for [f32; 2] {
|
|
fn into(self) -> v2 {
|
|
v2 {
|
|
x: self[0],
|
|
y: self[1],
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Representation of a 2D integer vector
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
#[allow(non_camel_case_types)]
|
|
pub struct v2i {
|
|
x: i64,
|
|
y: i64,
|
|
}
|
|
|
|
impl v2i {
|
|
/// The unit vector in the x direction.
|
|
pub const X: v2i = v2i { x: 1, y: 0 };
|
|
/// The unit vector in the y direction.
|
|
pub const Y: v2i = v2i { x: 0, y: 1 };
|
|
/// The zero vector.
|
|
pub const ZERO: v2i = v2i { x: 0, y: 0 };
|
|
|
|
/// Creates a new vector with the given components.
|
|
pub const fn new(x: i64, y: i64) -> Self {
|
|
v2i { x, y }
|
|
}
|
|
|
|
/// Creates a new vector from a point.
|
|
pub fn from_point(p: p2) -> Self {
|
|
Self {
|
|
x: p.x() as i64,
|
|
y: p.y() as i64,
|
|
}
|
|
}
|
|
|
|
/// Creates a 2D point from the vector.
|
|
pub fn as_point(&self) -> p2 {
|
|
p2::new(self.x as f32, self.y as f32)
|
|
}
|
|
|
|
/// Creates a integer 2D vector from a floating point 2D vector.
|
|
pub fn from_vec2(v: v2) -> Self {
|
|
Self {
|
|
x: v.x as i64,
|
|
y: v.y as i64,
|
|
}
|
|
}
|
|
|
|
/// Creates a floating point 2D vector from the integer vector.
|
|
pub fn as_vec2(&self) -> v2 {
|
|
v2 {
|
|
x: self.x as f32,
|
|
y: self.y as f32,
|
|
}
|
|
}
|
|
|
|
/// Gets the x component of the vector.
|
|
pub fn x(&self) -> i64 {
|
|
self.x
|
|
}
|
|
|
|
/// Gets the y component of the vector.
|
|
pub fn y(&self) -> i64 {
|
|
self.y
|
|
}
|
|
|
|
/// Sets the x component of the vector.
|
|
pub fn set_x(&mut self, new_x: i64) {
|
|
self.x = new_x;
|
|
}
|
|
|
|
/// Sets the y component of the vector.
|
|
pub fn set_y(&mut self, new_y: i64) {
|
|
self.y = new_y;
|
|
}
|
|
|
|
/// Gets the length of the vector.
|
|
pub fn length(&self) -> i64 {
|
|
((self.x * self.x + self.y * self.y) as f32).sqrt() as i64
|
|
}
|
|
|
|
/// Calculates the normalized version of the vector.
|
|
pub fn normalize(&self) -> Self {
|
|
let factor = 1.0 / self.length() as f32;
|
|
v2i {
|
|
x: (factor * self.x as f32) as i64,
|
|
y: (factor * self.y as f32) as i64,
|
|
}
|
|
}
|
|
|
|
/// Swizzles the vector components.
|
|
/// (x,y) -> (x,x)
|
|
pub fn xx(&self) -> Self {
|
|
Self {
|
|
x: self.x,
|
|
y: self.x,
|
|
}
|
|
}
|
|
|
|
/// Swizzles the vector components.
|
|
/// (x,y) -> (x,y)
|
|
pub fn xy(&self) -> Self {
|
|
Self {
|
|
x: self.x,
|
|
y: self.y,
|
|
}
|
|
}
|
|
|
|
/// Swizzles the vector components.
|
|
/// (x,y) -> (y,x)
|
|
pub fn yx(&self) -> Self {
|
|
Self {
|
|
x: self.y,
|
|
y: self.x,
|
|
}
|
|
}
|
|
|
|
/// Swizzles the vector components.
|
|
/// (x,y) -> (y,y)
|
|
pub fn yy(&self) -> Self {
|
|
Self {
|
|
x: self.y,
|
|
y: self.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Add<v2i> for v2i {
|
|
type Output = v2i;
|
|
|
|
fn add(self, other: v2i) -> v2i {
|
|
v2i {
|
|
x: self.x + other.x,
|
|
y: self.y + other.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Add<v2i> for v2 {
|
|
type Output = v2;
|
|
|
|
fn add(self, other: v2i) -> v2 {
|
|
v2 {
|
|
x: self.x + other.x as f32,
|
|
y: self.y + other.y as f32,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Add<v2> for v2i {
|
|
type Output = v2;
|
|
|
|
fn add(self, other: v2) -> v2 {
|
|
v2 {
|
|
x: self.x as f32 + other.x,
|
|
y: self.y as f32 + other.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AddAssign for v2i {
|
|
fn add_assign(&mut self, other: v2i) {
|
|
self.x += other.x;
|
|
self.y += other.y;
|
|
}
|
|
}
|
|
|
|
impl Sub<v2i> for v2i {
|
|
type Output = v2i;
|
|
|
|
fn sub(self, other: v2i) -> v2i {
|
|
v2i {
|
|
x: self.x - other.x,
|
|
y: self.y - other.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Sub<v2i> for v2 {
|
|
type Output = v2;
|
|
|
|
fn sub(self, other: v2i) -> v2 {
|
|
v2 {
|
|
x: self.x - other.x as f32,
|
|
y: self.y - other.y as f32,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Sub<v2> for v2i {
|
|
type Output = v2;
|
|
|
|
fn sub(self, other: v2) -> v2 {
|
|
v2 {
|
|
x: self.x as f32 - other.x,
|
|
y: self.y as f32 - other.y,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SubAssign for v2i {
|
|
fn sub_assign(&mut self, other: v2i) {
|
|
self.x -= other.x;
|
|
self.y -= other.y;
|
|
}
|
|
}
|
|
|
|
impl Mul<f32> for v2i {
|
|
type Output = v2i;
|
|
|
|
fn mul(self, other: f32) -> v2i {
|
|
v2i {
|
|
x: self.x * other as i64,
|
|
y: self.y * other as i64,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<v2i> for v2 {
|
|
fn from(v: v2i) -> v2 {
|
|
v2 {
|
|
x: v.x as f32,
|
|
y: v.y as f32,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<v2> for v2i {
|
|
fn from(v: v2) -> v2i {
|
|
v2i {
|
|
x: v.x as i64,
|
|
y: v.y as i64,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Into<[i64; 2]> for v2i {
|
|
fn into(self) -> [i64; 2] {
|
|
[self.x, self.y]
|
|
}
|
|
}
|
|
|
|
impl Into<[f32; 2]> for v2i {
|
|
fn into(self) -> [f32; 2] {
|
|
[self.x as f32, self.y as f32]
|
|
}
|
|
}
|
|
|
|
// ##################################################
|
|
// # VECTOR 3D #
|
|
// ##################################################
|
|
|
|
/// Representation of a 3D vector
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
#[allow(non_camel_case_types)]
|
|
pub struct v3 {
|
|
pub x: f32,
|
|
pub y: f32,
|
|
pub z: f32,
|
|
}
|
|
|
|
impl v3 {
|
|
/// The unit vector along the x-axis.
|
|
pub const X: v3 = v3 {
|
|
x: 1.0,
|
|
y: 0.0,
|
|
z: 0.0,
|
|
};
|
|
/// The unit vector along the y-axis.
|
|
pub const Y: v3 = v3 {
|
|
x: 0.0,
|
|
y: 1.0,
|
|
z: 0.0,
|
|
};
|
|
/// The unit vector along the z-axis.
|
|
pub const Z: v3 = v3 {
|
|
x: 0.0,
|
|
y: 0.0,
|
|
z: 1.0,
|
|
};
|
|
/// The zero vector.
|
|
pub const ZERO: v3 = v3 {
|
|
x: 0.0,
|
|
y: 0.0,
|
|
z: 0.0,
|
|
};
|
|
|
|
/// Creates a new vector with the given components.
|
|
pub const fn new(x: f32, y: f32, z: f32) -> Self {
|
|
v3 { x, y, z }
|
|
}
|
|
|
|
/// Creates a new vector from a point.
|
|
pub fn from_point(p: p3) -> Self {
|
|
Self {
|
|
x: p.x(),
|
|
y: p.y(),
|
|
z: p.z(),
|
|
}
|
|
}
|
|
|
|
/// Creates a new point from a vector.
|
|
pub fn as_point(&self) -> p3 {
|
|
p3::new(self.x as f32, self.y as f32, self.z as f32)
|
|
}
|
|
|
|
/// Gets the x-component of the vector.
|
|
pub fn x(&self) -> f32 {
|
|
self.x
|
|
}
|
|
|
|
/// Gets the y-component of the vector.
|
|
pub fn y(&self) -> f32 {
|
|
self.y
|
|
}
|
|
|
|
/// Gets the z-component of the vector.
|
|
pub fn z(&self) -> f32 {
|
|
self.z
|
|
}
|
|
|
|
/// Sets the x-component of the vector.
|
|
pub fn set_x(&mut self, new_x: f32) {
|
|
self.x = new_x;
|
|
}
|
|
|
|
/// Sets the y-component of the vector.
|
|
pub fn set_y(&mut self, new_y: f32) {
|
|
self.y = new_y;
|
|
}
|
|
|
|
/// Sets the z-component of the vector.
|
|
pub fn set_z(&mut self, new_z: f32) {
|
|
self.z = new_z;
|
|
}
|
|
}
|
|
|
|
impl Add<v3> for v3 {
|
|
type Output = v3;
|
|
|
|
fn add(self, other: v3) -> v3 {
|
|
v3 {
|
|
x: self.x + other.x,
|
|
y: self.y + other.y,
|
|
z: self.z + other.z,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AddAssign for v3 {
|
|
fn add_assign(&mut self, other: v3) {
|
|
self.x += other.x;
|
|
self.y += other.y;
|
|
self.z += other.z;
|
|
}
|
|
}
|
|
|
|
impl Sub<v3> for v3 {
|
|
type Output = v3;
|
|
|
|
fn sub(self, other: v3) -> v3 {
|
|
v3 {
|
|
x: self.x - other.x,
|
|
y: self.y - other.y,
|
|
z: self.z - other.z,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SubAssign for v3 {
|
|
fn sub_assign(&mut self, other: v3) {
|
|
self.x -= other.x;
|
|
self.y -= other.y;
|
|
self.z -= other.z;
|
|
}
|
|
}
|
|
|
|
impl Neg for v3 {
|
|
type Output = v3;
|
|
|
|
fn neg(self) -> v3 {
|
|
v3 {
|
|
x: -self.x,
|
|
y: -self.y,
|
|
z: -self.z,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Mul<f32> for v3 {
|
|
type Output = v3;
|
|
|
|
fn mul(self, other: f32) -> v3 {
|
|
v3 {
|
|
x: self.x * other,
|
|
y: self.y * other,
|
|
z: self.z * other,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Mul<v3> for f32 {
|
|
type Output = v3;
|
|
|
|
fn mul(self, other: v3) -> v3 {
|
|
v3 {
|
|
x: self * other.x,
|
|
y: self * other.y,
|
|
z: self * other.z,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Div<f32> for v3 {
|
|
type Output = v3;
|
|
|
|
fn div(self, other: f32) -> v3 {
|
|
v3 {
|
|
x: self.x / other,
|
|
y: self.y / other,
|
|
z: self.z / other,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Into<Quat> for v3 {
|
|
fn into(self) -> Quat {
|
|
Quat::new(0.0, self)
|
|
}
|
|
}
|
|
|
|
impl Into<[f32; 3]> for v3 {
|
|
fn into(self) -> [f32; 3] {
|
|
[self.x, self.y, self.z]
|
|
}
|
|
}
|
|
|
|
impl Into<v3> for [f32; 3] {
|
|
fn into(self) -> v3 {
|
|
v3 {
|
|
x: self[0],
|
|
y: self[1],
|
|
z: self[2],
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Representation of a 3D integer vector
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
#[allow(non_camel_case_types)]
|
|
pub struct v3i {
|
|
pub x: i64,
|
|
pub y: i64,
|
|
pub z: i64,
|
|
}
|
|
|
|
impl v3i {
|
|
/// The unit vector in the x-direction.
|
|
pub const X: v3i = v3i { x: 1, y: 0, z: 0 };
|
|
/// The unit vector in the y-direction.
|
|
pub const Y: v3i = v3i { x: 0, y: 1, z: 0 };
|
|
/// The unit vector in the z-direction.
|
|
pub const Z: v3i = v3i { x: 0, y: 0, z: 1 };
|
|
/// The zero vector.
|
|
pub const ZERO: v3i = v3i { x: 0, y: 0, z: 0 };
|
|
|
|
/// Creates a new vector with the given components.
|
|
pub const fn new(x: i64, y: i64, z: i64) -> Self {
|
|
v3i { x, y, z }
|
|
}
|
|
|
|
/// Creates a new vector from a point.
|
|
pub fn from_point(p: p3) -> Self {
|
|
Self {
|
|
x: p.x() as i64,
|
|
y: p.y() as i64,
|
|
z: p.z() as i64,
|
|
}
|
|
}
|
|
|
|
/// Gets the x-component of the vector.
|
|
pub fn x(&self) -> i64 {
|
|
self.x
|
|
}
|
|
|
|
/// Gets the y-component of the vector.
|
|
pub fn y(&self) -> i64 {
|
|
self.y
|
|
}
|
|
|
|
/// Gets the z-component of the vector.
|
|
pub fn z(&self) -> i64 {
|
|
self.z
|
|
}
|
|
|
|
/// Sets the x-component of the vector.
|
|
pub fn set_x(&mut self, new_x: i64) {
|
|
self.x = new_x;
|
|
}
|
|
|
|
/// Sets the y-component of the vector.
|
|
pub fn set_y(&mut self, new_y: i64) {
|
|
self.y = new_y;
|
|
}
|
|
|
|
/// Sets the z-component of the vector.
|
|
pub fn set_z(&mut self, new_z: i64) {
|
|
self.z = new_z;
|
|
}
|
|
|
|
/// Calculates the length of the vector.
|
|
pub fn length(&self) -> i64 {
|
|
((self.x * self.x + self.y * self.y + self.z * self.z) as f32).sqrt() as i64
|
|
}
|
|
|
|
/// Normalizes the vector.
|
|
pub fn normalize(&self) -> Self {
|
|
let factor = 1 / self.length();
|
|
v3i {
|
|
x: factor * self.x,
|
|
y: factor * self.y,
|
|
z: factor * self.z,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Add<v3i> for v3i {
|
|
type Output = v3i;
|
|
|
|
fn add(self, other: v3i) -> v3i {
|
|
v3i {
|
|
x: self.x + other.x,
|
|
y: self.y + other.y,
|
|
z: self.z + other.z,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Add<v3i> for v3 {
|
|
type Output = v3;
|
|
|
|
fn add(self, other: v3i) -> v3 {
|
|
v3 {
|
|
x: self.x + other.x as f32,
|
|
y: self.y + other.y as f32,
|
|
z: self.z + other.z as f32,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Add<v3> for v3i {
|
|
type Output = v3;
|
|
|
|
fn add(self, other: v3) -> v3 {
|
|
v3 {
|
|
x: self.x as f32 + other.x,
|
|
y: self.y as f32 + other.y,
|
|
z: self.z as f32 + other.z,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AddAssign for v3i {
|
|
fn add_assign(&mut self, other: v3i) {
|
|
self.x += other.x;
|
|
self.y += other.y;
|
|
self.z += other.z;
|
|
}
|
|
}
|
|
|
|
impl Sub<v3i> for v3i {
|
|
type Output = v3i;
|
|
|
|
fn sub(self, other: v3i) -> v3i {
|
|
v3i {
|
|
x: self.x - other.x,
|
|
y: self.y - other.y,
|
|
z: self.z - other.z,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Sub<v3i> for v3 {
|
|
type Output = v3;
|
|
|
|
fn sub(self, other: v3i) -> v3 {
|
|
v3 {
|
|
x: self.x - other.x as f32,
|
|
y: self.y - other.y as f32,
|
|
z: self.z - other.z as f32,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Sub<v3> for v3i {
|
|
type Output = v3;
|
|
|
|
fn sub(self, other: v3) -> v3 {
|
|
v3 {
|
|
x: self.x as f32 - other.x,
|
|
y: self.y as f32 - other.y,
|
|
z: self.z as f32 - other.z,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SubAssign for v3i {
|
|
fn sub_assign(&mut self, other: v3i) {
|
|
self.x -= other.x;
|
|
self.y -= other.y;
|
|
}
|
|
}
|
|
|
|
impl Mul<f32> for v3i {
|
|
type Output = v3i;
|
|
|
|
fn mul(self, other: f32) -> v3i {
|
|
v3i {
|
|
x: self.x * other as i64,
|
|
y: self.y * other as i64,
|
|
z: self.z * other as i64,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<v3i> for v3 {
|
|
fn from(v: v3i) -> v3 {
|
|
v3 {
|
|
x: v.x as f32,
|
|
y: v.y as f32,
|
|
z: v.z as f32,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<v3> for v3i {
|
|
fn from(v: v3) -> v3i {
|
|
v3i {
|
|
x: v.x as i64,
|
|
y: v.y as i64,
|
|
z: v.z as i64,
|
|
}
|
|
}
|
|
}
|
|
|
|
// ##################################################
|
|
// # VECTOR 4D #
|
|
// ##################################################
|
|
|
|
/// Representation of a 4D vector
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
#[allow(non_camel_case_types)]
|
|
pub struct v4 {
|
|
x: f32,
|
|
y: f32,
|
|
z: f32,
|
|
w: f32,
|
|
}
|
|
|
|
impl v4 {
|
|
/// The unit vector along the x-axis.
|
|
pub const X: v4 = v4 {
|
|
x: 1.0,
|
|
y: 0.0,
|
|
z: 0.0,
|
|
w: 0.0,
|
|
};
|
|
|
|
/// The unit vector along the y-axis.
|
|
pub const Y: v4 = v4 {
|
|
x: 0.0,
|
|
y: 1.0,
|
|
z: 0.0,
|
|
w: 0.0,
|
|
};
|
|
|
|
/// The unit vector along the z-axis.
|
|
pub const Z: v4 = v4 {
|
|
x: 0.0,
|
|
y: 0.0,
|
|
z: 1.0,
|
|
w: 0.0,
|
|
};
|
|
|
|
/// The unit vector along the w-axis.
|
|
pub const W: v4 = v4 {
|
|
x: 0.0,
|
|
y: 0.0,
|
|
z: 0.0,
|
|
w: 1.0,
|
|
};
|
|
|
|
/// The zero vector.
|
|
pub const ZERO: v4 = v4 {
|
|
x: 0.0,
|
|
y: 0.0,
|
|
z: 0.0,
|
|
w: 0.0,
|
|
};
|
|
|
|
/// Creates a new vector with the given components.
|
|
pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
|
|
v4 { x, y, z, w }
|
|
}
|
|
|
|
/// Gets the x-component of the vector.
|
|
pub fn x(&self) -> f32 {
|
|
self.x
|
|
}
|
|
|
|
/// Gets the y-component of the vector.
|
|
pub fn y(&self) -> f32 {
|
|
self.y
|
|
}
|
|
|
|
/// Gets the z-component of the vector.
|
|
pub fn z(&self) -> f32 {
|
|
self.z
|
|
}
|
|
|
|
/// Gets the w-component of the vector.
|
|
pub fn w(&self) -> f32 {
|
|
self.w
|
|
}
|
|
|
|
/// Sets the x-component of the vector.
|
|
pub fn set_x(&mut self, new_x: f32) {
|
|
self.x = new_x;
|
|
}
|
|
|
|
/// Sets the y-component of the vector.
|
|
pub fn set_y(&mut self, new_y: f32) {
|
|
self.y = new_y;
|
|
}
|
|
|
|
/// Sets the z-component of the vector.
|
|
pub fn set_z(&mut self, new_z: f32) {
|
|
self.z = new_z;
|
|
}
|
|
|
|
/// Sets the w-component of the vector.
|
|
pub fn set_w(&mut self, new_w: f32) {
|
|
self.w = new_w;
|
|
}
|
|
}
|
|
|
|
impl Add<v4> for v4 {
|
|
type Output = v4;
|
|
|
|
fn add(self, other: v4) -> v4 {
|
|
v4 {
|
|
x: self.x + other.x,
|
|
y: self.y + other.y,
|
|
z: self.z + other.z,
|
|
w: self.w + other.w,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AddAssign for v4 {
|
|
fn add_assign(&mut self, other: v4) {
|
|
self.x += other.x;
|
|
self.y += other.y;
|
|
self.z += other.z;
|
|
self.w += other.w;
|
|
}
|
|
}
|
|
|
|
impl Sub<v4> for v4 {
|
|
type Output = v4;
|
|
|
|
fn sub(self, other: v4) -> v4 {
|
|
v4 {
|
|
x: self.x - other.x,
|
|
y: self.y - other.y,
|
|
z: self.z - other.z,
|
|
w: self.w - other.w,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SubAssign for v4 {
|
|
fn sub_assign(&mut self, other: v4) {
|
|
self.x -= other.x;
|
|
self.y -= other.y;
|
|
self.z -= other.z;
|
|
self.w -= other.w;
|
|
}
|
|
}
|
|
|
|
impl Neg for v4 {
|
|
type Output = Self;
|
|
|
|
fn neg(self) -> Self::Output {
|
|
Self {
|
|
x: -self.x,
|
|
y: -self.y,
|
|
z: -self.z,
|
|
w: -self.w,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Mul<f32> for v4 {
|
|
type Output = v4;
|
|
|
|
fn mul(self, other: f32) -> v4 {
|
|
v4 {
|
|
x: self.x * other,
|
|
y: self.y * other,
|
|
z: self.z * other,
|
|
w: self.w * other,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Mul<v4> for f32 {
|
|
type Output = v4;
|
|
|
|
fn mul(self, other: v4) -> v4 {
|
|
v4 {
|
|
x: self * other.x,
|
|
y: self * other.y,
|
|
z: self * other.z,
|
|
w: self * other.w,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl MulAssign<f32> for v4 {
|
|
fn mul_assign(&mut self, other: f32) {
|
|
self.x *= other;
|
|
self.y *= other;
|
|
self.z *= other;
|
|
self.w *= other;
|
|
}
|
|
}
|
|
|
|
impl Div<f32> for v4 {
|
|
type Output = v4;
|
|
|
|
fn div(self, other: f32) -> v4 {
|
|
v4 {
|
|
x: self.x / other,
|
|
y: self.y / other,
|
|
z: self.z / other,
|
|
w: self.w / other,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Into<[f32; 4]> for v4 {
|
|
fn into(self) -> [f32; 4] {
|
|
[self.x, self.y, self.z, self.w]
|
|
}
|
|
}
|
|
|
|
impl InnerSpace for v2 {
|
|
fn dot(&self, other: &Self) -> f32 {
|
|
self.x * other.x + self.y * other.y
|
|
}
|
|
|
|
fn dist(&self, other: &Self) -> f32 {
|
|
v2 {
|
|
x: other.x - self.x,
|
|
y: other.y - self.y,
|
|
}
|
|
.length()
|
|
}
|
|
|
|
fn angle(&self, other: &Self) -> f32 {
|
|
(self.dot(other) / (self.length() * other.length())).acos()
|
|
}
|
|
|
|
fn length(&self) -> f32 {
|
|
(self.x * self.x + self.y * self.y).sqrt()
|
|
}
|
|
|
|
fn normalize(&self) -> Self {
|
|
let factor = 1.0 / self.length();
|
|
v2 {
|
|
x: factor * self.x,
|
|
y: factor * self.y,
|
|
}
|
|
}
|
|
|
|
fn normalize_mut(&mut self) {
|
|
let factor = 1.0 / self.length();
|
|
self.x *= factor;
|
|
self.y *= factor;
|
|
}
|
|
|
|
fn project_onto(&self, other: &Self) -> Self {
|
|
let factor = self.dot(other) / other.dot(other);
|
|
*other * factor
|
|
}
|
|
|
|
fn reflect(&self, normal: &Self) -> Self {
|
|
*self - *normal * 2.0 * self.dot(normal)
|
|
}
|
|
|
|
fn lerp(&self, other: &Self, t: f32) -> Self {
|
|
*self * (1.0 - t) + *other * t
|
|
}
|
|
|
|
fn to_point(&self) -> impl Point {
|
|
p2::new(self.x, self.y)
|
|
}
|
|
}
|
|
|
|
impl InnerSpace for v3 {
|
|
fn dot(&self, other: &Self) -> f32 {
|
|
self.x * other.x + self.y * other.y + self.z * other.z
|
|
}
|
|
|
|
fn dist(&self, other: &Self) -> f32 {
|
|
v3 {
|
|
x: other.x - self.x,
|
|
y: other.y - self.y,
|
|
z: other.z - self.z,
|
|
}
|
|
.length()
|
|
}
|
|
|
|
fn angle(&self, other: &Self) -> f32 {
|
|
(self.dot(other) / (self.length() * other.length())).acos()
|
|
}
|
|
|
|
fn length(&self) -> f32 {
|
|
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
|
|
}
|
|
|
|
fn normalize(&self) -> Self {
|
|
let factor = 1.0 / self.length();
|
|
v3 {
|
|
x: factor * self.x,
|
|
y: factor * self.y,
|
|
z: factor * self.z,
|
|
}
|
|
}
|
|
|
|
fn normalize_mut(&mut self) {
|
|
let factor = 1.0 / self.length();
|
|
self.x *= factor;
|
|
self.y *= factor;
|
|
self.z *= factor;
|
|
}
|
|
|
|
fn project_onto(&self, other: &Self) -> Self {
|
|
let factor = self.dot(other) / other.dot(other);
|
|
*other * factor
|
|
}
|
|
|
|
fn reflect(&self, normal: &Self) -> Self {
|
|
*self - *normal * 2.0 * self.dot(normal)
|
|
}
|
|
|
|
fn lerp(&self, other: &Self, t: f32) -> Self {
|
|
*self * (1.0 - t) + *other * t
|
|
}
|
|
|
|
fn to_point(&self) -> impl Point {
|
|
p3::new(self.x, self.y, self.z)
|
|
}
|
|
}
|
|
|
|
impl InnerSpace for v4 {
|
|
fn dot(&self, other: &Self) -> f32 {
|
|
self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
|
|
}
|
|
|
|
fn dist(&self, other: &Self) -> f32 {
|
|
v4 {
|
|
x: other.x - self.x,
|
|
y: other.y - self.y,
|
|
z: other.z - self.z,
|
|
w: other.w - self.w,
|
|
}
|
|
.length()
|
|
}
|
|
|
|
fn angle(&self, other: &Self) -> f32 {
|
|
(self.dot(other) / (self.length() * other.length())).acos()
|
|
}
|
|
|
|
fn length(&self) -> f32 {
|
|
(self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt()
|
|
}
|
|
|
|
fn normalize(&self) -> Self {
|
|
let factor = 1.0 / self.length();
|
|
v4 {
|
|
x: factor * self.x,
|
|
y: factor * self.y,
|
|
z: factor * self.z,
|
|
w: factor * self.w,
|
|
}
|
|
}
|
|
|
|
fn normalize_mut(&mut self) {
|
|
let factor = 1.0 / self.length();
|
|
self.x *= factor;
|
|
self.y *= factor;
|
|
self.z *= factor;
|
|
self.w *= factor;
|
|
}
|
|
|
|
fn project_onto(&self, other: &Self) -> Self {
|
|
let factor = self.dot(other) / other.dot(other);
|
|
*other * factor
|
|
}
|
|
|
|
fn reflect(&self, normal: &Self) -> Self {
|
|
*self - *normal * 2.0 * self.dot(normal)
|
|
}
|
|
|
|
fn lerp(&self, other: &Self, t: f32) -> Self {
|
|
*self * (1.0 - t) + *other * t
|
|
}
|
|
|
|
fn to_point(&self) -> impl Point {
|
|
p3::new(self.x / self.w, self.y / self.w, self.z / self.w)
|
|
}
|
|
}
|
|
|
|
macro_rules! generate_swizzles2 {
|
|
($VecType:ident, $($name:ident => ($a:ident, $b:ident)),* $(,)?) => {
|
|
impl $VecType {
|
|
$(
|
|
pub fn $name(&self) -> Self {
|
|
Self {
|
|
x: self.$a,
|
|
y: self.$b,
|
|
}
|
|
}
|
|
)*
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! generate_swizzles3 {
|
|
($VecType:ident, $($name:ident => ($a:ident, $b:ident, $c:ident)),* $(,)?) => {
|
|
impl $VecType {
|
|
$(
|
|
pub fn $name(&self) -> Self {
|
|
Self {
|
|
x: self.$a,
|
|
y: self.$b,
|
|
z: self.$c
|
|
}
|
|
}
|
|
)*
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! generate_swizzles4 {
|
|
($VecType:ident, $($name:ident => ($a:ident, $b:ident, $c:ident, $d:ident)),* $(,)?) => {
|
|
impl $VecType {
|
|
$(
|
|
pub fn $name(&self) -> Self {
|
|
Self {
|
|
x: self.$a,
|
|
y: self.$b,
|
|
z: self.$c,
|
|
w: self.$d
|
|
}
|
|
}
|
|
)*
|
|
}
|
|
};
|
|
}
|
|
|
|
generate_swizzles2!(v2,
|
|
xx => (x, x), xy => (x, y),
|
|
yx => (y, x), yy => (y, y)
|
|
);
|
|
|
|
generate_swizzles3!(v3,
|
|
xxx => (x, x, x), xxy => (x, x, y), xxz => (x, x, z),
|
|
xyx => (x, y, x), xyy => (x, y, y), xyz => (x, y, z),
|
|
xzx => (x, z, x), xzy => (x, z, y), xzz => (x, z, z),
|
|
yxx => (y, x, x), yxy => (y, x, y), yxz => (y, x, z),
|
|
yyx => (y, y, x), yyy => (y, y, y), yyz => (y, y, z),
|
|
yzx => (y, z, x), yzy => (y, z, y), yzz => (y, z, z),
|
|
zxx => (z, x, x), zxy => (z, x, y), zxz => (z, x, z),
|
|
zyx => (z, y, x), zyy => (z, y, y), zyz => (z, y, z),
|
|
zzx => (z, z, x), zzy => (z, z, y), zzz => (z, z, z)
|
|
);
|
|
|
|
generate_swizzles4!(v4,
|
|
xxxx => (x, x, x, x), xxxy => (x, x, x, y), xxxz => (x, x, x, z), xxxw => (x, x, x, w),
|
|
xxyx => (x, x, y, x), xxyy => (x, x, y, y), xxyz => (x, x, y, z), xxyw => (x, x, y, w),
|
|
xxzx => (x, x, z, x), xxzy => (x, x, z, y), xxzz => (x, x, z, z), xxzw => (x, x, z, w),
|
|
xxwx => (x, x, w, x), xxwy => (x, x, w, y), xxwz => (x, x, w, z), xxww => (x, x, w, w),
|
|
xyxx => (x, y, x, x), xyxy => (x, y, x, y), xyxz => (x, y, x, z), xyxw => (x, y, x, w),
|
|
xyyx => (x, y, y, x), xyyy => (x, y, y, y), xyyz => (x, y, y, z), xyyw => (x, y, y, w),
|
|
xyzx => (x, y, z, x), xyzy => (x, y, z, y), xyzz => (x, y, z, z), xyzw => (x, y, z, w),
|
|
xywx => (x, y, w, x), xywy => (x, y, w, y), xywz => (x, y, w, z), xyww => (x, y, w, w),
|
|
xzxx => (x, z, x, x), xzxy => (x, z, x, y), xzxz => (x, z, x, z), xzxw => (x, z, x, w),
|
|
xzyx => (x, z, y, x), xzyy => (x, z, y, y), xzyz => (x, z, y, z), xzyw => (x, z, y, w),
|
|
xzzx => (x, z, z, x), xzzy => (x, z, z, y), xzzz => (x, z, z, z), xzzw => (x, z, z, w),
|
|
xzwx => (x, z, w, x), xzwy => (x, z, w, y), xzwz => (x, z, w, z), xzww => (x, z, w, w),
|
|
xwxx => (x, w, x, x), xwxy => (x, w, x, y), xwxz => (x, w, x, z), xwxw => (x, w, x, w),
|
|
xwyx => (x, w, y, x), xwyy => (x, w, y, y), xwyz => (x, w, y, z), xwyw => (x, w, y, w),
|
|
xwzx => (x, w, z, x), xwzy => (x, w, z, y), xwzz => (x, w, z, z), xwzw => (x, w, z, w),
|
|
xwwx => (x, w, w, x), xwwy => (x, w, w, y), xwwz => (x, w, w, z), xwww => (x, w, w, w),
|
|
yxxx => (y, x, x, x), yxxy => (y, x, x, y), yxxz => (y, x, x, z), yxxw => (y, x, x, w),
|
|
yxyx => (y, x, y, x), yxyy => (y, x, y, y), yxyz => (y, x, y, z), yxyw => (y, x, y, w),
|
|
yxzx => (y, x, z, x), yxzy => (y, x, z, y), yxzz => (y, x, z, z), yxzw => (y, x, z, w),
|
|
yxwx => (y, x, w, x), yxwy => (y, x, w, y), yxwz => (y, x, w, z), yxww => (y, x, w, w),
|
|
yyxx => (y, y, x, x), yyxy => (y, y, x, y), yyxz => (y, y, x, z), yyxw => (y, y, x, w),
|
|
yyyx => (y, y, y, x), yyyy => (y, y, y, y), yyyz => (y, y, y, z), yyyw => (y, y, y, w),
|
|
yyzx => (y, y, z, x), yyzy => (y, y, z, y), yyzz => (y, y, z, z), yyzw => (y, y, z, w),
|
|
yywx => (y, y, w, x), yywy => (y, y, w, y), yywz => (y, y, w, z), yyww => (y, y, w, w)
|
|
);
|