Botcraft 1.21.10
Loading...
Searching...
No Matches
LpVec3.hpp
Go to the documentation of this file.
1#if PROTOCOL_VERSION > 772 /* > 1.21.8 */
2#pragma once
3
5
6#include <cmath>
7
8namespace ProtocolCraft
9{
10 class LpVec3 : public NetworkType
11 {
12 SERIALIZED_FIELD(X, double);
13 SERIALIZED_FIELD(Y, double);
14 SERIALIZED_FIELD(Z, double);
15
18
19 protected:
20 virtual void ReadImpl(ReadIterator& iter, size_t& length) override
21 {
22 const short s = ReadData<short, unsigned char>(iter, length);
23 if (s == 0)
24 {
25 X = 0.0;
26 Y = 0.0;
27 Z = 0.0;
28 return;
29 }
30 const short s2 = ReadData<short, unsigned char>(iter, length);
31 const long long int l = ReadData<long long int, unsigned int>(iter, length);
32 const long long int l2 = (l << 16) | (static_cast<long long int>(s2) << 8) | static_cast<long long int>(s);
33 long long int l3 = s & 0b11;
34 if ((s & 0b100) == 4)
35 {
36 l3 |= (ReadData<long long int, VarInt>(iter, length) & 0xFFFFFFFFL) << 2;
37 }
38 auto unpack = [](const long long int l) { return std::min(static_cast<double>(l & 0x7FFFL), 32766.0) * 2.0 / 32766.0 - 1.0; };
39 X = unpack(l2 >> 3) * l3;
40 Y = unpack(l2 >> 18) * l3;
41 Z = unpack(l2 >> 33) * l3;
42 }
43
44 virtual void WriteImpl(WriteContainer& container) const override
45 {
46 auto sanitize = [](const double d) { return std::isnan(d) ? 0.0 : std::clamp(d, -1.7179869183E10, 1.7179869183E10); };
47 const double d3 = sanitize(X);
48 const double d2 = sanitize(Y);
49 const double d = sanitize(Z);
50
51 const double max = std::max(std::abs(d3), std::max(std::abs(d2), std::abs(d)));
52 if (max < 3.051944088384301E-5)
53 {
54 WriteData<unsigned char>(0, container);
55 return;
56 }
57
58 const long long int l = static_cast<long long int>(std::ceil(max));
59 const bool has_extra_data = (l & 0b11) != l;
60 const long long int l2 = has_extra_data ? (l & 0b11L) | 0b100L : l;
61 auto pack = [](const double d) { return static_cast<long long int>(std::round((d * 0.5 + 0.5) * 32766.0)); };
62 const long long int l3 = pack(d3 / l) << 3;
63 const long long int l4 = pack(d2 / l) << 18;
64 const long long int l5 = pack(d / l) << 33;
65 const long long int l6 = l2 | l3 | l4 | l5;
66 WriteData<long long int, unsigned char>(l6, container);
67 WriteData<long long int, unsigned char>(l6 >> 8, container);
68 WriteData<long long int, unsigned int>(l6 >> 16, container);
69 if (has_extra_data)
70 {
71 WriteData<long long int, VarInt>(l >> 2, container);
72 }
73 }
74 };
75}
76#endif
SERIALIZED_FIELD(Y, double)
virtual void WriteImpl(WriteContainer &container) const override
Definition LpVec3.hpp:44
SERIALIZED_FIELD(X, double)
SERIALIZED_FIELD(Z, double)
virtual void ReadImpl(ReadIterator &iter, size_t &length) override
Definition LpVec3.hpp:20
std::vector< unsigned char > WriteContainer
std::vector< unsigned char >::const_iterator ReadIterator