rustial_engine/visualization/
point_cloud_layer.rs1use std::any::Any;
4
5use crate::layer::{Layer, LayerId, LayerKind};
6use super::{ColorRamp, PointInstanceSet};
7
8#[derive(Debug, Clone)]
10pub struct PointCloudLayer {
11 id: LayerId,
12 name: String,
13 visible: bool,
14 opacity: f32,
15 z_index: i32,
16 pub points: PointInstanceSet,
18 pub ramp: ColorRamp,
20}
21
22impl PointCloudLayer {
23 pub fn new(
25 name: impl Into<String>,
26 points: PointInstanceSet,
27 ramp: ColorRamp,
28 ) -> Self {
29 Self {
30 id: LayerId::next(),
31 name: name.into(),
32 visible: true,
33 opacity: 1.0,
34 z_index: 0,
35 points,
36 ramp,
37 }
38 }
39
40 pub fn set_points(&mut self, points: PointInstanceSet) {
42 self.points = points;
43 }
44}
45
46impl Layer for PointCloudLayer {
47 fn id(&self) -> LayerId {
48 self.id
49 }
50
51 fn name(&self) -> &str {
52 &self.name
53 }
54
55 fn kind(&self) -> LayerKind {
56 LayerKind::Visualization
57 }
58
59 fn visible(&self) -> bool {
60 self.visible
61 }
62
63 fn set_visible(&mut self, visible: bool) {
64 self.visible = visible;
65 }
66
67 fn opacity(&self) -> f32 {
68 self.opacity
69 }
70
71 fn set_opacity(&mut self, opacity: f32) {
72 self.opacity = opacity.clamp(0.0, 1.0);
73 }
74
75 fn z_index(&self) -> i32 {
76 self.z_index
77 }
78
79 fn as_any(&self) -> &dyn Any {
80 self
81 }
82
83 fn as_any_mut(&mut self) -> &mut dyn Any {
84 self
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use crate::visualization::{ColorStop, PointInstance};
92 use rustial_math::GeoCoord;
93
94 fn test_ramp() -> ColorRamp {
95 ColorRamp::new(vec![
96 ColorStop { value: 0.0, color: [0.0, 0.0, 1.0, 1.0] },
97 ColorStop { value: 1.0, color: [1.0, 0.0, 0.0, 1.0] },
98 ])
99 }
100
101 #[test]
102 fn point_cloud_layer_basics() {
103 let points = PointInstanceSet::new(vec![
104 PointInstance::new(GeoCoord::from_lat_lon(0.0, 0.0), 5.0)
105 .with_pick_id(1),
106 ]);
107 let layer = PointCloudLayer::new("points", points, test_ramp());
108 assert_eq!(layer.name(), "points");
109 assert_eq!(layer.points.len(), 1);
110 assert_eq!(layer.points.points[0].pick_id, 1);
111 }
112
113 #[test]
114 fn point_cloud_layer_downcast() {
115 let layer: Box<dyn Layer> = Box::new(PointCloudLayer::new(
116 "test",
117 PointInstanceSet::default(),
118 test_ramp(),
119 ));
120 assert!(layer.as_any().downcast_ref::<PointCloudLayer>().is_some());
121 }
122}