feat: added expression value to every primitive
This commit is contained in:
parent
63c391593d
commit
2b04362ecc
6 changed files with 121 additions and 48 deletions
|
|
@ -21,7 +21,6 @@ void initialize_terrain_editor_module(ModuleInitializationLevel p_level) {
|
|||
ClassDB::register_class<PlanePrimitive>();
|
||||
ClassDB::register_class<PointPrimitive>();
|
||||
ClassDB::register_class<NoisePrimitive>();
|
||||
ClassDB::register_class<ExpressionPrimitive>();
|
||||
ClassDB::register_class<PointPrimitiveNode>();
|
||||
ClassDB::register_class<TerrainMeshEditor>();
|
||||
ClassDB::register_class<SaveData>();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
void TerrainPrimitive::_bind_methods() {
|
||||
BIND_HPROPERTY(Variant::INT, blend_mode, PROPERTY_HINT_ENUM, BlendMode_hint());
|
||||
BIND_PROPERTY(Variant::FLOAT, blend_range);
|
||||
BIND_HPROPERTY(Variant::STRING, expression, PROPERTY_HINT_EXPRESSION);
|
||||
ClassDB::bind_method(D_METHOD("get_expression_error"), &self_type::get_expression_error);
|
||||
}
|
||||
|
||||
// by default does not modify height
|
||||
|
|
@ -54,12 +56,42 @@ float TerrainPrimitive::get_blend_range() const {
|
|||
return this->blend_range;
|
||||
}
|
||||
|
||||
void TerrainPrimitive::set_expression(String expression) {
|
||||
this->expr_text = expression;
|
||||
if (expression.is_empty()) {
|
||||
this->expression_valid = false;
|
||||
} else {
|
||||
_parse_new_expression(expression);
|
||||
}
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
String TerrainPrimitive::get_expression() const {
|
||||
return this->expr_text;
|
||||
}
|
||||
|
||||
String TerrainPrimitive::get_expression_error() const {
|
||||
if (this->expression_valid) {
|
||||
return "Valid Expression";
|
||||
} else {
|
||||
return this->expression->get_error_text();
|
||||
}
|
||||
}
|
||||
|
||||
void PlanePrimitive::_bind_methods() {
|
||||
BIND_PROPERTY(Variant::FLOAT, baseline);
|
||||
}
|
||||
|
||||
void PlanePrimitive::evaluate(Vector2, float &io_height) const {
|
||||
io_height = blend(io_height, this->baseline);
|
||||
void PlanePrimitive::_parse_new_expression(String expression) {
|
||||
this->expression_valid = this->expression->parse(expression, { "previous_height", "at", "baseline" }) == OK;
|
||||
}
|
||||
|
||||
void PlanePrimitive::evaluate(Vector2 at, float &io_height) const {
|
||||
float height{ this->baseline };
|
||||
if (this->expression_valid) {
|
||||
height = this->expression->execute({ io_height, at, this->baseline }, nullptr, false, true);
|
||||
}
|
||||
io_height = blend(io_height, height);
|
||||
}
|
||||
|
||||
void PlanePrimitive::set_baseline(float value) {
|
||||
|
|
@ -77,9 +109,17 @@ void PointPrimitive::_bind_methods() {
|
|||
BIND_PROPERTY(Variant::FLOAT, height);
|
||||
}
|
||||
|
||||
void PointPrimitive::_parse_new_expression(String expression) {
|
||||
this->expression_valid = this->expression->parse(expression, { "previous_height", "at", "center", "height", "sloped_height", "distance", "slope" }) == OK;
|
||||
}
|
||||
|
||||
void PointPrimitive::evaluate(Vector2 at, float &io_height) const {
|
||||
float distance{ at.distance_to(this->center) };
|
||||
io_height = blend(io_height, this->height + distance * this->slope);
|
||||
float height{ this->height + distance * this->slope };
|
||||
if (this->expression_valid) {
|
||||
height = this->expression->execute({ io_height, at, this->center, this->height, height, distance, this->slope }, nullptr, false, true);
|
||||
}
|
||||
io_height = blend(io_height, height);
|
||||
}
|
||||
|
||||
void PointPrimitive::set_center(Vector2 center) {
|
||||
|
|
@ -115,6 +155,10 @@ void NoisePrimitive::_bind_methods() {
|
|||
BIND_PROPERTY(Variant::FLOAT, noise_amplitude);
|
||||
}
|
||||
|
||||
void NoisePrimitive::_parse_new_expression(String expression) {
|
||||
this->expression_valid = this->expression->parse(expression, { "previous_height", "at", "noise", "amplitude", "scale" }) == OK;
|
||||
}
|
||||
|
||||
void NoisePrimitive::evaluate(Vector2 at, float &io_height) const {
|
||||
if (this->noise.is_valid()) {
|
||||
if (Math::is_nan(io_height) || Math::is_inf(io_height)) {
|
||||
|
|
@ -122,7 +166,11 @@ void NoisePrimitive::evaluate(Vector2 at, float &io_height) const {
|
|||
}
|
||||
float noise_sample{ this->noise->get_noise_2dv(at / this->noise_scale) };
|
||||
noise_sample *= this->noise_amplitude;
|
||||
io_height = blend(io_height, io_height + noise_sample);
|
||||
float height{ noise_sample + io_height };
|
||||
if (this->expression_valid) {
|
||||
height = this->expression->execute({ io_height, at, noise_sample, this->noise_amplitude, this->noise_scale }, nullptr, false, true);
|
||||
}
|
||||
io_height = blend(io_height, height);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -158,31 +206,3 @@ void NoisePrimitive::set_noise_amplitude(float value) {
|
|||
float NoisePrimitive::get_noise_amplitude() const {
|
||||
return this->noise_amplitude;
|
||||
}
|
||||
|
||||
void ExpressionPrimitive::_bind_methods() {
|
||||
BIND_HPROPERTY(Variant::STRING, expression, PROPERTY_HINT_EXPRESSION);
|
||||
}
|
||||
|
||||
void ExpressionPrimitive::evaluate(Vector2 at, float &io_height) const {
|
||||
if (!this->valid) {
|
||||
return;
|
||||
}
|
||||
Variant result{ this->expression->execute({ io_height, at }, nullptr, false, true) };
|
||||
if (!this->expression->has_execute_failed()) {
|
||||
io_height = blend(io_height, float(result.get(0)));
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionPrimitive::set_expression(String expression) {
|
||||
this->expression_string = expression;
|
||||
this->expression.unref();
|
||||
this->expression = memnew(Expression);
|
||||
Error error{ this->expression->parse(this->expression_string, { "height", "at" }) };
|
||||
if ((this->valid = error == OK)) {
|
||||
emit_changed();
|
||||
}
|
||||
}
|
||||
|
||||
String ExpressionPrimitive::get_expression() const {
|
||||
return this->expression_string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public:
|
|||
|
||||
protected:
|
||||
float blend(float under, float over) const;
|
||||
virtual void _parse_new_expression(String expression) = 0;
|
||||
|
||||
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
|
||||
|
|
@ -27,10 +28,18 @@ public:
|
|||
BlendMode get_blend_mode() const;
|
||||
void set_blend_range(float blend_range);
|
||||
float get_blend_range() const;
|
||||
void set_expression(String expression);
|
||||
String get_expression() const;
|
||||
String get_expression_error() const;
|
||||
|
||||
private:
|
||||
float blend_range{ 4.f };
|
||||
BlendMode blend_mode{ Peak };
|
||||
String expr_text{};
|
||||
|
||||
protected:
|
||||
bool expression_valid{};
|
||||
Ref<Expression> expression{ memnew(Expression) };
|
||||
};
|
||||
|
||||
MAKE_TYPE_INFO(TerrainPrimitive::BlendMode, Variant::INT);
|
||||
|
|
@ -39,6 +48,9 @@ class PlanePrimitive : public TerrainPrimitive {
|
|||
GDCLASS(PlanePrimitive, TerrainPrimitive);
|
||||
static void _bind_methods();
|
||||
|
||||
protected:
|
||||
void _parse_new_expression(String expression) override;
|
||||
|
||||
public:
|
||||
void evaluate(Vector2 at, float &io_height) const override;
|
||||
void set_baseline(float value);
|
||||
|
|
@ -52,6 +64,9 @@ class PointPrimitive : public TerrainPrimitive {
|
|||
GDCLASS(PointPrimitive, TerrainPrimitive);
|
||||
static void _bind_methods();
|
||||
|
||||
protected:
|
||||
void _parse_new_expression(String expression) override;
|
||||
|
||||
public:
|
||||
void evaluate(Vector2 at, float &io_height) const override;
|
||||
void set_center(Vector2 center);
|
||||
|
|
@ -71,6 +86,9 @@ class NoisePrimitive : public TerrainPrimitive {
|
|||
GDCLASS(NoisePrimitive, TerrainPrimitive);
|
||||
static void _bind_methods();
|
||||
|
||||
protected:
|
||||
void _parse_new_expression(String expression) override;
|
||||
|
||||
public:
|
||||
void evaluate(Vector2 at, float &io_height) const override;
|
||||
void set_noise(Ref<Noise> noise);
|
||||
|
|
@ -85,18 +103,3 @@ private:
|
|||
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> expression{ memnew(Expression) };
|
||||
String expression_string{ "height" };
|
||||
bool valid{ false };
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue