classicube_sys\vectors\vec/
mod.rs

1mod ops;
2
3use crate::{
4    bindings::*,
5    std_types::{c_float, cosf, floorf, sinf, sqrtf},
6    Vec3_IsZero, Vec3_Set,
7};
8
9impl Vec3 {
10    pub const fn new(x: c_float, y: c_float, z: c_float) -> Self {
11        Self { x, y, z }
12    }
13
14    pub const fn zero() -> Self {
15        Self {
16            x: 0.0,
17            y: 0.0,
18            z: 0.0,
19        }
20    }
21
22    pub const fn big_pos() -> Self {
23        Vec3_BigPos()
24    }
25
26    pub const fn create(x: c_float, y: c_float, z: c_float) -> Self {
27        Vec3_Create3(x, y, z)
28    }
29
30    pub fn set(&mut self, x: c_float, y: c_float, z: c_float) {
31        Vec3_Set!(self, x, y, z);
32    }
33
34    pub fn is_zero(&self) -> bool {
35        Vec3_IsZero!(self)
36    }
37
38    pub fn length_squared(&self) -> c_float {
39        Vec3_LengthSquared(self)
40    }
41
42    #[must_use]
43    pub fn lerp(&self, b: Vec3, blend: c_float) -> Self {
44        let mut result = Self::zero();
45        Vec3_Lerp(&mut result, self, &b, blend);
46        result
47    }
48
49    #[must_use]
50    pub fn normalize(&self) -> Self {
51        let mut result = Self::zero();
52        Vec3_Normalize(&mut result, self);
53        result
54    }
55
56    #[must_use]
57    pub fn transform(&self, mat: Matrix) -> Self {
58        let mut result = Self::zero();
59        Vec3_Transform(&mut result, self, &mat);
60        result
61    }
62
63    pub fn transform_y(y: c_float, mat: Matrix) -> Self {
64        let mut result = Self::zero();
65        Vec3_TransformY(&mut result, y, &mat);
66        result
67    }
68
69    pub fn rotate_x(v: Vec3, angle: c_float) -> Self {
70        Vec3_RotateX(v, angle)
71    }
72
73    pub fn rotate_y(v: Vec3, angle: c_float) -> Self {
74        Vec3_RotateY(v, angle)
75    }
76
77    pub fn rotate_y3(x: c_float, y: c_float, z: c_float, angle: c_float) -> Self {
78        Vec3_RotateY3(x, y, z, angle)
79    }
80
81    pub fn rotate_z(v: Vec3, angle: c_float) -> Self {
82        Vec3_RotateZ(v, angle)
83    }
84
85    pub fn floor(&self) -> IVec3 {
86        let mut result = IVec3::zero();
87        IVec3_Floor(&mut result, self);
88        result
89    }
90
91    pub fn get_dir_vector(yawRad: c_float, pitchRad: c_float) -> Self {
92        Vec3_GetDirVector(yawRad, pitchRad)
93    }
94}
95
96pub const fn Vec3_BigPos() -> Vec3 {
97    Vec3 {
98        x: 1e25_f32,
99        y: 1e25_f32,
100        z: 1e25_f32,
101    }
102}
103
104pub const fn Vec3_Create3(x: c_float, y: c_float, z: c_float) -> Vec3 {
105    Vec3 { x, y, z }
106}
107
108/// Returns the squared length of the vector.
109/// Squared length can be used for comparison, to avoid a costly sqrt()
110/// However, you must sqrt() this when adding lengths.
111pub fn Vec3_LengthSquared(v: &Vec3) -> c_float {
112    v.x * v.x + v.y * v.y + v.z * v.z
113}
114
115/// Linearly interpolates components of two vectors.
116pub fn Vec3_Lerp(result: &mut Vec3, a: &Vec3, b: &Vec3, blend: c_float) {
117    result.x = blend * (b.x - a.x) + a.x;
118    result.y = blend * (b.y - a.y) + a.y;
119    result.z = blend * (b.z - a.z) + a.z;
120}
121
122/// Scales all components of a vector to lie in [-1, 1]
123pub fn Vec3_Normalize(result: &mut Vec3, a: &Vec3) {
124    let lenSquared = a.x * a.x + a.y * a.y + a.z * a.z;
125    let scale = 1.0 / sqrtf(lenSquared);
126    result.x = a.x * scale;
127    result.y = a.y * scale;
128    result.z = a.z * scale;
129}
130
131/// Transforms a vector by the given matrix.
132pub fn Vec3_Transform(result: &mut Vec3, a: &Vec3, mat: &Matrix) {
133    // a could be pointing to result - can't directly assign x/y/z therefore
134    let x = a.x * mat.row1.x + a.y * mat.row2.x + a.z * mat.row3.x + mat.row4.x;
135    let y = a.x * mat.row1.y + a.y * mat.row2.y + a.z * mat.row3.y + mat.row4.y;
136    let z = a.x * mat.row1.z + a.y * mat.row2.z + a.z * mat.row3.z + mat.row4.z;
137    result.x = x;
138    result.y = y;
139    result.z = z;
140}
141
142/// Same as Vec3_Transform, but faster since x and z are assumed as 0.
143pub fn Vec3_TransformY(result: &mut Vec3, y: c_float, mat: &Matrix) {
144    result.x = y * mat.row2.x + mat.row4.x;
145    result.y = y * mat.row2.y + mat.row4.y;
146    result.z = y * mat.row2.z + mat.row4.z;
147}
148
149pub fn Vec3_RotateX(v: Vec3, angle: c_float) -> Vec3 {
150    let cosA = cosf(angle);
151    let sinA = sinf(angle);
152    Vec3_Create3(v.x, cosA * v.y + sinA * v.z, -sinA * v.y + cosA * v.z)
153}
154
155pub fn Vec3_RotateY(v: Vec3, angle: c_float) -> Vec3 {
156    let cosA = cosf(angle);
157    let sinA = sinf(angle);
158    Vec3_Create3(cosA * v.x - sinA * v.z, v.y, sinA * v.x + cosA * v.z)
159}
160
161pub fn Vec3_RotateY3(x: c_float, y: c_float, z: c_float, angle: c_float) -> Vec3 {
162    let cosA = cosf(angle);
163    let sinA = sinf(angle);
164    Vec3_Create3(cosA * x - sinA * z, y, sinA * x + cosA * z)
165}
166
167pub fn Vec3_RotateZ(v: Vec3, angle: c_float) -> Vec3 {
168    let cosA = cosf(angle);
169    let sinA = sinf(angle);
170    Vec3_Create3(cosA * v.x + sinA * v.y, -sinA * v.x + cosA * v.y, v.z)
171}
172
173/// Whether all of the components of the two vectors are equal.
174pub fn Vec3_Equals(a: &Vec3, b: &Vec3) -> bool {
175    #[allow(clippy::float_cmp)]
176    {
177        a.x == b.x && a.y == b.y && a.z == b.z
178    }
179}
180
181pub fn IVec3_Floor(result: &mut IVec3, a: &Vec3) {
182    result.x = floorf(a.x) as _;
183    result.y = floorf(a.y) as _;
184    result.z = floorf(a.z) as _;
185}
186
187/// Returns a normalised vector facing in the direction described by the given yaw and pitch.
188pub fn Vec3_GetDirVector(yawRad: c_float, pitchRad: c_float) -> Vec3 {
189    let x = -cosf(pitchRad) * -sinf(yawRad);
190    let y = -sinf(pitchRad);
191    let z = -cosf(pitchRad) * cosf(yawRad);
192    Vec3_Create3(x, y, z)
193}