Skip to main content

loam_math/
space.rs

1use std::borrow::Cow;
2
3pub trait Space {
4    type Point: Copy + Send + Sync + 'static;
5    type Vector: Copy + Send + Sync + 'static;
6    type Frame: Copy + Send + Sync + 'static;
7
8    fn frame_at(&self, at: Self::Point) -> Self::Frame;
9
10    fn distance(&self, a: Self::Point, b: Self::Point) -> f32;
11
12    /// Advances for unit time along the geodesic with initial velocity `v`.
13    fn exp(&self, at: Self::Point, v: Self::Vector) -> Self::Point;
14
15    fn log(&self, from: Self::Point, to: Self::Point) -> Self::Vector;
16
17    fn parallel_transport(
18        &self,
19        from: Self::Point,
20        to: Self::Point,
21        v: Self::Vector,
22    ) -> Self::Vector;
23
24    /// Composes transport along consecutive points; fewer than two points leave `v` unchanged.
25    fn parallel_transport_along(&self, path: &[Self::Point], v: Self::Vector) -> Self::Vector {
26        let mut current = v;
27        for w in path.windows(2) {
28            current = self.parallel_transport(w[0], w[1], current);
29        }
30        current
31    }
32
33    /// True when chart arithmetic respects the global geometry, including identifications.
34    fn is_chart_flat(&self) -> bool {
35        false
36    }
37
38    /// Geodesic distance from the chart origin beyond which [`Self::valid_point`] refuses a point.
39    fn chart_envelope(&self) -> f32;
40
41    /// Finite, inside the chart, and within [`Self::chart_envelope`] of the origin.
42    fn valid_point(&self, p: Self::Point) -> bool;
43}
44
45pub trait IsometryGroup: Space {
46    type Iso: Copy + Send + Sync + 'static;
47
48    fn iso_identity(&self) -> Self::Iso;
49
50    /// `a ∘ b`, apply `b` first, then `a`.
51    fn iso_compose(&self, a: Self::Iso, b: Self::Iso) -> Self::Iso;
52
53    fn iso_inverse(&self, a: Self::Iso) -> Self::Iso;
54
55    fn iso_apply(&self, iso: Self::Iso, p: Self::Point) -> Self::Point;
56
57    /// Maps tangents at `at` to tangents at `iso_apply(iso, at)`.
58    fn iso_transport(&self, iso: Self::Iso, at: Self::Point, v: Self::Vector) -> Self::Vector;
59}
60
61pub const FLAT_CHART_MAX_ARC: f32 = 40.0;
62
63#[derive(Clone, Copy, Debug, PartialEq)]
64pub enum WgslAccuracy {
65    Exact,
66    FirstOrder { residual: f32 },
67}
68
69impl WgslAccuracy {
70    pub fn residual(self) -> f32 {
71        match self {
72            WgslAccuracy::Exact => 0.0,
73            WgslAccuracy::FirstOrder { residual } => residual,
74        }
75    }
76}
77
78pub trait WgslSpace: Space {
79    /// Emits `loam_distance`, `loam_origin_distance`, `loam_exp`, `loam_log`, `loam_geodesic_step`, and `LOAM_MAX_ARC` over the space's point type.
80    fn wgsl_impl(&self) -> Cow<'static, str>;
81
82    fn wgsl_accuracy(&self) -> WgslAccuracy;
83}