use crate::BinarySerializable;
use glam::{Vec2, Vec3, Vec4};
use serde::{Deserialize, Serialize};
use std::fmt;
pub type Vector = Vec3;
pub type Vector2D = Vec2;
pub type Vector4 = Vec4;
pub type Quaternion = glam::Quat;
pub type Matrix3 = glam::Mat3;
pub type Matrix4 = glam::Mat4;
impl BinarySerializable for Vector {}
impl BinarySerializable for Vector2D {}
impl BinarySerializable for Vector4 {}
impl BinarySerializable for Quaternion {}
impl BinarySerializable for Matrix3 {}
impl BinarySerializable for Matrix4 {}
pub struct VectorConstants;
impl VectorConstants {
pub const FORWARD: Vector = Vec3::X;
pub const RIGHT: Vector = Vec3::Y;
pub const UP: Vector = Vec3::Z;
pub const ZERO: Vector = Vec3::ZERO;
pub const ONE: Vector = Vec3::ONE;
}
pub trait VectorExt {
fn size(self) -> f32;
fn size_squared(self) -> f32;
fn is_nearly_zero(self, tolerance: f32) -> bool;
fn is_normalized(self) -> bool;
fn get_safe_normal(self, tolerance: f32) -> Vector;
}
impl VectorExt for Vector {
fn size(self) -> f32 {
self.length()
}
fn size_squared(self) -> f32 {
self.length_squared()
}
fn is_nearly_zero(self, tolerance: f32) -> bool {
self.length_squared() <= tolerance * tolerance
}
fn is_normalized(self) -> bool {
(self.length_squared() - 1.0).abs() < 0.01
}
fn get_safe_normal(self, tolerance: f32) -> Vector {
let square_sum = self.length_squared();
if square_sum == 1.0 {
return self;
} else if square_sum < tolerance * tolerance {
return Vector::ZERO;
}
self.normalize()
}
}
pub trait Vector2DExt {
fn size(self) -> f32;
fn size_squared(self) -> f32;
fn is_nearly_zero(self, tolerance: f32) -> bool;
}
impl Vector2DExt for Vector2D {
fn size(self) -> f32 {
self.length()
}
fn size_squared(self) -> f32 {
self.length_squared()
}
fn is_nearly_zero(self, tolerance: f32) -> bool {
self.length_squared() <= tolerance * tolerance
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vector_constants() {
assert_eq!(VectorConstants::FORWARD, Vec3::new(1.0, 0.0, 0.0));
assert_eq!(VectorConstants::RIGHT, Vec3::new(0.0, 1.0, 0.0));
assert_eq!(VectorConstants::UP, Vec3::new(0.0, 0.0, 1.0));
}
#[test]
fn test_vector_ext() {
let v = Vector::new(3.0, 4.0, 0.0);
assert_eq!(v.size(), 5.0);
assert_eq!(v.size_squared(), 25.0);
assert!(!v.is_nearly_zero(0.1));
let normalized = v.get_safe_normal(0.001);
assert!(normalized.is_normalized());
}
}