Skip to main content

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