#pragma once #include "core/io/resource.h" #include "core/math/expression.h" #include "core/object/object.h" #include "modules/noise/noise.h" #include "terrain_editor/macros.h" class TerrainPrimitive : public Resource { GDCLASS(TerrainPrimitive, Resource); static void _bind_methods(); public: GDENUM(BlendMode, Peak, Valley, Both) protected: float blend(float under, float over) const; public: // evaluate the height of this primitive at point, returns the weight of the effect, out_height will be set to the closest point on the primitive virtual void evaluate(Vector2 at, float &io_height) const; void set_blend_mode(BlendMode mode); BlendMode get_blend_mode() const; void set_blend_range(float blend_range); float get_blend_range() const; private: float blend_range{ 4.f }; BlendMode blend_mode{ Peak }; }; MAKE_TYPE_INFO(TerrainPrimitive::BlendMode, Variant::INT); class PlanePrimitive : public TerrainPrimitive { GDCLASS(PlanePrimitive, TerrainPrimitive); static void _bind_methods(); public: void evaluate(Vector2 at, float &io_height) const override; void set_baseline(float value); float get_baseline() const; private: float baseline{ 1.f }; }; class PointPrimitive : public TerrainPrimitive { GDCLASS(PointPrimitive, TerrainPrimitive); static void _bind_methods(); public: void evaluate(Vector2 at, float &io_height) const override; void set_center(Vector2 center); Vector2 get_center() const; void set_slope(float radius); float get_slope() const; void set_height(float height); float get_height() const; private: Vector2 center{ 0.f, 0.f }; float slope{ -1.f }; float height{ 10.f }; }; class NoisePrimitive : public TerrainPrimitive { GDCLASS(NoisePrimitive, TerrainPrimitive); static void _bind_methods(); public: void evaluate(Vector2 at, float &io_height) const override; void set_noise(Ref noise); Ref get_noise() const; void set_noise_scale(float pixels_per_meter); float get_noise_scale() const; void set_noise_amplitude(float height); float get_noise_amplitude() const; private: Ref noise{}; float noise_scale{ 1.f }; float noise_amplitude{ 1.f }; }; class ExpressionPrimitive : public TerrainPrimitive { GDCLASS(ExpressionPrimitive, TerrainPrimitive); static void _bind_methods(); public: void evaluate(Vector2 at, float &io_height) const override; void set_expression(String expression); String get_expression() const; private: Ref expression{ memnew(Expression) }; String expression_string{ "height" }; bool valid{ false }; };