khora_core/math/mod.rs
1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Provides foundational mathematics primitives for 2D and 3D.
16//!
17//! This module contains a comprehensive set of types and functions for linear algebra
18//! and geometry, forming the mathematical backbone of the Khora Engine. It includes
19//! vectors, matrices, quaternions, and various utility functions designed for
20//! performance and ease of use.
21//!
22//! All angular functions in this module operate in **radians** by default, unless
23//! explicitly specified otherwise (e.g., `degrees_to_radians`).
24
25// --- Fundamental Constants ---
26
27/// A small constant for floating-point comparisons.
28pub const EPSILON: f32 = 1e-5;
29
30// Re-export standard mathematical constants for convenience.
31pub use std::f32::consts::{
32 E, FRAC_PI_2, FRAC_PI_3, FRAC_PI_4, FRAC_PI_6, FRAC_PI_8, LN_10, LN_2, LOG10_E, LOG2_E, PI,
33 SQRT_2, TAU,
34};
35
36/// The factor to convert degrees to radians (PI / 180.0).
37pub const DEG_TO_RAD: f32 = PI / 180.0;
38/// The factor to convert radians to degrees (180.0 / PI).
39pub const RAD_TO_DEG: f32 = 180.0 / PI;
40
41// --- Declare Sub-Modules ---
42
43pub mod affine_transform;
44pub mod color;
45pub mod dimension;
46pub mod geometry;
47pub mod matrix;
48pub mod quaternion;
49pub mod vector;
50
51// --- Re-export Principal Types ---
52
53pub use self::affine_transform::AffineTransform;
54pub use self::color::LinearRgba;
55pub use self::dimension::{Extent1D, Extent2D, Extent3D, Origin2D, Origin3D};
56pub use self::geometry::Aabb;
57pub use self::matrix::{Mat3, Mat4};
58pub use self::quaternion::{Quat, Quaternion};
59pub use self::vector::{Vec2, Vec3, Vec4};
60
61// --- Utility Functions ---
62
63/// Converts an angle from degrees to radians.
64///
65/// # Examples
66///
67/// ```
68/// use khora_core::math::{degrees_to_radians, PI};
69/// assert_eq!(degrees_to_radians(180.0), PI);
70/// ```
71#[inline]
72pub fn degrees_to_radians(degrees: f32) -> f32 {
73 degrees * DEG_TO_RAD
74}
75
76/// Converts an angle from radians to degrees.
77///
78/// # Examples
79///
80/// ```
81/// use khora_core::math::{radians_to_degrees, PI};
82/// assert_eq!(radians_to_degrees(PI), 180.0);
83/// ```
84#[inline]
85pub fn radians_to_degrees(radians: f32) -> f32 {
86 radians * RAD_TO_DEG
87}
88
89/// Clamps a value to a specified minimum and maximum range.
90///
91/// # Examples
92///
93/// ```
94/// use khora_core::math::clamp;
95/// assert_eq!(clamp(1.5, 0.0, 1.0), 1.0);
96/// assert_eq!(clamp(-1.0, 0.0, 1.0), 0.0);
97/// assert_eq!(clamp(0.5, 0.0, 1.0), 0.5);
98/// ```
99#[inline]
100pub fn clamp<T: PartialOrd>(value: T, min_val: T, max_val: T) -> T {
101 if value < min_val {
102 min_val
103 } else if value > max_val {
104 max_val
105 } else {
106 value
107 }
108}
109
110/// Clamps a floating-point value to the `[0.0, 1.0]` range.
111///
112/// # Examples
113///
114/// ```
115/// use khora_core::math::saturate;
116/// assert_eq!(saturate(1.5), 1.0);
117/// assert_eq!(saturate(-0.5), 0.0);
118/// ```
119#[inline]
120pub fn saturate(value: f32) -> f32 {
121 clamp(value, 0.0, 1.0)
122}
123
124/// Performs an approximate equality comparison between two floats with a custom tolerance.
125///
126/// # Examples
127///
128/// ```
129/// use khora_core::math::approx_eq_eps;
130/// assert!(approx_eq_eps(0.001, 0.002, 1e-2));
131/// assert!(!approx_eq_eps(0.001, 0.002, 1e-4));
132/// ```
133#[inline]
134pub fn approx_eq_eps(a: f32, b: f32, epsilon: f32) -> bool {
135 (a - b).abs() < epsilon
136}
137
138/// Performs an approximate equality comparison using the module's default [`EPSILON`].
139///
140/// # Examples
141///
142/// ```
143/// use khora_core::math::{approx_eq, EPSILON};
144/// assert!(approx_eq(1.0, 1.0 + EPSILON / 2.0));
145/// assert!(!approx_eq(1.0, 1.0 + EPSILON * 2.0));
146/// ```
147#[inline]
148pub fn approx_eq(a: f32, b: f32) -> bool {
149 approx_eq_eps(a, b, EPSILON)
150}