oxihuman_export/
geometry_instancing_export.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct GeoInstance {
11 pub mesh_id: u32,
12 pub position: [f32; 3],
13 pub rotation: [f32; 4],
14 pub scale: [f32; 3],
15}
16
17#[allow(dead_code)]
19#[derive(Debug, Clone)]
20pub struct GeoInstancingExport {
21 pub instances: Vec<GeoInstance>,
22}
23
24#[allow(dead_code)]
26pub fn new_geo_instancing_export() -> GeoInstancingExport {
27 GeoInstancingExport { instances: vec![] }
28}
29
30#[allow(dead_code)]
32pub fn add_instance(e: &mut GeoInstancingExport, mesh_id: u32, pos: [f32; 3]) {
33 e.instances.push(GeoInstance {
34 mesh_id,
35 position: pos,
36 rotation: [0.0, 0.0, 0.0, 1.0],
37 scale: [1.0, 1.0, 1.0],
38 });
39}
40
41#[allow(dead_code)]
43pub fn add_instance_full(
44 e: &mut GeoInstancingExport,
45 mesh_id: u32,
46 pos: [f32; 3],
47 rot: [f32; 4],
48 scale: [f32; 3],
49) {
50 e.instances.push(GeoInstance {
51 mesh_id,
52 position: pos,
53 rotation: rot,
54 scale,
55 });
56}
57
58#[allow(dead_code)]
60pub fn gi_count(e: &GeoInstancingExport) -> usize {
61 e.instances.len()
62}
63
64#[allow(dead_code)]
66pub fn instances_of_mesh(e: &GeoInstancingExport, mesh_id: u32) -> usize {
67 e.instances.iter().filter(|i| i.mesh_id == mesh_id).count()
68}
69
70#[allow(dead_code)]
72pub fn unique_mesh_count(e: &GeoInstancingExport) -> usize {
73 let mut ids: Vec<u32> = e.instances.iter().map(|i| i.mesh_id).collect();
74 ids.sort_unstable();
75 ids.dedup();
76 ids.len()
77}
78
79#[allow(dead_code)]
81pub fn gi_validate(e: &GeoInstancingExport) -> bool {
82 e.instances.iter().all(|i| {
83 let q = i.rotation;
84 let len_sq = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
85 (len_sq - 1.0).abs() < 0.1
86 })
87}
88
89#[allow(dead_code)]
91pub fn geo_instancing_to_json(e: &GeoInstancingExport) -> String {
92 format!(
93 "{{\"instances\":{},\"unique_meshes\":{}}}",
94 gi_count(e),
95 unique_mesh_count(e)
96 )
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102 #[test]
103 fn test_new() {
104 let e = new_geo_instancing_export();
105 assert_eq!(gi_count(&e), 0);
106 }
107 #[test]
108 fn test_add() {
109 let mut e = new_geo_instancing_export();
110 add_instance(&mut e, 0, [1.0, 0.0, 0.0]);
111 assert_eq!(gi_count(&e), 1);
112 }
113 #[test]
114 fn test_add_full() {
115 let mut e = new_geo_instancing_export();
116 add_instance_full(&mut e, 0, [0.0; 3], [0.0, 0.0, 0.0, 1.0], [2.0; 3]);
117 assert_eq!(gi_count(&e), 1);
118 }
119 #[test]
120 fn test_instances_of() {
121 let mut e = new_geo_instancing_export();
122 add_instance(&mut e, 0, [0.0; 3]);
123 add_instance(&mut e, 0, [1.0; 3]);
124 add_instance(&mut e, 1, [0.0; 3]);
125 assert_eq!(instances_of_mesh(&e, 0), 2);
126 }
127 #[test]
128 fn test_unique() {
129 let mut e = new_geo_instancing_export();
130 add_instance(&mut e, 0, [0.0; 3]);
131 add_instance(&mut e, 1, [0.0; 3]);
132 assert_eq!(unique_mesh_count(&e), 2);
133 }
134 #[test]
135 fn test_validate() {
136 let mut e = new_geo_instancing_export();
137 add_instance(&mut e, 0, [0.0; 3]);
138 assert!(gi_validate(&e));
139 }
140 #[test]
141 fn test_to_json() {
142 let e = new_geo_instancing_export();
143 assert!(geo_instancing_to_json(&e).contains("\"instances\":0"));
144 }
145 #[test]
146 fn test_empty_unique() {
147 let e = new_geo_instancing_export();
148 assert_eq!(unique_mesh_count(&e), 0);
149 }
150 #[test]
151 fn test_position() {
152 let mut e = new_geo_instancing_export();
153 add_instance(&mut e, 0, [5.0, 3.0, 1.0]);
154 assert!((e.instances[0].position[0] - 5.0).abs() < 1e-6);
155 }
156 #[test]
157 fn test_default_scale() {
158 let mut e = new_geo_instancing_export();
159 add_instance(&mut e, 0, [0.0; 3]);
160 assert!((e.instances[0].scale[0] - 1.0).abs() < 1e-6);
161 }
162}