summaryrefslogtreecommitdiffstats
path: root/src/Section.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Section.cpp')
-rw-r--r--src/Section.cpp267
1 files changed, 105 insertions, 162 deletions
diff --git a/src/Section.cpp b/src/Section.cpp
index c9af5c6..9b4292b 100644
--- a/src/Section.cpp
+++ b/src/Section.cpp
@@ -2,164 +2,134 @@
#include <bitset>
+void Section::CalculateHash() {
+ std::vector<unsigned char> rawData;
+ rawData.reserve(block.size() * sizeof(long long) + light.size() + sky.size());
+ std::copy(block.begin(), block.end(), std::back_inserter(rawData));
+ std::copy(light.begin(), light.end(), std::back_inserter(rawData));
+ if (!sky.empty())
+ std::copy(sky.begin(), sky.end(), std::back_inserter(rawData));
+
+ const unsigned char *from = reinterpret_cast<const unsigned char *>(rawData.data());
+ size_t length = rawData.size();
+
+ std::string str(from, from + length);
+ hash = std::hash<std::string>{}(str);
+}
+
+Section::Section(Vector pos, unsigned char bitsPerBlock, std::vector<unsigned short> palette, std::vector<long long> blockData, std::vector<unsigned char> lightData, std::vector<unsigned char> skyData) {
+ if (bitsPerBlock < 4)
+ bitsPerBlock = 4;
+ if (bitsPerBlock > 8)
+ bitsPerBlock = 13;
+ this->bitsPerBlock = bitsPerBlock;
+
+ this->worldPosition = pos;
+ this->block = std::move(blockData);
+ this->palette = std::move(palette);
+ this->light = std::move(lightData);
+ this->sky = std::move(skyData);
+
+ CalculateHash();
+}
+
+Section::Section() {
+
+ CalculateHash();
+}
+
Section::~Section() {
+
}
Section::Section(Section && other) noexcept {
using std::swap;
swap(*this, other);
+ CalculateHash();
}
-Block &Section::GetBlock(Vector pos) {
- return blocks[pos.y * 256 + pos.z * 16 + pos.x];
+Section &Section::operator=(Section other) noexcept {
+ using std::swap;
+ swap(*this, other);
+ CalculateHash();
+ return *this;
}
-Block Section::GetBlock(Vector pos) const
-{
- if (blocks.empty()) {
- static Block fallback;
- return fallback;
+BlockId Section::GetBlockId(Vector pos) const {
+ if (block.empty())
+ return BlockId{ 0,0 };
+ int value;
+
+ unsigned char individualValueMask = ((1 << bitsPerBlock) - 1);
+
+ int blockNumber = (((pos.y * 16) + pos.z) * 16) + pos.x;
+ int startLong = (blockNumber * bitsPerBlock) / 64;
+ int startOffset = (blockNumber * bitsPerBlock) % 64;
+ int endLong = ((blockNumber + 1) * bitsPerBlock - 1) / 64;
+
+ unsigned short t;
+
+ if (startLong == endLong) {
+ t = (block[startLong] >> startOffset);
+ }
+ else {
+ int endOffset = 64 - startOffset;
+ t = (block[startLong] >> startOffset |block[endLong] << endOffset);
}
- return blocks[pos.y * 256 + pos.z * 16 + pos.x];
+
+ t &= individualValueMask;
+
+
+ if (t >= palette.size()) {
+ //LOG(ERROR) << "Out of palette: " << t;
+ value = 0;
+ }
+ else
+ value = palette[t];
+
+ BlockId blockId;
+ blockId.id = value >> 4;
+ blockId.state = value & 0xF;
+ return blockId;
}
-double totalParsingTime = 0;
+unsigned char Section::GetBlockLight(Vector pos)
+{
+ int blockNumber = pos.y * 256 + pos.z * 16 + pos.x;
+ unsigned char lightValue = this->light[blockNumber];
+ return (blockNumber % 2 == 0) ? (lightValue & 0xF) : (lightValue >> 4);
+}
-Section::Section(PackedSection data)
+unsigned char Section::GetBlockSkyLight(Vector pos)
{
- if (data.blocks.empty())
- return;
- worldPosition = data.position;
-
- bool useFirst = false;
-
- if (useFirst) {
- unsigned char *blocksData = reinterpret_cast<unsigned char*>(data.blocks.data());
- 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() * 8; i++) {
- for (int j = 0; j < 8; j++) {
- t |= (blocksData[i] & 0x01) ? 0x80 : 0x00;
- t >>= 1;
- blocksData[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 & 0x0F;
- byte second = t >> 4;
- 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 & 0x0F;
- byte second = t >> 4;
- sky.push_back(first);
- sky.push_back(second);
- }
- }
-
- for (int i = 0; i < 4096; i++) {
- unsigned short blockId = !data.palette.empty() ? data.palette[blocks[i]] : blocks[i];
- Block block(blockId >> 4, blockId & 0xF, light[i], sky.empty() ? 0 : sky[i]);
- this->blocks.push_back(block);
- }
- } else {
-
- std::vector<unsigned short> blocks;
- blocks.reserve(4096);
-
- unsigned char individualValueMask = ((1 << data.bitsPerBlock) - 1);
-
- for (int blockNumber = 0; blockNumber < 4096; blockNumber++) {
- int startLong = (blockNumber * data.bitsPerBlock) / 64;
- int startOffset = (blockNumber * data.bitsPerBlock) % 64;
- int endLong = ((blockNumber + 1) * data.bitsPerBlock - 1) / 64;
-
- unsigned short t;
-
- if (startLong == endLong) {
- t = (data.blocks[startLong] >> startOffset);
- }
- else {
- int endOffset = 64 - startOffset;
- t = (data.blocks[startLong] >> startOffset | data.blocks[endLong] << endOffset);
- }
-
- t &= individualValueMask;
-
-
- if (t >= data.palette.size()) {
- //LOG(ERROR) << "Out of palette: "<<t;
- blocks.push_back(0);
- }
- else
- blocks.push_back(data.palette.empty() ? t : data.palette[t]);
- }
-
-
- std::vector<unsigned char> light;
- light.reserve(4096);
- for (int i = 0; i < 2048; i++) {
- unsigned char t = data.light[i];
- light.push_back(t & 0xF);
- light.push_back(t >> 4 & 0xF);
- }
-
- std::vector<unsigned char> sky;
- if (!data.sky.empty()) {
- sky.reserve(4096);
- for (int i = 0; i < 2048; i++) {
- unsigned char t = data.sky[i];
- sky.push_back(t & 0xF);
- sky.push_back(t >> 4 & 0xF);
- }
- }
-
- for (int i = 0; i < 4096; i++) {
- unsigned short blockId = blocks[i];
- Block block(blockId >> 4, blockId & 0xF, light[i], sky.empty() ? 0 : sky[i]);
- this->blocks.push_back(block);
- }
- }
+ int blockNumber = pos.y * 256 + pos.z * 16 + pos.x;
+ unsigned char skyValue = this->sky[blockNumber];
+ return (blockNumber % 2 == 0) ? (skyValue & 0xF) : (skyValue >> 4);
}
-Section &Section::operator=(Section other) noexcept {
- using std::swap;
- swap(*this, other);
- return *this;
+void Section::SetBlockId(Vector pos, BlockId value) {
+ LOG(WARNING) << "Block changing not implemented!";
}
void swap(Section& lhs, Section& rhs) noexcept {
- std::swap(lhs.blocks, rhs.blocks);
+ std::swap(lhs.block, rhs.block);
+ std::swap(lhs.light, rhs.light);
+ std::swap(lhs.sky, rhs.sky);
+ std::swap(lhs.bitsPerBlock, rhs.bitsPerBlock);
+ std::swap(lhs.palette, rhs.palette);
+ std::swap(lhs.hash, rhs.hash);
std::swap(lhs.worldPosition, rhs.worldPosition);
}
Section::Section(const Section &other) {
worldPosition = other.worldPosition;
- this->blocks = other.blocks;
+ this->block = other.block;
+ this->light = other.light;
+ this->sky = other.sky;
+ this->bitsPerBlock = other.bitsPerBlock;
+ this->palette = other.palette;
+ this->hash = other.hash;
+ this->worldPosition = other.worldPosition;
}
Vector Section::GetPosition() const {
@@ -167,32 +137,5 @@ Vector Section::GetPosition() const {
}
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;
-
- for (long long *t = reinterpret_cast<long long *>(dataBlocks); (byte*)t < dataBlocks + dataBlocksLength; t++) {
- long long l = *t;
- endswap(l);
- this->blocks.push_back(l);
- }
-
- light.assign(dataLight, dataLight + 2048);
-
- if (dataSky != nullptr) {
- sky.assign(dataSky, dataSky + 2048);
- }
-}
+ return hash;
+} \ No newline at end of file