1#![allow(dead_code)]
2#[allow(dead_code)]
8pub struct ThreeJsGeometry {
9 pub uuid: String,
10 pub vertices: Vec<f32>,
11 pub faces: Vec<u32>,
12}
13
14#[allow(dead_code)]
15pub struct ThreeJsObject {
16 pub name: String,
17 pub geometry_uuid: String,
18 pub position: [f32; 3],
19}
20
21#[allow(dead_code)]
22pub struct ThreeJsScene {
23 pub objects: Vec<ThreeJsObject>,
24 pub geometries: Vec<ThreeJsGeometry>,
25}
26
27#[allow(dead_code)]
28pub fn new_three_js_scene() -> ThreeJsScene {
29 ThreeJsScene {
30 objects: Vec::new(),
31 geometries: Vec::new(),
32 }
33}
34
35#[allow(dead_code)]
36pub fn add_geometry(scene: &mut ThreeJsScene, uuid: &str, verts: Vec<f32>, faces: Vec<u32>) {
37 scene.geometries.push(ThreeJsGeometry {
38 uuid: uuid.to_string(),
39 vertices: verts,
40 faces,
41 });
42}
43
44#[allow(dead_code)]
45pub fn add_object(scene: &mut ThreeJsScene, name: &str, geo_uuid: &str, pos: [f32; 3]) {
46 scene.objects.push(ThreeJsObject {
47 name: name.to_string(),
48 geometry_uuid: geo_uuid.to_string(),
49 position: pos,
50 });
51}
52
53#[allow(dead_code)]
54pub fn export_threejs_to_json(scene: &ThreeJsScene) -> String {
55 let mut s = "{\"geometries\":[".to_string();
56 for (i, g) in scene.geometries.iter().enumerate() {
57 if i > 0 {
58 s.push(',');
59 }
60 s.push_str(&format!(
61 "{{\"uuid\":\"{}\",\"vertex_count\":{},\"face_count\":{}}}",
62 g.uuid,
63 g.vertices.len(),
64 g.faces.len()
65 ));
66 }
67 s.push_str("],\"objects\":[");
68 for (i, o) in scene.objects.iter().enumerate() {
69 if i > 0 {
70 s.push(',');
71 }
72 s.push_str(&format!(
73 "{{\"name\":\"{}\",\"geometry\":\"{}\",\"position\":[{},{},{}]}}",
74 o.name, o.geometry_uuid, o.position[0], o.position[1], o.position[2]
75 ));
76 }
77 s.push_str("]}");
78 s
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn new_scene_empty() {
87 let s = new_three_js_scene();
88 assert!(s.objects.is_empty());
89 assert!(s.geometries.is_empty());
90 }
91
92 #[test]
93 fn add_geometry_stored() {
94 let mut s = new_three_js_scene();
95 add_geometry(&mut s, "uuid-1", vec![0.0, 0.0, 0.0], vec![0, 1, 2]);
96 assert_eq!(s.geometries.len(), 1);
97 }
98
99 #[test]
100 fn geometry_uuid_stored() {
101 let mut s = new_three_js_scene();
102 add_geometry(&mut s, "my-uuid", vec![], vec![]);
103 assert_eq!(s.geometries[0].uuid, "my-uuid");
104 }
105
106 #[test]
107 fn add_object_stored() {
108 let mut s = new_three_js_scene();
109 add_object(&mut s, "mesh1", "uuid-1", [0.0, 0.0, 0.0]);
110 assert_eq!(s.objects.len(), 1);
111 }
112
113 #[test]
114 fn object_position_stored() {
115 let mut s = new_three_js_scene();
116 add_object(&mut s, "o", "u", [1.0, 2.0, 3.0]);
117 assert!((s.objects[0].position[2] - 3.0).abs() < 1e-6);
118 }
119
120 #[test]
121 fn export_json_contains_uuid() {
122 let mut s = new_three_js_scene();
123 add_geometry(&mut s, "test-geo-uuid", vec![], vec![]);
124 let j = export_threejs_to_json(&s);
125 assert!(j.contains("test-geo-uuid"));
126 }
127
128 #[test]
129 fn export_json_contains_object_name() {
130 let mut s = new_three_js_scene();
131 add_object(&mut s, "MyMesh", "u", [0.0, 0.0, 0.0]);
132 let j = export_threejs_to_json(&s);
133 assert!(j.contains("MyMesh"));
134 }
135
136 #[test]
137 fn geometry_vertices_stored() {
138 let mut s = new_three_js_scene();
139 add_geometry(&mut s, "u", vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0], vec![]);
140 assert_eq!(s.geometries[0].vertices.len(), 6);
141 }
142
143 #[test]
144 fn geometry_faces_stored() {
145 let mut s = new_three_js_scene();
146 add_geometry(&mut s, "u", vec![], vec![0, 1, 2]);
147 assert_eq!(s.geometries[0].faces.len(), 3);
148 }
149}