1use crate::bsvo::{read_bsvo, write_bsvo, write_empty_bsvo, BsvoHeader};
2use crate::bvox::{append_to_bvox, read_bvox, write_bvox, write_empty_bvox, BvoxHeader, DEFAULT_CHUNK_RES, DEFAULT_CHUNK_SIZE};
3use crate::svo::{DEFAULT_SVO_MAX_DEPTH, SVO};
4use crate::vox::{morton_decode_3d_grid, morton_encode_3d_grid, pos_to_index, DEFAULT_VOX_MAT};
5use glam::Vec3;
6use rand::distributions::{Bernoulli, Distribution};
7use rand::thread_rng;
8use std::error::Error;
9
10pub mod bsvo;
11pub mod svo;
12pub mod vox;
13pub mod bvox;
14pub mod rle;
15
16const CHUNK_RES: u32 = DEFAULT_CHUNK_RES;
21const CHUNK_SIZE: u32 = DEFAULT_CHUNK_SIZE;
22const SVO_MAX_DEPTH: u8 = DEFAULT_SVO_MAX_DEPTH;
23
24pub fn gen_rand_vox_grid(size: usize, probability_of_one: f64) -> Vec<u8> {
25 let mut rng = thread_rng();
26 let dist = Bernoulli::new(probability_of_one).unwrap();
27 (0..size).map(|_| dist.sample(&mut rng) as u8).collect()
28}
29
30pub fn test_empty_bsvo_and_bvox() -> Result<(), Box<dyn Error>> {
31 let bvox_header = BvoxHeader::default();
32 write_empty_bvox("output/empty.bvox", bvox_header)?;
33
34 let bsvo_header = BsvoHeader::default();
35 write_empty_bsvo("output/empty.bsvo", bsvo_header)?;
36
37 Ok(())
38}
39
40pub fn test_bvox_read_write() -> Result<(), Box<dyn Error>> {
41 let chunk = gen_rand_vox_grid(CHUNK_SIZE as usize, 0.1);
42
43 let mut morton_chunk = vec![0; CHUNK_SIZE as usize];
44 morton_encode_3d_grid(&chunk, CHUNK_RES, CHUNK_SIZE, &mut morton_chunk);
45
46 let chunk_data = vec![morton_chunk.clone()];
47
48 let header = BvoxHeader::new(CHUNK_RES, CHUNK_SIZE, true, true);
49 write_bvox("output/test_bvox_rw.bvox", &chunk_data, header)?;
50
51 let (_, read_chunk_data) = read_bvox("output/test_bvox_rw.bvox")?;
52
53 let mut decoded_morton = vec![0; CHUNK_SIZE as usize];
54 morton_decode_3d_grid(&read_chunk_data[0], CHUNK_RES, CHUNK_SIZE, &mut decoded_morton);
55
56 for i in 0..CHUNK_SIZE {
57 assert_eq!(chunk[i as usize], decoded_morton[i as usize]);
58 }
59
60 Ok(())
61}
62
63pub fn test_bvox_append() -> Result<(), Box<dyn Error>> {
64 let chunk = gen_rand_vox_grid(CHUNK_SIZE as usize, 0.1);
65
66 let mut morton_chunk = vec![0; CHUNK_SIZE as usize];
67 morton_encode_3d_grid(&chunk, CHUNK_RES, CHUNK_SIZE, &mut morton_chunk);
68
69 let header = BvoxHeader::new(CHUNK_RES, CHUNK_SIZE, true, true);
70 write_empty_bvox("output/test_bvox_append.bvox", header)?;
71 append_to_bvox("output/test_bvox_append.bvox", &morton_chunk)?;
72
73 let (_, read_chunk_data) = read_bvox("output/test_bvox_append.bvox")?;
74
75 let mut decoded_morton = vec![0; CHUNK_SIZE as usize];
76 morton_decode_3d_grid(&read_chunk_data[0], CHUNK_RES, CHUNK_SIZE, &mut decoded_morton);
77
78 for i in 0..CHUNK_SIZE {
79 assert_eq!(chunk[i as usize], decoded_morton[i as usize]);
80 }
81
82 Ok (())
83}
84
85pub fn test_bvox_compression() -> Result<(), Box<dyn Error>> {
86 let chunk = gen_rand_vox_grid(CHUNK_SIZE as usize, 0.1);
87 let chunk_data = vec![chunk];
88
89 let header_normal = BvoxHeader::new(CHUNK_RES, CHUNK_SIZE, false, false);
90 write_bvox("output/test_bvox_compression_base.bvox", &chunk_data, header_normal)?;
91
92 let header_rle = BvoxHeader::new(CHUNK_RES, CHUNK_SIZE, true, false);
93 write_bvox("output/test_bvox_compression_rle.bvox", &chunk_data, header_rle)?;
94
95 let (_, read_normal) = read_bvox("output/test_bvox_compression_base.bvox")?;
96 let (_, read_rle) = read_bvox("output/test_bvox_compression_rle.bvox")?;
97
98 for i in 0..CHUNK_SIZE {
99 assert_eq!(read_normal[0][i as usize], read_rle[0][i as usize]);
100 }
101
102 Ok(())
103}
104
105pub fn test_bsvo_read_write() -> Result<(), Box<dyn Error>> {
106 let chunk = gen_rand_vox_grid(CHUNK_SIZE as usize, 0.1);
107
108 let mut morton_chunk = vec![0u8; CHUNK_SIZE as usize];
109 morton_encode_3d_grid(&chunk, CHUNK_RES, CHUNK_SIZE, &mut morton_chunk);
110
111 let chunk_data = vec![morton_chunk.clone()];
112
113 let header = BvoxHeader::new(CHUNK_RES, CHUNK_SIZE, true, true);
114 write_bvox("output/test_bsvo_rw.bvox", &chunk_data, header)?;
115
116 let (_, read_chunk_data) = read_bvox("output/test_bsvo_rw.bvox")?;
117
118 let svo = SVO::from_grid(&read_chunk_data[0], CHUNK_RES, SVO_MAX_DEPTH);
119
120 let bsvo_header = BsvoHeader::new(svo.depth, svo.root_span, true);
121 write_bsvo("output/test_bsvo_rw.bsvo", &svo, bsvo_header)?;
122
123 let (_, read_svo) = read_bsvo("output/test_bsvo_rw.bsvo")?;
124
125 for i in 0..read_svo.nodes.len() {
126 assert_eq!(svo.nodes[i], read_svo.nodes[i]);
127 }
128
129 let svo_node_count = svo.count_leaf_nodes();
130 let chunk_node_count = chunk.iter().filter(|&&v| v > 0).count() as u32;
131 assert_eq!(svo_node_count, chunk_node_count);
132
133 Ok(())
134}
135
136pub fn test_gen_random_svo() -> Result<(), Box<dyn Error>> {
137 let mut svo = SVO::new(SVO_MAX_DEPTH);
138 svo.gen_random_svo(0);
139
140 let bsvo_header = BsvoHeader::new(svo.depth, svo.root_span, false);
141 write_bsvo("output/random_svo.bsvo", &svo, bsvo_header)?;
142
143 let (_, read_svo) = read_bsvo("output/random_svo.bsvo")?;
144
145 for i in 0..svo.nodes.len() {
146 assert_eq!(svo.nodes[i], read_svo.nodes[i]);
147 }
148
149 Ok(())
150}
151
152pub fn cube_grid_and_svo() -> Result<(), Box<dyn Error>> {
153 let mut chunk = vec![0; CHUNK_SIZE as usize];
154 let min = CHUNK_RES / 4;
155 let max = 3 * CHUNK_RES / 4;
156
157 for x in min..max {
158 for y in min..max {
159 for z in min..max {
160 chunk[pos_to_index(x, y, z, CHUNK_RES) as usize] = DEFAULT_VOX_MAT;
161 }
162 }
163 }
164
165 let mut morton_chunk = vec![0u8; CHUNK_SIZE as usize];
166 morton_encode_3d_grid(&chunk, CHUNK_RES, CHUNK_SIZE, &mut morton_chunk);
167
168 let chunk_data = vec![morton_chunk.clone()];
169
170 let header = BvoxHeader::new(CHUNK_RES, CHUNK_SIZE, true, true);
171 write_bvox("output/cube.bvox", &chunk_data, header)?;
172
173 let (_, read_chunk_data) = read_bvox("output/cube.bvox")?;
174
175 let svo = SVO::from_grid(&read_chunk_data[0], CHUNK_RES, SVO_MAX_DEPTH);
176
177 let bsvo_header = BsvoHeader::new(svo.depth, svo.root_span, true);
178 write_bsvo("output/cube.bsvo", &svo, bsvo_header)?;
179
180 Ok (())
181}
182
183pub fn tiny_grid_and_svo() -> Result<(), Box<dyn Error>> {
184 let chunk_res = 8;
185 let chunk_size = chunk_res * chunk_res * chunk_res;
186 let depth = 3;
187
188 let mut chunk = vec![0; chunk_size as usize];
189 let min = 2;
190 let max = 4;
191
192 for x in min..max {
193 for y in min..max {
194 for z in min..max {
195 chunk[pos_to_index(x, y, z, chunk_res) as usize] = DEFAULT_VOX_MAT;
196 }
197 }
198 }
199
200 let mut morton_chunk = vec![0; chunk_size as usize];
201 morton_encode_3d_grid(&chunk, chunk_res, chunk_size, &mut morton_chunk);
202
203 let chunk_data = vec![morton_chunk.clone()];
204
205 let header = BvoxHeader::new(chunk_res, chunk_size, true, true);
206 write_bvox("output/tiny_grid.bvox", &chunk_data, header)?;
207
208 let (_, read_chunk_data) = read_bvox("output/tiny_grid.bvox")?;
209
210 let svo = SVO::from_grid(&read_chunk_data[0], chunk_res, depth);
211
212 let bsvo_header = BsvoHeader::new(svo.depth, svo.root_span, true);
213 write_bsvo("output/tiny_svo.bsvo", &svo, bsvo_header)?;
214
215 Ok(())
216}
217
218pub fn test_svo_simplest() {
219 let mut svo = SVO::new(1);
220 svo.insert_node(Vec3::splat(0.0));
221
222 let bsvo_header = BsvoHeader::new(svo.depth, svo.root_span, false);
223 write_bsvo("output/simplest.bsvo", &svo, bsvo_header).unwrap();
224}
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229
230 #[test]
231 fn gen_empty() {
232 test_empty_bsvo_and_bvox().unwrap();
233 }
234
235 #[test]
236 fn bvox_append() {
237 test_bvox_append().unwrap();
238 }
239
240 #[test]
241 fn random_svo() {
242 test_gen_random_svo().unwrap();
243 }
244
245 #[test]
246 fn bvox_rw() {
247 test_bvox_read_write().unwrap();
248 }
249
250 #[test]
251 fn bvox_compression() {
252 test_bvox_compression().unwrap();
253 }
254
255 #[test]
256 fn bsvo_rw() {
257 test_bsvo_read_write().unwrap();
258 }
259
260 #[test]
261 fn cube() {
262 cube_grid_and_svo().unwrap();
263 }
264
265 #[test]
266 fn tiny_grid_and_svo_for_testing() {
267 tiny_grid_and_svo().unwrap();
268 }
269
270 #[test]
271 fn simplest() {
272 test_svo_simplest();
273 }
274}