Fixed lighting issues.
parent
2bdc999294
commit
5ff8f9b78b
|
@ -399,25 +399,6 @@ inline u8 ChunkMeshBuilder::getAmbientOcclusion(s8f x, s8f y, s8f z, const gk::V
|
|||
}
|
||||
|
||||
inline u8 ChunkMeshBuilder::getLightForVertex(Light light, s8f x, s8f y, s8f z, const gk::Vector3i &offset, const gk::Vector3i &normal, const ChunkData &chunk) {
|
||||
std::function<s8(const ChunkData &chunk, s8, s8, s8)> getLight = [&](const ChunkData &chunk, s8 x, s8 y, s8 z) -> s8 {
|
||||
// if (x < 0) return chunk->getSurroundingChunk(0) && chunk->getSurroundingChunk(0)->isInitialized() ? getLight(chunk->getSurroundingChunk(0), x + CHUNK_WIDTH, y, z) : -1;
|
||||
// if (x >= CHUNK_WIDTH) return chunk->getSurroundingChunk(1) && chunk->getSurroundingChunk(1)->isInitialized() ? getLight(chunk->getSurroundingChunk(1), x - CHUNK_WIDTH, y, z) : -1;
|
||||
// if (y < 0) return chunk->getSurroundingChunk(2) && chunk->getSurroundingChunk(2)->isInitialized() ? getLight(chunk->getSurroundingChunk(2), x, y + CHUNK_DEPTH, z) : -1;
|
||||
// if (y >= CHUNK_DEPTH) return chunk->getSurroundingChunk(3) && chunk->getSurroundingChunk(3)->isInitialized() ? getLight(chunk->getSurroundingChunk(3), x, y - CHUNK_DEPTH, z) : -1;
|
||||
// if (z < 0) return chunk->getSurroundingChunk(4) && chunk->getSurroundingChunk(4)->isInitialized() ? getLight(chunk->getSurroundingChunk(4), x, y, z + CHUNK_HEIGHT) : -1;
|
||||
// if (z >= CHUNK_HEIGHT) return chunk->getSurroundingChunk(5) && chunk->getSurroundingChunk(5)->isInitialized() ? getLight(chunk->getSurroundingChunk(5), x, y, z - CHUNK_HEIGHT) : -1;
|
||||
//
|
||||
// if (light == Light::Sun)
|
||||
// return chunk->isInitialized() ? chunk->lightmap().getSunlight(x, y, z) : -1;
|
||||
// else
|
||||
// return chunk->isInitialized() ? chunk->lightmap().getTorchlight(x, y, z) : -1;
|
||||
// FIXME
|
||||
|
||||
return (light == Light::Sun)
|
||||
? chunk.getSunlight(x, y, z)
|
||||
: chunk.getTorchlight(x, y, z);
|
||||
};
|
||||
|
||||
gk::Vector3i minOffset{
|
||||
(normal.x != 0) ? offset.x : 0,
|
||||
(normal.y != 0) ? offset.y : 0,
|
||||
|
@ -431,6 +412,10 @@ inline u8 ChunkMeshBuilder::getLightForVertex(Light light, s8f x, s8f y, s8f z,
|
|||
{x + offset.x, y + offset.y, z + offset.z}
|
||||
};
|
||||
|
||||
auto getLight = [&](const ChunkData &chunk, s8 x, s8 y, s8 z) -> s8 {
|
||||
return (light == Light::Sun) ? chunk.getSunlight(x, y, z) : chunk.getTorchlight(x, y, z);
|
||||
};
|
||||
|
||||
// Get light values for surrounding nodes
|
||||
s8 lightValues[4] = {
|
||||
getLight(chunk, surroundingBlocks[0].x, surroundingBlocks[0].y, surroundingBlocks[0].z),
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
struct ChunkData {
|
||||
s32 x, y, z;
|
||||
u32 data[CHUNK_HEIGHT + 2][CHUNK_DEPTH + 2][CHUNK_WIDTH + 2];
|
||||
u8 lightData[CHUNK_HEIGHT + 2][CHUNK_DEPTH + 2][CHUNK_WIDTH + 2];
|
||||
std::optional<u8> lightData[CHUNK_HEIGHT + 2][CHUNK_DEPTH + 2][CHUNK_WIDTH + 2];
|
||||
|
||||
void loadFromChunk(const Chunk &chunk) {
|
||||
x = chunk.x();
|
||||
|
@ -49,7 +49,7 @@ struct ChunkData {
|
|||
for (s8f y = -1 ; y <= CHUNK_DEPTH ; ++y) {
|
||||
for (s8f x = -1 ; x <= CHUNK_WIDTH ; ++x) {
|
||||
data[z + 1][y + 1][x + 1] = chunk.getFullBlock(x, y, z);
|
||||
lightData[z + 1][y + 1][x + 1] = chunk.lightmap().getLightData(x, y, z);
|
||||
lightData[z + 1][y + 1][x + 1] = chunk.lightmap().tryGetLightData(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,12 +63,14 @@ struct ChunkData {
|
|||
return (data[z + 1][y + 1][x + 1] >> 16) & 0xffff;
|
||||
}
|
||||
|
||||
u8 getTorchlight(s8f x, s8f y, s8f z) const {
|
||||
return lightData[z + 1][y + 1][x + 1] & 0xf;
|
||||
s8 getTorchlight(s8f x, s8f y, s8f z) const {
|
||||
auto torchlight = lightData[z + 1][y + 1][x + 1];
|
||||
return torchlight ? torchlight.value() & 0xf : -1;
|
||||
}
|
||||
|
||||
u8 getSunlight(s8f x, s8f y, s8f z) const {
|
||||
return (lightData[z + 1][y + 1][x + 1] >> 4) & 0xf;
|
||||
s8 getSunlight(s8f x, s8f y, s8f z) const {
|
||||
auto sunlight = lightData[z + 1][y + 1][x + 1];
|
||||
return sunlight ? (sunlight.value() >> 4) & 0xf : -1;
|
||||
}
|
||||
|
||||
const BlockState *getBlockState(s8f x, s8f y, s8f z) const {
|
||||
|
|
|
@ -80,7 +80,7 @@ void ClientWorld::update(bool allowWorldReload) {
|
|||
void ClientWorld::requestChunkMeshing() {
|
||||
for (auto it = m_chunksToMesh.begin() ; it != m_chunksToMesh.end() ; ) {
|
||||
ClientChunk *chunk = (ClientChunk *)getChunk(it->second.x, it->second.y, it->second.z);
|
||||
if(chunk && !chunk->isReadyForMeshing() && chunk->areAllNeighboursInitialized()) {
|
||||
if(chunk && !chunk->isReadyForMeshing() && chunk->areAllNeighboursLoaded()) {
|
||||
chunk->setReadyForMeshing(true);
|
||||
chunk->setChanged();
|
||||
addChunkToUpdate(chunk);
|
||||
|
@ -133,7 +133,7 @@ void ClientWorld::receiveChunkData(Network::Packet &packet) {
|
|||
chunk = it.first->second.get();
|
||||
}
|
||||
|
||||
createChunkNeighbours(chunk);
|
||||
linkChunkNeighbours(chunk);
|
||||
|
||||
// Receive chunk data
|
||||
// bool hasUpdatedChunk = false;
|
||||
|
@ -225,7 +225,7 @@ Chunk *ClientWorld::getChunk(int cx, int cy, int cz) const {
|
|||
return it->second.get();
|
||||
}
|
||||
|
||||
void ClientWorld::createChunkNeighbours(ClientChunk *chunk) {
|
||||
void ClientWorld::linkChunkNeighbours(ClientChunk *chunk) {
|
||||
gk::Vector3i surroundingChunks[6] = {
|
||||
{chunk->x() - 1, chunk->y(), chunk->z()},
|
||||
{chunk->x() + 1, chunk->y(), chunk->z()},
|
||||
|
@ -242,14 +242,6 @@ void ClientWorld::createChunkNeighbours(ClientChunk *chunk) {
|
|||
const s32 scz = surroundingChunks[i].z;
|
||||
|
||||
ClientChunk *neighbour = (ClientChunk *)getChunk(scx, scy, scz);
|
||||
// if (!neighbour) {
|
||||
// auto it = m_chunks.emplace(gk::Vector3i{scx, scy, scz}, new ClientChunk(scx, scy, scz, *m_dimension, *this, m_textureAtlas));
|
||||
// neighbour = it.first->second.get();
|
||||
|
||||
// if (m_eventHandler)
|
||||
// m_eventHandler->emplaceEvent<ChunkCreatedEvent>(gk::Vector3i{scx, scy, scz}, false);
|
||||
// }
|
||||
|
||||
if (neighbour) {
|
||||
chunk->setSurroundingChunk(i, neighbour);
|
||||
neighbour->setSurroundingChunk((i % 2 == 0) ? i + 1 : i - 1, chunk);
|
||||
|
|
|
@ -80,7 +80,7 @@ class ClientWorld : public World, public gk::Drawable {
|
|||
const Sky *sky() const { return m_sky; }
|
||||
|
||||
private:
|
||||
void createChunkNeighbours(ClientChunk *chunk);
|
||||
void linkChunkNeighbours(ClientChunk *chunk);
|
||||
|
||||
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
|
||||
|
||||
|
|
|
@ -233,6 +233,13 @@ BlockData *Chunk::addBlockData(int x, int y, int z, int inventoryWidth, int inve
|
|||
return it->second.get();
|
||||
}
|
||||
|
||||
void Chunk::setSurroundingChunk(u8 i, Chunk *chunk) {
|
||||
if (i < 6) {
|
||||
m_surroundingChunkPresence.set(i, chunk != nullptr);
|
||||
m_surroundingChunks[i] = chunk;
|
||||
}
|
||||
}
|
||||
|
||||
bool Chunk::areAllNeighboursInitialized() const {
|
||||
return m_surroundingChunks[Chunk::West] && m_surroundingChunks[Chunk::West]->isInitialized()
|
||||
&& m_surroundingChunks[Chunk::East] && m_surroundingChunks[Chunk::East]->isInitialized()
|
||||
|
|
|
@ -85,11 +85,13 @@ class Chunk : public gk::NonCopyable {
|
|||
|
||||
World &world() { return m_world; }
|
||||
|
||||
bool hasSurroundingChunk(u8 i) { return (i > 5) ? false : m_surroundingChunkPresence[i]; }
|
||||
Chunk *getSurroundingChunk(u8 i) { return (i > 5) ? nullptr : m_surroundingChunks[i]; }
|
||||
const Chunk *getSurroundingChunk(u8 i) const { return (i > 5) ? nullptr : m_surroundingChunks[i]; }
|
||||
void setSurroundingChunk(u8 i, Chunk *chunk) { if (i < 6) m_surroundingChunks[i] = chunk; }
|
||||
void setSurroundingChunk(u8 i, Chunk *chunk);
|
||||
|
||||
bool areAllNeighboursInitialized() const;
|
||||
bool areAllNeighboursLoaded() const { return m_surroundingChunkPresence.all(); }
|
||||
|
||||
bool isInitialized() const { return m_isInitialized; }
|
||||
void setInitialized(bool isInitialized) { m_isInitialized = isInitialized; }
|
||||
|
@ -123,6 +125,7 @@ class Chunk : public gk::NonCopyable {
|
|||
ChunkLightmap m_lightmap{this};
|
||||
|
||||
Chunk *m_surroundingChunks[6]{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
|
||||
std::bitset<6> m_surroundingChunkPresence;
|
||||
|
||||
bool m_isInitialized = false;
|
||||
bool m_hasChanged = false;
|
||||
|
|
|
@ -219,6 +219,17 @@ void ChunkLightmap::updateSunlight() {
|
|||
}
|
||||
}
|
||||
|
||||
std::optional<u8> ChunkLightmap::tryGetLightData(int x, int y, int z) const {
|
||||
if(x < 0) return m_chunk->getSurroundingChunk(0) ? m_chunk->getSurroundingChunk(0)->lightmap().tryGetLightData(x + CHUNK_WIDTH, y, z) : std::nullopt;
|
||||
if(x >= CHUNK_WIDTH) return m_chunk->getSurroundingChunk(1) ? m_chunk->getSurroundingChunk(1)->lightmap().tryGetLightData(x - CHUNK_WIDTH, y, z) : std::nullopt;
|
||||
if(y < 0) return m_chunk->getSurroundingChunk(2) ? m_chunk->getSurroundingChunk(2)->lightmap().tryGetLightData(x, y + CHUNK_DEPTH, z) : std::nullopt;
|
||||
if(y >= CHUNK_DEPTH) return m_chunk->getSurroundingChunk(3) ? m_chunk->getSurroundingChunk(3)->lightmap().tryGetLightData(x, y - CHUNK_DEPTH, z) : std::nullopt;
|
||||
if(z < 0) return m_chunk->getSurroundingChunk(4) ? m_chunk->getSurroundingChunk(4)->lightmap().tryGetLightData(x, y, z + CHUNK_HEIGHT) : std::nullopt;
|
||||
if(z >= CHUNK_HEIGHT) return m_chunk->getSurroundingChunk(5) ? m_chunk->getSurroundingChunk(5)->lightmap().tryGetLightData(x, y, z - CHUNK_HEIGHT) : std::nullopt;
|
||||
|
||||
return m_lightMap[z][y][x];
|
||||
}
|
||||
|
||||
u8 ChunkLightmap::getLightData(int x, int y, int z) const {
|
||||
if(x < 0) return m_chunk->getSurroundingChunk(0) ? m_chunk->getSurroundingChunk(0)->lightmap().getLightData(x + CHUNK_WIDTH, y, z) : 15;
|
||||
if(x >= CHUNK_WIDTH) return m_chunk->getSurroundingChunk(1) ? m_chunk->getSurroundingChunk(1)->lightmap().getLightData(x - CHUNK_WIDTH, y, z) : 15;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#ifndef CHUNKLIGHTMAP_HPP_
|
||||
#define CHUNKLIGHTMAP_HPP_
|
||||
|
||||
#include <optional>
|
||||
#include <queue>
|
||||
|
||||
#include <gk/core/IntTypes.hpp>
|
||||
|
@ -63,6 +64,7 @@ class ChunkLightmap {
|
|||
void updateTorchlight();
|
||||
void updateSunlight();
|
||||
|
||||
std::optional<u8> tryGetLightData(int x, int y, int z) const;
|
||||
u8 getLightDataRaw(int x, int y, int z) const { return m_lightMap[z][y][x]; }
|
||||
u8 getLightData(int x, int y, int z) const;
|
||||
u8 getSunlight(int x, int y, int z) const;
|
||||
|
|
Loading…
Reference in New Issue