From 04ab1a3420b46af046a898ee5510e0d9b25ed24c Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Sun, 27 Aug 2017 20:24:28 +0500 Subject: 2017-08-27 --- src/Section.cpp | 267 ++++++++++++++++++++++---------------------------------- 1 file changed, 105 insertions(+), 162 deletions(-) (limited to 'src/Section.cpp') 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 +void Section::CalculateHash() { + std::vector 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(rawData.data()); + size_t length = rawData.size(); + + std::string str(from, from + length); + hash = std::hash{}(str); +} + +Section::Section(Vector pos, unsigned char bitsPerBlock, std::vector palette, std::vector blockData, std::vector lightData, std::vector 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(data.blocks.data()); - std::vector 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 time = end - begin; - totalParsingTime += time.count(); - } - std::vector 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 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 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: "< 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 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(blocks.data()); - size_t length = blocks.size() * sizeof(Block); - - std::string str(from, from + length); - return std::hash{}(str); -} - -PackedSection::PackedSection(Vector position, byte * dataBlocks, size_t dataBlocksLength, byte * dataLight, byte * dataSky, byte bitsPerBlock, std::vector palette) -{ - this->position = position; - - this->palette = palette; - - this->bitsPerBlock = bitsPerBlock; - - for (long long *t = reinterpret_cast(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 -- cgit v1.2.3