Seamless chunk borders #4
|
@ -21,6 +21,7 @@ namespace chunkmanager
|
||||||
void destroy();
|
void destroy();
|
||||||
oneapi::tbb::concurrent_queue<Chunk::Chunk*>& getDeleteVector();
|
oneapi::tbb::concurrent_queue<Chunk::Chunk*>& getDeleteVector();
|
||||||
std::array<std::array<int, 3>, chunks_volume>& getChunksIndices();
|
std::array<std::array<int, 3>, chunks_volume>& getChunksIndices();
|
||||||
|
Block getBlockAtPos(int x, int y, int z);
|
||||||
void update();
|
void update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace Chunk
|
||||||
{
|
{
|
||||||
this->position = pos;
|
this->position = pos;
|
||||||
this->setState(CHUNK_STATE_EMPTY, true);
|
this->setState(CHUNK_STATE_EMPTY, true);
|
||||||
|
this->setBlocks(0, CHUNK_MAX_INDEX, Block::AIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunk ::~Chunk()
|
Chunk ::~Chunk()
|
||||||
|
@ -43,6 +44,8 @@ namespace Chunk
|
||||||
|
|
||||||
Block Chunk::getBlock(int x, int y, int z)
|
Block Chunk::getBlock(int x, int y, int z)
|
||||||
{
|
{
|
||||||
|
if(x < 0 || y < 0 || z < 0 || x > CHUNK_SIZE -1 || y > CHUNK_SIZE -1 || z > CHUNK_SIZE-1 ||
|
||||||
|
!getState(CHUNK_STATE_GENERATED)) return Block::AIR;
|
||||||
return blocks.at(HILBERT_XYZ_ENCODE[x][y][z]);
|
return blocks.at(HILBERT_XYZ_ENCODE[x][y][z]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <oneapi/tbb/concurrent_hash_map.h>
|
#include <oneapi/tbb/concurrent_hash_map.h>
|
||||||
|
|
||||||
|
#include "block.hpp"
|
||||||
#include "chunk.hpp"
|
#include "chunk.hpp"
|
||||||
#include "chunkgenerator.hpp"
|
#include "chunkgenerator.hpp"
|
||||||
#include "chunkmesher.hpp"
|
#include "chunkmesher.hpp"
|
||||||
|
@ -202,4 +203,27 @@ namespace chunkmanager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Block getBlockAtPos(int x, int y, int z){
|
||||||
|
if(x < 0 || y < 0 || z < 0) return Block::NULLBLK;
|
||||||
|
|
||||||
|
int cx = static_cast<int>(x / CHUNK_SIZE);
|
||||||
|
int cy = static_cast<int>(y / CHUNK_SIZE);
|
||||||
|
int cz = static_cast<int>(z / CHUNK_SIZE);
|
||||||
|
|
||||||
|
if(cx < 0 || cy < 0 || cz < 0 || cx > 1023 || cy > 1023 || cz > 1023) return Block::NULLBLK;
|
||||||
|
|
||||||
|
//std::cout << "Block at " << x << ", " << y << ", " << z << " is in chunk " << cx << "," << cy << "," << cz << "\n";
|
||||||
|
ChunkTable::accessor a;
|
||||||
|
if(!chunks.find(a, calculateIndex(cx, cy, cz))) return Block::NULLBLK;
|
||||||
|
else {
|
||||||
|
int bx = x % CHUNK_SIZE;
|
||||||
|
int by = y % CHUNK_SIZE;
|
||||||
|
int bz = z % CHUNK_SIZE;
|
||||||
|
|
||||||
|
Block b = a->second->getBlock(bx, by, bz);
|
||||||
|
//std::cout << "Block is at " << bx << "," << by << "," << bz << "(" << (int)b << ")\n";
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
#include "chunkmesher.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
#include "chunk.hpp"
|
#include "chunk.hpp"
|
||||||
#include "chunkmesher.hpp"
|
#include "chunkmanager.hpp"
|
||||||
#include "globals.hpp"
|
#include "globals.hpp"
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
#include "spacefilling.hpp"
|
#include "spacefilling.hpp"
|
||||||
|
@ -93,25 +95,38 @@ void mesh(Chunk::Chunk* chunk)
|
||||||
{
|
{
|
||||||
for (x[u] = 0; x[u] < CHUNK_SIZE; x[u]++)
|
for (x[u] = 0; x[u] < CHUNK_SIZE; x[u]++)
|
||||||
{
|
{
|
||||||
Block b1 = (x[dim] >= 0) ? blocks[HILBERT_XYZ_ENCODE[x[0]][x[1]][x[2]]] : Block::NULLBLK;
|
Block b1, b2;
|
||||||
Block b2 = (x[dim] < CHUNK_SIZE - 1)
|
if(x[dim] >= 0) b1 = blocks[HILBERT_XYZ_ENCODE[x[0]][x[1]][x[2]]];
|
||||||
? blocks[HILBERT_XYZ_ENCODE[x[0] + q[0]][x[1] + q[1]][x[2] + q[2]]]
|
else{
|
||||||
: Block::NULLBLK;
|
int cx = chunk->getPosition().x*CHUNK_SIZE;
|
||||||
|
int cy = chunk->getPosition().y*CHUNK_SIZE;
|
||||||
|
int cz = chunk->getPosition().z*CHUNK_SIZE;
|
||||||
|
|
||||||
// This is the original line taken from rob's code, readapted (replace voxelFace
|
int bx = cx+x[0];
|
||||||
// with b1 and b2).
|
int by = cy+x[1];
|
||||||
// mask[n++] = ((voxelFace != Block::NULLBLK && voxelFace1 != Block::NULLBLK &&
|
int bz = cz+x[2];
|
||||||
// voxelFace.equals(voxelFace1))) ? Block::NULLBLK : backFace ? voxelFace1 : voxelFace;
|
|
||||||
|
|
||||||
// Additionally checking whether b1 and b2 are AIR or Block::NULLBLK allows face culling,
|
b1 = chunkmanager::getBlockAtPos(bx, by, bz);
|
||||||
// thus not rendering faces that cannot be seen
|
}
|
||||||
// Removing the control for Block::NULLBLK disables chunk borders, which is
|
|
||||||
// not always wanted and needs further checking
|
if(x[dim] < CHUNK_SIZE - 1) b2 = blocks[HILBERT_XYZ_ENCODE[x[0] + q[0]][x[1]
|
||||||
// This can be surely refactored in something that isn't such a big one-liner
|
+ q[1]][x[2] + q[2]]];
|
||||||
mask[n++] = b1 != Block::NULLBLK && b2 != Block::NULLBLK && b1 == b2 ? Block::NULLBLK
|
else{
|
||||||
: backFace ? b1 == Block::AIR || b1 == Block::NULLBLK ? b2 : Block::NULLBLK
|
int cx = chunk->getPosition().x*CHUNK_SIZE;
|
||||||
: b2 == Block::AIR || b2 == Block::NULLBLK ? b1
|
int cy = chunk->getPosition().y*CHUNK_SIZE;
|
||||||
: Block::NULLBLK;
|
int cz = chunk->getPosition().z*CHUNK_SIZE;
|
||||||
|
|
||||||
|
int bx = cx+x[0] + q[0];
|
||||||
|
int by = cy+x[1] + q[1];
|
||||||
|
int bz = cz+x[2] + q[2];
|
||||||
|
|
||||||
|
b2 = chunkmanager::getBlockAtPos(bx, by, bz);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the mask
|
||||||
|
mask[n++] = b1 != Block::NULLBLK && b2 != Block::NULLBLK && b1 == b2 ? Block::NULLBLK
|
||||||
|
: backFace ? b1 == Block::AIR ? b2 : Block::NULLBLK
|
||||||
|
: b2 == Block::AIR ? b1 : Block::NULLBLK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue