chunk flags converted to a bitfield

This commit is contained in:
MihailRis 2024-05-31 11:59:12 +03:00
parent 3e0455358a
commit 3003386670
12 changed files with 41 additions and 77 deletions

View File

@ -374,7 +374,7 @@ void WorldRegions::put(Chunk* chunk){
chunk->encode(), CHUNK_DATA_LEN, true); chunk->encode(), CHUNK_DATA_LEN, true);
// Writing lights cache // Writing lights cache
if (doWriteLights && chunk->isLighted()) { if (doWriteLights && chunk->flags.lighted) {
put(chunk->x, chunk->z, REGION_LAYER_LIGHTS, put(chunk->x, chunk->z, REGION_LAYER_LIGHTS,
chunk->lightmap.encode(), LIGHTMAP_DATA_LEN, true); chunk->lightmap.encode(), LIGHTMAP_DATA_LEN, true);
} }

View File

@ -333,7 +333,7 @@ void Hud::openInventory(
if (blockinv == nullptr) { if (blockinv == nullptr) {
blockinv = level->inventories->createVirtual(blockUI->getSlotsCount()); blockinv = level->inventories->createVirtual(blockUI->getSlotsCount());
} }
level->chunks->getChunkByVoxel(block.x, block.y, block.z)->setUnsaved(true); level->chunks->getChunkByVoxel(block.x, block.y, block.z)->flags.unsaved;
blockUI->bind(blockinv, content); blockUI->bind(blockinv, content);
blockPos = block; blockPos = block;
currentblockid = level->chunks->get(block.x, block.y, block.z)->id; currentblockid = level->chunks->get(block.x, block.y, block.z)->id;

View File

@ -56,19 +56,16 @@ ChunksRenderer::~ChunksRenderer() {
} }
std::shared_ptr<Mesh> ChunksRenderer::render(std::shared_ptr<Chunk> chunk, bool important) { std::shared_ptr<Mesh> ChunksRenderer::render(std::shared_ptr<Chunk> chunk, bool important) {
chunk->setModified(false); chunk->flags.modified = false;
if (important) { if (important) {
auto mesh = renderer->render(chunk.get(), level->chunksStorage.get()); auto mesh = renderer->render(chunk.get(), level->chunksStorage.get());
meshes[glm::ivec2(chunk->x, chunk->z)] = mesh; meshes[glm::ivec2(chunk->x, chunk->z)] = mesh;
return mesh; return mesh;
} }
glm::ivec2 key(chunk->x, chunk->z); glm::ivec2 key(chunk->x, chunk->z);
if (inwork.find(key) != inwork.end()) { if (inwork.find(key) != inwork.end()) {
return nullptr; return nullptr;
} }
inwork[key] = true; inwork[key] = true;
threadPool.enqueueJob(chunk); threadPool.enqueueJob(chunk);
return nullptr; return nullptr;
@ -86,7 +83,7 @@ std::shared_ptr<Mesh> ChunksRenderer::getOrRender(std::shared_ptr<Chunk> chunk,
if (found == meshes.end()) { if (found == meshes.end()) {
return render(chunk, important); return render(chunk, important);
} }
if (chunk->isModified()) { if (chunk->flags.modified) {
render(chunk, important); render(chunk, important);
} }
return found->second; return found->second;

View File

@ -79,7 +79,7 @@ bool WorldRenderer::drawChunk(
bool culling bool culling
){ ){
auto chunk = level->chunks->chunks[index]; auto chunk = level->chunks->chunks[index];
if (!chunk->isLighted()) { if (!chunk->flags.lighted) {
return false; return false;
} }
float distance = glm::distance( float distance = glm::distance(

View File

@ -21,7 +21,7 @@ void LightSolver::add(int x, int y, int z, int emission) {
addqueue.push(lightentry {x, y, z, ubyte(emission)}); addqueue.push(lightentry {x, y, z, ubyte(emission)});
Chunk* chunk = chunks->getChunkByVoxel(x, y, z); Chunk* chunk = chunks->getChunkByVoxel(x, y, z);
chunk->setModified(true); chunk->flags.modified = true;
chunk->lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, emission); chunk->lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, emission);
} }
@ -67,7 +67,7 @@ void LightSolver::solve(){
if (chunk) { if (chunk) {
int lx = x - chunk->x * CHUNK_W; int lx = x - chunk->x * CHUNK_W;
int lz = z - chunk->z * CHUNK_D; int lz = z - chunk->z * CHUNK_D;
chunk->setModified(true); chunk->flags.modified = true;
ubyte light = chunk->lightmap.get(lx,y,lz, channel); ubyte light = chunk->lightmap.get(lx,y,lz, channel);
if (light != 0 && light == entry.light-1){ if (light != 0 && light == entry.light-1){
@ -96,7 +96,7 @@ void LightSolver::solve(){
if (chunk) { if (chunk) {
int lx = x - chunk->x * CHUNK_W; int lx = x - chunk->x * CHUNK_W;
int lz = z - chunk->z * CHUNK_D; int lz = z - chunk->z * CHUNK_D;
chunk->setModified(true); chunk->flags.modified = true;
ubyte light = chunk->lightmap.get(lx, y, lz, channel); ubyte light = chunk->lightmap.get(lx, y, lz, channel);
voxel& v = chunk->voxels[vox_index(lx, y, lz)]; voxel& v = chunk->voxels[vox_index(lx, y, lz)];

View File

@ -132,7 +132,7 @@ void BlocksController::randomTick(int tickid, int parts) {
if ((index + tickid) % parts != 0) if ((index + tickid) % parts != 0)
continue; continue;
auto& chunk = chunks->chunks[index]; auto& chunk = chunks->chunks[index];
if (chunk == nullptr || !chunk->isLighted()) if (chunk == nullptr || !chunk->flags.lighted)
continue; continue;
for (int s = 0; s < segments; s++) { for (int s = 0; s < segments; s++) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {

View File

@ -61,7 +61,7 @@ bool ChunksController::loadVisible(){
int index = z * w + x; int index = z * w + x;
auto& chunk = chunks->chunks[index]; auto& chunk = chunks->chunks[index];
if (chunk != nullptr){ if (chunk != nullptr){
if (chunk->isLoaded() && !chunk->isLighted()) { if (chunk->flags.loaded && !chunk->flags.lighted) {
if (buildLights(chunk)) { if (buildLights(chunk)) {
return true; return true;
} }
@ -99,12 +99,12 @@ bool ChunksController::buildLights(std::shared_ptr<Chunk> chunk) {
} }
} }
if (surrounding == MIN_SURROUNDING) { if (surrounding == MIN_SURROUNDING) {
bool lightsCache = chunk->isLoadedLights(); bool lightsCache = chunk->flags.loadedLights;
if (!lightsCache) { if (!lightsCache) {
lighting->buildSkyLight(chunk->x, chunk->z); lighting->buildSkyLight(chunk->x, chunk->z);
} }
lighting->onChunkLoaded(chunk->x, chunk->z, !lightsCache); lighting->onChunkLoaded(chunk->x, chunk->z, !lightsCache);
chunk->setLighted(true); chunk->flags.lighted = true;
return true; return true;
} }
return false; return false;
@ -114,20 +114,20 @@ void ChunksController::createChunk(int x, int z) {
auto chunk = level->chunksStorage->create(x, z); auto chunk = level->chunksStorage->create(x, z);
chunks->putChunk(chunk); chunks->putChunk(chunk);
if (!chunk->isLoaded()) { if (!chunk->flags.loaded) {
generator->generate( generator->generate(
chunk->voxels, x, z, chunk->voxels, x, z,
level->getWorld()->getSeed() level->getWorld()->getSeed()
); );
chunk->setUnsaved(true); chunk->flags.unsaved = true;
} }
chunk->updateHeights(); chunk->updateHeights();
if (!chunk->isLoadedLights()) { if (!chunk->flags.loadedLights) {
Lighting::prebuildSkyLight( Lighting::prebuildSkyLight(
chunk.get(), level->content->getIndices() chunk.get(), level->content->getIndices()
); );
} }
chunk->setLoaded(true); chunk->flags.loaded = true;
chunk->setReady(true); chunk->flags.ready = true;
} }

View File

@ -42,12 +42,12 @@ void Chunk::updateHeights() {
void Chunk::addBlockInventory(std::shared_ptr<Inventory> inventory, void Chunk::addBlockInventory(std::shared_ptr<Inventory> inventory,
uint x, uint y, uint z) { uint x, uint y, uint z) {
inventories[vox_index(x, y, z)] = inventory; inventories[vox_index(x, y, z)] = inventory;
setUnsaved(true); flags.unsaved = true;
} }
void Chunk::removeBlockInventory(uint x, uint y, uint z) { void Chunk::removeBlockInventory(uint x, uint y, uint z) {
if (inventories.erase(vox_index(x, y, z))) { if (inventories.erase(vox_index(x, y, z))) {
setUnsaved(true); flags.unsaved = true;
} }
} }

View File

@ -9,14 +9,6 @@
#include "voxel.hpp" #include "voxel.hpp"
#include "../lighting/Lightmap.hpp" #include "../lighting/Lightmap.hpp"
struct ChunkFlag {
static const int MODIFIED = 0x1;
static const int READY = 0x2;
static const int LOADED = 0x4;
static const int LIGHTED = 0x8;
static const int UNSAVED = 0x10;
static const int LOADED_LIGHTS = 0x20;
};
inline constexpr int CHUNK_DATA_LEN = CHUNK_VOL*4; inline constexpr int CHUNK_DATA_LEN = CHUNK_VOL*4;
class Lightmap; class Lightmap;
@ -31,7 +23,14 @@ public:
int bottom, top; int bottom, top;
voxel voxels[CHUNK_VOL] {}; voxel voxels[CHUNK_VOL] {};
Lightmap lightmap; Lightmap lightmap;
int flags = 0; struct {
bool modified: 1;
bool ready: 1;
bool loaded: 1;
bool lighted: 1;
bool unsaved: 1;
bool loadedLights: 1;
} flags {};
/* Block inventories map where key is index of block in voxels array */ /* Block inventories map where key is index of block in voxels array */
chunk_inventories_map inventories; chunk_inventories_map inventories;
@ -45,14 +44,6 @@ public:
// unused // unused
std::unique_ptr<Chunk> clone() const; std::unique_ptr<Chunk> clone() const;
// flags getters/setters below
inline void setFlags(int mask, bool value){
if (value)
flags |= mask;
else
flags &= ~(mask);
}
/* Creates new block inventory given size /* Creates new block inventory given size
@return inventory id or 0 if block does not exists */ @return inventory id or 0 if block does not exists */
void addBlockInventory(std::shared_ptr<Inventory> inventory, void addBlockInventory(std::shared_ptr<Inventory> inventory,
@ -63,35 +54,11 @@ public:
/* @return inventory bound to the given block or nullptr */ /* @return inventory bound to the given block or nullptr */
std::shared_ptr<Inventory> getBlockInventory(uint x, uint y, uint z) const; std::shared_ptr<Inventory> getBlockInventory(uint x, uint y, uint z) const;
inline bool isUnsaved() const {return flags & ChunkFlag::UNSAVED;}
inline bool isModified() const {return flags & ChunkFlag::MODIFIED;}
inline bool isLighted() const {return flags & ChunkFlag::LIGHTED;}
inline bool isLoaded() const {return flags & ChunkFlag::LOADED;}
inline bool isLoadedLights() const {return flags & ChunkFlag::LOADED_LIGHTS;}
inline bool isReady() const {return flags & ChunkFlag::READY;}
inline void setUnsaved(bool newState) {setFlags(ChunkFlag::UNSAVED, newState);}
inline void setModified(bool newState) {setFlags(ChunkFlag::MODIFIED, newState);}
inline void setModifiedAndUnsaved() { inline void setModifiedAndUnsaved() {
setModified(true); flags.modified = true;
setUnsaved(true); flags.unsaved = true;
} }
inline void setLoaded(bool newState) {setFlags(ChunkFlag::LOADED, newState);}
inline void setLoadedLights(bool newState) {setFlags(ChunkFlag::LOADED_LIGHTS, newState);}
inline void setLighted(bool newState) {setFlags(ChunkFlag::LIGHTED, newState);}
inline void setReady(bool newState) {setFlags(ChunkFlag::READY, newState);}
std::unique_ptr<ubyte[]> encode() const; std::unique_ptr<ubyte[]> encode() const;
/** /**

View File

@ -186,14 +186,14 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state)
else if (id == 0) chunk->updateHeights(); else if (id == 0) chunk->updateHeights();
if (lx == 0 && (chunk = getChunk(cx+ox-1, cz+oz))) if (lx == 0 && (chunk = getChunk(cx+ox-1, cz+oz)))
chunk->setModified(true); chunk->flags.modified = true;
if (lz == 0 && (chunk = getChunk(cx+ox, cz+oz-1))) if (lz == 0 && (chunk = getChunk(cx+ox, cz+oz-1)))
chunk->setModified(true); chunk->flags.modified = true;
if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cz+oz))) if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cz+oz)))
chunk->setModified(true); chunk->flags.modified = true;
if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cz+oz+1))) if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cz+oz+1)))
chunk->setModified(true); chunk->flags.modified = true;
} }
voxel* Chunks::rayCast( voxel* Chunks::rayCast(
@ -497,12 +497,12 @@ void Chunks::saveAndClear(){
for (size_t i = 0; i < volume; i++){ for (size_t i = 0; i < volume; i++){
Chunk* chunk = chunks[i].get(); Chunk* chunk = chunks[i].get();
chunks[i] = nullptr; chunks[i] = nullptr;
if (chunk == nullptr || !chunk->isLighted()) if (chunk == nullptr || !chunk->flags.lighted)
continue; continue;
bool lightsUnsaved = !chunk->isLoadedLights() && bool lightsUnsaved = !chunk->flags.loadedLights &&
worldFiles->doesWriteLights(); worldFiles->doesWriteLights();
if (!chunk->isUnsaved() && !lightsUnsaved) if (!chunk->flags.unsaved && !lightsUnsaved)
continue; continue;
regions.put(chunk); regions.put(chunk);
} }

View File

@ -61,7 +61,7 @@ std::shared_ptr<Chunk> ChunksStorage::create(int x, int z) {
chunk->decode(data.get()); chunk->decode(data.get());
auto invs = regions.fetchInventories(chunk->x, chunk->z); auto invs = regions.fetchInventories(chunk->x, chunk->z);
chunk->setBlockInventories(std::move(invs)); chunk->setBlockInventories(std::move(invs));
chunk->setLoaded(true); chunk->flags.loaded = true;
for(auto& entry : chunk->inventories) { for(auto& entry : chunk->inventories) {
level->inventories->store(entry.second); level->inventories->store(entry.second);
} }
@ -71,7 +71,7 @@ std::shared_ptr<Chunk> ChunksStorage::create(int x, int z) {
auto lights = regions.getLights(chunk->x, chunk->z); auto lights = regions.getLights(chunk->x, chunk->z);
if (lights) { if (lights) {
chunk->lightmap.set(lights.get()); chunk->lightmap.set(lights.get());
chunk->setLoadedLights(true); chunk->flags.loadedLights = true;
} }
return chunk; return chunk;
} }

View File

@ -57,11 +57,11 @@ void World::write(Level* level) {
for (size_t i = 0; i < chunks->volume; i++) { for (size_t i = 0; i < chunks->volume; i++) {
auto chunk = chunks->chunks[i]; auto chunk = chunks->chunks[i];
if (chunk == nullptr || !chunk->isLighted()) if (chunk == nullptr || !chunk->flags.lighted)
continue; continue;
bool lightsUnsaved = !chunk->isLoadedLights() && bool lightsUnsaved = !chunk->flags.loadedLights &&
settings.debug.doWriteLights.get(); settings.debug.doWriteLights.get();
if (!chunk->isUnsaved() && !lightsUnsaved) if (!chunk->flags.unsaved && !lightsUnsaved)
continue; continue;
regions.put(chunk.get()); regions.put(chunk.get());
} }