oxihuman_morph/
infant_morph.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone)]
9pub struct InfantMorphConfig {
10 pub head_ratio: f32,
12 pub limb_scale: f32,
14 pub belly_roundness: f32,
16}
17
18impl Default for InfantMorphConfig {
19 fn default() -> Self {
20 InfantMorphConfig {
21 head_ratio: 1.0,
22 limb_scale: 0.45,
23 belly_roundness: 0.8,
24 }
25 }
26}
27
28#[derive(Debug, Clone)]
30pub struct InfantMorph {
31 pub age_months: f32,
33 pub config: InfantMorphConfig,
34 pub enabled: bool,
35}
36
37pub fn new_infant_morph() -> InfantMorph {
39 InfantMorph {
40 age_months: 0.0,
41 config: InfantMorphConfig::default(),
42 enabled: true,
43 }
44}
45
46pub fn im_set_age(m: &mut InfantMorph, months: f32) {
48 m.age_months = months.clamp(0.0, 24.0);
49}
50
51pub fn im_weight(m: &InfantMorph) -> f32 {
53 m.age_months / 24.0
54}
55
56pub fn im_head_scale(m: &InfantMorph) -> f32 {
58 let t = im_weight(m);
59 m.config.head_ratio * (1.0 - 0.3 * t)
60}
61
62pub fn im_limb_scale(m: &InfantMorph) -> f32 {
64 let t = im_weight(m);
65 m.config.limb_scale + 0.1 * t
66}
67
68pub fn im_to_json(m: &InfantMorph) -> String {
70 format!(
71 r#"{{"age_months":{:.1},"enabled":{},"head_scale":{:.3}}}"#,
72 m.age_months,
73 m.enabled,
74 im_head_scale(m)
75 )
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn default_is_newborn() {
84 let m = new_infant_morph();
85 assert!((m.age_months - 0.0).abs() < 1e-6 );
86 }
87
88 #[test]
89 fn set_age_clamps_upper() {
90 let mut m = new_infant_morph();
91 im_set_age(&mut m, 100.0);
92 assert!((m.age_months - 24.0).abs() < 1e-6 );
93 }
94
95 #[test]
96 fn weight_at_24_months_is_one() {
97 let mut m = new_infant_morph();
98 im_set_age(&mut m, 24.0);
99 assert!((im_weight(&m) - 1.0).abs() < 1e-6 );
100 }
101
102 #[test]
103 fn head_scale_decreases_with_age() {
104 let mut m = new_infant_morph();
105 im_set_age(&mut m, 0.0);
106 let h0 = im_head_scale(&m);
107 im_set_age(&mut m, 24.0);
108 let h24 = im_head_scale(&m);
109 assert!(h0 > h24 );
110 }
111
112 #[test]
113 fn limb_scale_increases_with_age() {
114 let mut m = new_infant_morph();
115 im_set_age(&mut m, 0.0);
116 let l0 = im_limb_scale(&m);
117 im_set_age(&mut m, 24.0);
118 let l24 = im_limb_scale(&m);
119 assert!(l24 > l0 );
120 }
121
122 #[test]
123 fn to_json_has_age() {
124 let mut m = new_infant_morph();
125 im_set_age(&mut m, 6.0);
126 assert!(im_to_json(&m).contains("6.0") );
127 }
128
129 #[test]
130 fn enabled_toggle() {
131 let mut m = new_infant_morph();
132 m.enabled = false;
133 assert!(!m.enabled );
134 }
135
136 #[test]
137 fn belly_roundness_in_config() {
138 let m = new_infant_morph();
139 assert!(m.config.belly_roundness > 0.0 );
140 }
141}