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