terrain-editor/modules/terrain_editor/terrain_mesh_generator.h

83 lines
2.5 KiB
C++

#pragma once
#include "core/math/color.h"
#include "core/object/object.h"
#include "core/os/semaphore.h"
#include "core/os/thread.h"
#include "core/variant/callable.h"
#include "scene/main/node.h"
#include "scene/resources/gradient.h"
#include "scene/resources/mesh.h"
#include "scene/resources/surface_tool.h"
#include "terrain_editor/terrain_chunk.h"
#include "terrain_editor/terrain_primitive.h"
class TerrainMeshGenerator : public Node {
GDCLASS(TerrainMeshGenerator, Node);
struct TerrainMeshTask {
Ref<ArrayMesh> mesh;
Rect2 area;
size_t side_points;
Ref<SurfaceTool> out_surface;
Callable callback;
};
static void _bind_methods();
void enter_tree();
void process();
void on_configuration_changed();
protected:
void _notification(int what);
void rebuild_chunks();
static void background_generation_thread(void *user);
Color color_at_height(float height) const;
float evaluate_point(Vector2 at) const;
void generate_grid(Rect2 area, Ref<SurfaceTool> mesh, size_t side_points);
public:
void push_task(Rect2 area, Ref<ArrayMesh> mesh, size_t side_points, Callable callback = Callable());
void set_primitives(Array array);
Array get_primitives() const;
void set_vertex_color_gradient(Ref<Gradient> gradient);
Ref<Gradient> get_vertex_color_gradient() const;
void set_color_gradient_start_height(float value);
float get_color_gradient_start_height() const;
void set_color_gradient_end_height(float value);
float get_color_gradient_end_height() const;
void set_chunk_count(int num);
int get_chunk_count() const;
void set_chunk_scene(Ref<PackedScene> scene);
Ref<PackedScene> get_chunk_scene() const;
private:
// main thread exclusive data
Ref<PackedScene> chunk_scene{};
Vector<TerrainChunk *> chunks{};
// worker thread owned data
Mutex settings_lock{}; // needs to be locked to modify any of the below, worker thread locks while working
Array primitives_buffer{}; // main thread buffer for primitives
Vector<Ref<TerrainPrimitive>> primitives{}; // work thread buffer for primitives
Ref<Gradient> vertex_color_gradient{};
float color_gradient_start_height{ 0.f };
float color_gradient_end_height{ 10.f };
int chunks_per_side{ 10 };
Thread thread{};
Mutex input_lock{};
bool end_thread{ false };
Vector<TerrainMeshTask> input_queue{};
Semaphore work_signal{};
Mutex output_lock{};
Vector<TerrainMeshTask> output_queue{};
private:
Callable generation_changed{ callable_mp(this, &self_type::on_configuration_changed) };
public:
static String const sig_primitives_changed;
static String const sig_primitive_list_changed;
};