autd3_driver/firmware/operation/stm/
control_point.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use crate::{
    firmware::fpga::{EmitIntensity, Phase},
    geometry::{Isometry, Point3},
};

use derive_more::{Deref, DerefMut};
use derive_new::new;

/// A pair of a focal point and a phase offset.
#[derive(Clone, Copy, PartialEq, Debug, Default, new)]
#[repr(C)]
pub struct ControlPoint {
    /// The focal point.
    pub point: Point3,
    /// The phase offset of the control point.
    pub phase_offset: Phase,
}

impl ControlPoint {
    pub(crate) fn transform(&self, iso: &Isometry) -> Self {
        Self {
            point: iso.transform_point(&self.point),
            phase_offset: self.phase_offset,
        }
    }
}

impl From<Point3> for ControlPoint {
    fn from(point: Point3) -> Self {
        Self {
            point,
            ..Default::default()
        }
    }
}

impl From<&Point3> for ControlPoint {
    fn from(point: &Point3) -> Self {
        Self {
            point: *point,
            ..Default::default()
        }
    }
}

/// A collection of control points and the intensity of all control points.
#[derive(Clone, PartialEq, Debug, Deref, DerefMut, new)]
#[repr(C)]
pub struct ControlPoints<const N: usize> {
    #[deref]
    #[deref_mut]
    /// The control points.
    pub points: [ControlPoint; N],
    /// The intensity of all control points.
    pub intensity: EmitIntensity,
}

impl<const N: usize> Default for ControlPoints<N> {
    fn default() -> Self {
        Self {
            points: [Default::default(); N],
            intensity: EmitIntensity::MAX,
        }
    }
}

impl<const N: usize> ControlPoints<N> {
    pub(crate) fn transform(&self, iso: &nalgebra::Isometry3<f32>) -> Self {
        Self {
            points: self.points.map(|p| p.transform(iso)),
            intensity: self.intensity,
        }
    }
}

impl<C> From<C> for ControlPoints<1>
where
    ControlPoint: From<C>,
{
    fn from(point: C) -> Self {
        Self {
            points: [point.into()],
            ..Default::default()
        }
    }
}

impl<C, const N: usize> From<[C; N]> for ControlPoints<N>
where
    ControlPoint: From<C>,
{
    fn from(points: [C; N]) -> Self {
        Self {
            points: points.map(ControlPoint::from),
            ..Default::default()
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn from_vector3() {
        let v = Point3::new(1.0, 2.0, 3.0);
        let cp = ControlPoint::from(v);
        assert_eq!(v, cp.point);
    }

    #[test]
    fn from_vector3_ref() {
        let v = Point3::new(1.0, 2.0, 3.0);
        let cp = ControlPoint::from(&v);
        assert_eq!(v, cp.point);
    }

    #[test]
    fn from_control_point() {
        let v1 = Point3::new(1.0, 2.0, 3.0);
        let v2 = Point3::new(4.0, 5.0, 6.0);
        let cp = ControlPoints::from([v1, v2]);
        assert_eq!(EmitIntensity::MAX, cp.intensity);
        assert_eq!(v1, cp[0].point);
        assert_eq!(v2, cp[1].point);
    }
}