moon_engine/
math.rs

1//! Math related functionality, and aliases to [`nalgebra`] structs.
2//!
3//! Also includes the [`Color32`] and [`Color8`] structs.
4
5/// An alias to [`nalgebra::Vector2<f32>`].
6pub type Vec2 = nalgebra::Vector2<f32>;
7
8/// An alias to [`nalgebra::Vector3<f32>`].
9pub type Vec3 = nalgebra::Vector3<f32>;
10
11/// An alias to [`nalgebra::Vector4<f32>`].
12pub type Vec4 = nalgebra::Vector4<f32>;
13
14/// An alias to [`nalgebra::Matrix4<f32>`].
15pub type Mat4 = nalgebra::Matrix4<f32>;
16
17/// An alias to [`nalgebra::Orthographic3<f32>`].
18pub type Ortho = nalgebra::Orthographic3<f32>;
19
20/// An RGBA color represented with four [`f32`]s.
21///
22/// [`Color32`] is definied as a tuple-styled struct, with public members.
23///
24/// # Examples
25///
26/// ```
27/// use moon_engine::math::Color32;
28/// let color = Color32::default();
29/// ```
30#[derive(Clone, Copy, Debug)]
31pub struct Color32(pub f32, pub f32, pub f32, pub f32);
32
33impl Default for Color32 {
34    fn default() -> Self {
35        Self(1.0, 1.0, 1.0, 1.0)
36    }
37}
38
39impl Add for Color32 {
40    type Output = Color32;
41
42    fn add(self, rhs: Self) -> Self::Output {
43        Color32(
44            clamp(self.0 + rhs.0, 0.0, 1.0),
45            clamp(self.1 + rhs.1, 0.0, 1.0),
46            clamp(self.2 + rhs.2, 0.0, 1.0),
47            clamp(self.3 + rhs.3, 0.0, 1.0),
48        )
49    }
50}
51
52impl Mul<f32> for Color32 {
53    type Output = Color32;
54
55    fn mul(self, rhs: f32) -> Self::Output {
56        Color32(self.0 * rhs, self.1 * rhs, self.2 * rhs, self.3 * rhs)
57    }
58}
59
60impl Color32 {
61    /// Get the Red component of the [`Color32`].
62    ///
63    /// This is the same as the X component.
64    pub const fn r(&self) -> f32 {
65        self.0
66    }
67    /// Get the X component of the [`Color32`].
68    ///
69    /// This is the same as the Red component.
70    pub const fn x(&self) -> f32 {
71        self.0
72    }
73    /// Get the Green component of the [`Color32`].
74    ///
75    /// This is the same as the Y component.
76    pub const fn g(&self) -> f32 {
77        self.1
78    }
79    /// Get the Y component of the [`Color32`].
80    ///
81    /// This is the same as the Green component.
82    pub const fn y(&self) -> f32 {
83        self.1
84    }
85    /// Get the Blue component of the [`Color32`].
86    ///
87    /// This is the same as the Z component.
88    pub const fn b(&self) -> f32 {
89        self.2
90    }
91    /// Get the Z component of the [`Color32`].
92    ///
93    /// This is the same as the Blue component.
94    pub const fn z(&self) -> f32 {
95        self.2
96    }
97    /// Get the Alpha component of the [`Color32`].
98    ///
99    /// This is the same as the W component.
100    pub const fn a(&self) -> f32 {
101        self.3
102    }
103    /// Get the W component of the [`Color32`].
104    ///
105    /// This is the same as the Alpha component.
106    pub const fn w(&self) -> f32 {
107        self.3
108    }
109
110    /// Pure White Color.
111    pub const WHITE: Color32 = Color32(1.0, 1.0, 1.0, 1.0);
112    /// Pure Black Color.
113    pub const BLACK: Color32 = Color32(0.0, 0.0, 0.0, 1.0);
114    /// Magenta Color.
115    pub const MAGENTA: Color32 = Color32(1.0, 0.0, 1.0, 1.0);
116    /// All fields zeroed out.
117    pub const ZEROES: Color32 = Color32(0.0, 0.0, 0.0, 0.0);
118}
119
120impl From<&[f32; 4]> for Color32 {
121    fn from(slice: &[f32; 4]) -> Self {
122        Self(slice[0], slice[1], slice[2], slice[3])
123    }
124}
125
126impl From<Color32> for [f32; 4] {
127    fn from(color: Color32) -> Self {
128        [color.0, color.1, color.2, color.3]
129    }
130}
131
132impl From<&[u8; 4]> for Color32 {
133    fn from(slice: &[u8; 4]) -> Self {
134        Self::from(Color8(slice[0], slice[1], slice[2], slice[3]))
135    }
136}
137
138impl From<Color32> for [u8; 4] {
139    fn from(color: Color32) -> Self {
140        let color = Color8::from(color);
141        [color.0, color.1, color.2, color.3]
142    }
143}
144
145impl From<Color32> for Vec<u8> {
146    fn from(color: Color32) -> Self {
147        let color = Color8::from(color);
148        vec![color.0, color.1, color.2, color.3]
149    }
150}
151
152impl From<Color8> for Color32 {
153    fn from(color: Color8) -> Self {
154        Self(
155            color.0 as f32 / 255.0,
156            color.1 as f32 / 255.0,
157            color.2 as f32 / 255.0,
158            color.3 as f32 / 255.0,
159        )
160    }
161}
162
163/// An RGBA color represented with four [`u8`]s.
164///
165/// [`Color8`] is definied as a tuple-styled struct, with public members.
166///
167/// # Examples
168///
169/// ```
170/// use moon_engine::math::Color8;
171/// let color = Color8::default();
172/// ```
173#[derive(Clone, Copy)]
174pub struct Color8(pub u8, pub u8, pub u8, pub u8);
175
176impl Default for Color8 {
177    fn default() -> Self {
178        Self(255, 255, 255, 255)
179    }
180}
181
182impl Color8 {
183    /// Get the Red component of the [`Color8`].
184    ///
185    /// This is the same as the X component.
186    pub const fn r(&self) -> u8 {
187        self.0
188    }
189    /// Get the X component of the [`Color8`].
190    ///
191    /// This is the same as the Red component.
192    pub const fn x(&self) -> u8 {
193        self.0
194    }
195    /// Get the Green component of the [`Color8`].
196    ///
197    /// This is the same as the Y component.
198    pub const fn g(&self) -> u8 {
199        self.1
200    }
201    /// Get the Y component of the [`Color8`].
202    ///
203    /// This is the same as the Green component.
204    pub const fn y(&self) -> u8 {
205        self.1
206    }
207    /// Get the Blue component of the [`Color8`].
208    ///
209    /// This is the same as the Z component.
210    pub const fn b(&self) -> u8 {
211        self.2
212    }
213    /// Get the Z component of the [`Color8`].
214    ///
215    /// This is the same as the Blue component.
216    pub const fn z(&self) -> u8 {
217        self.2
218    }
219    /// Get the Alpha component of the [`Color8`].
220    ///
221    /// This is the same as the W component.
222    pub const fn a(&self) -> u8 {
223        self.3
224    }
225    /// Get the W component of the [`Color8`].
226    ///
227    /// This is the same as the Alpha component.
228    pub const fn w(&self) -> u8 {
229        self.3
230    }
231}
232
233impl From<&[u8; 4]> for Color8 {
234    fn from(slice: &[u8; 4]) -> Self {
235        Self(slice[0], slice[1], slice[2], slice[3])
236    }
237}
238
239impl From<Color8> for [u8; 4] {
240    fn from(color: Color8) -> Self {
241        [color.0, color.1, color.2, color.3]
242    }
243}
244
245impl From<Color32> for Color8 {
246    fn from(color: Color32) -> Self {
247        Self(
248            (color.0 * 255.0) as u8,
249            (color.1 * 255.0) as u8,
250            (color.2 * 255.0) as u8,
251            (color.3 * 255.0) as u8,
252        )
253    }
254}
255
256/// A [`Point`] is an alias to Vec2.
257pub type Point = Vec2;
258
259use std::ops::{Add, Mul};
260
261pub use nalgebra::clamp;
262
263/// Trait for generating random values
264pub trait Random {
265    /// Get a random value.
266    fn random() -> Self;
267    /// Get a random value, expanded to another range.
268    fn random_range_max(max: Self) -> Self;
269    /// Get a random value, expanded to another range.
270    fn random_range(min: Self, max: Self) -> Self;
271}
272
273impl Random for f32 {
274    fn random() -> Self {
275        js_sys::Math::random() as f32
276    }
277
278    fn random_range_max(max: Self) -> Self {
279        f32::random() * max
280    }
281
282    fn random_range(min: Self, max: Self) -> Self {
283        f32::random() * (max - min) + min
284    }
285}
286
287impl Random for Vec2 {
288    fn random() -> Self {
289        Vec2::new(f32::random(), f32::random())
290    }
291
292    fn random_range_max(max: Self) -> Self {
293        Vec2::new(f32::random_range_max(max.x), f32::random_range_max(max.y))
294    }
295
296    fn random_range(min: Self, max: Self) -> Self {
297        Vec2::new(
298            f32::random_range(min.x, max.x),
299            f32::random_range(min.y, max.y),
300        )
301    }
302}
303
304impl Random for Color32 {
305    fn random() -> Self {
306        Color32(f32::random(), f32::random(), f32::random(), 1.0)
307    }
308
309    fn random_range_max(max: Self) -> Self {
310        Color32(
311            f32::random_range_max(max.0),
312            f32::random_range_max(max.1),
313            f32::random_range_max(max.2),
314            f32::random_range_max(max.3),
315        )
316    }
317
318    fn random_range(min: Self, max: Self) -> Self {
319        Color32(
320            f32::random_range(min.0, max.0),
321            f32::random_range(min.1, max.1),
322            f32::random_range(min.2, max.2),
323            f32::random_range(min.3, max.3),
324        )
325    }
326}
327
328/// Linearly interpolate between two values.
329pub trait Lerp: Sized + Mul<f32, Output = Self> + Add<Self, Output = Self> {
330    /// Linearly interpolate between two values.
331    fn lerp(min: Self, max: Self, factor: f32) -> Self {
332        min * (1.0 - factor) + max * factor
333    }
334}
335
336impl Lerp for f32 {}
337impl Lerp for Vec2 {}
338impl Lerp for Color32 {}