Skip to main content

proof_engine/geometry/
mod.rs

1//! Computational Geometry Engine — real-time mathematical surface construction,
2//! manipulation, and rendering.
3//!
4//! Provides parametric surfaces, implicit surface extraction (marching cubes),
5//! CSG operations, subdivision surfaces, Voronoi/Delaunay, convex hull,
6//! Bezier/NURBS, geodesics, curvature visualization, and topology operations.
7//!
8//! A game can define a dungeon room as "the interior of a Klein bottle" and the
9//! engine renders it with correct topology. Boss arenas can be non-Euclidean spaces.
10
11pub mod parametric;
12pub mod implicit;
13pub mod csg;
14pub mod subdivision;
15pub mod voronoi;
16pub mod hull;
17pub mod bezier;
18pub mod geodesic;
19pub mod curvature;
20pub mod topology;
21pub mod deformation;
22
23pub use parametric::{ParametricSurface, SurfaceSample, SurfaceGrid};
24pub use implicit::{ScalarField, MarchingCubes, IsoVertex};
25pub use csg::{CsgOp, CsgNode, CsgTree};
26pub use subdivision::{SubdivisionScheme, SubdivMesh};
27pub use voronoi::{VoronoiDiagram, VoronoiCell, DelaunayTriangulation};
28pub use hull::ConvexHull;
29pub use bezier::{BezierSurface, NurbsSurface, ControlPoint};
30pub use geodesic::GeodesicSolver;
31pub use curvature::{CurvatureField, CurvatureType};
32pub use topology::{TopologyOp, SurfaceTopology, TopologicalSurface};
33pub use deformation::{Deformer, DeformField};
34
35use glam::{Vec2, Vec3, Vec4};
36
37/// A triangle in 3D space with vertex indices.
38#[derive(Debug, Clone, Copy)]
39pub struct Triangle {
40    pub a: u32,
41    pub b: u32,
42    pub c: u32,
43}
44
45/// A mesh of vertices and triangles produced by geometry operations.
46#[derive(Debug, Clone)]
47pub struct GeoMesh {
48    pub vertices: Vec<Vec3>,
49    pub normals: Vec<Vec3>,
50    pub uvs: Vec<Vec2>,
51    pub colors: Vec<Vec4>,
52    pub triangles: Vec<Triangle>,
53}
54
55impl GeoMesh {
56    pub fn new() -> Self {
57        Self {
58            vertices: Vec::new(),
59            normals: Vec::new(),
60            uvs: Vec::new(),
61            colors: Vec::new(),
62            triangles: Vec::new(),
63        }
64    }
65
66    pub fn vertex_count(&self) -> usize { self.vertices.len() }
67    pub fn triangle_count(&self) -> usize { self.triangles.len() }
68
69    pub fn add_vertex(&mut self, pos: Vec3, normal: Vec3, uv: Vec2) -> u32 {
70        let idx = self.vertices.len() as u32;
71        self.vertices.push(pos);
72        self.normals.push(normal);
73        self.uvs.push(uv);
74        self.colors.push(Vec4::ONE);
75        idx
76    }
77
78    pub fn add_triangle(&mut self, a: u32, b: u32, c: u32) {
79        self.triangles.push(Triangle { a, b, c });
80    }
81
82    /// Compute flat normals from triangle geometry.
83    pub fn recompute_normals(&mut self) {
84        for n in &mut self.normals { *n = Vec3::ZERO; }
85        for tri in &self.triangles {
86            let a = self.vertices[tri.a as usize];
87            let b = self.vertices[tri.b as usize];
88            let c = self.vertices[tri.c as usize];
89            let n = (b - a).cross(c - a);
90            self.normals[tri.a as usize] += n;
91            self.normals[tri.b as usize] += n;
92            self.normals[tri.c as usize] += n;
93        }
94        for n in &mut self.normals {
95            let len = n.length();
96            if len > 1e-8 { *n /= len; }
97        }
98    }
99
100    /// Bounding box (min, max).
101    pub fn bounds(&self) -> (Vec3, Vec3) {
102        let mut min = Vec3::splat(f32::MAX);
103        let mut max = Vec3::splat(f32::MIN);
104        for v in &self.vertices {
105            min = min.min(*v);
106            max = max.max(*v);
107        }
108        (min, max)
109    }
110
111    /// Merge another mesh into this one.
112    pub fn merge(&mut self, other: &GeoMesh) {
113        let offset = self.vertices.len() as u32;
114        self.vertices.extend_from_slice(&other.vertices);
115        self.normals.extend_from_slice(&other.normals);
116        self.uvs.extend_from_slice(&other.uvs);
117        self.colors.extend_from_slice(&other.colors);
118        for tri in &other.triangles {
119            self.triangles.push(Triangle {
120                a: tri.a + offset,
121                b: tri.b + offset,
122                c: tri.c + offset,
123            });
124        }
125    }
126}
127
128impl Default for GeoMesh {
129    fn default() -> Self { Self::new() }
130}