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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#include "Section.hpp"
Section::~Section() {
}
Block &Section::GetBlock(Vector pos) {
return blocks[pos.y * 256 + pos.z * 16 + pos.x];
}
Block Section::GetBlock(Vector pos) const
{
if (blocks.empty()) {
static Block fallback;
return fallback;
}
return blocks[pos.y * 256 + pos.z * 16 + pos.x];
}
double totalParsingTime = 0;
Section::Section(PackedSection data)
{
if (data.blocks.empty())
return;
worldPosition = data.position;
long long *longArray = reinterpret_cast<long long *>(data.blocks.data());
for (size_t i = 0; i < data.blocks.size() / 8; i++)
endswap(&longArray[i]);
std::vector<unsigned short> blocks;
blocks.reserve(4096);
{
auto begin = std::chrono::steady_clock::now();
int bitPos = 0;
unsigned short t = 0;
for (size_t i = 0; i < data.blocks.size(); i++) {
for (int j = 0; j < 8; j++) {
t |= (data.blocks.data()[i] & 0x01) ? 0x80 : 0x00;
t >>= 1;
data.blocks.data()[i] >>= 1;
bitPos++;
if (bitPos >= data.bitsPerBlock) {
bitPos = 0;
t >>= data.bitsPerBlock - 1;
blocks.push_back(t);
t = 0;
}
}
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double, std::milli> time = end - begin;
totalParsingTime += time.count();
}
std::vector<byte> light;
light.reserve(4096);
for (int i = 0; i < 2048; i++) {
byte t = data.light[i];
byte first = t & 0xF;
byte second = (t >> 4) & 0xF;
light.push_back(0);
light.push_back(0);
}
std::vector<byte> sky;
if (!data.sky.empty()) {
sky.reserve(4096);
for (int i = 0; i < 2048; i++) {
byte t = data.sky[i];
byte first = t & 0xF;
byte second = (t >> 4) & 0xF;
sky.push_back(first);
sky.push_back(0xF);
}
}
for (int i = 0; i < 4096; i++) {
unsigned short blockId = data.palette.size() > 0 ? data.palette[blocks[i]] : blocks[i];
Block block(blockId >> 4, blockId & 0xF, light[i], sky.empty() ? 0 : sky[i]);
this->blocks.push_back(block);
}
}
Section &Section::operator=(Section other) {
std::swap(*this, other);
return *this;
}
void swap(Section &a, Section &b) {
using std::swap;
swap(a.blocks, b.blocks);
}
Section::Section(const Section &other) {
worldPosition = other.worldPosition;
this->blocks = other.blocks;
}
Vector Section::GetPosition() const {
return worldPosition;
}
size_t Section::GetHash() const {
if (blocks.empty()) return 0;
const unsigned char *from = reinterpret_cast<const unsigned char *>(blocks.data());
size_t length = blocks.size() * sizeof(Block);
std::string str(from, from + length);
return std::hash<std::string>{}(str);
}
PackedSection::PackedSection(Vector position, byte * dataBlocks, size_t dataBlocksLength, byte * dataLight, byte * dataSky, byte bitsPerBlock, std::vector<unsigned short> palette)
{
this->position = position;
this->palette = palette;
this->bitsPerBlock = bitsPerBlock;
blocks.assign(dataBlocks, dataBlocks + dataBlocksLength);
light.assign(dataLight, dataLight + 2048);
if (dataSky != nullptr) {
sky.assign(dataSky, dataSky + 2048);
}
}
|