105 lines
4.7 KiB
C++
105 lines
4.7 KiB
C++
#pragma once
|
|
|
|
#include "Abstract.hpp"
|
|
#include "surrounding.hpp"
|
|
|
|
#include "core/queue/safe_queue.hpp"
|
|
#include "core/queue/safe_priority_queue.hpp"
|
|
#include "core/generational/vector.hpp"
|
|
#include "core/generational/map.hpp"
|
|
#include "../render/api/Models.hpp"
|
|
#include "core/geometry/math.hpp"
|
|
#include <thread>
|
|
|
|
using namespace data;
|
|
namespace contouring {
|
|
/// Dual Marching Cube 1:1 contouring
|
|
class FlatDualMC final: public Abstract {
|
|
public:
|
|
FlatDualMC(const std::string&);
|
|
virtual ~FlatDualMC();
|
|
|
|
void update(const world::cell_pos &pos, const world::Elements &) override;
|
|
|
|
void onGui() override;
|
|
|
|
std::string getOptions() const override;
|
|
std::pair<float, float> getFarRange() const override;
|
|
size_t getQueueSize() override;
|
|
|
|
void onUpdate(const world::area_chunk_pos &pos, glm::ll offset, const world::ChunkContainer &data, geometry::Faces neighbors) override;
|
|
void onNotify(const world::area_chunk_pos &pos, glm::ll offset, const world::ChunkContainer &data) override;
|
|
void onNotify(const world::part_id&, glm::ll offset, const glm::ucvec3& size, const std::vector<std::shared_ptr<world::EdittableChunk>>&, bool update) override;
|
|
void onLoad(const world::model_id&, std::istream&) override;
|
|
void onUnload(const world::model_id&) override;
|
|
|
|
void getTerrainModels(terrain_draw_call draw, const std::optional<geometry::Frustum>& frustum, const world::cell_pos& offset, bool solid) const override;
|
|
void getTerrainModels(terrain_draw_call draw, const world::world_pos &from, float far_dist, const std::vector<glm::vec3> &occlusion, const world::cell_pos&offset, bool solid) const override;
|
|
|
|
render::Model* getModel(const world::part_id&) const override;
|
|
void getUniqueModels(unique_draw_call draw, const world::Elements&, const std::optional<geometry::Frustum>& frustum, const world::cell_pos& offset) const override;
|
|
|
|
render::Model* getModel(const world::model_id&) const override;
|
|
void getInstancedModels(instanced_draw_call draw, const world::Elements&, const std::optional<geometry::Frustum>& frustum, const world::cell_pos& offset, world::node_id ignore) const override;
|
|
|
|
uint16_t getVisibleDist() const override { return keepDistance; }
|
|
|
|
private:
|
|
struct area_models {
|
|
std::unique_ptr<render::LodModel> main;
|
|
std::unique_ptr<render::LodModel> transparent;
|
|
struct data {
|
|
data() { }
|
|
data(data&& src):
|
|
main(std::move(src.main)), transparent(std::move(src.transparent)) { }
|
|
|
|
render::LodModel::LodData main;
|
|
render::LodModel::LodData transparent;
|
|
};
|
|
};
|
|
struct part_job {
|
|
glm::ucvec3 size;
|
|
std::vector<std::shared_ptr<world::EdittableChunk>> chunks;
|
|
};
|
|
|
|
robin_hood::unordered_map<world::area_id, robin_hood::pair<area_info, robin_hood::unordered_map<world::chunk_pos, area_models>>> areas;
|
|
generational::vector<std::unique_ptr<render::Model>, world::Part> parts;
|
|
generational::vector<std::unique_ptr<render::Model>, world::Model> models;
|
|
|
|
safe_priority_queue_map<world::area_chunk_pos, surrounding::corners, glm::ll> areaLoadQueue;
|
|
safe_queue<std::pair<world::area_chunk_pos, area_models::data>> areaLoadedQueue;
|
|
safe_priority_queue_map<world::part_id, part_job, glm::ll> partLoadQueue;
|
|
safe_queue<std::pair<world::part_id, render::Model::Data>> partLoadedQueue;
|
|
safe_queue<std::pair<world::model_id, render::Model::Data>> modelLoadedQueue;
|
|
|
|
bool running = true;
|
|
std::vector<std::thread> workers;
|
|
|
|
void enqueue(const world::area_chunk_pos&, glm::ll offset, const world::ChunkContainer &);
|
|
|
|
uint16_t loadDistance = 3;
|
|
uint16_t keepDistance = 4;
|
|
bool transparency = false;
|
|
float iso = .1f;
|
|
bool manifold = true;
|
|
bool reordering = true;
|
|
float lod_strength = .15;
|
|
float lod_quality = 0;
|
|
std::deque<bool> lod_levels;
|
|
|
|
std::vector<std::pair<float, float>> loadedLevels;
|
|
|
|
enum class Layer {
|
|
Solid = 1,
|
|
Transparent = 2,
|
|
Both = Solid | Transparent,
|
|
};
|
|
friend inline bool operator&&(Layer a, Layer b) {
|
|
return static_cast<int>(a) & static_cast<int>(b);
|
|
}
|
|
|
|
void render(const surrounding::corners &surrounding, render::Model::Data::indices_t& idx, std::vector<render::VertexData>& ver, Layer layer) const;
|
|
void render(const surrounding::corners &surrounding, render::LodModel::LodData& out, std::vector<render::VertexData>& tmp, Layer layer) const;
|
|
};
|
|
}
|