#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 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 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>&, 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& 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 &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& 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& 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 main; std::unique_ptr 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> chunks; }; robin_hood::unordered_map>> areas; generational::vector, world::Part> parts; generational::vector, world::Model> models; safe_priority_queue_map areaLoadQueue; safe_queue> areaLoadedQueue; safe_priority_queue_map partLoadQueue; safe_queue> partLoadedQueue; safe_queue> modelLoadedQueue; bool running = true; std::vector 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 lod_levels; std::vector> loadedLevels; enum class Layer { Solid = 1, Transparent = 2, Both = Solid | Transparent, }; friend inline bool operator&&(Layer a, Layer b) { return static_cast(a) & static_cast(b); } void render(const surrounding::corners &surrounding, render::Model::Data::indices_t& idx, std::vector& ver, Layer layer) const; void render(const surrounding::corners &surrounding, render::LodModel::LodData& out, std::vector& tmp, Layer layer) const; }; }