1use crate::{BBox, BBox3D, Point, Point3D, BBOX};
2
3use libm::round;
4
5use alloc::{vec, vec::Vec};
6
7use core::cmp::Ordering;
8
9pub trait CustomOrd {
11 fn custom_cmp(&self, other: &Self) -> Ordering;
13}
14impl CustomOrd for u64 {
15 fn custom_cmp(&self, other: &Self) -> Ordering {
16 self.partial_cmp(other).unwrap_or(Ordering::Equal)
17 }
18}
19impl CustomOrd for i64 {
20 fn custom_cmp(&self, other: &Self) -> Ordering {
21 self.partial_cmp(other).unwrap_or(Ordering::Equal)
22 }
23}
24impl CustomOrd for f32 {
25 fn custom_cmp(&self, other: &Self) -> Ordering {
26 if self.is_nan() || other.is_nan() {
27 Ordering::Equal } else {
29 self.partial_cmp(other).unwrap_or(Ordering::Equal)
30 }
31 }
32}
33impl CustomOrd for f64 {
34 fn custom_cmp(&self, other: &Self) -> Ordering {
35 if self.is_nan() || other.is_nan() {
36 Ordering::Equal } else {
38 self.partial_cmp(other).unwrap_or(Ordering::Equal)
39 }
40 }
41}
42#[derive(Debug, Default, Clone, Copy)]
44pub struct CustomOrdWrapper<T>(pub T);
45impl<T: CustomOrd> CustomOrd for CustomOrdWrapper<T> {
46 fn custom_cmp(&self, other: &Self) -> Ordering {
47 self.0.custom_cmp(&other.0)
48 }
49}
50impl<T: CustomOrd> PartialOrd for CustomOrdWrapper<T> {
51 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
52 Some(self.cmp(other))
53 }
54}
55impl<T: CustomOrd> Eq for CustomOrdWrapper<T> {}
56impl<T: CustomOrd> PartialEq for CustomOrdWrapper<T> {
57 fn eq(&self, other: &Self) -> bool {
58 self.0.custom_cmp(&other.0) == Ordering::Equal
59 }
60}
61impl<T: CustomOrd> Ord for CustomOrdWrapper<T> {
62 fn cmp(&self, other: &Self) -> Ordering {
63 self.custom_cmp(other)
64 }
65}
66
67pub fn command_encode(cmd: u8, len: u32) -> u64 {
69 ((len << 3) + ((cmd as u32) & 0x7)) as u64
70}
71
72#[derive(Debug, PartialEq)]
74pub struct Command {
75 pub cmd: u8,
77 pub len: u32,
79}
80
81pub fn command_decode(cmd: u64) -> Command {
83 Command { cmd: (cmd & 0x7) as u8, len: (cmd >> 3) as u32 }
84}
85
86pub fn zigzag(n: i32) -> u32 {
88 ((n << 1) ^ (n >> 31)) as u32
89}
90
91pub fn zagzig(n: u32) -> i32 {
93 ((n >> 1) as i32) ^ -(n as i32 & 1)
94}
95
96pub fn weave_2d(a: u16, b: u16) -> u32 {
99 let mut a = a as u32;
100 let mut b = b as u32;
101 let mut result: u32 = 0;
102 for i in 0..16 {
103 result |= (a & 1) << (i * 2); result |= (b & 1) << (i * 2 + 1); a >>= 1;
107 b >>= 1;
108 }
109
110 result
111}
112
113pub fn unweave_2d(num: u32) -> (u16, u16) {
115 let mut num = num;
116 let mut a: u16 = 0;
117 let mut b: u16 = 0;
118 for i in 0..16 {
119 let bit = 1 << i;
120 if num & 1 != 0 {
121 a |= bit;
122 }
123 if num & 2 != 0 {
124 b |= bit;
125 }
126 num >>= 2;
127 }
128
129 (a, b)
130}
131
132pub fn weave_3d(a: u16, b: u16, c: u16) -> u64 {
135 let mut result: u64 = 0;
137 let mut a: u64 = a.into();
138 let mut b: u64 = b.into();
139 let mut c: u64 = c.into();
140
141 for i in 0..16 {
142 if a & 1 != 0 {
143 result |= 1 << (i * 3);
144 } if b & 1 != 0 {
146 result |= 1 << (i * 3 + 1);
147 } if c & 1 != 0 {
149 result |= 1 << (i * 3 + 2);
150 } a >>= 1;
153 b >>= 1;
154 c >>= 1;
155 }
156
157 result
158}
159
160pub fn unweave_3d(num: u64) -> (u32, u32, u32) {
163 let mut a = 0;
164 let mut b = 0;
165 let mut c = 0;
166 let mut num = num; for i in 0..16 {
169 let bit = 1 << i;
170 if (num & 1) != 0 {
171 a |= bit;
172 }
173 if (num & 2) != 0 {
174 b |= bit;
175 }
176 if (num & 4) != 0 {
177 c |= bit;
178 }
179 num >>= 3; }
181
182 (a, b, c)
183}
184
185pub fn weave_and_delta_encode_array(array: &[Point]) -> Vec<u64> {
187 let mut res = Vec::new();
188 let mut prev_x = 0;
189 let mut prev_y = 0;
190
191 for point in array.iter() {
192 let pos_x = zigzag(point.x - prev_x);
193 let pos_y = zigzag(point.y - prev_y);
194 res.push(weave_2d(pos_x as u16, pos_y as u16).into());
195 prev_x = point.x;
196 prev_y = point.y;
197 }
198
199 res
200}
201
202pub fn unweave_and_delta_decode_array(array: &[u64]) -> Vec<Point> {
204 let mut res = Vec::new();
205 let mut prev_x = 0;
206 let mut prev_y = 0;
207
208 for &encoded_num in array {
209 let (a, b) = unweave_2d(encoded_num as u32);
210 let x = zagzig(a as u32) + prev_x;
211 let y = zagzig(b as u32) + prev_y;
212 res.push(Point::new(x, y));
213 prev_x = x;
214 prev_y = y;
215 }
216
217 res
218}
219
220pub fn weave_and_delta_encode_3d_array(array: &[Point3D]) -> Vec<u64> {
222 let mut res = Vec::new();
223 let mut offset_x = 0;
224 let mut offset_y = 0;
225 let mut offset_z = 0;
226
227 for point in array.iter() {
228 let pos_x = zigzag(point.x - offset_x);
229 let pos_y = zigzag(point.y - offset_y);
230 let pos_z = zigzag(point.z - offset_z);
231 res.push(weave_3d(pos_x as u16, pos_y as u16, pos_z as u16));
232 offset_x = point.x;
233 offset_y = point.y;
234 offset_z = point.z;
235 }
236
237 res
238}
239
240pub fn unweave_and_delta_decode_3d_array(array: &[u64]) -> Vec<Point3D> {
242 let mut res = Vec::new();
243 let mut offset_x = 0;
244 let mut offset_y = 0;
245 let mut offset_z = 0;
246
247 for &encoded_num in array {
248 let (a, b, c) = unweave_3d(encoded_num);
249 let x = zagzig(a) + offset_x;
250 let y = zagzig(b) + offset_y;
251 let z = zagzig(c) + offset_z;
252 res.push(Point3D::new(x, y, z));
253 offset_x = x;
254 offset_y = y;
255 offset_z = z;
256 }
257
258 res
259}
260
261pub fn delta_encode_array(array: &[u32]) -> Vec<u32> {
263 let mut res = Vec::new();
264 let mut offset = 0;
265
266 for &num in array {
267 let num = num as i32;
268 let encoded = zigzag(num - offset);
269 res.push(encoded);
270 offset = num;
271 }
272
273 res
274}
275
276pub fn delta_decode_array(array: &[u32]) -> Vec<u32> {
278 let mut res = Vec::new();
279 let mut offset = 0;
280
281 for &encoded_num in array {
282 let num = zagzig(encoded_num) + offset;
283 res.push(num as u32);
284 offset = num;
285 }
286
287 res
288}
289
290pub fn delta_encode_sorted_array(array: &[i32]) -> Vec<u32> {
292 let mut res = Vec::new();
293 let mut offset = 0;
294
295 for &num in array {
296 let delta = (num - offset) as u32; res.push(delta);
298 offset = num;
299 }
300
301 res
302}
303
304pub fn delta_decode_sorted_array(array: &[u32]) -> Vec<i32> {
306 let mut res = Vec::new();
307 let mut offset = 0;
308
309 for &encoded_num in array {
310 let num = encoded_num as i32 + offset; res.push(num);
312 offset = num;
313 }
314
315 res
316}
317
318pub fn quantize_lon(lon: f64) -> i32 {
322 round((lon + 180.0) * 16_777_215.0 / 360.0) as i32
323}
324
325pub fn quantize_lat(lat: f64) -> i32 {
329 ((lat + 90.0) * 16_777_215.0 / 180.0) as i32
330}
331
332pub fn dequantize_lon(q_lon: i32) -> f64 {
334 (q_lon as f64 * 360.0 / 16_777_215.0) - 180.0
335}
336
337pub fn dequantize_lat(q_lat: i32) -> f64 {
339 (q_lat as f64 * 180.0 / 16_777_215.0) - 90.0
340}
341
342pub fn pack24_bit_uint(buffer: &mut [u8], value: i32, offset: usize) {
344 buffer[offset] = ((value >> 16) & 0xff) as u8;
345 buffer[offset + 1] = ((value >> 8) & 0xff) as u8;
346 buffer[offset + 2] = (value & 0xff) as u8;
347}
348
349pub fn unpack24_bit_uint(buffer: &[u8], offset: usize) -> i32 {
351 ((buffer[offset] as i32) << 16)
352 | ((buffer[offset + 1] as i32) << 8)
353 | (buffer[offset + 2] as i32)
354}
355
356pub fn pack_float(buffer: &mut [u8], value: f32, offset: usize) {
358 let bytes: [u8; 4] = value.to_le_bytes(); buffer[offset..offset + 4].copy_from_slice(&bytes);
360}
361
362pub fn unpack_float(buffer: &[u8], offset: usize) -> f32 {
364 f32::from_le_bytes(buffer[offset..offset + 4].try_into().unwrap()) }
366
367impl BBox {
386 pub fn quantize(&self) -> Vec<u8> {
388 let mut buffer = vec![0u8; 12];
389
390 let q_lon1 = quantize_lon(self.left);
391 let q_lat1 = quantize_lat(self.bottom);
392 let q_lon2 = quantize_lon(self.right);
393 let q_lat2 = quantize_lat(self.top);
394
395 pack24_bit_uint(&mut buffer, q_lon1, 0);
396 pack24_bit_uint(&mut buffer, q_lat1, 3);
397 pack24_bit_uint(&mut buffer, q_lon2, 6);
398 pack24_bit_uint(&mut buffer, q_lat2, 9);
399
400 buffer
401 }
402
403 pub fn dequantize(buf: &[u8]) -> BBox {
405 let q_lon1 = unpack24_bit_uint(buf, 0);
406 let q_lat1 = unpack24_bit_uint(buf, 3);
407 let q_lon2 = unpack24_bit_uint(buf, 6);
408 let q_lat2 = unpack24_bit_uint(buf, 9);
409
410 BBox {
411 left: dequantize_lon(q_lon1),
412 bottom: dequantize_lat(q_lat1),
413 right: dequantize_lon(q_lon2),
414 top: dequantize_lat(q_lat2),
415 }
416 }
417}
418impl BBox3D {
419 pub fn quantize(&self) -> Vec<u8> {
421 let mut buffer = vec![0u8; 20];
422
423 let q_lon1 = quantize_lon(self.left);
424 let q_lat1 = quantize_lat(self.bottom);
425 let q_lon2 = quantize_lon(self.right);
426 let q_lat2 = quantize_lat(self.top);
427
428 pack24_bit_uint(&mut buffer, q_lon1, 0);
429 pack24_bit_uint(&mut buffer, q_lat1, 3);
430 pack24_bit_uint(&mut buffer, q_lon2, 6);
431 pack24_bit_uint(&mut buffer, q_lat2, 9);
432
433 pack_float(&mut buffer, self.near as f32, 12);
434 pack_float(&mut buffer, self.far as f32, 16);
435
436 buffer
437 }
438
439 pub fn dequantize(buf: &[u8]) -> BBox3D {
441 let q_lon1 = unpack24_bit_uint(buf, 0);
442 let q_lat1 = unpack24_bit_uint(buf, 3);
443 let q_lon2 = unpack24_bit_uint(buf, 6);
444 let q_lat2 = unpack24_bit_uint(buf, 9);
445
446 let near = unpack_float(buf, 12) as f64;
447 let far = unpack_float(buf, 16) as f64;
448
449 BBox3D {
450 left: dequantize_lon(q_lon1),
451 bottom: dequantize_lat(q_lat1),
452 right: dequantize_lon(q_lon2),
453 top: dequantize_lat(q_lat2),
454 near,
455 far,
456 }
457 }
458}
459
460impl BBOX {
461 pub fn quantize(&self) -> Vec<u8> {
463 match self {
464 BBOX::BBox(bbox) => bbox.quantize(),
465 BBOX::BBox3D(bbox) => bbox.quantize(),
466 }
467 }
468
469 pub fn dequantize(buf: &[u8]) -> BBOX {
471 buf.into()
472 }
473}
474
475impl From<&[u8]> for BBOX {
476 fn from(buf: &[u8]) -> Self {
477 if buf.len() == 12 {
478 BBOX::BBox(BBox::dequantize(buf))
479 } else {
480 BBOX::BBox3D(BBox3D::dequantize(buf))
481 }
482 }
483}