pointrain_core/pc/
xyzi.rs1#[cfg(feature = "rerun")]
2use rerun::{EntityPath, MsgSender, MsgSenderError};
3
4use crate::{
5    traits::{PointCloud, PointCloudWithIntensity},
6    types::{Float, Position},
7};
8
9#[derive(Debug, Default, Clone, Copy, PartialEq)]
10pub struct PointXYZI {
11    pub pos: Position,
12    pub intensity: Float,
13}
14
15#[derive(Debug, Default, Clone)]
16pub struct PointCloudXYZI {
17    positions: Vec<Position>,
18    intensities: Vec<Float>,
19}
20
21impl PointCloudXYZI {
22    pub fn new() -> Self {
23        Self::default()
24    }
25
26    #[cfg(feature = "rerun")]
27    pub fn rerun_msg_sender(
28        &self,
29        label: impl Into<EntityPath>,
30    ) -> Result<MsgSender, MsgSenderError> {
31        use rerun::components::{ColorRGBA, Point3D};
32
33        let max_intensity = self.intensities.iter().fold(f32::NAN, |a, b| b.max(a));
34        assert!(max_intensity.is_finite());
35
36        let turbo = colorgrad::turbo();
37        let colors: Vec<_> = self
38            .intensities
39            .iter()
40            .map(|i| {
41                let t = i / (max_intensity + 1e-6);
42                let [r, g, b, _] = turbo.at(t as f64).to_rgba8();
43                ColorRGBA::from_rgb(r, g, b)
44            })
45            .collect();
46
47        let points: Vec<_> = self
48            .positions
49            .iter()
50            .map(|p| Point3D::new(p.x, p.y, p.z))
51            .collect();
52
53        MsgSender::new(label.into())
54            .with_component(&points)?
55            .with_component(&colors)
56    }
57}
58
59impl PointCloud for PointCloudXYZI {
60    type Point = PointXYZI;
61
62    fn with_capacity(capacity: usize) -> Self {
63        Self {
64            positions: Vec::with_capacity(capacity),
65            intensities: Vec::with_capacity(capacity),
66        }
67    }
68
69    fn positions(&self) -> &[Position] {
70        &self.positions
71    }
72
73    fn add_point(&mut self, p: Self::Point) -> &mut Self {
74        self.positions.push(p.pos);
75        self.intensities.push(p.intensity);
76        self
77    }
78}
79
80impl PointCloudWithIntensity for PointCloudXYZI {
81    fn intensities(&self) -> &[Float] {
82        &self.intensities
83    }
84}