azalea_entity/
vec_delta_codec.rs

1use azalea_core::{delta::PositionDelta8, position::Vec3};
2
3#[derive(Debug, Clone, Default)]
4pub struct VecDeltaCodec {
5    base: Vec3,
6}
7
8impl VecDeltaCodec {
9    pub fn new(base: Vec3) -> Self {
10        Self { base }
11    }
12
13    pub fn decode(&self, delta: &PositionDelta8) -> Vec3 {
14        let x = delta.xa as i64;
15        let y = delta.ya as i64;
16        let z = delta.za as i64;
17
18        if x == 0 && y == 0 && z == 0 {
19            return self.base;
20        }
21
22        let new_x = if x == 0 {
23            self.base.x
24        } else {
25            decode(encode(self.base.x) + x)
26        };
27        let new_y = if y == 0 {
28            self.base.y
29        } else {
30            decode(encode(self.base.y) + y)
31        };
32        let new_z = if z == 0 {
33            self.base.z
34        } else {
35            decode(encode(self.base.z) + z)
36        };
37
38        Vec3::new(new_x, new_y, new_z)
39    }
40
41    pub fn encode_x(&self, pos: Vec3) -> i64 {
42        encode(pos.x) - encode(self.base.x)
43    }
44    pub fn encode_y(&self, pos: Vec3) -> i64 {
45        encode(pos.y) - encode(self.base.y)
46    }
47    pub fn encode_z(&self, pos: Vec3) -> i64 {
48        encode(pos.z) - encode(self.base.z)
49    }
50
51    pub fn set_base(&mut self, pos: Vec3) {
52        self.base = pos;
53    }
54    pub fn base(&self) -> Vec3 {
55        self.base
56    }
57}
58
59fn encode(value: f64) -> i64 {
60    (value * 4096.).round() as i64
61}
62fn decode(value: i64) -> f64 {
63    (value as f64) / 4096.
64}