Skip to main content

spatialrust_scene/
surfel.rs

1//! Oriented surfel clouds.
2
3use spatialrust_math::Vec3;
4
5use crate::{SceneError, SceneResult};
6
7/// One oriented disc surfel.
8#[derive(Clone, Copy, Debug, PartialEq)]
9pub struct Surfel {
10    /// Center.
11    pub position: Vec3<f32>,
12    /// Unit normal.
13    pub normal: Vec3<f32>,
14    /// Disc radius.
15    pub radius: f32,
16}
17
18/// Collection of surfels.
19#[derive(Clone, Debug, Default, PartialEq)]
20pub struct SurfelCloud {
21    surfels: Vec<Surfel>,
22}
23
24impl SurfelCloud {
25    /// Creates an empty cloud.
26    #[must_use]
27    pub fn new() -> Self {
28        Self::default()
29    }
30
31    /// Pushes a validated surfel.
32    pub fn push(&mut self, surfel: Surfel) -> SceneResult<()> {
33        if !(surfel.radius.is_finite() && surfel.radius > 0.0) {
34            return Err(SceneError::InvalidConfiguration("surfel radius must be > 0".into()));
35        }
36        if !(surfel.normal.length().is_finite()) || surfel.normal.length() < 1e-6 {
37            return Err(SceneError::InvalidConfiguration("surfel normal must be non-zero".into()));
38        }
39        self.surfels.push(surfel);
40        Ok(())
41    }
42
43    /// Returns surfels.
44    #[must_use]
45    pub fn as_slice(&self) -> &[Surfel] {
46        &self.surfels
47    }
48}