move Lighting instance to ChunksController

This commit is contained in:
MihailRis 2024-12-17 05:13:49 +03:00
parent c5049d0e24
commit b7664b4188
14 changed files with 60 additions and 61 deletions

View File

@ -8,11 +8,7 @@ assert(player.get_name(pid) == "Xerxes")
test.sleep_until(function() return world.count_chunks() >= 9 end, 1000) test.sleep_until(function() return world.count_chunks() >= 9 end, 1000)
print(world.count_chunks()) print(world.count_chunks())
for i=1,10 do timeit(10000000, block.get, 0, 0, 0)
print("--------------------")
timeit(10000000, block.get_fast, 0, 0, 0)
timeit(10000000, block.get, 0, 0, 0)
end
block.destruct(0, 0, 0, pid) block.destruct(0, 0, 0, pid)
assert(block.get(0, 0, 0) == 0) assert(block.get(0, 0, 0) == 0)

View File

@ -14,10 +14,10 @@
#include "world/Level.hpp" #include "world/Level.hpp"
#include "world/World.hpp" #include "world/World.hpp"
BlocksController::BlocksController(const Level& level, uint padding) BlocksController::BlocksController(const Level& level, Lighting& lighting, uint padding)
: level(level), : level(level),
chunks(*level.chunks), chunks(*level.chunks),
lighting(*level.lighting), lighting(lighting),
randTickClock(20, 3), randTickClock(20, 3),
blocksTickClock(20, 1), blocksTickClock(20, 1),
worldTickClock(20, 1), worldTickClock(20, 1),

View File

