Browse Source

lighting changes

fix/style
Martin Dørum 3 years ago
parent
commit
c9ce067e11

+ 9
- 9
libswan/include/swan/LightServer.h View File

@@ -14,7 +14,7 @@ namespace Swan {

struct NewLightChunk {
std::bitset<CHUNK_WIDTH * CHUNK_HEIGHT> blocks;
std::map<std::pair<int, int>, uint8_t> light_sources;
std::map<std::pair<int, int>, int> light_sources;
};

struct LightChunk {
@@ -25,7 +25,7 @@ struct LightChunk {
std::bitset<CHUNK_WIDTH * CHUNK_HEIGHT> blocks;
uint8_t light_levels[CHUNK_WIDTH * CHUNK_HEIGHT] = { 0 };
uint8_t blocks_line[CHUNK_WIDTH] = { 0 };
std::map<std::pair<int, int>, uint8_t> light_sources;
std::map<std::pair<int, int>, int> light_sources;

bool was_updated = false;
};
@@ -42,8 +42,8 @@ public:

void onSolidBlockAdded(TilePos pos);
void onSolidBlockRemoved(TilePos pos);
void onLightAdded(TilePos pos, uint8_t level);
void onLightRemoved(TilePos pos, uint8_t level);
void onLightAdded(TilePos pos, int level);
void onLightRemoved(TilePos pos, int level);
void onChunkAdded(ChunkPos pos, NewLightChunk &&chunk);
void onChunkRemoved(ChunkPos pos);

@@ -56,7 +56,7 @@ private:

TilePos pos;
union {
size_t num;
int num;
};
};

@@ -65,7 +65,7 @@ private:

int recalcTile(
LightChunk &chunk, ChunkPos cpos, Vec2i rpos, TilePos base,
std::vector<std::pair<TilePos, uint8_t>> &lights);
std::vector<std::pair<TilePos, int>> &lights);
void processUpdatedChunk(LightChunk &chunk, ChunkPos cpos);
void processEvent(const Event &event, std::vector<NewLightChunk> &newChunks);
void run();
@@ -97,13 +97,13 @@ inline void LightServer::onSolidBlockRemoved(TilePos pos) {
cond_.notify_one();
}

