summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-02-01 07:47:22 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-02-01 07:47:22 +0100
commitcd45c4009c606bceb11a1d4202204ecd0969b5ef (patch)
treee5ae5057c2ae14c5962c35cabfb72296a1e2d690
parent2d2671a6866864bc8fb927a63e2d6eecddff3d6a (diff)
downloadMinedMap-cd45c4009c606bceb11a1d4202204ecd0969b5ef.tar
MinedMap-cd45c4009c606bceb11a1d4202204ecd0969b5ef.zip
Compute top non-air layer
This doesn't yet ignore non-opaque blocks.
-rw-r--r--src/MinedMap.cpp9
-rw-r--r--src/World/Block.hpp41
-rw-r--r--src/World/Chunk.cpp57
-rw-r--r--src/World/Chunk.hpp25
4 files changed, 103 insertions, 29 deletions
diff --git a/src/MinedMap.cpp b/src/MinedMap.cpp
index 8759d9d..fea62ce 100644
--- a/src/MinedMap.cpp
+++ b/src/MinedMap.cpp
@@ -42,14 +42,7 @@ int main(int argc, char *argv[]) {
World::Region region(argv[1]);
const World::Chunk &chunk = *region(0, 0);
-
- for (auto &entry : chunk.getSections()) {
- std::cout << entry->getType() << ":" << std::endl;
-
- for (auto &entry2 : *entry) {
- std::cout << entry2.first << " " << entry2.second->getType() << std::endl;
- }
- }
+ World::Chunk::Blocks layer = chunk.getTopLayer();
return 0;
}
diff --git a/src/World/Block.hpp b/src/World/Block.hpp
new file mode 100644
index 0000000..4bf0a0d
--- /dev/null
+++ b/src/World/Block.hpp
@@ -0,0 +1,41 @@
+/*
+ Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#pragma once
+
+#include <stdint.h>
+
+
+namespace MinedMap {
+namespace World {
+
+struct Block {
+ uint8_t id;
+ uint8_t data;
+};
+
+}
+}
diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp
index 915e5f3..2dc9014 100644
--- a/src/World/Chunk.cpp
+++ b/src/World/Chunk.cpp
@@ -39,6 +39,20 @@
namespace MinedMap {
namespace World {
+Chunk::Chunk(Buffer buffer) {
+ size_t size = buffer.get32();
+
+ Buffer buffer2(buffer.get(size), size);
+
+ uint8_t format = buffer2.get8();
+ if (format != 2)
+ throw std::invalid_argument("unknown chunk format");
+
+ inflateChunk(buffer2);
+ parseChunk();
+ analyzeChunk();
+}
+
void Chunk::inflateChunk(Buffer buffer) {
size_t outlen = 0;
uint8_t *output = nullptr;
@@ -97,11 +111,11 @@ void Chunk::analyzeChunk() {
}
}
-uint8_t Chunk::getBlockAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z) {
+uint8_t Chunk::getBlockAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z) const {
return (*section->get<NBT::ByteArrayTag>("Blocks"))[getIndex(x, y, z)];
}
-uint8_t Chunk::getDataAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z) {
+uint8_t Chunk::getDataAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z) const {
size_t i = getIndex(x, y, z);
uint8_t v = (*section->get<NBT::ByteArrayTag>("Data"))[i / 2];
@@ -111,18 +125,37 @@ uint8_t Chunk::getDataAt(const std::shared_ptr<const NBT::CompoundTag> &section,
return (v & 0xf);
}
-Chunk::Chunk(Buffer buffer) {
- size_t size = buffer.get32();
+Chunk::Blocks Chunk::getTopLayer() const {
+ size_t done = 0;
+ Blocks blocks = {};
+
+ for (auto it = sections->rbegin(); it != sections->rend(); ++it) {
+ if (done == SIZE*SIZE)
+ break;
+
+ for (ssize_t y = SIZE-1; y >= 0; y--) {
+ if (done == SIZE*SIZE)
+ break;
+
+ for (size_t x = 0; x < SIZE; x++) {
+ for (size_t z = 0; z < SIZE; z++) {
+ if (blocks.blocks[x][z].id)
+ continue;
+
+ uint8_t block = getBlockAt(*it, x, y, z);
+ if (block) {
+ blocks.blocks[x][z].id = block;
+ blocks.blocks[x][z].data = getDataAt(*it, x, y, z);
+ done++;
+ }
+ }
+ }
+ }
+ }
- Buffer buffer2(buffer.get(size), size);
+ std::cerr << "Done: " << done << std::endl;
- uint8_t format = buffer2.get8();
- if (format != 2)
- throw std::invalid_argument("unknown chunk format");
-
- inflateChunk(buffer2);
- parseChunk();
- analyzeChunk();
+ return blocks;
}
}
diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp
index d063d48..22054db 100644
--- a/src/World/Chunk.hpp
+++ b/src/World/Chunk.hpp
@@ -27,6 +27,7 @@
#pragma once
+#include "Block.hpp"
#include "../Buffer.hpp"
#include "../UniqueCPtr.hpp"
#include "../NBT/CompoundTag.hpp"
@@ -43,7 +44,18 @@ class Chunk : public std::shared_ptr<const NBT::CompoundTag> {
public:
static const size_t SIZE = 16;
+ struct Blocks {
+ Block blocks[SIZE][SIZE];
+ };
+
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 256*y + 16*z + x;
+ }
+
size_t len;
UniqueCPtr<uint8_t[]> data;
@@ -56,15 +68,8 @@ private:
void parseChunk();
void analyzeChunk();
- 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 256*y + 16*z + x;
- }
-
- uint8_t getBlockAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z);
- uint8_t getDataAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z);
+ uint8_t getBlockAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z) const;
+ uint8_t getDataAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z) const;
public:
Chunk(Buffer buffer);
@@ -72,6 +77,8 @@ public:
const NBT::ListTag<NBT::CompoundTag> & getSections() const {
return *sections;
}
+
+ Blocks getTopLayer() const;
};
}