oxihuman_morph/
surface_deform.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone)]
9pub struct SurfaceDeformBinding {
10 pub face_index: usize,
11 pub barycentric: [f32; 3],
12 pub normal_offset: f32,
13}
14
15#[derive(Debug, Clone)]
17pub struct SurfaceDeform {
18 pub bindings: Vec<SurfaceDeformBinding>,
19 pub strength: f32,
20 pub is_bound: bool,
21}
22
23impl SurfaceDeform {
24 pub fn new(vertex_count: usize) -> Self {
25 SurfaceDeform {
26 bindings: (0..vertex_count)
27 .map(|_| SurfaceDeformBinding {
28 face_index: 0,
29 barycentric: [1.0 / 3.0; 3],
30 normal_offset: 0.0,
31 })
32 .collect(),
33 strength: 1.0,
34 is_bound: false,
35 }
36 }
37}
38
39pub fn new_surface_deform(vertex_count: usize) -> SurfaceDeform {
41 SurfaceDeform::new(vertex_count)
42}
43
44pub fn surface_deform_bind(sd: &mut SurfaceDeform) {
46 sd.is_bound = true;
47}
48
49pub fn surface_deform_unbind(sd: &mut SurfaceDeform) {
51 sd.is_bound = false;
52}
53
54pub fn surface_deform_set_strength(sd: &mut SurfaceDeform, strength: f32) {
56 sd.strength = strength.clamp(0.0, 1.0);
57}
58
59pub fn surface_deform_vertex_count(sd: &SurfaceDeform) -> usize {
61 sd.bindings.len()
62}
63
64pub fn surface_deform_to_json(sd: &SurfaceDeform) -> String {
66 format!(
67 r#"{{"vertices":{},"strength":{:.4},"bound":{}}}"#,
68 sd.bindings.len(),
69 sd.strength,
70 sd.is_bound
71 )
72}
73
74pub fn surface_deform_bary_sum(sd: &SurfaceDeform, binding_index: usize) -> f32 {
76 if binding_index < sd.bindings.len() {
77 let b = &sd.bindings[binding_index];
78 b.barycentric[0] + b.barycentric[1] + b.barycentric[2]
79 } else {
80 0.0
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_new_surface_deform_vertex_count() {
90 let sd = new_surface_deform(15);
91 assert_eq!(
92 surface_deform_vertex_count(&sd),
93 15, );
95 }
96
97 #[test]
98 fn test_initial_not_bound() {
99 let sd = new_surface_deform(5);
100 assert!(!sd.is_bound ,);
101 }
102
103 #[test]
104 fn test_bind_sets_is_bound() {
105 let mut sd = new_surface_deform(5);
106 surface_deform_bind(&mut sd);
107 assert!(sd.is_bound ,);
108 }
109
110 #[test]
111 fn test_unbind_clears_is_bound() {
112 let mut sd = new_surface_deform(5);
113 surface_deform_bind(&mut sd);
114 surface_deform_unbind(&mut sd);
115 assert!(!sd.is_bound ,);
116 }
117
118 #[test]
119 fn test_set_strength_clamps() {
120 let mut sd = new_surface_deform(2);
121 surface_deform_set_strength(&mut sd, 3.0);
122 assert!((sd.strength - 1.0).abs() < 1e-5, );
123 }
124
125 #[test]
126 fn test_set_strength_negative_clamps() {
127 let mut sd = new_surface_deform(2);
128 surface_deform_set_strength(&mut sd, -1.0);
129 assert!((sd.strength).abs() < 1e-6, );
130 }
131
132 #[test]
133 fn test_bary_sum_near_one() {
134 let sd = new_surface_deform(3);
135 let s = surface_deform_bary_sum(&sd, 0);
136 assert!((s - 1.0).abs() < 1e-5, );
137 }
138
139 #[test]
140 fn test_bary_sum_out_of_bounds() {
141 let sd = new_surface_deform(2);
142 let s = surface_deform_bary_sum(&sd, 99);
143 assert!((s).abs() < 1e-6 ,);
144 }
145
146 #[test]
147 fn test_to_json_contains_bound() {
148 let sd = new_surface_deform(3);
149 let j = surface_deform_to_json(&sd);
150 assert!(j.contains("bound") ,);
151 }
152
153 #[test]
154 fn test_default_strength_one() {
155 let sd = new_surface_deform(1);
156 assert!((sd.strength - 1.0).abs() < 1e-5, );
157 }
158}