Skip to main content

gizmo_math/
lib.rs

1//! # Gizmo Math
2//!
3//! Gizmo Engine'nin temel matematik altyapısını ve render/fizik veri tiplerini barındırır.
4//!
5//! ## Konvansiyonlar (Conventions)
6//! - **Koordinat Sistemi**: Sağ-Elli (Right-Handed, RH).
7//! - **Yukarı Ekseni**: Y-Up (0.0, 1.0, 0.0).
8//! - **İleri Ekseni**: -Z (Kamera her zaman eksi Z eksenine doğru bakar).
9//! - **Matris Düzeni**: Column-Major (glam mimarisi ile uyumlu).
10//!
11//! Normal matrisi hesaplamaları için yapılandırılmış `Mat3`, ve 3B uzay sınırları
12//! hesaplamaları için boyut optimize edilmiş `Aabb`, `Frustum`, `Ray` yapıları barındırır.
13
14pub mod aabb;
15pub mod fixed;
16pub mod frustum;
17pub mod ray;
18pub mod spatial;
19
20// Geriye dönük uyumluluk veya ekstra yardımcı metodlar için pub modüller kalsın
21// ama custom tipleri glam ile değiştiriyoruz.
22pub use bevy_math::{EulerRot, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A, Vec4};
23
24pub use aabb::Aabb;
25pub use fixed::{Fp32, FpVec3};
26pub use frustum::{Frustum, Intersection, Plane};
27pub use ray::Ray;
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32
33    #[test]
34    fn ray_intersects_aabb_inside_frustum() {
35        // Frustum: Camera at (0, 0, 5), looking at -Z (RH geometry)
36        let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 5.0), Vec3::ZERO, Vec3::Y);
37        let proj = Mat4::perspective_rh(std::f32::consts::FRAC_PI_4, 1.0, 0.1, 100.0);
38        let vp = proj * view;
39        let frustum = Frustum::from_matrix(&vp);
40
41        // Center AABB at origin
42        let aabb = Aabb::new(Vec3::splat(-1.0), Vec3::splat(1.0));
43
44        // Ensure AABB is cleanly within the camera frustum limits
45        assert_eq!(frustum.test_aabb(aabb), Intersection::Inside);
46
47        // Ray shooting exactly down the -Z axis from the camera position targeting the object
48        let ray = Ray::new(Vec3::new(0.0, 0.0, 5.0), Vec3::new(0.0, 0.0, -1.0));
49
50        // Math simulation verification: It should collide with the box
51        let t = ray.intersect_aabb(aabb);
52        assert!(t.is_some());
53
54        let intersection_distance = t.unwrap();
55        // Distance from camera Z=5 to AABB Front-Face Z=1 requires a travel distance of precisely 4 units
56        assert!((intersection_distance - 4.0).abs() < 1e-5);
57    }
58
59    #[test]
60    fn aabb_transform_then_frustum_cull() {
61        // Frustum: Camera at (0, 0, 5), looking at -Z (RH bounds)
62        let view = Mat4::look_at_rh(Vec3::new(0.0, 0.0, 5.0), Vec3::ZERO, Vec3::Y);
63        let proj = Mat4::perspective_rh(std::f32::consts::FRAC_PI_4, 1.0, 0.1, 100.0);
64        let vp = proj * view;
65        let frustum = Frustum::from_matrix(&vp);
66
67        // Default Unit AABB representing a local unscaled Model
68        let local_aabb = Aabb::new(Vec3::splat(-0.5), Vec3::splat(0.5));
69
70        // Scene Step 1: Object is pushed into the active view frustum
71        let inside_mat = Mat4::from_translation(Vec3::new(0.0, 0.0, -10.0));
72        let world_aabb_inside = local_aabb.transform(&inside_mat);
73        assert_eq!(frustum.test_aabb(world_aabb_inside), Intersection::Inside);
74
75        // Scene Step 2: Object is rotated and pushed way outside to the right of the visible frustum limits
76        let outside_mat = Mat4::from_translation(Vec3::new(100.0, 0.0, 0.0));
77        let world_aabb_outside = local_aabb.transform(&outside_mat);
78        assert_eq!(frustum.test_aabb(world_aabb_outside), Intersection::Outside);
79    }
80}