oxihuman_morph/
eye_size_morph.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone, Copy, PartialEq)]
9pub enum EyeSide {
10 Left,
11 Right,
12 Both,
13}
14
15#[derive(Debug, Clone)]
17pub struct EyeSizeMorph {
18 pub side: EyeSide,
19 pub aperture: f32,
20 pub width: f32,
21 pub height: f32,
22 pub tilt: f32,
23 pub morph_count: usize,
24 pub enabled: bool,
25}
26
27impl EyeSizeMorph {
28 pub fn new(morph_count: usize) -> Self {
29 EyeSizeMorph {
30 side: EyeSide::Both,
31 aperture: 0.5,
32 width: 0.5,
33 height: 0.5,
34 tilt: 0.0,
35 morph_count,
36 enabled: true,
37 }
38 }
39}
40
41pub fn new_eye_size_morph(morph_count: usize) -> EyeSizeMorph {
43 EyeSizeMorph::new(morph_count)
44}
45
46pub fn esm_set_side(morph: &mut EyeSizeMorph, side: EyeSide) {
48 morph.side = side;
49}
50
51pub fn esm_set_aperture(morph: &mut EyeSizeMorph, aperture: f32) {
53 morph.aperture = aperture.clamp(0.0, 1.0);
54}
55
56pub fn esm_set_width(morph: &mut EyeSizeMorph, width: f32) {
58 morph.width = width.clamp(0.0, 1.0);
59}
60
61pub fn esm_set_height(morph: &mut EyeSizeMorph, height: f32) {
63 morph.height = height.clamp(0.0, 1.0);
64}
65
66pub fn esm_set_tilt(morph: &mut EyeSizeMorph, tilt: f32) {
68 morph.tilt = tilt.clamp(-1.0, 1.0);
69}
70
71pub fn esm_evaluate(morph: &EyeSizeMorph) -> Vec<f32> {
73 if !morph.enabled || morph.morph_count == 0 {
75 return vec![];
76 }
77 let w = (morph.aperture + morph.width + morph.height) / 3.0;
78 vec![w.clamp(0.0, 1.0); morph.morph_count]
79}
80
81pub fn esm_set_enabled(morph: &mut EyeSizeMorph, enabled: bool) {
83 morph.enabled = enabled;
84}
85
86pub fn esm_to_json(morph: &EyeSizeMorph) -> String {
88 let side = match morph.side {
89 EyeSide::Left => "left",
90 EyeSide::Right => "right",
91 EyeSide::Both => "both",
92 };
93 format!(
94 r#"{{"side":"{}","aperture":{},"width":{},"height":{},"tilt":{},"enabled":{}}}"#,
95 side, morph.aperture, morph.width, morph.height, morph.tilt, morph.enabled
96 )
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn test_default_side() {
105 let m = new_eye_size_morph(4);
106 assert_eq!(m.side, EyeSide::Both );
107 }
108
109 #[test]
110 fn test_set_side() {
111 let mut m = new_eye_size_morph(4);
112 esm_set_side(&mut m, EyeSide::Left);
113 assert_eq!(m.side, EyeSide::Left );
114 }
115
116 #[test]
117 fn test_aperture_clamped() {
118 let mut m = new_eye_size_morph(4);
119 esm_set_aperture(&mut m, 2.0);
120 assert!((m.aperture - 1.0).abs() < 1e-6 );
121 }
122
123 #[test]
124 fn test_width_clamped() {
125 let mut m = new_eye_size_morph(4);
126 esm_set_width(&mut m, -0.5);
127 assert!((m.width).abs() < 1e-6 );
128 }
129
130 #[test]
131 fn test_height_clamped() {
132 let mut m = new_eye_size_morph(4);
133 esm_set_height(&mut m, 1.5);
134 assert!((m.height - 1.0).abs() < 1e-6 );
135 }
136
137 #[test]
138 fn test_tilt_clamped() {
139 let mut m = new_eye_size_morph(4);
140 esm_set_tilt(&mut m, 3.0);
141 assert!((m.tilt - 1.0).abs() < 1e-6 );
142 }
143
144 #[test]
145 fn test_evaluate_length() {
146 let m = new_eye_size_morph(5);
147 assert_eq!(
148 esm_evaluate(&m).len(),
149 5 );
151 }
152
153 #[test]
154 fn test_evaluate_disabled() {
155 let mut m = new_eye_size_morph(4);
156 esm_set_enabled(&mut m, false);
157 assert!(esm_evaluate(&m).is_empty() );
158 }
159
160 #[test]
161 fn test_to_json_has_side() {
162 let m = new_eye_size_morph(4);
163 let j = esm_to_json(&m);
164 assert!(j.contains("\"side\"") );
165 }
166
167 #[test]
168 fn test_enabled_default() {
169 let m = new_eye_size_morph(4);
170 assert!(m.enabled );
171 }
172}