1
0
Fork 0
Univerxel/src/contouring/FlatSurroundingBox.cpp

113 lines
5.2 KiB
C++
Raw Normal View History

2020-07-18 15:42:45 +00:00
#include "FlatSurroundingBox.hpp"
#include "boxing.hpp"
#include "../world/Chunk.hpp"
2020-07-31 23:17:09 +00:00
#include <imgui.h> // NOLINT
2020-07-18 15:42:45 +00:00
2020-07-25 16:45:03 +00:00
using namespace geometry;
2020-07-18 15:42:45 +00:00
namespace contouring {
2020-07-22 20:55:13 +00:00
FlatSurroundingBox::FlatSurroundingBox(const std::string &opt) : AbstractFlat(opt) {
for (size_t i = 1; i <= 4; i++) {
2020-07-31 17:09:44 +00:00
workers.emplace_back([&] {
2020-07-22 20:55:13 +00:00
while (running) {
2020-08-02 20:15:53 +00:00
std::pair<area_<chunk_pos>, surrounding::faces> ctx;
2020-07-22 20:55:13 +00:00
loadQueue.wait();
if (loadQueue.pop(ctx)) {
2020-07-25 16:45:03 +00:00
std::vector<buffer::VertexData> vertices;
2020-07-22 20:55:13 +00:00
render(ctx.second, vertices);
{
2020-07-31 17:09:44 +00:00
loadedQueue.emplace(ctx.first, vertices);
2020-07-22 20:55:13 +00:00
}
}
}
2020-07-31 17:09:44 +00:00
});
2020-07-22 20:55:13 +00:00
}
}
FlatSurroundingBox::~FlatSurroundingBox() {
running = false;
2020-08-05 13:14:57 +00:00
loadQueue.notify_all();
2020-07-18 15:42:45 +00:00
2020-07-22 20:55:13 +00:00
for(auto& worker: workers) {
if (worker.joinable())
worker.join();
}
}
2020-08-03 16:15:02 +00:00
void FlatSurroundingBox::enqueue(const area_<chunk_pos> &pos, const chunk_pos& offset, const world::ChunkContainer &data) {
const auto dist2 = glm::length2(offset - pos.second);
2020-07-22 20:55:13 +00:00
if (dist2 <= loadDistance * loadDistance) {
2020-07-24 19:42:47 +00:00
surrounding::faces surrounding;
2020-08-02 20:15:53 +00:00
if(surrounding::load(surrounding, pos.second, data)) {
2020-07-22 20:55:13 +00:00
loadQueue.push(pos, surrounding, -dist2);
2020-07-18 15:42:45 +00:00
}
}
2020-07-22 20:55:13 +00:00
}
2020-08-03 16:15:02 +00:00
void FlatSurroundingBox::onUpdate(const area_<chunk_pos> &pos, const chunk_pos& offset, const world::ChunkContainer &data, Faces neighbors) {
enqueue(pos, offset, data);
2020-07-22 20:55:13 +00:00
if (neighbors && Faces::Right)
2020-08-03 16:15:02 +00:00
enqueue(std::make_pair(pos.first, pos.second + g_face_offsets[static_cast<int>(Face::Right)]), offset, data);
2020-07-22 20:55:13 +00:00
if (neighbors && Faces::Left)
2020-08-03 16:15:02 +00:00
enqueue(std::make_pair(pos.first, pos.second + g_face_offsets[static_cast<int>(Face::Left)]), offset, data);
2020-07-22 20:55:13 +00:00
if (neighbors && Faces::Up)
2020-08-03 16:15:02 +00:00
enqueue(std::make_pair(pos.first, pos.second + g_face_offsets[static_cast<int>(Face::Up)]), offset, data);
2020-07-22 20:55:13 +00:00
if (neighbors && Faces::Down)
2020-08-03 16:15:02 +00:00
enqueue(std::make_pair(pos.first, pos.second + g_face_offsets[static_cast<int>(Face::Down)]), offset, data);
2020-07-22 20:55:13 +00:00
if (neighbors && Faces::Forward)
2020-08-03 16:15:02 +00:00
enqueue(std::make_pair(pos.first, pos.second + g_face_offsets[static_cast<int>(Face::Forward)]), offset, data);
2020-07-22 20:55:13 +00:00
if (neighbors && Faces::Backward)
2020-08-03 16:15:02 +00:00
enqueue(std::make_pair(pos.first, pos.second + g_face_offsets[static_cast<int>(Face::Backward)]), offset, data);
2020-07-18 15:42:45 +00:00
}
2020-08-03 16:15:02 +00:00
void FlatSurroundingBox::onNotify(const area_<chunk_pos> &pos, const chunk_pos& offset, const world::ChunkContainer &data) {
2020-08-02 20:15:53 +00:00
const auto it = buffers.find(pos.first);
2020-08-03 16:15:02 +00:00
if(it == buffers.end() || it->second.second.find(pos.second) == it->second.second.end()) {
enqueue(pos, offset, data);
2020-07-22 20:55:13 +00:00
}
}
2020-07-18 15:42:45 +00:00
2020-08-02 20:15:53 +00:00
void FlatSurroundingBox::update(const voxel_pos& pos, const world::area_map& areas) {
std::pair<area_<chunk_pos>, buffer::ShortIndexed::Data> out;
2020-07-22 20:55:13 +00:00
//MAYBE: clear out of range loadQueue.trim(keepDistance * keepDistance)
while(loadedQueue.pop(out)) {
2020-07-25 16:45:03 +00:00
const auto buffer = new buffer::ShortIndexed(GL_TRIANGLES, out.second);
2020-08-03 16:15:02 +00:00
auto& bfs = buffers[out.first.first].second; //NOTE: buffer.first uninitialized
2020-08-02 20:15:53 +00:00
if (const auto it = bfs.find(out.first.second); it != bfs.end()) {
2020-07-18 15:42:45 +00:00
if(it->second != NULL)
delete it->second;
it->second = buffer;
} else {
2020-08-02 20:15:53 +00:00
bfs.emplace(out.first.second, buffer);
2020-07-18 15:42:45 +00:00
}
}
2020-08-07 17:08:02 +00:00
AbstractFlat::clear(pos, areas);
2020-07-18 15:42:45 +00:00
}
2020-07-24 19:42:47 +00:00
bool FlatSurroundingBox::isTransparent(const surrounding::faces &surrounding, const std::pair<ushort, ushort> &idx) {
2020-08-02 09:47:25 +00:00
return surrounding[idx.first]->get(idx.second).density() < world::Voxel::DENSITY_MAX; // MAYBE: materials::transparent
2020-07-18 15:42:45 +00:00
}
2020-07-25 16:45:03 +00:00
void FlatSurroundingBox::render(const surrounding::faces &surrounding, std::vector<buffer::VertexData> &vertices) {
const auto center = surrounding[surrounding::CENTER];
2020-07-18 15:42:45 +00:00
vertices.clear();
2020-08-02 20:15:53 +00:00
for (ushort i = 0; i < world::CHUNK_SIZE; i++) {
2020-08-02 09:47:25 +00:00
if (center->get(i).density() > 0) {
Faces faces = center->get(i).density() < world::Voxel::DENSITY_MAX ? Faces::All :
2020-07-18 15:42:45 +00:00
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Right)) & Faces::Right) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Left)) & Faces::Left) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Up)) & Faces::Up) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Down)) & Faces::Down) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Forward)) & Faces::Forward) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Backward)) & Faces::Backward);
2020-08-02 20:15:53 +00:00
box::addCube(vertices, glm::fromIdx(i), center->get(i).material(), faces, glm::vec3(center->get(i).density() * 1.f / world::Voxel::DENSITY_MAX));
2020-07-18 15:42:45 +00:00
}
}
}
}