From 0f6c467566ab4765df340f6c9f4b11f084aca1f1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 17 Nov 2021 13:16:00 +0100 Subject: [PATCH] World: Chunk: replace division/modulo with shift/mask for height values Preparation for negative y coordinates. --- src/World/Chunk.cpp | 14 +++++++------- src/World/Chunk.hpp | 15 ++++++++++----- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index e99af79..3845c9b 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -53,7 +53,7 @@ uint8_t Chunk::getBiome(block_idx_t x, y_idx_t y, block_idx_t z) const { throw std::invalid_argument("corrupt chunk data"); if (biomeInts) - return biomeInts->getValue((y/BGROUP)*BSIZE*BSIZE + (z/BGROUP)*BSIZE + (x/BGROUP)); + return biomeInts->getValue((y>>BSHIFT)*BSIZE*BSIZE + (z>>BSHIFT)*BSIZE + (x>>BSHIFT)); else if (biomeIntsPre115) return biomeIntsPre115->getValue(z*SIZE + x); else if (biomeBytes) @@ -67,14 +67,14 @@ Block Chunk::getBlock(block_idx_t x, Chunk::Height height, block_idx_t z) const block.depth = height.depth; - section_idx_t Y = height.y / SIZE; - block_idx_t y = height.y % SIZE; + section_idx_t Y = height.y >> HSHIFT; + block_idx_t y = height.y & HMASK; if (Y < sections.size() && sections[Y]) block.type = sections[Y]->getBlockStateAt(x, y, z); - section_idx_t Yt = (height.y + 1) / SIZE; - block_idx_t yt = (height.y + 1) % SIZE; + section_idx_t Yt = (height.y + 1) >> HSHIFT; + block_idx_t yt = (height.y + 1) & HMASK; if (Yt < sections.size() && sections[Yt]) block.blockLight = sections[Yt]->getBlockLightAt(x, yt, z); @@ -97,7 +97,7 @@ bool Chunk::getHeight( return false; if (height->y == 0) - height->y = SIZE*section->getY() + y; + height->y = (section->getY() << HSHIFT) + y; if (!(flags & WITH_DEPTH)) return true; @@ -105,7 +105,7 @@ bool Chunk::getHeight( if (type->flags & BLOCK_WATER) return false; - height->depth = SIZE*section->getY() + y; + height->depth = (section->getY() << HSHIFT) + y; return true; } diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 26d10d1..817b29f 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -29,13 +29,18 @@ public: // Maximum Y value static const y_idx_t MAXY = 256; + // Shift to get from height to section index + static const unsigned HSHIFT = 4; + // Mask to get from height to y index inside section + static const block_idx_t HMASK = 0xf; + // Since Minecraft 1.15, biome information is stored for // 4x4x4 block groups - static const uint32_t BGROUP = 4; + static const unsigned BSHIFT = 2; // Number of biome values in a chunk in x/z dimensions - static const uint32_t BSIZE = SIZE / BGROUP; + static const uint32_t BSIZE = SIZE >> BSHIFT; // Number of biome values in a chunk in y dimension - static const uint32_t BMAXY = MAXY / BGROUP; + static const uint32_t BMAXY = MAXY >> BSHIFT; // Flags static const int WITH_DEPTH = (1 << 0); @@ -63,12 +68,12 @@ private: ) const; const Resource::BlockType * getBlockStateAt(block_idx_t x, y_idx_t y, block_idx_t z) const { - section_idx_t Y = y / SIZE; + section_idx_t Y = y >> HSHIFT; if (Y >= sections.size() || !sections[Y]) return nullptr; - return sections[Y]->getBlockStateAt(x, y % SIZE, z); + return sections[Y]->getBlockStateAt(x, y & HMASK, z); }