@ -34,7 +34,7 @@ class BlocksController {
FastRandom random {}; FastRandom random {};
std::vector<on_block_interaction> blockInteractionCallbacks; std::vector<on_block_interaction> blockInteractionCallbacks;
public: public:
BlocksController(const Level& level, uint padding); BlocksController(const Level& level, Lighting& lighting, uint padding);
void updateSides(int x, int y, int z); void updateSides(int x, int y, int z);
void updateSides(int x, int y, int z, int w, int h, int d); void updateSides(int x, int y, int z, int w, int h, int d);

View File

@ -25,7 +25,7 @@ const uint MIN_SURROUNDING = 9;
ChunksController::ChunksController(Level& level, uint padding) ChunksController::ChunksController(Level& level, uint padding)
: level(level), : level(level),
chunks(*level.chunks), chunks(*level.chunks),
lighting(*level.lighting), lighting(std::make_unique<Lighting>(level.content, level.chunks.get())),
padding(padding), padding(padding),
generator(std::make_unique<WorldGenerator>( generator(std::make_unique<WorldGenerator>(
level.content->generators.require(level.getWorld()->getGenerator()), level.content->generators.require(level.getWorld()->getGenerator()),
@ -107,9 +107,9 @@ bool ChunksController::buildLights(const std::shared_ptr<Chunk>& chunk) {
if (surrounding == MIN_SURROUNDING) { if (surrounding == MIN_SURROUNDING) {
bool lightsCache = chunk->flags.loadedLights; 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->flags.lighted = true; chunk->flags.lighted = true;
return true; return true;
} }

View File

@ -15,7 +15,6 @@ class ChunksController {
private: private:
Level& level; Level& level;
Chunks& chunks; Chunks& chunks;
Lighting& lighting;
uint padding; uint padding;
std::unique_ptr<WorldGenerator> generator; std::unique_ptr<WorldGenerator> generator;
@ -24,6 +23,8 @@ private:
bool buildLights(const std::shared_ptr<Chunk>& chunk); bool buildLights(const std::shared_ptr<Chunk>& chunk);
void createChunk(int x, int y); void createChunk(int x, int y);
public: public:
std::unique_ptr<Lighting> lighting;
ChunksController(Level& level, uint padding); ChunksController(Level& level, uint padding);
~ChunksController(); ~ChunksController();

View File

@ -20,12 +20,12 @@ static debug::Logger logger("level-control");
LevelController::LevelController(Engine* engine, std::unique_ptr<Level> levelPtr) LevelController::LevelController(Engine* engine, std::unique_ptr<Level> levelPtr)
: settings(engine->getSettings()), : settings(engine->getSettings()),
level(std::move(levelPtr)), level(std::move(levelPtr)),
blocks(std::make_unique<BlocksController>(
*level, settings.chunks.padding.get()
)),
chunks(std::make_unique<ChunksController>( chunks(std::make_unique<ChunksController>(
*level, settings.chunks.padding.get() *level, settings.chunks.padding.get()
)) { )) {
blocks = std::make_unique<BlocksController>(
*level, *chunks->lighting, settings.chunks.padding.get()
);
scripting::on_world_load(this); scripting::on_world_load(this);
} }

View File

@ -104,7 +104,13 @@ static int l_set(lua::State* L) {
return 0; return 0;
} }
blocks_agent::set(*level->chunksStorage, x, y, z, id, int2blockstate(state)); blocks_agent::set(*level->chunksStorage, x, y, z, id, int2blockstate(state));
level->lighting->onBlockSet(x, y, z, id);
auto chunksController = controller->getChunksController();
if (chunksController == nullptr) {
return 1;
}
Lighting& lighting = *chunksController->lighting;
lighting.onBlockSet(x, y, z, id);
if (!noupdate) { if (!noupdate) {
blocks->updateSides(x, y, z); blocks->updateSides(x, y, z);
} }
@ -120,15 +126,6 @@ static int l_get(lua::State* L) {
return lua::pushinteger(L, id); return lua::pushinteger(L, id);
} }
static int l_get_fast(lua::State* L) {
auto x = lua::tointeger(L, 1);
auto y = lua::tointeger(L, 2);
auto z = lua::tointeger(L, 3);
auto vox = blocks_agent::get(*level->chunks, x, y, z);
int id = vox == nullptr ? -1 : vox->id;
return lua::pushinteger(L, id);
}
static int l_get_x(lua::State* L) { static int l_get_x(lua::State* L) {
auto x = lua::tointeger(L, 1); auto x = lua::tointeger(L, 1);
auto y = lua::tointeger(L, 2); auto y = lua::tointeger(L, 2);
@ -638,7 +635,6 @@ const luaL_Reg blocklib[] = {
{"is_solid_at", lua::wrap<l_is_solid_at>}, {"is_solid_at", lua::wrap<l_is_solid_at>},
{"is_replaceable_at", lua::wrap<l_is_replaceable_at>}, {"is_replaceable_at", lua::wrap<l_is_replaceable_at>},
{"set", lua::wrap<l_set>}, {"set", lua::wrap<l_set>},
{"get_fast", lua::wrap<l_get_fast>},
{"get", lua::wrap<l_get>}, {"get", lua::wrap<l_get>},
{"get_X", lua::wrap<l_get_x>}, {"get_X", lua::wrap<l_get_x>},
{"get_Y", lua::wrap<l_get_y>}, {"get_Y", lua::wrap<l_get_y>},

View File

@ -16,6 +16,8 @@
#include "voxels/GlobalChunks.hpp" #include "voxels/GlobalChunks.hpp"
#include "world/Level.hpp" #include "world/Level.hpp"
#include "world/World.hpp" #include "world/World.hpp"
#include "logic/LevelController.hpp"
#include "logic/ChunksController.hpp"
using namespace scripting; using namespace scripting;
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -203,30 +205,37 @@ static int l_set_chunk_data(lua::State* L) {
} else { } else {
chunk->decode(buffer->data().data()); chunk->decode(buffer->data().data());
} }
auto chunksController = controller->getChunksController();
if (chunksController == nullptr) {
return 1;
}
Lighting& lighting = *chunksController->lighting;
chunk->updateHeights(); chunk->updateHeights();
level->lighting->buildSkyLight(x, y); lighting.buildSkyLight(x, y);
chunk->flags.modified = true; chunk->flags.modified = true;
level->lighting->onChunkLoaded(x, y, true); lighting.onChunkLoaded(x, y, true);
chunk = level->chunks->getChunk(x - 1, y); chunk = level->chunks->getChunk(x - 1, y);
if (chunk != nullptr) { if (chunk != nullptr) {
chunk->flags.modified = true; chunk->flags.modified = true;
level->lighting->onChunkLoaded(x - 1, y, true); lighting.onChunkLoaded(x - 1, y, true);
} }
chunk = level->chunks->getChunk(x + 1, y); chunk = level->chunks->getChunk(x + 1, y);
if (chunk != nullptr) { if (chunk != nullptr) {
chunk->flags.modified = true; chunk->flags.modified = true;
level->lighting->onChunkLoaded(x + 1, y, true); lighting.onChunkLoaded(x + 1, y, true);
} }
chunk = level->chunks->getChunk(x, y - 1); chunk = level->chunks->getChunk(x, y - 1);
if (chunk != nullptr) { if (chunk != nullptr) {
chunk->flags.modified = true; chunk->flags.modified = true;
level->lighting->onChunkLoaded(x, y - 1, true); lighting.onChunkLoaded(x, y - 1, true);
} }
chunk = level->chunks->getChunk(x, y + 1); chunk = level->chunks->getChunk(x, y + 1);
if (chunk != nullptr) { if (chunk != nullptr) {
chunk->flags.modified = true; chunk->flags.modified = true;
level->lighting->onChunkLoaded(x, y + 1, true); lighting.onChunkLoaded(x, y + 1, true);
} }
return 1; return 1;

View File

@ -44,6 +44,9 @@ Player::Player(
position(position), position(position),
inventory(std::move(inv)), inventory(std::move(inv)),
eid(eid), eid(eid),
chunks(std::make_unique<Chunks>(
3, 3, 0, 0, level->events.get(), level->content->getIndices()
)),
fpCamera(level->getCamera("core:first-person")), fpCamera(level->getCamera("core:first-person")),
spCamera(level->getCamera("core:third-person-front")), spCamera(level->getCamera("core:third-person-front")),
tpCamera(level->getCamera("core:third-person-back")), tpCamera(level->getCamera("core:third-person-back")),

View File

@ -8,6 +8,7 @@
#include "settings.hpp" #include "settings.hpp"
#include "voxels/voxel.hpp" #include "voxels/voxel.hpp"
class Chunks;
class Camera; class Camera;
class Inventory; class Inventory;
class ContentReport; class ContentReport;
@ -55,6 +56,7 @@ class Player : public Serializable {
entityid_t eid; entityid_t eid;
entityid_t selectedEid = 0; entityid_t selectedEid = 0;
public: public:
std::unique_ptr<Chunks> chunks; // not in use yet
std::shared_ptr<Camera> fpCamera, spCamera, tpCamera; std::shared_ptr<Camera> fpCamera, spCamera, tpCamera;
std::shared_ptr<Camera> currentCamera; std::shared_ptr<Camera> currentCamera;
bool debug = false; bool debug = false;

View File

@ -1,6 +1,5 @@
#include "Chunks.hpp" #include "Chunks.hpp"
#include <limits.h>
#include <math.h> #include <math.h>
#include <algorithm> #include <algorithm>
@ -20,9 +19,6 @@
#include "world/Level.hpp" #include "world/Level.hpp"
#include "world/LevelEvents.hpp" #include "world/LevelEvents.hpp"
#include "VoxelsVolume.hpp" #include "VoxelsVolume.hpp"
#include "Block.hpp"
#include "Chunk.hpp"
#include "voxel.hpp"
#include "blocks_agent.hpp" #include "blocks_agent.hpp"
Chunks::Chunks( Chunks::Chunks(
@ -30,16 +26,15 @@ Chunks::Chunks(
int32_t d, int32_t d,
int32_t ox, int32_t ox,
int32_t oz, int32_t oz,
WorldFiles* wfile, LevelEvents* events,
Level* level const ContentIndices* indices
) )
: level(level), : events(events),
indices(level ? level->content->getIndices() : nullptr), indices(indices),
areaMap(w, d), areaMap(w, d) {
worldFiles(wfile) {
areaMap.setCenter(ox-w/2, oz-d/2); areaMap.setCenter(ox-w/2, oz-d/2);
areaMap.setOutCallback([this](int, int, const auto& chunk) { areaMap.setOutCallback([this](int, int, const auto& chunk) {
this->level->events->trigger(EVT_CHUNK_HIDDEN, chunk.get()); this->events->trigger(EVT_CHUNK_HIDDEN, chunk.get());
}); });
} }
@ -319,8 +314,9 @@ void Chunks::resize(uint32_t newW, uint32_t newD) {
bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) { bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) {
if (areaMap.set(chunk->x, chunk->z, chunk)) { if (areaMap.set(chunk->x, chunk->z, chunk)) {
if (level) if (events) {
level->events->trigger(LevelEventType::EVT_CHUNK_SHOWN, chunk.get()); events->trigger(LevelEventType::EVT_CHUNK_SHOWN, chunk.get());
}
return true; return true;
} }
return false; return false;
@ -330,8 +326,6 @@ bool Chunks::putChunk(const std::shared_ptr<Chunk>& chunk) {
// 25.06.2024: not now // 25.06.2024: not now
// 11.11.2024: not now // 11.11.2024: not now
void Chunks::getVoxels(VoxelsVolume* volume, bool backlight) const { void Chunks::getVoxels(VoxelsVolume* volume, bool backlight) const {
const Content* content = level->content;
auto indices = content->getIndices();
voxel* voxels = volume->getVoxels(); voxel* voxels = volume->getVoxels();
light_t* lights = volume->getLights(); light_t* lights = volume->getLights();
int x = volume->getX(); int x = volume->getX();

View File

@ -20,12 +20,11 @@ class Chunk;
class WorldFiles; class WorldFiles;
class LevelEvents; class LevelEvents;
class Block; class Block;
class Level;
class VoxelsVolume; class VoxelsVolume;
/// Player-centred chunks matrix /// Player-centred chunks matrix
class Chunks { class Chunks {
Level* level; LevelEvents* events;
const ContentIndices* const indices; const ContentIndices* const indices;
void eraseSegments(const Block& def, blockstate state, int x, int y, int z); void eraseSegments(const Block& def, blockstate state, int x, int y, int z);
@ -40,15 +39,14 @@ class Chunks {
); );
util::AreaMap2D<std::shared_ptr<Chunk>, int32_t> areaMap; util::AreaMap2D<std::shared_ptr<Chunk>, int32_t> areaMap;
WorldFiles* worldFiles;
public: public:
Chunks( Chunks(
int32_t w, int32_t w,
int32_t d, int32_t d,
int32_t ox, int32_t ox,
int32_t oz, int32_t oz,
WorldFiles* worldFiles, LevelEvents* events,
Level* level const ContentIndices* indices
); );
~Chunks() = default; ~Chunks() = default;
@ -156,4 +154,8 @@ public:
const ContentIndices& getContentIndices() const { const ContentIndices& getContentIndices() const {
return *indices; return *indices;
} }
static inline constexpr unsigned matrixSize(int loadDistance, int padding) {
return (loadDistance + padding) * 2;
}
}; };

View File

@ -23,14 +23,14 @@ Level::Level(
const Content* content, const Content* content,
EngineSettings& settings EngineSettings& settings
) )
: world(std::move(worldPtr)), : settings(settings),
world(std::move(worldPtr)),
content(content), content(content),
chunksStorage(std::make_unique<GlobalChunks>(this)), chunksStorage(std::make_unique<GlobalChunks>(this)),
physics(std::make_unique<PhysicsSolver>(glm::vec3(0, -22.6f, 0))), physics(std::make_unique<PhysicsSolver>(glm::vec3(0, -22.6f, 0))),
events(std::make_unique<LevelEvents>()), events(std::make_unique<LevelEvents>()),
entities(std::make_unique<Entities>(this)), entities(std::make_unique<Entities>(this)),
players(std::make_unique<Players>(this)), players(std::make_unique<Players>(this)) {
settings(settings) {
const auto& worldInfo = world->getInfo(); const auto& worldInfo = world->getInfo();
auto& cameraIndices = content->getIndices(ResourceType::CAMERA); auto& cameraIndices = content->getIndices(ResourceType::CAMERA);
for (size_t i = 0; i < cameraIndices.size(); i++) { for (size_t i = 0; i < cameraIndices.size(); i++) {
@ -65,11 +65,9 @@ Level::Level(
(settings.chunks.loadDistance.get() + settings.chunks.padding.get()) * (settings.chunks.loadDistance.get() + settings.chunks.padding.get()) *
2; 2;
chunks = std::make_unique<Chunks>( chunks = std::make_unique<Chunks>(
matrixSize, matrixSize, 0, 0, world->wfile.get(), this matrixSize, matrixSize, 0, 0, events.get(), content->getIndices()
); );
lighting = std::make_unique<Lighting>(content, chunks.get());
inventories = std::make_unique<Inventories>(*this); inventories = std::make_unique<Inventories>(*this);
} }

View File

@ -22,6 +22,7 @@ struct EngineSettings;
/// @brief A level, contains chunks and objects /// @brief A level, contains chunks and objects
class Level { class Level {
const EngineSettings& settings;
std::unique_ptr<World> world; std::unique_ptr<World> world;
public: public:
const Content* const content; const Content* const content;
@ -31,14 +32,11 @@ public:
std::unique_ptr<Inventories> inventories; std::unique_ptr<Inventories> inventories;
std::unique_ptr<PhysicsSolver> physics; std::unique_ptr<PhysicsSolver> physics;
std::unique_ptr<Lighting> lighting;
std::unique_ptr<LevelEvents> events; std::unique_ptr<LevelEvents> events;
std::unique_ptr<Entities> entities; std::unique_ptr<Entities> entities;
std::unique_ptr<Players> players; std::unique_ptr<Players> players;
std::vector<std::shared_ptr<Camera>> cameras; // move somewhere? std::vector<std::shared_ptr<Camera>> cameras; // move somewhere?
const EngineSettings& settings;
Level( Level(
std::unique_ptr<World> world, std::unique_ptr<World> world,
const Content* content, const Content* content,