oxihuman_morph/
eye_lid_crease.rs1#![allow(dead_code)]
5
6use std::f32::consts::FRAC_PI_4;
9
10#[allow(dead_code)]
11#[derive(Debug, Clone)]
12pub struct EyeLidCreaseConfig {
13 pub min_depth: f32,
14 pub max_depth: f32,
15}
16
17#[allow(dead_code)]
18#[derive(Debug, Clone)]
19pub struct EyeLidCreaseState {
20 pub depth: f32,
21 pub height: f32,
22 pub symmetry: f32,
23 pub fold: f32,
24}
25
26#[allow(dead_code)]
27pub fn default_eye_lid_crease_config() -> EyeLidCreaseConfig {
28 EyeLidCreaseConfig {
29 min_depth: 0.0,
30 max_depth: 1.0,
31 }
32}
33
34#[allow(dead_code)]
35pub fn new_eye_lid_crease_state() -> EyeLidCreaseState {
36 EyeLidCreaseState {
37 depth: 0.5,
38 height: 0.5,
39 symmetry: 1.0,
40 fold: 0.0,
41 }
42}
43
44#[allow(dead_code)]
45pub fn elc_set_depth(state: &mut EyeLidCreaseState, cfg: &EyeLidCreaseConfig, v: f32) {
46 state.depth = v.clamp(cfg.min_depth, cfg.max_depth);
47}
48
49#[allow(dead_code)]
50pub fn elc_set_height(state: &mut EyeLidCreaseState, v: f32) {
51 state.height = v.clamp(0.0, 1.0);
52}
53
54#[allow(dead_code)]
55pub fn elc_set_symmetry(state: &mut EyeLidCreaseState, v: f32) {
56 state.symmetry = v.clamp(0.0, 1.0);
57}
58
59#[allow(dead_code)]
60pub fn elc_set_fold(state: &mut EyeLidCreaseState, v: f32) {
61 state.fold = v.clamp(0.0, 1.0);
62}
63
64#[allow(dead_code)]
65pub fn elc_reset(state: &mut EyeLidCreaseState) {
66 *state = new_eye_lid_crease_state();
67}
68
69#[allow(dead_code)]
70pub fn elc_crease_angle(state: &EyeLidCreaseState) -> f32 {
71 state.depth * FRAC_PI_4
72}
73
74#[allow(dead_code)]
75pub fn elc_to_weights(state: &EyeLidCreaseState) -> Vec<(String, f32)> {
76 vec![
77 ("eyelid_crease_depth".to_string(), state.depth),
78 ("eyelid_crease_height".to_string(), state.height),
79 ("eyelid_crease_symmetry".to_string(), state.symmetry),
80 ("eyelid_crease_fold".to_string(), state.fold),
81 ]
82}
83
84#[allow(dead_code)]
85pub fn elc_to_json(state: &EyeLidCreaseState) -> String {
86 format!(
87 r#"{{"depth":{:.4},"height":{:.4},"symmetry":{:.4},"fold":{:.4}}}"#,
88 state.depth, state.height, state.symmetry, state.fold
89 )
90}
91
92#[allow(dead_code)]
93pub fn elc_blend(a: &EyeLidCreaseState, b: &EyeLidCreaseState, t: f32) -> EyeLidCreaseState {
94 let t = t.clamp(0.0, 1.0);
95 EyeLidCreaseState {
96 depth: a.depth + (b.depth - a.depth) * t,
97 height: a.height + (b.height - a.height) * t,
98 symmetry: a.symmetry + (b.symmetry - a.symmetry) * t,
99 fold: a.fold + (b.fold - a.fold) * t,
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn test_default_config() {
109 let cfg = default_eye_lid_crease_config();
110 assert!(cfg.min_depth.abs() < 1e-6);
111 }
112
113 #[test]
114 fn test_new_state() {
115 let s = new_eye_lid_crease_state();
116 assert!((s.depth - 0.5).abs() < 1e-6);
117 assert!((s.fold).abs() < 1e-6);
118 }
119
120 #[test]
121 fn test_set_depth_clamps() {
122 let cfg = default_eye_lid_crease_config();
123 let mut s = new_eye_lid_crease_state();
124 elc_set_depth(&mut s, &cfg, 5.0);
125 assert!((s.depth - 1.0).abs() < 1e-6);
126 }
127
128 #[test]
129 fn test_set_height() {
130 let mut s = new_eye_lid_crease_state();
131 elc_set_height(&mut s, 0.8);
132 assert!((s.height - 0.8).abs() < 1e-6);
133 }
134
135 #[test]
136 fn test_set_fold() {
137 let mut s = new_eye_lid_crease_state();
138 elc_set_fold(&mut s, 0.6);
139 assert!((s.fold - 0.6).abs() < 1e-6);
140 }
141
142 #[test]
143 fn test_reset() {
144 let cfg = default_eye_lid_crease_config();
145 let mut s = new_eye_lid_crease_state();
146 elc_set_depth(&mut s, &cfg, 0.9);
147 elc_reset(&mut s);
148 assert!((s.depth - 0.5).abs() < 1e-6);
149 }
150
151 #[test]
152 fn test_crease_angle() {
153 let mut s = new_eye_lid_crease_state();
154 s.depth = 1.0;
155 assert!((elc_crease_angle(&s) - FRAC_PI_4).abs() < 1e-6);
156 }
157
158 #[test]
159 fn test_to_weights() {
160 let s = new_eye_lid_crease_state();
161 assert_eq!(elc_to_weights(&s).len(), 4);
162 }
163
164 #[test]
165 fn test_blend() {
166 let a = new_eye_lid_crease_state();
167 let mut b = new_eye_lid_crease_state();
168 b.depth = 1.0;
169 let mid = elc_blend(&a, &b, 0.5);
170 assert!((mid.depth - 0.75).abs() < 1e-6);
171 }
172
173 #[test]
174 fn test_to_json() {
175 let s = new_eye_lid_crease_state();
176 let j = elc_to_json(&s);
177 assert!(j.contains("depth"));
178 assert!(j.contains("fold"));
179 }
180}