aboutsummaryrefslogtreecommitdiff
path: root/azalea-entity/src/vec_delta_codec.rs
blob: 5221ec472bbe5fba6c550529429f960c3a7f81c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use azalea_core::{delta::PositionDelta8, position::Vec3};

#[derive(Clone, Debug, Default)]
pub struct VecDeltaCodec {
    base: Vec3,
}

impl VecDeltaCodec {
    pub fn new(base: Vec3) -> Self {
        Self { base }
    }

    pub fn decode(&self, delta: &PositionDelta8) -> Vec3 {
        let x = delta.xa as i64;
        let y = delta.ya as i64;
        let z = delta.za as i64;

        if x == 0 && y == 0 && z == 0 {
            return self.base;
        }

        let new_x = if x == 0 {
            self.base.x
        } else {
            decode(encode(self.base.x) + x)
        };
        let new_y = if y == 0 {
            self.base.y
        } else {
            decode(encode(self.base.y) + y)
        };
        let new_z = if z == 0 {
            self.base.z
        } else {
            decode(encode(self.base.z) + z)
        };

        Vec3::new(new_x, new_y, new_z)
    }

    pub fn encode_x(&self, pos: Vec3) -> i64 {
        encode(pos.x) - encode(self.base.x)
    }
    pub fn encode_y(&self, pos: Vec3) -> i64 {
        encode(pos.y) - encode(self.base.y)
    }
    pub fn encode_z(&self, pos: Vec3) -> i64 {
        encode(pos.z) - encode(self.base.z)
    }

    pub fn set_base(&mut self, pos: Vec3) {
        self.base = pos;
    }
    pub fn base(&self) -> Vec3 {
        self.base
    }
}

fn encode(value: f64) -> i64 {
    (value * 4096.).round() as i64
}
fn decode(value: i64) -> f64 {
    (value as f64) / 4096.
}