From e880f8997feaaab8cf8a908cff8de241c6133bef Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 1 Feb 2015 14:35:31 +0100 Subject: Performance improvements --- src/World/Chunk.hpp | 98 +++++++++++++++++++++-------------------------------- 1 file changed, 38 insertions(+), 60 deletions(-) (limited to 'src/World/Chunk.hpp') diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 333d5e5..a4948b7 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -47,83 +47,61 @@ class Chunk { public: static const size_t SIZE = 16; - class Section { - private: - static size_t getIndex(size_t x, size_t y, size_t z) { - if (x >= SIZE || y >= SIZE || z >= SIZE) - throw std::range_error("Chunk::getIndex(): bad coordinates"); - - return SIZE*SIZE*y + SIZE*z + x; - } - - std::shared_ptr blocks; - std::shared_ptr data; - - std::shared_ptr blockLight; - std::shared_ptr skyLight; - - unsigned Y; - - public: - Section(const NBT::CompoundTag &s) { - blocks = assertValue(s.get("Blocks")); - data = assertValue(s.get("Data")); - blockLight = assertValue(s.get("BlockLight")); - skyLight = assertValue(s.get("SkyLight")); - - if (blocks->getLength() != SIZE*SIZE*SIZE || data->getLength() != SIZE*SIZE*SIZE/2 - || blockLight->getLength() != SIZE*SIZE*SIZE/2 || skyLight->getLength() != SIZE*SIZE*SIZE/2) - throw std::invalid_argument("corrupt chunk data"); - - Y = assertValue(s.get("Y"))->getValue() * SIZE; - } - - uint8_t getBlockAt(size_t x, size_t y, size_t z) const { - return blocks->get(getIndex(x, y, z)); - } - - uint8_t getDataAt(size_t x, size_t y, size_t z) const { - return data->getHalf(getIndex(x, y, z)); - } - - uint8_t getBlockLightAt(size_t x, size_t y, size_t z) const { - return blockLight->getHalf(getIndex(x, y, z)); - } - - uint8_t getSkyLightAt(size_t x, size_t y, size_t z) const { - return skyLight->getHalf(getIndex(x, y, z)); - } - - unsigned getY() const { - return Y; - } - }; - struct Blocks { Block blocks[SIZE][SIZE]; }; + private: size_t len; UniqueCPtr data; std::shared_ptr root; std::shared_ptr level; + std::shared_ptr> sections; - std::vector
sections; unsigned maxY; - std::unique_ptr blocks; + std::unique_ptr blockIDs; + std::unique_ptr blockData; + std::unique_ptr blockSkyLight; + std::unique_ptr blockBlockLight; + - Block & getBlock(size_t x, size_t y, size_t z) { - return blocks[SIZE*SIZE*y + SIZE*z + x]; + size_t getIndex(size_t x, size_t y, size_t z) const { + if (x >= SIZE || y >= maxY || z >= SIZE) + throw std::range_error("Chunk::getIndex(): bad coordinates"); + + return SIZE*SIZE*y + SIZE*z + x; } - const Block & getBlock(size_t x, size_t y, size_t z) const { - return blocks[SIZE*SIZE*y + SIZE*z + x]; + uint8_t getHalf(const uint8_t *v, size_t x, size_t y, size_t z) const { + size_t i = getIndex(x, y, z); + + if (i % 2) + return (v[i/2] >> 4); + else + return (v[i/2] & 0xf); } + uint8_t getBlockAt(size_t x, size_t y, size_t z) const { + return blockIDs[getIndex(x, y, z)]; + } + + uint8_t getDataAt(size_t x, size_t y, size_t z) const { + return getHalf(blockData.get(), x, y, z); + } + + uint8_t getBlockLightAt(size_t x, size_t y, size_t z) const { + return getHalf(blockBlockLight.get(), x, y, z); + } + + uint8_t getSkyLightAt(size_t x, size_t y, size_t z) const { + return getHalf(blockSkyLight.get(), x, y, z); + } + + void inflateChunk(Buffer buffer); void parseChunk(); void analyzeChunk(); @@ -135,8 +113,8 @@ public: return *level; } - const std::vector
& getSections() const { - return sections; + const NBT::ListTag & getSections() const { + return *sections; } Blocks getTopLayer() const; -- cgit v1.2.3