ue_types/
vector.rs

1//! Vector types and utilities
2
3use crate::BinarySerializable;
4use glam::{Vec2, Vec3, Vec4};
5use serde::{Deserialize, Serialize};
6use std::fmt;
7
8/// 3D Vector representing position, velocity, direction, etc.
9/// This is the most commonly used vector type in UE.
10pub type Vector = Vec3;
11
12/// 2D Vector for UI coordinates, texture coordinates, etc.
13pub type Vector2D = Vec2;
14
15/// 4D Vector for homogeneous coordinates, RGBA colors, etc.
16pub type Vector4 = Vec4;
17
18/// Quaternion for rotations (preferred over Rotator for math operations)
19pub type Quaternion = glam::Quat;
20
21/// 3x3 Matrix
22pub type Matrix3 = glam::Mat3;
23
24/// 4x4 Matrix for transformations
25pub type Matrix4 = glam::Mat4;
26
27// Implement BinarySerializable for glam types
28impl BinarySerializable for Vector {}
29impl BinarySerializable for Vector2D {}
30impl BinarySerializable for Vector4 {}
31impl BinarySerializable for Quaternion {}
32impl BinarySerializable for Matrix3 {}
33impl BinarySerializable for Matrix4 {}
34
35/// UE-style vector constants and utility functions
36pub struct VectorConstants;
37
38impl VectorConstants {
39    /// Forward vector (positive X)
40    pub const FORWARD: Vector = Vec3::X;
41    
42    /// Right vector (positive Y)  
43    pub const RIGHT: Vector = Vec3::Y;
44    
45    /// Up vector (positive Z)
46    pub const UP: Vector = Vec3::Z;
47    
48    /// Zero vector
49    pub const ZERO: Vector = Vec3::ZERO;
50    
51    /// One vector (1, 1, 1)
52    pub const ONE: Vector = Vec3::ONE;
53}
54
55/// Extension trait for Vector operations common in UE
56pub trait VectorExt {
57    /// Get the size (magnitude) of the vector
58    fn size(self) -> f32;
59    
60    /// Get the squared size (magnitude squared) - faster than size()
61    fn size_squared(self) -> f32;
62    
63    /// Check if the vector is nearly zero
64    fn is_nearly_zero(self, tolerance: f32) -> bool;
65    
66    /// Check if the vector is normalized (unit length)
67    fn is_normalized(self) -> bool;
68    
69    /// Get a normalized copy of the vector
70    fn get_safe_normal(self, tolerance: f32) -> Vector;
71}
72
73impl VectorExt for Vector {
74    fn size(self) -> f32 {
75        self.length()
76    }
77    
78    fn size_squared(self) -> f32 {
79        self.length_squared()
80    }
81    
82    fn is_nearly_zero(self, tolerance: f32) -> bool {
83        self.length_squared() <= tolerance * tolerance
84    }
85    
86    fn is_normalized(self) -> bool {
87        (self.length_squared() - 1.0).abs() < 0.01
88    }
89    
90    fn get_safe_normal(self, tolerance: f32) -> Vector {
91        let square_sum = self.length_squared();
92        if square_sum == 1.0 {
93            return self;
94        } else if square_sum < tolerance * tolerance {
95            return Vector::ZERO;
96        }
97        self.normalize()
98    }
99}
100
101/// Extension trait for Vector2D operations
102pub trait Vector2DExt {
103    /// Get the size (magnitude) of the 2D vector
104    fn size(self) -> f32;
105    
106    /// Get the squared size (magnitude squared)
107    fn size_squared(self) -> f32;
108    
109    /// Check if the vector is nearly zero
110    fn is_nearly_zero(self, tolerance: f32) -> bool;
111}
112
113impl Vector2DExt for Vector2D {
114    fn size(self) -> f32 {
115        self.length()
116    }
117    
118    fn size_squared(self) -> f32 {
119        self.length_squared()
120    }
121    
122    fn is_nearly_zero(self, tolerance: f32) -> bool {
123        self.length_squared() <= tolerance * tolerance
124    }
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130
131    #[test]
132    fn test_vector_constants() {
133        assert_eq!(VectorConstants::FORWARD, Vec3::new(1.0, 0.0, 0.0));
134        assert_eq!(VectorConstants::RIGHT, Vec3::new(0.0, 1.0, 0.0));
135        assert_eq!(VectorConstants::UP, Vec3::new(0.0, 0.0, 1.0));
136    }
137
138    #[test]
139    fn test_vector_ext() {
140        let v = Vector::new(3.0, 4.0, 0.0);
141        assert_eq!(v.size(), 5.0);
142        assert_eq!(v.size_squared(), 25.0);
143        assert!(!v.is_nearly_zero(0.1));
144        
145        let normalized = v.get_safe_normal(0.001);
146        assert!(normalized.is_normalized());
147    }
148}