oxihuman_morph/
gaze_driven_shape.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone, Copy)]
9pub struct GazeDirection {
10 pub yaw: f32,
11 pub pitch: f32,
12}
13
14impl Default for GazeDirection {
15 fn default() -> Self {
16 GazeDirection {
17 yaw: 0.0,
18 pitch: 0.0,
19 }
20 }
21}
22
23#[derive(Debug, Clone)]
25pub struct GazeDrivenShape {
26 pub direction: GazeDirection,
27 pub morph_count: usize,
28 pub yaw_gain: f32,
29 pub pitch_gain: f32,
30 pub enabled: bool,
31}
32
33impl GazeDrivenShape {
34 pub fn new(morph_count: usize) -> Self {
35 GazeDrivenShape {
36 direction: GazeDirection::default(),
37 morph_count,
38 yaw_gain: 1.0,
39 pitch_gain: 1.0,
40 enabled: true,
41 }
42 }
43}
44
45pub fn new_gaze_driven_shape(morph_count: usize) -> GazeDrivenShape {
47 GazeDrivenShape::new(morph_count)
48}
49
50pub fn gds_set_direction(gds: &mut GazeDrivenShape, direction: GazeDirection) {
52 gds.direction = direction;
53}
54
55pub fn gds_evaluate(gds: &GazeDrivenShape) -> Vec<f32> {
57 vec![0.0; gds.morph_count]
59}
60
61pub fn gds_set_gains(gds: &mut GazeDrivenShape, yaw_gain: f32, pitch_gain: f32) {
63 gds.yaw_gain = yaw_gain;
64 gds.pitch_gain = pitch_gain;
65}
66
67pub fn gds_set_enabled(gds: &mut GazeDrivenShape, enabled: bool) {
69 gds.enabled = enabled;
70}
71
72pub fn gds_to_json(gds: &GazeDrivenShape) -> String {
74 format!(
75 r#"{{"morph_count":{},"yaw":{:.4},"pitch":{:.4},"enabled":{}}}"#,
76 gds.morph_count, gds.direction.yaw, gds.direction.pitch, gds.enabled
77 )
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn test_new_morph_count() {
86 let g = new_gaze_driven_shape(4);
87 assert_eq!(g.morph_count, 4 ,);
88 }
89
90 #[test]
91 fn test_default_direction_zero() {
92 let g = new_gaze_driven_shape(4);
93 assert!((g.direction.yaw).abs() < 1e-6, );
94 assert!((g.direction.pitch).abs() < 1e-6, );
95 }
96
97 #[test]
98 fn test_set_direction() {
99 let mut g = new_gaze_driven_shape(4);
100 gds_set_direction(
101 &mut g,
102 GazeDirection {
103 yaw: 0.3,
104 pitch: -0.1,
105 },
106 );
107 assert!((g.direction.yaw - 0.3).abs() < 1e-5, );
108 }
109
110 #[test]
111 fn test_evaluate_length() {
112 let g = new_gaze_driven_shape(6);
113 let out = gds_evaluate(&g);
114 assert_eq!(out.len(), 6 ,);
115 }
116
117 #[test]
118 fn test_evaluate_zeroed() {
119 let g = new_gaze_driven_shape(3);
120 let out = gds_evaluate(&g);
121 assert!(out.iter().all(|&v| v.abs() < 1e-6), );
122 }
123
124 #[test]
125 fn test_set_gains() {
126 let mut g = new_gaze_driven_shape(2);
127 gds_set_gains(&mut g, 0.5, 2.0);
128 assert!((g.yaw_gain - 0.5).abs() < 1e-5, );
129 assert!((g.pitch_gain - 2.0).abs() < 1e-5, );
130 }
131
132 #[test]
133 fn test_set_enabled() {
134 let mut g = new_gaze_driven_shape(2);
135 gds_set_enabled(&mut g, false);
136 assert!(!g.enabled ,);
137 }
138
139 #[test]
140 fn test_to_json_contains_morph_count() {
141 let g = new_gaze_driven_shape(5);
142 let j = gds_to_json(&g);
143 assert!(j.contains("\"morph_count\""), );
144 }
145
146 #[test]
147 fn test_enabled_default() {
148 let g = new_gaze_driven_shape(1);
149 assert!(g.enabled ,);
150 }
151
152 #[test]
153 fn test_default_gains() {
154 let g = new_gaze_driven_shape(1);
155 assert!((g.yaw_gain - 1.0).abs() < 1e-5, );
156 assert!((g.pitch_gain - 1.0).abs() < 1e-5, );
157 }
158}