1
0
Fork 0

Contouring: check surrounding chunks

This commit is contained in:
May B. 2020-07-14 19:03:32 +02:00
parent 5563ae4082
commit adc8b1c3c8
6 changed files with 132 additions and 6 deletions

View File

@ -9,6 +9,8 @@
- [ ] Edition
- [ ] Entity
- [ ] Planet
- [ ] CubicSphere
- [ ] Healpix
- [ ] Galaxy
- [ ] Biomes
- https://imgur.com/kM8b5Zq
@ -36,13 +38,16 @@
- Eye adaptation
- [ ] Post processing
- https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing
- Bloom
- [x] Skybox
- [ ] Environment mapping
- [ ] Deferred
- [ ] Cascaded shadow maps
- [ ] RayCast
## Contouring
- [x] Box contouring
- [x] Ignore sides
- [ ] LOD
- [ ] Dual MC
- [ ] Collision

View File

@ -0,0 +1,34 @@
#pragma once
#include "chunk_surrounding.hpp"
#include "boxing.hpp"
using namespace contouring;
class SurrondingFlatBox {
public:
SurrondingFlatBox();
~SurrondingFlatBox();
private:
static inline bool isTransparent(const surrounding::chunks& surrounding, const std::pair<ushort, ushort>& idx) {
return surrounding[idx.first]->begin()[idx.second].Density < UCHAR_MAX; // MAYBE: materials::transparent
}
public:
static void render(const surrounding::chunks& surrounding, std::vector<VertexData> &vertices)
{
const auto voxels = surrounding[surrounding::CENTER]->begin();
vertices.clear();
for (ushort i = 0; i < CHUNK_SIZE; i++) {
if (voxels[i].Density > 0) {
Faces faces = voxels[i].Density < UCHAR_MAX ? Faces::All :
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Right)) & Faces::Right) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Left)) & Faces::Left) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Up)) & Faces::Up) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Down)) & Faces::Down) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Forward)) & Faces::Forward) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Backward)) & Faces::Backward);
contouring::box::addCube(vertices, Chunk::getPosition(i), voxels[i].Material, faces, glm::vec3(voxels[i].Density * 1.f / UCHAR_MAX));
}
}
}
};

View File

@ -0,0 +1,47 @@
#pragma once
#include "../world/Chunk.hpp"
#include <array>
#include <memory>
namespace contouring::surrounding {
const auto CENTER = 6;
typedef std::array<std::shared_ptr<const Chunk>, 7> chunks;
std::pair<ushort, ushort> getNeighborIdx(ushort idx, Face face) {
switch (face) {
case Face::Forward:
if (idx % CHUNK_LENGTH >= CHUNK_LENGTH - 1)
return {static_cast<int>(Face::Forward), idx - (CHUNK_LENGTH - 1)};
return {CENTER, idx + 1};
case Face::Backward:
if (idx % CHUNK_LENGTH <= 0)
return {static_cast<int>(Face::Backward), idx + (CHUNK_LENGTH - 1)};
return {CENTER, idx - 1};
case Face::Up:
if ((idx / CHUNK_LENGTH) % CHUNK_LENGTH >= CHUNK_LENGTH - 1)
return {static_cast<int>(Face::Up), idx - (CHUNK_LENGTH2 - CHUNK_LENGTH)};
return {CENTER, idx + CHUNK_LENGTH};
case Face::Down:
if ((idx / CHUNK_LENGTH) % CHUNK_LENGTH <= 0)
return {static_cast<int>(Face::Down), idx + (CHUNK_LENGTH2 - CHUNK_LENGTH)};
return {CENTER, idx - CHUNK_LENGTH};
case Face::Right:
if (idx / CHUNK_LENGTH2 >= CHUNK_LENGTH - 1)
return {static_cast<int>(Face::Right), idx - (CHUNK_SIZE - CHUNK_LENGTH2)};
return {CENTER, idx + CHUNK_LENGTH2};
case Face::Left:
if (idx / CHUNK_LENGTH2 <= 0)
return {static_cast<int>(Face::Left), idx + (CHUNK_SIZE - CHUNK_LENGTH2)};
return {CENTER, idx - CHUNK_LENGTH2};
default:
return {CENTER, idx};
}
}
}

View File

@ -3,6 +3,11 @@
enum class Face {
Right, Left, Up, Down, Forward, Backward
};
const glm::ivec3 g_face_offsets[6] = {
glm::ivec3(1,0,0), glm::ivec3(-1,0,0),
glm::ivec3(0,1,0), glm::ivec3(0,-1,0),
glm::ivec3(0,0,1), glm::ivec3(0,0,-1),
};
enum class Faces {
None = 0,

View File

@ -23,6 +23,22 @@ public:
const Voxel* begin() const {
return voxels.begin();
}
inline void invalidate() {
upToDate = false;
}
inline const Voxel& get(ushort idx) const {
return voxels[idx];
}
const Voxel& getAt(const chunk_voxel_pos& pos) const {
return get(getIdx(pos));
}
void set(ushort idx, const Voxel& val) {
voxels[idx] = val;
invalidate();
}
void setAt(const chunk_voxel_pos& pos, const Voxel& val) {
set(getIdx(pos), val);
}
static inline chunk_voxel_pos getPosition(ushort idx) {
return chunk_voxel_pos(idx / CHUNK_LENGTH2, (idx / CHUNK_LENGTH) % CHUNK_LENGTH, idx % CHUNK_LENGTH);

View File

@ -1,6 +1,6 @@
#include "World.hpp"
#include "../contouring/FlatBox.hpp"
#include "../contouring/SurrondingFlatBox.hpp"
#include "../render/buffer/ShortIndexedBuffer.hpp"
World::World(const World::options& options) {
@ -24,12 +24,25 @@ void World::update(const camera_pos& pos, World::report& rep) {
}
if (chunk->update()) { // MAYBE: update joints
if(chunk->buffer != NULL)
delete chunk->buffer;
//TODO: extract in contouring
contouring::surrounding::chunks surrounding;
surrounding[contouring::surrounding::CENTER] = chunk;
bool all_found = true;
for (size_t i = 0; all_found && i < contouring::surrounding::CENTER; i++) {
const auto it = chunks.find(chunkPos + g_face_offsets[i]);
if (it != chunks.end())
surrounding[i] = it->second;
else
all_found = false;
}
if(all_found) {
if (chunk->buffer != NULL)
delete chunk->buffer;
std::vector<VertexData> vertices;
FlatBox::render(chunk->begin(), vertices);
chunk->buffer = new ShortIndexedBuffer(GL_TRIANGLES, vertices);
std::vector<VertexData> vertices;
SurrondingFlatBox::render(surrounding, vertices);
chunk->buffer = new ShortIndexedBuffer(GL_TRIANGLES, vertices);
}
}
}
}
@ -68,6 +81,12 @@ void World::update(const camera_pos& pos, World::report& rep) {
const auto pos = loadQueue.pop();
const auto chunk = std::make_shared<Chunk>(pos, generator);
chunks.insert({pos, chunk});
//trigger surronding render
for (size_t i = 0; i < contouring::surrounding::CENTER; i++) {
const auto it = chunks.find(pos + g_face_offsets[i]);
if (it != chunks.end())
it->second->invalidate();
}
}
rep.chunk_count.push(chunks.size());
}