#pragma once #include "core/object/object.h" #include "core/variant/variant.h" #include "macros.h" #include "scene/3d/marker_3d.h" #include "scene/resources/curve.h" #include class Terrain; class TerrainModifier : public Marker3D { GDCLASS(TerrainModifier, Marker3D); static void _bind_methods(); protected: void _notification(int what); void push_changed(Rect2 bounds); public: virtual float evaluate_at(Vector2 world_coordinate, float before); private: Vector3 thread_safe_global_position{}; Terrain *terrain{ nullptr }; Rect2 bounds{ { -INFINITY, -INFINITY }, { INFINITY, INFINITY } }; protected: void set_bounds(Rect2 bounds); Rect2 get_bounds() const; public: Vector3 get_thread_safe_global_position() const; GET_SET_FNS(Terrain *, terrain); }; struct SharedMutex { void lock_shared(); void unlock_shared(); void lock_exclusive(); void unlock_exclusive(); private: Mutex lock{}; int shared_count{}; }; class TerrainModifierDistance : public TerrainModifier { GDCLASS(TerrainModifierDistance, TerrainModifier); static void _bind_methods(); void curves_changed(); bool update_bounds(); protected: void _notification(int what); float distance_at(Vector2 const &world_coordinate); public: float evaluate_at(Vector2 world_coordinate, float before) override; PackedStringArray get_configuration_warnings() const override; private: SharedMutex lock{}; Ref distance_weight_curve{}; public: void set_distance_weight_curve(Ref curve); Ref get_distance_weight_curve() const; }; class TerrainModifierPathPoint : public Marker3D { GDCLASS(TerrainModifierPathPoint, Marker3D); static void _bind_methods(); protected: void _notification(int what); public: class TerrainModifierPath *path{ nullptr }; }; class TerrainModifierPath : public TerrainModifier { GDCLASS(TerrainModifierPath, TerrainModifier); static void _bind_methods(); void curves_changed(); bool update_bounds(); protected: void _notification(int what); float evaluate_line(Vector3 a, bool a_end, Vector3 b, bool b_end, Vector2 world_coordinate, float &out_dot, float &out_distance); public: float evaluate_at(Vector2 world_coordinate, float before) override; void path_changed(); PackedStringArray get_configuration_warnings() const override; private: SharedMutex lock{}; float min_height{}; float max_height{}; bool closed{ false }; Vector points{}; Ref curve_left{}; Ref curve_right{}; public: void set_curve_left(Ref curve); Ref get_curve_left() const; void set_curve_right(Ref curve); Ref get_curve_right() const; };