#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" class Terrain; class TerrainModifier : public Marker3D { GDCLASS(TerrainModifier, Marker3D); static void _bind_methods(); public: GDENUM(BlendMode, Add, Subtract, Override); protected: void _notification(int what); void changed(); void changed_deferred(); float blend(float under, float over); public: virtual float evaluate_at(Vector2 world_coordinate, float before); private: float blend_distance{ 10.0 }; BlendMode blend_mode{ Add }; Vector3 thread_safe_global_position{}; bool dirty{ false }; Terrain *terrain{ nullptr }; public: Vector3 get_thread_safe_global_position() const; void set_blend_distance(float value); float get_blend_distance() const; void set_blend_mode(BlendMode mode); BlendMode get_blend_mode() const; GET_SET_FNS(bool, dirty); GET_SET_FNS(Terrain *, terrain); static String const sig_changed; }; MAKE_TYPE_INFO(TerrainModifier::BlendMode, Variant::INT); 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(); protected: virtual 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{}; Ref distance_height_curve{}; public: void set_distance_weight_curve(Ref curve); Ref get_distance_weight_curve() const; void set_distance_height_curve(Ref curve); Ref get_distance_height_curve() const; };