Skip to main content

box2d_rust/math_functions/
types.rs

1// Math types, constants, and operator overloads.
2// Part of the math_functions module (see mod.rs).
3
4/// 2D vector
5/// This can be used to represent a point or free vector
6#[derive(Debug, Clone, Copy, PartialEq, Default)]
7pub struct Vec2 {
8    pub x: f32,
9    pub y: f32,
10}
11
12/// Cosine and sine pair
13/// This uses a custom implementation designed for cross-platform determinism
14#[derive(Debug, Clone, Copy, PartialEq)]
15pub struct CosSin {
16    pub cosine: f32,
17    pub sine: f32,
18}
19
20/// 2D rotation
21/// This is similar to using a complex number for rotation
22#[derive(Debug, Clone, Copy, PartialEq)]
23pub struct Rot {
24    pub c: f32,
25    pub s: f32,
26}
27
28/// A 2D rigid transform
29#[derive(Debug, Clone, Copy, PartialEq)]
30pub struct Transform {
31    pub p: Vec2,
32    pub q: Rot,
33}
34
35/// A world position. Double precision in large world mode so coordinates stay accurate far
36/// from the origin.
37#[cfg(feature = "double-precision")]
38#[derive(Debug, Clone, Copy, PartialEq, Default)]
39pub struct Pos {
40    pub x: f64,
41    pub y: f64,
42}
43
44/// A world transform with double precision translation and float rotation. Rotation is frame
45/// local and never needs the extra range, the same split as Jolt's DMat44.
46#[cfg(feature = "double-precision")]
47#[derive(Debug, Clone, Copy, PartialEq)]
48pub struct WorldTransform {
49    pub p: Pos,
50    pub q: Rot,
51}
52
53#[cfg(not(feature = "double-precision"))]
54pub type Pos = Vec2;
55
56#[cfg(not(feature = "double-precision"))]
57pub type WorldTransform = Transform;
58
59/// A 2-by-2 Matrix stored as columns
60#[derive(Debug, Clone, Copy, PartialEq)]
61pub struct Mat22 {
62    pub cx: Vec2,
63    pub cy: Vec2,
64}
65
66/// Axis-aligned bounding box
67#[derive(Debug, Clone, Copy, PartialEq, Default)]
68pub struct Aabb {
69    pub lower_bound: Vec2,
70    pub upper_bound: Vec2,
71}
72
73/// separation = dot(normal, point) - offset
74#[derive(Debug, Clone, Copy, PartialEq)]
75pub struct Plane {
76    pub normal: Vec2,
77    pub offset: f32,
78}
79
80/// <https://en.wikipedia.org/wiki/Pi>
81/// The C `B2_PI` literal (3.14159265359f) rounds to exactly this f32 value.
82pub const PI: f32 = core::f32::consts::PI;
83
84pub const VEC2_ZERO: Vec2 = Vec2 { x: 0.0, y: 0.0 };
85pub const ROT_IDENTITY: Rot = Rot { c: 1.0, s: 0.0 };
86pub const TRANSFORM_IDENTITY: Transform = Transform {
87    p: Vec2 { x: 0.0, y: 0.0 },
88    q: Rot { c: 1.0, s: 0.0 },
89};
90pub const MAT22_ZERO: Mat22 = Mat22 {
91    cx: Vec2 { x: 0.0, y: 0.0 },
92    cy: Vec2 { x: 0.0, y: 0.0 },
93};
94
95#[cfg(feature = "double-precision")]
96pub const POS_ZERO: Pos = Pos { x: 0.0, y: 0.0 };
97#[cfg(not(feature = "double-precision"))]
98pub const POS_ZERO: Pos = VEC2_ZERO;
99
100#[cfg(feature = "double-precision")]
101pub const WORLD_TRANSFORM_IDENTITY: WorldTransform = WorldTransform {
102    p: Pos { x: 0.0, y: 0.0 },
103    q: Rot { c: 1.0, s: 0.0 },
104};
105#[cfg(not(feature = "double-precision"))]
106pub const WORLD_TRANSFORM_IDENTITY: WorldTransform = TRANSFORM_IDENTITY;
107
108impl Vec2 {
109    pub const fn new(x: f32, y: f32) -> Self {
110        Vec2 { x, y }
111    }
112}
113
114impl Rot {
115    pub const fn new(c: f32, s: f32) -> Self {
116        Rot { c, s }
117    }
118}
119
120impl Transform {
121    pub const fn new(p: Vec2, q: Rot) -> Self {
122        Transform { p, q }
123    }
124}
125
126// Operator overloads mirroring the C++ operators in math_functions.h
127
128impl core::ops::AddAssign for Vec2 {
129    fn add_assign(&mut self, b: Vec2) {
130        self.x += b.x;
131        self.y += b.y;
132    }
133}
134
135impl core::ops::SubAssign for Vec2 {
136    fn sub_assign(&mut self, b: Vec2) {
137        self.x -= b.x;
138        self.y -= b.y;
139    }
140}
141
142impl core::ops::MulAssign<f32> for Vec2 {
143    fn mul_assign(&mut self, b: f32) {
144        self.x *= b;
145        self.y *= b;
146    }
147}
148
149impl core::ops::Neg for Vec2 {
150    type Output = Vec2;
151    fn neg(self) -> Vec2 {
152        Vec2 {
153            x: -self.x,
154            y: -self.y,
155        }
156    }
157}
158
159impl core::ops::Add for Vec2 {
160    type Output = Vec2;
161    fn add(self, b: Vec2) -> Vec2 {
162        Vec2 {
163            x: self.x + b.x,
164            y: self.y + b.y,
165        }
166    }
167}
168
169impl core::ops::Sub for Vec2 {
170    type Output = Vec2;
171    fn sub(self, b: Vec2) -> Vec2 {
172        Vec2 {
173            x: self.x - b.x,
174            y: self.y - b.y,
175        }
176    }
177}
178
179impl core::ops::Mul<Vec2> for f32 {
180    type Output = Vec2;
181    fn mul(self, b: Vec2) -> Vec2 {
182        Vec2 {
183            x: self * b.x,
184            y: self * b.y,
185        }
186    }
187}
188
189impl core::ops::Mul<f32> for Vec2 {
190    type Output = Vec2;
191    fn mul(self, b: f32) -> Vec2 {
192        Vec2 {
193            x: self.x * b,
194            y: self.y * b,
195        }
196    }
197}