Skip to main content

box3d_rust/math_functions/
types.rs

1// Math types, constants, and operator overloads.
2// Part of the math_functions module (see mod.rs).
3
4/// A 2D vector.
5#[derive(Debug, Clone, Copy, PartialEq, Default)]
6pub struct Vec2 {
7    pub x: f32,
8    pub y: f32,
9}
10
11/// A 3D vector.
12#[derive(Debug, Clone, Copy, PartialEq, Default)]
13pub struct Vec3 {
14    pub x: f32,
15    pub y: f32,
16    pub z: f32,
17}
18
19/// Cosine and sine pair.
20/// This uses a custom implementation designed for cross-platform determinism.
21#[derive(Debug, Clone, Copy, PartialEq)]
22pub struct CosSin {
23    /// cosine and sine
24    pub cosine: f32,
25    pub sine: f32,
26}
27
28/// A quaternion.
29#[derive(Debug, Clone, Copy, PartialEq)]
30pub struct Quat {
31    pub v: Vec3,
32    pub s: f32,
33}
34
35/// A rigid transform.
36#[derive(Debug, Clone, Copy, PartialEq)]
37pub struct Transform {
38    pub p: Vec3,
39    pub q: Quat,
40}
41
42/// A world position. Double precision in large world mode so coordinates stay accurate far
43/// from the origin.
44#[cfg(feature = "double-precision")]
45#[derive(Debug, Clone, Copy, PartialEq, Default)]
46pub struct Pos {
47    pub x: f64,
48    pub y: f64,
49    pub z: f64,
50}
51
52/// A world transform with double precision translation and float quaternion rotation. Rotation
53/// is frame local and never needs the extra range, the same split as Jolt's DMat44.
54#[cfg(feature = "double-precision")]
55#[derive(Debug, Clone, Copy, PartialEq)]
56pub struct WorldTransform {
57    pub p: Pos,
58    pub q: Quat,
59}
60
61#[cfg(not(feature = "double-precision"))]
62pub type Pos = Vec3;
63
64#[cfg(not(feature = "double-precision"))]
65pub type WorldTransform = Transform;
66
67/// A 3x3 matrix.
68#[derive(Debug, Clone, Copy, PartialEq)]
69pub struct Matrix3 {
70    pub cx: Vec3,
71    pub cy: Vec3,
72    pub cz: Vec3,
73}
74
75/// Axis aligned bounding box.
76#[derive(Debug, Clone, Copy, PartialEq, Default)]
77pub struct Aabb {
78    pub lower_bound: Vec3,
79    pub upper_bound: Vec3,
80}
81
82/// A plane.
83/// separation = dot(normal, point) - offset
84#[derive(Debug, Clone, Copy, PartialEq)]
85pub struct Plane {
86    pub normal: Vec3,
87    pub offset: f32,
88}
89
90/// The closest points between two segments or infinite lines.
91#[derive(Debug, Clone, Copy, PartialEq)]
92pub struct SegmentDistanceResult {
93    pub point1: Vec3,
94    pub fraction1: f32,
95    pub point2: Vec3,
96    pub fraction2: f32,
97}
98
99/// <https://en.wikipedia.org/wiki/Pi>
100/// The C `B3_PI` literal (3.14159265359f) rounds to exactly this f32 value.
101pub const PI: f32 = core::f32::consts::PI;
102
103/// Convenience constant to convert from degrees to radians. (B3_DEG_TO_RAD)
104pub const DEG_TO_RAD: f32 = 0.01745329251;
105
106/// Convenience constant to convert from radians to degrees. (B3_RAD_TO_DEG)
107pub const RAD_TO_DEG: f32 = 57.2957795131;
108
109/// Minimum scale used for scaling collision meshes, etc. (B3_MIN_SCALE)
110pub const MIN_SCALE: f32 = 0.01;
111
112pub const VEC2_ZERO: Vec2 = Vec2 { x: 0.0, y: 0.0 };
113
114pub const VEC3_ZERO: Vec3 = Vec3 {
115    x: 0.0,
116    y: 0.0,
117    z: 0.0,
118};
119pub const VEC3_ONE: Vec3 = Vec3 {
120    x: 1.0,
121    y: 1.0,
122    z: 1.0,
123};
124pub const VEC3_AXIS_X: Vec3 = Vec3 {
125    x: 1.0,
126    y: 0.0,
127    z: 0.0,
128};
129pub const VEC3_AXIS_Y: Vec3 = Vec3 {
130    x: 0.0,
131    y: 1.0,
132    z: 0.0,
133};
134pub const VEC3_AXIS_Z: Vec3 = Vec3 {
135    x: 0.0,
136    y: 0.0,
137    z: 1.0,
138};
139pub const QUAT_IDENTITY: Quat = Quat {
140    v: Vec3 {
141        x: 0.0,
142        y: 0.0,
143        z: 0.0,
144    },
145    s: 1.0,
146};
147pub const TRANSFORM_IDENTITY: Transform = Transform {
148    p: Vec3 {
149        x: 0.0,
150        y: 0.0,
151        z: 0.0,
152    },
153    q: Quat {
154        v: Vec3 {
155            x: 0.0,
156            y: 0.0,
157            z: 0.0,
158        },
159        s: 1.0,
160    },
161};
162pub const MAT3_ZERO: Matrix3 = Matrix3 {
163    cx: Vec3 {
164        x: 0.0,
165        y: 0.0,
166        z: 0.0,
167    },
168    cy: Vec3 {
169        x: 0.0,
170        y: 0.0,
171        z: 0.0,
172    },
173    cz: Vec3 {
174        x: 0.0,
175        y: 0.0,
176        z: 0.0,
177    },
178};
179pub const MAT3_IDENTITY: Matrix3 = Matrix3 {
180    cx: Vec3 {
181        x: 1.0,
182        y: 0.0,
183        z: 0.0,
184    },
185    cy: Vec3 {
186        x: 0.0,
187        y: 1.0,
188        z: 0.0,
189    },
190    cz: Vec3 {
191        x: 0.0,
192        y: 0.0,
193        z: 1.0,
194    },
195};
196
197// Valid in both modes: 0.0f promotes to double, the identity rotation stays float
198#[cfg(feature = "double-precision")]
199pub const POS_ZERO: Pos = Pos {
200    x: 0.0,
201    y: 0.0,
202    z: 0.0,
203};
204#[cfg(not(feature = "double-precision"))]
205pub const POS_ZERO: Pos = VEC3_ZERO;
206
207#[cfg(feature = "double-precision")]
208pub const WORLD_TRANSFORM_IDENTITY: WorldTransform = WorldTransform {
209    p: Pos {
210        x: 0.0,
211        y: 0.0,
212        z: 0.0,
213    },
214    q: Quat {
215        v: Vec3 {
216            x: 0.0,
217            y: 0.0,
218            z: 0.0,
219        },
220        s: 1.0,
221    },
222};
223#[cfg(not(feature = "double-precision"))]
224pub const WORLD_TRANSFORM_IDENTITY: WorldTransform = TRANSFORM_IDENTITY;
225
226impl Vec2 {
227    pub const fn new(x: f32, y: f32) -> Self {
228        Vec2 { x, y }
229    }
230}
231
232impl Vec3 {
233    pub const fn new(x: f32, y: f32, z: f32) -> Self {
234        Vec3 { x, y, z }
235    }
236}
237
238impl Quat {
239    pub const fn new(v: Vec3, s: f32) -> Self {
240        Quat { v, s }
241    }
242}
243
244impl Transform {
245    pub const fn new(p: Vec3, q: Quat) -> Self {
246        Transform { p, q }
247    }
248}
249
250// Operator overloads mirroring the C++ operators in math_functions.h
251
252impl core::ops::AddAssign for Vec3 {
253    fn add_assign(&mut self, b: Vec3) {
254        self.x += b.x;
255        self.y += b.y;
256        self.z += b.z;
257    }
258}
259
260impl core::ops::SubAssign for Vec3 {
261    fn sub_assign(&mut self, b: Vec3) {
262        self.x -= b.x;
263        self.y -= b.y;
264        self.z -= b.z;
265    }
266}
267
268impl core::ops::MulAssign<f32> for Vec3 {
269    fn mul_assign(&mut self, b: f32) {
270        self.x *= b;
271        self.y *= b;
272        self.z *= b;
273    }
274}
275
276impl core::ops::Neg for Vec3 {
277    type Output = Vec3;
278    fn neg(self) -> Vec3 {
279        Vec3 {
280            x: -self.x,
281            y: -self.y,
282            z: -self.z,
283        }
284    }
285}
286
287impl core::ops::Add for Vec3 {
288    type Output = Vec3;
289    fn add(self, b: Vec3) -> Vec3 {
290        Vec3 {
291            x: self.x + b.x,
292            y: self.y + b.y,
293            z: self.z + b.z,
294        }
295    }
296}
297
298impl core::ops::Sub for Vec3 {
299    type Output = Vec3;
300    fn sub(self, b: Vec3) -> Vec3 {
301        Vec3 {
302            x: self.x - b.x,
303            y: self.y - b.y,
304            z: self.z - b.z,
305        }
306    }
307}
308
309impl core::ops::Mul<Vec3> for f32 {
310    type Output = Vec3;
311    fn mul(self, b: Vec3) -> Vec3 {
312        Vec3 {
313            x: self * b.x,
314            y: self * b.y,
315            z: self * b.z,
316        }
317    }
318}
319
320impl core::ops::Mul<f32> for Vec3 {
321    type Output = Vec3;
322    fn mul(self, b: f32) -> Vec3 {
323        Vec3 {
324            x: self.x * b,
325            y: self.y * b,
326            z: self.z * b,
327        }
328    }
329}
330
331impl core::ops::Mul for Vec3 {
332    type Output = Vec3;
333    fn mul(self, b: Vec3) -> Vec3 {
334        Vec3 {
335            x: self.x * b.x,
336            y: self.y * b.y,
337            z: self.z * b.z,
338        }
339    }
340}