autd3_driver/firmware/operation/stm/
control_point.rs1use crate::{
2 firmware::fpga::{EmitIntensity, Phase},
3 geometry::{Isometry, Point3},
4};
5
6use derive_more::{Deref, DerefMut};
7
8#[derive(Clone, Copy, PartialEq, Debug, Default)]
10#[repr(C)]
11pub struct ControlPoint {
12 pub point: Point3,
14 pub phase_offset: Phase,
16}
17
18impl ControlPoint {
19 pub const fn new(point: Point3, phase_offset: Phase) -> Self {
21 Self {
22 point,
23 phase_offset,
24 }
25 }
26
27 pub(crate) fn transform(&self, iso: &Isometry) -> Self {
28 Self {
29 point: iso.transform_point(&self.point),
30 phase_offset: self.phase_offset,
31 }
32 }
33}
34
35impl From<Point3> for ControlPoint {
36 fn from(point: Point3) -> Self {
37 Self {
38 point,
39 ..Default::default()
40 }
41 }
42}
43
44impl From<&Point3> for ControlPoint {
45 fn from(point: &Point3) -> Self {
46 Self {
47 point: *point,
48 ..Default::default()
49 }
50 }
51}
52
53#[derive(Clone, PartialEq, Debug, Deref, DerefMut)]
55#[repr(C)]
56pub struct ControlPoints<const N: usize> {
57 #[deref]
58 #[deref_mut]
59 pub points: [ControlPoint; N],
61 pub intensity: EmitIntensity,
63}
64
65impl<const N: usize> Default for ControlPoints<N> {
66 fn default() -> Self {
67 Self {
68 points: [Default::default(); N],
69 intensity: EmitIntensity::MAX,
70 }
71 }
72}
73
74impl<const N: usize> ControlPoints<N> {
75 pub const fn new(points: [ControlPoint; N], intensity: EmitIntensity) -> Self {
77 Self { points, intensity }
78 }
79
80 pub(crate) fn transform(&self, iso: &nalgebra::Isometry3<f32>) -> Self {
81 Self {
82 points: self.points.map(|p| p.transform(iso)),
83 intensity: self.intensity,
84 }
85 }
86}
87
88impl<C> From<C> for ControlPoints<1>
89where
90 ControlPoint: From<C>,
91{
92 fn from(point: C) -> Self {
93 Self {
94 points: [point.into()],
95 ..Default::default()
96 }
97 }
98}
99
100impl<C, const N: usize> From<[C; N]> for ControlPoints<N>
101where
102 ControlPoint: From<C>,
103{
104 fn from(points: [C; N]) -> Self {
105 Self {
106 points: points.map(ControlPoint::from),
107 ..Default::default()
108 }
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115
116 #[test]
117 fn from_vector3() {
118 let v = Point3::new(1.0, 2.0, 3.0);
119 let cp = ControlPoint::from(v);
120 assert_eq!(v, cp.point);
121 }
122
123 #[test]
124 fn from_vector3_ref() {
125 let v = Point3::new(1.0, 2.0, 3.0);
126 let cp = ControlPoint::from(&v);
127 assert_eq!(v, cp.point);
128 }
129
130 #[test]
131 fn from_control_point() {
132 let v1 = Point3::new(1.0, 2.0, 3.0);
133 let v2 = Point3::new(4.0, 5.0, 6.0);
134 let cp = ControlPoints::from([v1, v2]);
135 assert_eq!(EmitIntensity::MAX, cp.intensity);
136 assert_eq!(v1, cp[0].point);
137 assert_eq!(v2, cp[1].point);
138 }
139}