oxihuman_morph/
face_length_control.rs1#![allow(dead_code)]
7
8#[allow(dead_code)]
10#[derive(Debug, Clone)]
11pub struct FaceLengthConfig {
12 pub min_scale: f32,
13 pub max_scale: f32,
14}
15
16#[allow(dead_code)]
18#[derive(Debug, Clone)]
19pub struct FaceLengthState {
20 pub scale: f32,
21 pub upper_contribution: f32,
22 pub lower_contribution: f32,
23}
24
25#[allow(dead_code)]
26pub fn default_face_length_config() -> FaceLengthConfig {
27 FaceLengthConfig {
28 min_scale: 0.5,
29 max_scale: 2.0,
30 }
31}
32
33#[allow(dead_code)]
34pub fn new_face_length_state() -> FaceLengthState {
35 FaceLengthState {
36 scale: 1.0,
37 upper_contribution: 0.5,
38 lower_contribution: 0.5,
39 }
40}
41
42#[allow(dead_code)]
43pub fn facel_set_scale(state: &mut FaceLengthState, cfg: &FaceLengthConfig, v: f32) {
44 state.scale = v.clamp(cfg.min_scale, cfg.max_scale);
45}
46
47#[allow(dead_code)]
48pub fn facel_set_upper_contrib(state: &mut FaceLengthState, v: f32) {
49 state.upper_contribution = v.clamp(0.0, 1.0);
50}
51
52#[allow(dead_code)]
53pub fn facel_set_lower_contrib(state: &mut FaceLengthState, v: f32) {
54 state.lower_contribution = v.clamp(0.0, 1.0);
55}
56
57#[allow(dead_code)]
58pub fn facel_reset(state: &mut FaceLengthState) {
59 *state = new_face_length_state();
60}
61
62#[allow(dead_code)]
63pub fn facel_to_weights(state: &FaceLengthState) -> Vec<(String, f32)> {
64 vec![
65 ("face_length_scale".to_string(), state.scale),
66 (
67 "face_length_upper_contrib".to_string(),
68 state.upper_contribution,
69 ),
70 (
71 "face_length_lower_contrib".to_string(),
72 state.lower_contribution,
73 ),
74 ]
75}
76
77#[allow(dead_code)]
78pub fn facel_to_json(state: &FaceLengthState) -> String {
79 format!(
80 r#"{{"scale":{:.4},"upper_contribution":{:.4},"lower_contribution":{:.4}}}"#,
81 state.scale, state.upper_contribution, state.lower_contribution
82 )
83}
84
85#[allow(dead_code)]
86pub fn facel_clamp(state: &mut FaceLengthState, cfg: &FaceLengthConfig) {
87 state.scale = state.scale.clamp(cfg.min_scale, cfg.max_scale);
88 state.upper_contribution = state.upper_contribution.clamp(0.0, 1.0);
89 state.lower_contribution = state.lower_contribution.clamp(0.0, 1.0);
90}
91
92#[allow(dead_code)]
93pub fn facel_effective_scale(state: &FaceLengthState) -> f32 {
94 state.scale * (1.0 + (state.upper_contribution + state.lower_contribution) * 0.05)
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn test_default_config() {
103 let cfg = default_face_length_config();
104 assert!((cfg.min_scale - 0.5).abs() < 1e-6);
105 assert!((cfg.max_scale - 2.0).abs() < 1e-6);
106 }
107
108 #[test]
109 fn test_new_state_defaults() {
110 let s = new_face_length_state();
111 assert!((s.scale - 1.0).abs() < 1e-6);
112 assert!((s.upper_contribution - 0.5).abs() < 1e-6);
113 }
114
115 #[test]
116 fn test_set_scale_clamps() {
117 let cfg = default_face_length_config();
118 let mut s = new_face_length_state();
119 facel_set_scale(&mut s, &cfg, 10.0);
120 assert!((s.scale - 2.0).abs() < 1e-6);
121 facel_set_scale(&mut s, &cfg, 0.1);
122 assert!((s.scale - 0.5).abs() < 1e-6);
123 }
124
125 #[test]
126 fn test_set_upper_contrib() {
127 let mut s = new_face_length_state();
128 facel_set_upper_contrib(&mut s, 0.8);
129 assert!((s.upper_contribution - 0.8).abs() < 1e-6);
130 }
131
132 #[test]
133 fn test_set_lower_contrib() {
134 let mut s = new_face_length_state();
135 facel_set_lower_contrib(&mut s, 0.2);
136 assert!((s.lower_contribution - 0.2).abs() < 1e-6);
137 }
138
139 #[test]
140 fn test_reset() {
141 let cfg = default_face_length_config();
142 let mut s = new_face_length_state();
143 facel_set_scale(&mut s, &cfg, 1.5);
144 facel_reset(&mut s);
145 assert!((s.scale - 1.0).abs() < 1e-6);
146 }
147
148 #[test]
149 fn test_to_weights_count() {
150 let s = new_face_length_state();
151 assert_eq!(facel_to_weights(&s).len(), 3);
152 }
153
154 #[test]
155 fn test_to_json_contains_fields() {
156 let s = new_face_length_state();
157 let j = facel_to_json(&s);
158 assert!(j.contains("scale"));
159 assert!(j.contains("upper_contribution"));
160 }
161
162 #[test]
163 fn test_effective_scale() {
164 let s = new_face_length_state();
165 let eff = facel_effective_scale(&s);
166 assert!(eff >= 1.0);
167 }
168}