oxihuman_export/
collision_box_export.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
7pub struct CollisionBox {
8 pub name: String,
9 pub center: [f32; 3],
10 pub half_extents: [f32; 3],
11 pub rotation: [f32; 4], }
13
14#[allow(dead_code)]
15pub struct CollisionBoxBundle {
16 pub boxes: Vec<CollisionBox>,
17}
18
19#[allow(dead_code)]
20pub fn new_collision_box_bundle() -> CollisionBoxBundle {
21 CollisionBoxBundle { boxes: vec![] }
22}
23
24#[allow(dead_code)]
25pub fn add_collision_box(bundle: &mut CollisionBoxBundle, b: CollisionBox) {
26 bundle.boxes.push(b);
27}
28
29#[allow(dead_code)]
30pub fn collision_box_count(bundle: &CollisionBoxBundle) -> usize {
31 bundle.boxes.len()
32}
33
34#[allow(dead_code)]
35pub fn box_volume(b: &CollisionBox) -> f32 {
36 b.half_extents[0] * b.half_extents[1] * b.half_extents[2] * 8.0
37}
38
39#[allow(dead_code)]
40pub fn box_surface_area(b: &CollisionBox) -> f32 {
41 let [ex, ey, ez] = b.half_extents;
42 8.0 * (ex * ey + ey * ez + ez * ex)
43}
44
45#[allow(dead_code)]
46pub fn default_collision_box(name: &str) -> CollisionBox {
47 CollisionBox {
48 name: name.to_string(),
49 center: [0.0; 3],
50 half_extents: [0.5, 0.5, 0.5],
51 rotation: [0.0, 0.0, 0.0, 1.0],
52 }
53}
54
55#[allow(dead_code)]
56pub fn validate_collision_box(b: &CollisionBox) -> bool {
57 b.half_extents.iter().all(|&e| e > 0.0) && !b.name.is_empty()
58}
59
60#[allow(dead_code)]
61pub fn collision_box_to_json(b: &CollisionBox) -> String {
62 format!(
63 "{{\"name\":\"{}\",\"center\":[{},{},{}],\"half_extents\":[{},{},{}]}}",
64 b.name,
65 b.center[0],
66 b.center[1],
67 b.center[2],
68 b.half_extents[0],
69 b.half_extents[1],
70 b.half_extents[2]
71 )
72}
73
74#[allow(dead_code)]
75pub fn collision_box_bundle_to_json(bundle: &CollisionBoxBundle) -> String {
76 format!("{{\"box_count\":{}}}", bundle.boxes.len())
77}
78
79#[allow(dead_code)]
80pub fn find_box_by_name<'a>(
81 bundle: &'a CollisionBoxBundle,
82 name: &str,
83) -> Option<&'a CollisionBox> {
84 bundle.boxes.iter().find(|b| b.name == name)
85}
86
87#[allow(dead_code)]
88pub fn total_box_volume(bundle: &CollisionBoxBundle) -> f32 {
89 bundle.boxes.iter().map(box_volume).sum()
90}
91
92#[allow(dead_code)]
93pub fn point_in_box(b: &CollisionBox, p: [f32; 3]) -> bool {
94 (p[0] - b.center[0]).abs() <= b.half_extents[0]
96 && (p[1] - b.center[1]).abs() <= b.half_extents[1]
97 && (p[2] - b.center[2]).abs() <= b.half_extents[2]
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 fn unit_box() -> CollisionBox {
105 default_collision_box("torso")
106 }
107
108 #[test]
109 fn test_add_box() {
110 let mut b = new_collision_box_bundle();
111 add_collision_box(&mut b, unit_box());
112 assert_eq!(collision_box_count(&b), 1);
113 }
114
115 #[test]
116 fn test_box_volume() {
117 let b = unit_box();
118 assert!((box_volume(&b) - 1.0).abs() < 1e-5);
119 }
120
121 #[test]
122 fn test_box_surface_area() {
123 let b = unit_box();
124 assert!((box_surface_area(&b) - 6.0).abs() < 1e-5);
125 }
126
127 #[test]
128 fn test_validate_box() {
129 let b = unit_box();
130 assert!(validate_collision_box(&b));
131 }
132
133 #[test]
134 fn test_validate_zero_extent_fails() {
135 let mut b = unit_box();
136 b.half_extents[0] = 0.0;
137 assert!(!validate_collision_box(&b));
138 }
139
140 #[test]
141 fn test_find_box_found() {
142 let mut bundle = new_collision_box_bundle();
143 add_collision_box(&mut bundle, unit_box());
144 assert!(find_box_by_name(&bundle, "torso").is_some());
145 }
146
147 #[test]
148 fn test_point_in_box() {
149 let b = unit_box();
150 assert!(point_in_box(&b, [0.0, 0.0, 0.0]));
151 assert!(!point_in_box(&b, [1.0, 0.0, 0.0]));
152 }
153
154 #[test]
155 fn test_total_volume() {
156 let mut bundle = new_collision_box_bundle();
157 add_collision_box(&mut bundle, unit_box());
158 add_collision_box(&mut bundle, unit_box());
159 assert!((total_box_volume(&bundle) - 2.0).abs() < 1e-5);
160 }
161
162 #[test]
163 fn test_to_json() {
164 let b = unit_box();
165 let j = collision_box_to_json(&b);
166 assert!(j.contains("torso"));
167 }
168
169 #[test]
170 fn test_bundle_to_json() {
171 let mut bundle = new_collision_box_bundle();
172 add_collision_box(&mut bundle, unit_box());
173 let j = collision_box_bundle_to_json(&bundle);
174 assert!(j.contains("box_count"));
175 }
176}