bones_framework/networking/
proto.rs1use numquant::{IntRange, Quantized};
5
6use crate::prelude::*;
7
8#[derive(Debug, Deref, DerefMut, Default)]
11pub struct DenseMoveDirection(pub Vec2);
12
13type MoveDirQuant = Quantized<IntRange<u16, 0b11111, 0, 1>>;
16
17impl From<u16> for DenseMoveDirection {
18 fn from(bits: u16) -> Self {
19 let bit_length = 6;
22 let quantized = 0b011111;
23 let sign = 0b100000;
24 let x_move_bits = bits & quantized;
26 let x_move_sign = if bits & sign == 0 { 1.0 } else { -1.0 };
27 let y_move_bits = (bits >> bit_length) & quantized;
29 let y_move_sign = if (bits >> bit_length) & sign == 0 {
30 1.0
31 } else {
32 -1.0
33 };
34
35 let mut x = MoveDirQuant::from_raw(x_move_bits).to_f32();
37 x *= x_move_sign;
38 if x.abs() < 0.02 {
39 x = 0.0;
40 }
41 let mut y = MoveDirQuant::from_raw(y_move_bits).to_f32();
42 y *= y_move_sign;
43 if y.abs() < 0.02 {
44 y = 0.0;
45 }
46
47 DenseMoveDirection(Vec2::new(x, y))
48 }
49}
50
51impl From<DenseMoveDirection> for u16 {
52 fn from(dir: DenseMoveDirection) -> Self {
53 let x_bits = MoveDirQuant::from_f32(dir.x.abs()).raw();
54 let y_bits = MoveDirQuant::from_f32(dir.y.abs()).raw();
55 let x_sign_bit = if dir.x.is_sign_positive() {
56 0
57 } else {
58 0b100000
59 };
60 let y_sign_bit = if dir.y.is_sign_positive() {
61 0
62 } else {
63 0b100000
64 };
65
66 (x_bits | x_sign_bit) | ((y_bits | y_sign_bit) << 6)
67 }
68}
69
70impl From<u32> for DenseMoveDirection {
71 fn from(bits: u32) -> Self {
72 let bits_16 = bits as u16;
73 bits_16.into()
74 }
75}
76
77impl From<DenseMoveDirection> for u32 {
78 fn from(dir: DenseMoveDirection) -> Self {
79 let bits_16 = u16::from(dir);
80 bits_16 as u32
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use crate::prelude::proto::DenseMoveDirection;
87
88 #[test]
89 pub fn zeroed_dense_move_dir() {
93 let bits: u16 = 0;
94 let dense_move_dir = DenseMoveDirection::from(bits);
95 assert_eq!(dense_move_dir.0, glam::Vec2::ZERO);
96 }
97}