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 color;
44pub mod dimension;
45pub mod geometry;
46pub mod matrix;
47pub mod quaternion;
48pub mod vector;
49
50// --- Re-export Principal Types ---
51
52pub use self::color::LinearRgba;
53pub use self::dimension::{Extent1D, Extent2D, Extent3D, Origin2D, Origin3D};
54pub use self::geometry::Aabb;
55pub use self::matrix::{Mat3, Mat4};
56pub use self::quaternion::Quaternion;
57pub use self::vector::{Vec2, Vec3, Vec4};
58
59// --- Utility Functions ---
60
61/// Converts an angle from degrees to radians.
62///
63/// # Examples
64///
65/// ```
66/// use khora_core::math::{degrees_to_radians, PI};
67/// assert_eq!(degrees_to_radians(180.0), PI);
68/// ```
69#[inline]
70pub fn degrees_to_radians(degrees: f32) -> f32 {
71    degrees * DEG_TO_RAD
72}
73
74/// Converts an angle from radians to degrees.
75///
76/// # Examples
77///
78/// ```
79/// use khora_core::math::{radians_to_degrees, PI};
80/// assert_eq!(radians_to_degrees(PI), 180.0);
81/// ```
82#[inline]
83pub fn radians_to_degrees(radians: f32) -> f32 {
84    radians * RAD_TO_DEG
85}
86
87/// Clamps a value to a specified minimum and maximum range.
88///
89/// # Examples
90///
91/// ```
92/// use khora_core::math::clamp;
93/// assert_eq!(clamp(1.5, 0.0, 1.0), 1.0);
94/// assert_eq!(clamp(-1.0, 0.0, 1.0), 0.0);
95/// assert_eq!(clamp(0.5, 0.0, 1.0), 0.5);
96/// ```
97#[inline]
98pub fn clamp<T: PartialOrd>(value: T, min_val: T, max_val: T) -> T {
99    if value < min_val {
100        min_val
101    } else if value > max_val {
102        max_val
103    } else {
104        value
105    }
106}
107
108/// Clamps a floating-point value to the `[0.0, 1.0]` range.
109///
110/// # Examples
111///
112/// ```/// use khora_core::math::saturate;
113/// assert_eq!(saturate(1.5), 1.0);
114/// assert_eq!(saturate(-0.5), 0.0);
115/// ```
116#[inline]
117pub fn saturate(value: f32) -> f32 {
118    clamp(value, 0.0, 1.0)
119}
120
121/// Performs an approximate equality comparison between two floats with a custom tolerance.
122///
123/// # Examples
124///
125/// ```
126/// use khora_core::math::approx_eq_eps;
127/// assert!(approx_eq_eps(0.001, 0.002, 1e-2));
128/// assert!(!approx_eq_eps(0.001, 0.002, 1e-4));
129/// ```
130#[inline]
131pub fn approx_eq_eps(a: f32, b: f32, epsilon: f32) -> bool {
132    (a - b).abs() < epsilon
133}
134
135/// Performs an approximate equality comparison using the module's default [`EPSILON`].
136///
137/// # Examples
138///
139/// ```
140/// use khora_core::math::{approx_eq, EPSILON};
141/// assert!(approx_eq(1.0, 1.0 + EPSILON / 2.0));
142/// assert!(!approx_eq(1.0, 1.0 + EPSILON * 2.0));
143/// ```
144#[inline]
145pub fn approx_eq(a: f32, b: f32) -> bool {
146    approx_eq_eps(a, b, EPSILON)
147}