Contouring: check surrounding chunks
This commit is contained in:
parent
5563ae4082
commit
adc8b1c3c8
5
TODO.md
5
TODO.md
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue