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}