oxihuman_export/
joint_scale_export.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
8#[derive(Debug, Clone)]
9pub struct JointScaleEntry {
10 pub joint_name: String,
11 pub scale: [f32; 3],
12}
13
14#[allow(dead_code)]
15#[derive(Debug, Clone)]
16pub struct JointScaleExport {
17 pub entries: Vec<JointScaleEntry>,
18}
19
20#[allow(dead_code)]
21pub fn new_joint_scale_export() -> JointScaleExport {
22 JointScaleExport {
23 entries: Vec::new(),
24 }
25}
26
27#[allow(dead_code)]
28pub fn add_joint_scale(exp: &mut JointScaleExport, joint: &str, scale: [f32; 3]) {
29 exp.entries.push(JointScaleEntry {
30 joint_name: joint.to_string(),
31 scale,
32 });
33}
34
35#[allow(dead_code)]
36pub fn joint_scale_count(exp: &JointScaleExport) -> usize {
37 exp.entries.len()
38}
39
40#[allow(dead_code)]
41pub fn find_joint_scale<'a>(exp: &'a JointScaleExport, joint: &str) -> Option<&'a JointScaleEntry> {
42 exp.entries.iter().find(|e| e.joint_name == joint)
43}
44
45#[allow(dead_code)]
46pub fn is_uniform_scale(entry: &JointScaleEntry) -> bool {
47 let [x, y, z] = entry.scale;
48 (x - y).abs() < 1e-5 && (y - z).abs() < 1e-5
49}
50
51#[allow(dead_code)]
52pub fn uniform_scale_count(exp: &JointScaleExport) -> usize {
53 exp.entries.iter().filter(|e| is_uniform_scale(e)).count()
54}
55
56#[allow(dead_code)]
57pub fn avg_scale_magnitude(exp: &JointScaleExport) -> f32 {
58 if exp.entries.is_empty() {
59 return 0.0;
60 }
61 let sum: f32 = exp
62 .entries
63 .iter()
64 .map(|e| {
65 let [x, y, z] = e.scale;
66 (x * x + y * y + z * z).sqrt() / 3.0_f32.sqrt()
67 })
68 .sum();
69 sum / exp.entries.len() as f32
70}
71
72#[allow(dead_code)]
73pub fn set_scale(exp: &mut JointScaleExport, joint: &str, scale: [f32; 3]) {
74 if let Some(e) = exp.entries.iter_mut().find(|e| e.joint_name == joint) {
75 e.scale = scale;
76 }
77}
78
79#[allow(dead_code)]
80pub fn joint_scale_to_json(exp: &JointScaleExport) -> String {
81 format!(
82 "{{\"entry_count\":{},\"uniform_count\":{}}}",
83 joint_scale_count(exp),
84 uniform_scale_count(exp)
85 )
86}
87
88#[allow(dead_code)]
89pub fn scales_positive(exp: &JointScaleExport) -> bool {
90 exp.entries.iter().all(|e| e.scale.iter().all(|&s| s > 0.0))
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_empty() {
99 let exp = new_joint_scale_export();
100 assert_eq!(joint_scale_count(&exp), 0);
101 }
102
103 #[test]
104 fn test_add_entry() {
105 let mut exp = new_joint_scale_export();
106 add_joint_scale(&mut exp, "spine", [1.0, 1.2, 1.0]);
107 assert_eq!(joint_scale_count(&exp), 1);
108 }
109
110 #[test]
111 fn test_find_entry() {
112 let mut exp = new_joint_scale_export();
113 add_joint_scale(&mut exp, "hip", [1.0; 3]);
114 assert!(find_joint_scale(&exp, "hip").is_some());
115 }
116
117 #[test]
118 fn test_is_uniform() {
119 let e = JointScaleEntry {
120 joint_name: "x".to_string(),
121 scale: [2.0, 2.0, 2.0],
122 };
123 assert!(is_uniform_scale(&e));
124 }
125
126 #[test]
127 fn test_not_uniform() {
128 let e = JointScaleEntry {
129 joint_name: "x".to_string(),
130 scale: [1.0, 2.0, 1.0],
131 };
132 assert!(!is_uniform_scale(&e));
133 }
134
135 #[test]
136 fn test_uniform_count() {
137 let mut exp = new_joint_scale_export();
138 add_joint_scale(&mut exp, "a", [1.0; 3]);
139 add_joint_scale(&mut exp, "b", [1.0, 2.0, 1.0]);
140 assert_eq!(uniform_scale_count(&exp), 1);
141 }
142
143 #[test]
144 fn test_set_scale() {
145 let mut exp = new_joint_scale_export();
146 add_joint_scale(&mut exp, "knee", [1.0; 3]);
147 set_scale(&mut exp, "knee", [2.0, 2.0, 2.0]);
148 let e = find_joint_scale(&exp, "knee").expect("should succeed");
149 assert!((e.scale[0] - 2.0).abs() < 1e-5);
150 }
151
152 #[test]
153 fn test_json_output() {
154 let exp = new_joint_scale_export();
155 let j = joint_scale_to_json(&exp);
156 assert!(j.contains("entry_count"));
157 }
158
159 #[test]
160 fn test_scales_positive() {
161 let mut exp = new_joint_scale_export();
162 add_joint_scale(&mut exp, "ok", [1.0, 0.5, 2.0]);
163 assert!(scales_positive(&exp));
164 }
165
166 #[test]
167 fn test_avg_scale_magnitude_one() {
168 let mut exp = new_joint_scale_export();
169 add_joint_scale(&mut exp, "unit", [1.0; 3]);
170 assert!((avg_scale_magnitude(&exp) - 1.0).abs() < 1e-4);
171 }
172}