inline void LightServer::onLightAdded(TilePos pos, uint8_t level) {
inline void LightServer::onLightAdded(TilePos pos, int level) {
std::lock_guard<std::mutex> lock(mut_);
buffers_[buffer_].push_back({ Event::Tag::LIGHT_ADDED, pos, { .num = level } });
cond_.notify_one();
}

inline void LightServer::onLightRemoved(TilePos pos, uint8_t level) {
inline void LightServer::onLightRemoved(TilePos pos, int level) {
std::lock_guard<std::mutex> lock(mut_);
buffers_[buffer_].push_back({ Event::Tag::LIGHT_REMOVED, pos, { .num = level } });
cond_.notify_one();
@@ -112,7 +112,7 @@ inline void LightServer::onLightRemoved(TilePos pos, uint8_t level) {
inline void LightServer::onChunkAdded(Vec2i pos, NewLightChunk &&chunk) {
std::lock_guard<std::mutex> lock(mut_);
buffers_[buffer_].push_back({ Event::Tag::CHUNK_ADDED, pos,
{ .num = new_chunk_buffers_[buffer_].size() } });
{ .num = (int)new_chunk_buffers_[buffer_].size() } });
new_chunk_buffers_[buffer_].push_back(std::move(chunk));
cond_.notify_one();
}

+ 3
- 3
libswan/include/swan/WorldPlane.h View File

@@ -76,6 +76,9 @@ public:

void debugBox(TilePos pos);

void addLight(TilePos pos, uint8_t level);
void removeLight(TilePos pos, uint8_t level);

// LightingCallback implementation
void onLightChunkUpdated(const LightChunk &chunk, Vec2i pos) final;

@@ -85,9 +88,6 @@ public:
std::mutex mut_;

private:
void addLight(TilePos pos, uint8_t level);
void removeLight(TilePos pos, uint8_t level);

std::unique_ptr<LightServer> lighting_;

std::map<std::pair<int, int>, Chunk> chunks_;

+ 29
- 14
libswan/src/LightServer.cc View File

@@ -104,6 +104,9 @@ void LightServer::processEvent(const Event &evt, std::vector<NewLightChunk> &new
case Event::Tag::LIGHT_REMOVED:
info << cpos << ": Remove " << evt.num << " light to " << rpos;
ch->light_sources[rpos] -= evt.num;
if (ch->light_sources[rpos] == 0) {
ch->light_sources.erase(rpos);
}
break;

// These were handled earlier
@@ -115,7 +118,7 @@ void LightServer::processEvent(const Event &evt, std::vector<NewLightChunk> &new

int LightServer::recalcTile(
LightChunk &chunk, ChunkPos cpos, Vec2i rpos, TilePos base,
std::vector<std::pair<TilePos, uint8_t>> &lights) {
std::vector<std::pair<TilePos, int>> &lights) {
TilePos pos = rpos + base;

constexpr int accuracy = 4;
@@ -133,8 +136,6 @@ int LightServer::recalcTile(
currtile = t;
};

proceed();

bool hit = false;
while ((currpos - from).squareLength() <= diff.squareLength()) {
if (tileIsSolid(currtile)) {
@@ -162,21 +163,35 @@ int LightServer::recalcTile(
float dist = ((Vec2)(lightpos - pos)).length();
int light = level - (int)dist;

int hit =
if (!tileIsSolid(pos)) {
bool hit = raycast(
Vec2(pos.x + 0.5, pos.y + 0.5),
Vec2(lightpos.x + 0.5, lightpos.y + 0.5));
if (!hit) {
acc += light;
}

continue;
}

bool blocked =
raycast(
Vec2(pos.x + 0.3, pos.y + 0.3),
Vec2(lightpos.x + 0.3, lightpos.y + 0.3)) +
Vec2(pos.x + 0.5, pos.y - 0.1),
Vec2(lightpos.x + 0.5, lightpos.y + 0.5)) &&
raycast(
Vec2(pos.x + 0.7, pos.y + 0.3),
Vec2(lightpos.x + 0.7, lightpos.y + 0.3)) +
Vec2(pos.x + 0.5, pos.y + 1.1),
Vec2(lightpos.x + 0.5, lightpos.y + 0.5)) &&
raycast(
Vec2(pos.x + 0.3, pos.y + 0.7),
Vec2(lightpos.x + 0.3, lightpos.y + 0.7)) +
Vec2(pos.x - 0.1, pos.y + 0.5),
Vec2(lightpos.x + 0.5, lightpos.y + 0.5)) &&
raycast(
Vec2(pos.x + 0.7, pos.y + 0.7),
Vec2(lightpos.x + 0.7, lightpos.y + 0.7));
Vec2(pos.x + 1.1, pos.y + 0.5),
Vec2(lightpos.x + 0.5, lightpos.y + 0.5));

if (!blocked) {
acc += light;
}

acc += (light * (4 - hit)) / 4;
if (acc >= 255) {
return 255;
}
@@ -188,7 +203,7 @@ int LightServer::recalcTile(
void LightServer::processUpdatedChunk(LightChunk &chunk, ChunkPos cpos) {
auto start = std::chrono::steady_clock::now();
TilePos base = cpos * Vec2i(CHUNK_WIDTH, CHUNK_HEIGHT);
std::vector<std::pair<TilePos, uint8_t>> lights;
std::vector<std::pair<TilePos, int>> lights;

for (auto &[pos, level]: chunk.light_sources) {
lights.emplace_back(Vec2i(pos) + base, level);

+ 8
- 7
libswan/src/WorldPlane.cc View File

@@ -218,7 +218,6 @@ void WorldPlane::draw(Win &win) {
// Just init one chunk per frame
if (chunk_init_list_.size() > 0) {
Chunk *chunk = chunk_init_list_.front();
info << "render chunk " << chunk->pos_;
chunk_init_list_.pop_front();
chunk->render(ctx, win.renderer_);
}
@@ -295,18 +294,20 @@ void WorldPlane::debugBox(TilePos pos) {
debug_boxes_.push_back(pos);
}

void WorldPlane::onLightChunkUpdated(const LightChunk &chunk, ChunkPos pos) {
std::lock_guard<std::mutex> lock(mut_);
Chunk &realChunk = getChunk(pos);
realChunk.setLightData(chunk.light_levels);
}

void WorldPlane::addLight(TilePos pos, uint8_t level) {
getChunk(chunkPos(pos));
lighting_->onLightAdded(pos, level);
}

void WorldPlane::removeLight(TilePos pos, uint8_t level) {
getChunk(chunkPos(pos));
lighting_->onLightRemoved(pos, level);
}

void WorldPlane::onLightChunkUpdated(const LightChunk &chunk, ChunkPos pos) {
std::lock_guard<std::mutex> lock(mut_);
Chunk &realChunk = getChunk(pos);
realChunk.setLightData(chunk.light_levels);
}

}

Loading…
Cancel
Save