[ChunkLightmap] Added. Lot of code removed from Chunk.
This commit is contained in:
parent
22a09ed831
commit
e236622408
2
TODO
2
TODO
@ -89,6 +89,8 @@ TODO
|
||||
▸ TODO: Occlusion culling
|
||||
◦ TODO: Face-merging
|
||||
→ Trouver une solution pour utiliser un texture atlas avec ça
|
||||
• TODO: Séparer le pipeline 2D du pipeline 3D
|
||||
◦ TODO: Ajouter une implémentation de VAO par type de rendu (2D/Chunk/Liquid/Plant)
|
||||
|
||||
# Idées diverses
|
||||
|
||||
|
@ -14,12 +14,20 @@
|
||||
#ifndef CONFIG_HPP_
|
||||
#define CONFIG_HPP_
|
||||
|
||||
#define SCREEN_WIDTH 1600
|
||||
#define SCREEN_HEIGHT 1050
|
||||
namespace {
|
||||
constexpr const char *APP_NAME = "KubKraft";
|
||||
|
||||
#define APP_NAME "KubKraft"
|
||||
constexpr float SCREEN_WIDTH = 1600;
|
||||
constexpr float SCREEN_HEIGHT = 1050;
|
||||
|
||||
#define DIST_NEAR 0.1f
|
||||
#define DIST_FAR 1000.0f
|
||||
constexpr float DIST_NEAR = 0.1f;
|
||||
constexpr float DIST_FAR = 1000.0f;
|
||||
|
||||
constexpr int CHUNK_WIDTH = 16.0f;
|
||||
constexpr int CHUNK_HEIGHT = 32.0f;
|
||||
constexpr int CHUNK_DEPTH = 16.0f;
|
||||
|
||||
constexpr int SEALEVEL = 4;
|
||||
}
|
||||
|
||||
#endif // CONFIG_HPP_
|
||||
|
@ -20,29 +20,13 @@
|
||||
|
||||
#include "Block.hpp"
|
||||
#include "ChunkBuilder.hpp"
|
||||
#include "ChunkLightmap.hpp"
|
||||
#include "IDrawable.hpp"
|
||||
#include "NonCopyable.hpp"
|
||||
#include "Shader.hpp"
|
||||
#include "Texture.hpp"
|
||||
#include "VertexBuffer.hpp"
|
||||
|
||||
#include <queue>
|
||||
|
||||
struct LightNode {
|
||||
LightNode(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
};
|
||||
|
||||
struct LightRemovalNode {
|
||||
LightRemovalNode(int _x, int _y, int _z, int _value) : x(_x), y(_y), z(_z), value(_value) {}
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int value;
|
||||
};
|
||||
|
||||
class Chunk : public NonCopyable, public IDrawable {
|
||||
public:
|
||||
Chunk(s32 x, s32 y, s32 z, Texture &texture);
|
||||
@ -52,12 +36,6 @@ class Chunk : public NonCopyable, public IDrawable {
|
||||
u32 getBlock(int x, int y, int z) const;
|
||||
void setBlock(int x, int y, int z, u32 id);
|
||||
|
||||
void addLight(Chunk &chunk, int x, int y, int z, int val);
|
||||
void addSunlight(Chunk &chunk, int x, int y, int z, int val);
|
||||
void removeLight(Chunk &chunk, int x, int y, int z);
|
||||
|
||||
void updateLights(Chunk &chunk);
|
||||
|
||||
s32 x() const { return m_x; }
|
||||
s32 y() const { return m_y; }
|
||||
s32 z() const { return m_z; }
|
||||
@ -69,10 +47,11 @@ class Chunk : public NonCopyable, public IDrawable {
|
||||
Chunk *below() const { return m_surroundingChunks[4]; }
|
||||
Chunk *above() const { return m_surroundingChunks[5]; }
|
||||
Chunk *getSurroundingChunk(u8 i) { return (i > 5) ? nullptr : m_surroundingChunks[i]; }
|
||||
const Chunk *getSurroundingChunk(u8 i) const { return (i > 5) ? nullptr : m_surroundingChunks[i]; }
|
||||
|
||||
static const u8 width = 16;
|
||||
static const u8 height = 32;
|
||||
static const u8 depth = 16;
|
||||
static constexpr u8 width = CHUNK_WIDTH;
|
||||
static constexpr u8 height = CHUNK_HEIGHT;
|
||||
static constexpr u8 depth = CHUNK_DEPTH;
|
||||
|
||||
void setLeft(Chunk *left) { m_surroundingChunks[0] = left; }
|
||||
void setRight(Chunk *right) { m_surroundingChunks[1] = right; }
|
||||
@ -88,11 +67,8 @@ class Chunk : public NonCopyable, public IDrawable {
|
||||
void setGenerated(bool isGenerated) { m_isGenerated = isGenerated; }
|
||||
void setInitialized(bool isInitialized) { m_isInitialized = isInitialized; }
|
||||
|
||||
int getSunlight(int x, int y, int z) const;
|
||||
void setSunlight(int x, int y, int z, int val);
|
||||
|
||||
int getTorchlight(int x, int y, int z) const;
|
||||
void setTorchlight(int x, int y, int z, int val);
|
||||
ChunkLightmap &lightmap() { return m_lightmap; }
|
||||
const ChunkLightmap &lightmap() const { return m_lightmap; }
|
||||
|
||||
private:
|
||||
void draw(RenderTarget &target, RenderStates states) const override;
|
||||
@ -108,13 +84,8 @@ class Chunk : public NonCopyable, public IDrawable {
|
||||
using DataArray = u32[Chunk::width][Chunk::height][Chunk::depth];
|
||||
DataArray m_data;
|
||||
|
||||
using LightMapArray = u8[Chunk::width][Chunk::height][Chunk::depth];
|
||||
LightMapArray m_lightMap;
|
||||
std::queue<LightNode> m_lightBfsQueue;
|
||||
std::queue<LightRemovalNode> m_lightRemovalBfsQueue;
|
||||
std::queue<LightNode> m_sunlightBfsQueue;
|
||||
|
||||
ChunkBuilder m_builder;
|
||||
ChunkLightmap m_lightmap{this};
|
||||
|
||||
VertexBuffer m_vbo;
|
||||
std::size_t m_verticesCount;
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Types.hpp"
|
||||
#include "Vertex.hpp"
|
||||
#include "Types.hpp"
|
||||
|
||||
class Block;
|
||||
class Chunk;
|
||||
|
66
include/world/ChunkLightmap.hpp
Normal file
66
include/world/ChunkLightmap.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* Filename: ChunkLightmap.hpp
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Created: 25/06/2018 14:32:36
|
||||
*
|
||||
* Author: Quentin Bazin, <quent42340@gmail.com>
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#ifndef CHUNKLIGHTMAP_HPP_
|
||||
#define CHUNKLIGHTMAP_HPP_
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "Config.hpp"
|
||||
#include "Types.hpp"
|
||||
|
||||
struct LightNode {
|
||||
LightNode(int _x, int _y, int _z) : x(_x), y(_y), z(_z) {}
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
};
|
||||
|
||||
struct LightRemovalNode {
|
||||
LightRemovalNode(int _x, int _y, int _z, int _value) : x(_x), y(_y), z(_z), value(_value) {}
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int value;
|
||||
};
|
||||
|
||||
class Chunk;
|
||||
|
||||
class ChunkLightmap {
|
||||
public:
|
||||
ChunkLightmap(Chunk *chunk);
|
||||
|
||||
void addLight(int x, int y, int z, int val);
|
||||
void addSunlight(int x, int y, int z, int val);
|
||||
void removeLight(int x, int y, int z);
|
||||
|
||||
void updateLights();
|
||||
|
||||
int getSunlight(int x, int y, int z) const;
|
||||
int getTorchlight(int x, int y, int z) const;
|
||||
|
||||
private:
|
||||
void setTorchlight(int x, int y, int z, int val);
|
||||
void setSunlight(int x, int y, int z, int val);
|
||||
|
||||
Chunk *m_chunk = nullptr;
|
||||
|
||||
using LightMapArray = u8[CHUNK_WIDTH][CHUNK_HEIGHT][CHUNK_DEPTH];
|
||||
LightMapArray m_lightMap;
|
||||
|
||||
std::queue<LightNode> m_lightBfsQueue;
|
||||
std::queue<LightRemovalNode> m_lightRemovalBfsQueue;
|
||||
std::queue<LightNode> m_sunlightBfsQueue;
|
||||
};
|
||||
|
||||
#endif // CHUNKLIGHTMAP_HPP_
|
@ -16,8 +16,6 @@
|
||||
|
||||
class Chunk;
|
||||
|
||||
#define SEALEVEL 4
|
||||
|
||||
class TerrainGenerator {
|
||||
public:
|
||||
void generate(Chunk &chunk) const;
|
||||
|
@ -40,7 +40,7 @@ void main() {
|
||||
// color *= light(vec3(1.0, 1.0, 1.0), vec4(lightPosition, 1.0), 0.5, 0.5);
|
||||
|
||||
if (v_lightValue.x != -1) {
|
||||
float ambientIntensity = max(v_lightValue.x, v_lightValue.y) / 16.0;
|
||||
float ambientIntensity = max(max(v_lightValue.x, v_lightValue.y) / 16.0, 4.0 / 16.0);
|
||||
float diffuseIntensity = max(v_lightValue.x, v_lightValue.y) / 32.0;
|
||||
|
||||
color = light(color, vec3(1.0, 1.0, 1.0), v_coord3d, ambientIntensity, diffuseIntensity);
|
||||
|
@ -20,15 +20,14 @@ Chunk::Chunk(s32 x, s32 y, s32 z, Texture &texture) : m_texture(texture) {
|
||||
m_z = z;
|
||||
|
||||
std::memset(m_data, 0, sizeof(m_data));
|
||||
std::memset(m_lightMap, 0, sizeof(m_lightMap));
|
||||
}
|
||||
|
||||
void Chunk::update(World &world) {
|
||||
void Chunk::update(World &) {
|
||||
if (!m_isChanged) return;
|
||||
|
||||
m_isChanged = false;
|
||||
|
||||
updateLights(*this);
|
||||
m_lightmap.updateLights();
|
||||
|
||||
m_verticesCount = m_builder.buildChunk(*this, m_vbo);
|
||||
|
||||
@ -73,10 +72,9 @@ void Chunk::setBlock(int x, int y, int z, u32 type) {
|
||||
}
|
||||
|
||||
if (type == 2)
|
||||
addLight(*this, x, y, z, 14);
|
||||
// else if (m_data[x][y][z] == 2)
|
||||
m_lightmap.addLight(x, y, z, 14);
|
||||
else
|
||||
removeLight(*this, x, y, z);
|
||||
m_lightmap.removeLight(x, y, z);
|
||||
|
||||
m_data[x][y][z] = type;
|
||||
|
||||
@ -90,144 +88,6 @@ void Chunk::setBlock(int x, int y, int z, u32 type) {
|
||||
if(z == depth - 1 && back()) { back()->m_isChanged = true; }
|
||||
}
|
||||
|
||||
void Chunk::addLight(Chunk &chunk, int x, int y, int z, int val) {
|
||||
chunk.setTorchlight(x, y, z, val);
|
||||
m_lightBfsQueue.emplace(x, y, z);
|
||||
}
|
||||
|
||||
void Chunk::addSunlight(Chunk &chunk, int x, int y, int z, int val) {
|
||||
chunk.setSunlight(x, y, z, val);
|
||||
m_sunlightBfsQueue.emplace(x, y, z);
|
||||
}
|
||||
|
||||
void Chunk::removeLight(Chunk &chunk, int x, int y, int z) {
|
||||
m_lightRemovalBfsQueue.emplace(x, y, z, chunk.getTorchlight(x, y, z));
|
||||
chunk.setTorchlight(x, y, z, 0);
|
||||
}
|
||||
|
||||
void Chunk::updateLights(Chunk &chunk) {
|
||||
while (!m_lightRemovalBfsQueue.empty()) {
|
||||
LightRemovalNode node = m_lightRemovalBfsQueue.front();
|
||||
m_lightRemovalBfsQueue.pop();
|
||||
|
||||
LightNode surroundingNodes[6] = {
|
||||
{node.x - 1, node.y, node.z},
|
||||
{node.x + 1, node.y, node.z},
|
||||
{node.x, node.y - 1, node.z},
|
||||
{node.x, node.y + 1, node.z},
|
||||
{node.x, node.y, node.z - 1},
|
||||
{node.x, node.y, node.z + 1},
|
||||
};
|
||||
|
||||
for (const LightNode &surroundingNode : surroundingNodes) {
|
||||
int level = chunk.getTorchlight(surroundingNode.x, surroundingNode.y, surroundingNode.z);
|
||||
if (level != 0 && level < node.value) {
|
||||
chunk.setTorchlight(surroundingNode.x, surroundingNode.y, surroundingNode.z, 0);
|
||||
|
||||
m_lightRemovalBfsQueue.emplace(surroundingNode.x, surroundingNode.y, surroundingNode.z, level);
|
||||
}
|
||||
else if (level >= node.value) {
|
||||
m_lightBfsQueue.emplace(surroundingNode.x, surroundingNode.y, surroundingNode.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!m_lightBfsQueue.empty()) {
|
||||
LightNode node = m_lightBfsQueue.front();
|
||||
m_lightBfsQueue.pop();
|
||||
|
||||
LightNode surroundingNodes[6] = {
|
||||
{node.x - 1, node.y, node.z},
|
||||
{node.x + 1, node.y, node.z},
|
||||
{node.x, node.y - 1, node.z},
|
||||
{node.x, node.y + 1, node.z},
|
||||
{node.x, node.y, node.z - 1},
|
||||
{node.x, node.y, node.z + 1},
|
||||
};
|
||||
|
||||
int lightLevel = chunk.getTorchlight(node.x, node.y, node.z);
|
||||
for (const LightNode &surroundingNode : surroundingNodes) {
|
||||
if (chunk.getTorchlight(surroundingNode.x, surroundingNode.y, surroundingNode.z) + 2 <= lightLevel) {
|
||||
chunk.setTorchlight(surroundingNode.x, surroundingNode.y, surroundingNode.z, lightLevel - 1);
|
||||
|
||||
if (!Registry::getInstance().getBlock(getBlock(surroundingNode.x, surroundingNode.y, surroundingNode.z)).isOpaque()) {
|
||||
m_lightBfsQueue.emplace(surroundingNode.x, surroundingNode.y, surroundingNode.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!m_sunlightBfsQueue.empty()) {
|
||||
LightNode node = m_sunlightBfsQueue.front();
|
||||
m_sunlightBfsQueue.pop();
|
||||
|
||||
LightNode surroundingNodes[6] = {
|
||||
{node.x - 1, node.y, node.z},
|
||||
{node.x + 1, node.y, node.z},
|
||||
{node.x, node.y - 1, node.z},
|
||||
{node.x, node.y + 1, node.z},
|
||||
{node.x, node.y, node.z - 1},
|
||||
{node.x, node.y, node.z + 1},
|
||||
};
|
||||
|
||||
int sunlightLevel = chunk.getSunlight(node.x, node.y, node.z);
|
||||
for (const LightNode &surroundingNode : surroundingNodes) {
|
||||
if (/*!Registry::getInstance().getBlock(getBlock(surroundingNode.x, surroundingNode.y, surroundingNode.z)).isOpaque()
|
||||
&& */ chunk.getSunlight(surroundingNode.x, surroundingNode.y, surroundingNode.z) + 2 <= sunlightLevel) {
|
||||
if (sunlightLevel == 16 && surroundingNode.y == node.y - 1)
|
||||
chunk.setSunlight(surroundingNode.x, surroundingNode.y, surroundingNode.z, sunlightLevel);
|
||||
else
|
||||
chunk.setSunlight(surroundingNode.x, surroundingNode.y, surroundingNode.z, sunlightLevel - 1);
|
||||
|
||||
m_sunlightBfsQueue.emplace(surroundingNode.x, surroundingNode.y, surroundingNode.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Chunk::getSunlight(int x, int y, int z) const {
|
||||
if(x < 0) return m_surroundingChunks[0] ? m_surroundingChunks[0]->getSunlight(x + Chunk::width, y, z) : 0;
|
||||
if(x >= Chunk::width) return m_surroundingChunks[1] ? m_surroundingChunks[1]->getSunlight(x - Chunk::width, y, z) : 0;
|
||||
if(y < 0) return m_surroundingChunks[4] ? m_surroundingChunks[4]->getSunlight(x, y + Chunk::height, z) : 0;
|
||||
if(y >= Chunk::height) return m_surroundingChunks[5] ? m_surroundingChunks[5]->getSunlight(x, y - Chunk::height, z) : 0;
|
||||
if(z < 0) return m_surroundingChunks[2] ? m_surroundingChunks[2]->getSunlight(x, y, z + Chunk::depth) : 0;
|
||||
if(z >= Chunk::depth) return m_surroundingChunks[3] ? m_surroundingChunks[3]->getSunlight(x, y, z - Chunk::depth) : 0;
|
||||
return (m_lightMap[x][y][z] >> 4) & 0xf;
|
||||
}
|
||||
|
||||
void Chunk::setSunlight(int x, int y, int z, int val) {
|
||||
if(x < 0) { if(m_surroundingChunks[0]) m_surroundingChunks[0]->setSunlight(x + Chunk::width, y, z, val); return; }
|
||||
if(x >= Chunk::width) { if(m_surroundingChunks[1]) m_surroundingChunks[1]->setSunlight(x - Chunk::width, y, z, val); return; }
|
||||
if(y < 0) { if(m_surroundingChunks[4]) m_surroundingChunks[4]->setSunlight(x, y + Chunk::height, z, val); return; }
|
||||
if(y >= Chunk::height) { if(m_surroundingChunks[5]) m_surroundingChunks[5]->setSunlight(x, y - Chunk::height, z, val); return; }
|
||||
if(z < 0) { if(m_surroundingChunks[2]) m_surroundingChunks[2]->setSunlight(x, y, z + Chunk::depth, val); return; }
|
||||
if(z >= Chunk::depth) { if(m_surroundingChunks[3]) m_surroundingChunks[3]->setSunlight(x, y, z - Chunk::depth, val); return; }
|
||||
m_lightMap[x][y][z] = (m_lightMap[x][y][z] & 0xf) | (val << 4);
|
||||
|
||||
m_isChanged = true;
|
||||
}
|
||||
|
||||
int Chunk::getTorchlight(int x, int y, int z) const {
|
||||
if(x < 0) return m_surroundingChunks[0] ? m_surroundingChunks[0]->getTorchlight(x + Chunk::width, y, z) : 0;
|
||||
if(x >= Chunk::width) return m_surroundingChunks[1] ? m_surroundingChunks[1]->getTorchlight(x - Chunk::width, y, z) : 0;
|
||||
if(y < 0) return m_surroundingChunks[4] ? m_surroundingChunks[4]->getTorchlight(x, y + Chunk::height, z) : 0;
|
||||
if(y >= Chunk::height) return m_surroundingChunks[5] ? m_surroundingChunks[5]->getTorchlight(x, y - Chunk::height, z) : 0;
|
||||
if(z < 0) return m_surroundingChunks[2] ? m_surroundingChunks[2]->getTorchlight(x, y, z + Chunk::depth) : 0;
|
||||
if(z >= Chunk::depth) return m_surroundingChunks[3] ? m_surroundingChunks[3]->getTorchlight(x, y, z - Chunk::depth) : 0;
|
||||
return m_lightMap[x][y][z] & 0xf;
|
||||
}
|
||||
|
||||
void Chunk::setTorchlight(int x, int y, int z, int val) {
|
||||
if(x < 0) { if(m_surroundingChunks[0]) m_surroundingChunks[0]->setTorchlight(x + Chunk::width, y, z, val); return; }
|
||||
if(x >= Chunk::width) { if(m_surroundingChunks[1]) m_surroundingChunks[1]->setTorchlight(x - Chunk::width, y, z, val); return; }
|
||||
if(y < 0) { if(m_surroundingChunks[4]) m_surroundingChunks[4]->setTorchlight(x, y + Chunk::height, z, val); return; }
|
||||
if(y >= Chunk::height) { if(m_surroundingChunks[5]) m_surroundingChunks[5]->setTorchlight(x, y - Chunk::height, z, val); return; }
|
||||
if(z < 0) { if(m_surroundingChunks[2]) m_surroundingChunks[2]->setTorchlight(x, y, z + Chunk::depth, val); return; }
|
||||
if(z >= Chunk::depth) { if(m_surroundingChunks[3]) m_surroundingChunks[3]->setTorchlight(x, y, z - Chunk::depth, val); return; }
|
||||
m_lightMap[x][y][z] = (m_lightMap[x][y][z] & 0xf0) | val;
|
||||
|
||||
m_isChanged = true;
|
||||
}
|
||||
|
||||
|
||||
void Chunk::draw(RenderTarget &target, RenderStates states) const {
|
||||
if(m_verticesCount == 0) return;
|
||||
|
||||
|
@ -141,14 +141,14 @@ void ChunkBuilder::addFace(u8 x, u8 y, u8 z, u8 i, const Chunk &chunk, const Blo
|
||||
vertex.texCoord[0] = faceTexCoords[j * 2];
|
||||
vertex.texCoord[1] = faceTexCoords[j * 2 + 1];
|
||||
|
||||
int sunlight = chunk.getSunlight(x, y, z);
|
||||
int sunlight = chunk.lightmap().getSunlight(x, y, z);
|
||||
if ((i == 0 || i == 1 || i == 4 || i == 5) && sunlight > 2)
|
||||
vertex.lightValue[0] = sunlight - 2;
|
||||
if (i == 4 && sunlight > 3)
|
||||
vertex.lightValue[0] = sunlight - 3;
|
||||
else
|
||||
vertex.lightValue[0] = sunlight;
|
||||
vertex.lightValue[1] = chunk.getTorchlight(x, y, z);
|
||||
vertex.lightValue[1] = chunk.lightmap().getTorchlight(x, y, z);
|
||||
|
||||
m_vertices.emplace_back(vertex);
|
||||
}
|
||||
|
157
source/world/ChunkLightmap.cpp
Normal file
157
source/world/ChunkLightmap.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* Filename: ChunkLightmap.cpp
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Created: 25/06/2018 14:32:44
|
||||
*
|
||||
* Author: Quentin Bazin, <quent42340@gmail.com>
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#include "Chunk.hpp"
|
||||
#include "ChunkLightmap.hpp"
|
||||
#include "Registry.hpp"
|
||||
|
||||
ChunkLightmap::ChunkLightmap(Chunk *chunk) : m_chunk(chunk) {
|
||||
std::memset(m_lightMap, 0, sizeof(m_lightMap));
|
||||
}
|
||||
|
||||
void ChunkLightmap::addLight(int x, int y, int z, int val) {
|
||||
setTorchlight(x, y, z, val);
|
||||
m_lightBfsQueue.emplace(x, y, z);
|
||||
}
|
||||
|
||||
void ChunkLightmap::addSunlight(int x, int y, int z, int val) {
|
||||
setSunlight(x, y, z, val);
|
||||
m_sunlightBfsQueue.emplace(x, y, z);
|
||||
}
|
||||
|
||||
void ChunkLightmap::removeLight(int x, int y, int z) {
|
||||
m_lightRemovalBfsQueue.emplace(x, y, z, getTorchlight(x, y, z));
|
||||
setTorchlight(x, y, z, 0);
|
||||
}
|
||||
|
||||
void ChunkLightmap::updateLights() {
|
||||
while (!m_lightRemovalBfsQueue.empty()) {
|
||||
LightRemovalNode node = m_lightRemovalBfsQueue.front();
|
||||
m_lightRemovalBfsQueue.pop();
|
||||
|
||||
LightNode surroundingNodes[6] = {
|
||||
{node.x - 1, node.y, node.z},
|
||||
{node.x + 1, node.y, node.z},
|
||||
{node.x, node.y - 1, node.z},
|
||||
{node.x, node.y + 1, node.z},
|
||||
{node.x, node.y, node.z - 1},
|
||||
{node.x, node.y, node.z + 1},
|
||||
};
|
||||
|
||||
for (const LightNode &surroundingNode : surroundingNodes) {
|
||||
int level = getTorchlight(surroundingNode.x, surroundingNode.y, surroundingNode.z);
|
||||
if (level != 0 && level < node.value) {
|
||||
setTorchlight(surroundingNode.x, surroundingNode.y, surroundingNode.z, 0);
|
||||
|
||||
m_lightRemovalBfsQueue.emplace(surroundingNode.x, surroundingNode.y, surroundingNode.z, level);
|
||||
}
|
||||
else if (level >= node.value) {
|
||||
m_lightBfsQueue.emplace(surroundingNode.x, surroundingNode.y, surroundingNode.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!m_lightBfsQueue.empty()) {
|
||||
LightNode node = m_lightBfsQueue.front();
|
||||
m_lightBfsQueue.pop();
|
||||
|
||||
LightNode surroundingNodes[6] = {
|
||||
{node.x - 1, node.y, node.z},
|
||||
{node.x + 1, node.y, node.z},
|
||||
{node.x, node.y - 1, node.z},
|
||||
{node.x, node.y + 1, node.z},
|
||||
{node.x, node.y, node.z - 1},
|
||||
{node.x, node.y, node.z + 1},
|
||||
};
|
||||
|
||||
int lightLevel = getTorchlight(node.x, node.y, node.z);
|
||||
for (const LightNode &surroundingNode : surroundingNodes) {
|
||||
if (getTorchlight(surroundingNode.x, surroundingNode.y, surroundingNode.z) + 2 <= lightLevel) {
|
||||
setTorchlight(surroundingNode.x, surroundingNode.y, surroundingNode.z, lightLevel - 1);
|
||||
|
||||
if (!Registry::getInstance().getBlock(m_chunk->getBlock(surroundingNode.x, surroundingNode.y, surroundingNode.z)).isOpaque()) {
|
||||
m_lightBfsQueue.emplace(surroundingNode.x, surroundingNode.y, surroundingNode.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!m_sunlightBfsQueue.empty()) {
|
||||
LightNode node = m_sunlightBfsQueue.front();
|
||||
m_sunlightBfsQueue.pop();
|
||||
|
||||
LightNode surroundingNodes[6] = {
|
||||
{node.x - 1, node.y, node.z},
|
||||
{node.x + 1, node.y, node.z},
|
||||
{node.x, node.y - 1, node.z},
|
||||
{node.x, node.y + 1, node.z},
|
||||
{node.x, node.y, node.z - 1},
|
||||
{node.x, node.y, node.z + 1},
|
||||
};
|
||||
|
||||
int sunlightLevel = getSunlight(node.x, node.y, node.z);
|
||||
for (const LightNode &surroundingNode : surroundingNodes) {
|
||||
if (getSunlight(surroundingNode.x, surroundingNode.y, surroundingNode.z) + 2 <= sunlightLevel) {
|
||||
if (sunlightLevel == 16 && surroundingNode.y == node.y - 1)
|
||||
setSunlight(surroundingNode.x, surroundingNode.y, surroundingNode.z, sunlightLevel);
|
||||
else
|
||||
setSunlight(surroundingNode.x, surroundingNode.y, surroundingNode.z, sunlightLevel - 1);
|
||||
|
||||
m_sunlightBfsQueue.emplace(surroundingNode.x, surroundingNode.y, surroundingNode.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ChunkLightmap::getSunlight(int x, int y, int z) const {
|
||||
if(x < 0) return m_chunk->getSurroundingChunk(0) ? m_chunk->getSurroundingChunk(0)->lightmap().getSunlight(x + Chunk::width, y, z) : 0;
|
||||
if(x >= Chunk::width) return m_chunk->getSurroundingChunk(1) ? m_chunk->getSurroundingChunk(1)->lightmap().getSunlight(x - Chunk::width, y, z) : 0;
|
||||
if(y < 0) return m_chunk->getSurroundingChunk(4) ? m_chunk->getSurroundingChunk(4)->lightmap().getSunlight(x, y + Chunk::height, z) : 0;
|
||||
if(y >= Chunk::height) return m_chunk->getSurroundingChunk(5) ? m_chunk->getSurroundingChunk(5)->lightmap().getSunlight(x, y - Chunk::height, z) : 0;
|
||||
if(z < 0) return m_chunk->getSurroundingChunk(2) ? m_chunk->getSurroundingChunk(2)->lightmap().getSunlight(x, y, z + Chunk::depth) : 0;
|
||||
if(z >= Chunk::depth) return m_chunk->getSurroundingChunk(3) ? m_chunk->getSurroundingChunk(3)->lightmap().getSunlight(x, y, z - Chunk::depth) : 0;
|
||||
return (m_lightMap[x][y][z] >> 4) & 0xf;
|
||||
}
|
||||
|
||||
int ChunkLightmap::getTorchlight(int x, int y, int z) const {
|
||||
if(x < 0) return m_chunk->getSurroundingChunk(0) ? m_chunk->getSurroundingChunk(0)->lightmap().getTorchlight(x + Chunk::width, y, z) : 0;
|
||||
if(x >= Chunk::width) return m_chunk->getSurroundingChunk(1) ? m_chunk->getSurroundingChunk(1)->lightmap().getTorchlight(x - Chunk::width, y, z) : 0;
|
||||
if(y < 0) return m_chunk->getSurroundingChunk(4) ? m_chunk->getSurroundingChunk(4)->lightmap().getTorchlight(x, y + Chunk::height, z) : 0;
|
||||
if(y >= Chunk::height) return m_chunk->getSurroundingChunk(5) ? m_chunk->getSurroundingChunk(5)->lightmap().getTorchlight(x, y - Chunk::height, z) : 0;
|
||||
if(z < 0) return m_chunk->getSurroundingChunk(2) ? m_chunk->getSurroundingChunk(2)->lightmap().getTorchlight(x, y, z + Chunk::depth) : 0;
|
||||
if(z >= Chunk::depth) return m_chunk->getSurroundingChunk(3) ? m_chunk->getSurroundingChunk(3)->lightmap().getTorchlight(x, y, z - Chunk::depth) : 0;
|
||||
return m_lightMap[x][y][z] & 0xf;
|
||||
}
|
||||
|
||||
void ChunkLightmap::setSunlight(int x, int y, int z, int val) {
|
||||
if(x < 0) { if(m_chunk->getSurroundingChunk(0)) m_chunk->getSurroundingChunk(0)->lightmap().setSunlight(x + Chunk::width, y, z, val); return; }
|
||||
if(x >= Chunk::width) { if(m_chunk->getSurroundingChunk(1)) m_chunk->getSurroundingChunk(1)->lightmap().setSunlight(x - Chunk::width, y, z, val); return; }
|
||||
if(y < 0) { if(m_chunk->getSurroundingChunk(4)) m_chunk->getSurroundingChunk(4)->lightmap().setSunlight(x, y + Chunk::height, z, val); return; }
|
||||
if(y >= Chunk::height) { if(m_chunk->getSurroundingChunk(5)) m_chunk->getSurroundingChunk(5)->lightmap().setSunlight(x, y - Chunk::height, z, val); return; }
|
||||
if(z < 0) { if(m_chunk->getSurroundingChunk(2)) m_chunk->getSurroundingChunk(2)->lightmap().setSunlight(x, y, z + Chunk::depth, val); return; }
|
||||
if(z >= Chunk::depth) { if(m_chunk->getSurroundingChunk(3)) m_chunk->getSurroundingChunk(3)->lightmap().setSunlight(x, y, z - Chunk::depth, val); return; }
|
||||
m_lightMap[x][y][z] = (m_lightMap[x][y][z] & 0xf) | (val << 4);
|
||||
|
||||
m_chunk->setChanged(true);
|
||||
};
|
||||
|
||||
void ChunkLightmap::setTorchlight(int x, int y, int z, int val) {
|
||||
if(x < 0) { if(m_chunk->getSurroundingChunk(0)) m_chunk->getSurroundingChunk(0)->lightmap().setTorchlight(x + Chunk::width, y, z, val); return; }
|
||||
if(x >= Chunk::width) { if(m_chunk->getSurroundingChunk(1)) m_chunk->getSurroundingChunk(1)->lightmap().setTorchlight(x - Chunk::width, y, z, val); return; }
|
||||
if(y < 0) { if(m_chunk->getSurroundingChunk(4)) m_chunk->getSurroundingChunk(4)->lightmap().setTorchlight(x, y + Chunk::height, z, val); return; }
|
||||
if(y >= Chunk::height) { if(m_chunk->getSurroundingChunk(5)) m_chunk->getSurroundingChunk(5)->lightmap().setTorchlight(x, y - Chunk::height, z, val); return; }
|
||||
if(z < 0) { if(m_chunk->getSurroundingChunk(2)) m_chunk->getSurroundingChunk(2)->lightmap().setTorchlight(x, y, z + Chunk::depth, val); return; }
|
||||
if(z >= Chunk::depth) { if(m_chunk->getSurroundingChunk(3)) m_chunk->getSurroundingChunk(3)->lightmap().setTorchlight(x, y, z - Chunk::depth, val); return; }
|
||||
m_lightMap[x][y][z] = (m_lightMap[x][y][z] & 0xf0) | val;
|
||||
|
||||
m_chunk->setChanged(true);
|
||||
}
|
||||
|
@ -81,14 +81,14 @@ void TerrainGenerator::testCraftGeneration(Chunk &chunk) const {
|
||||
chunk.setBlock(x + ix, y + h + iy, z + iz, 4);
|
||||
|
||||
if (iy == 2)
|
||||
chunk.addSunlight(chunk, x + ix, y + h + iy, z + iz, 15);
|
||||
chunk.lightmap().addSunlight(x + ix, y + h + iy, z + iz, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
chunk.addSunlight(chunk, x, y, z, 15);
|
||||
chunk.lightmap().addSunlight(x, y, z, 15);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user