feat: added expression value to every primitive

This commit is contained in:
Sara Gerretsen 2026-01-07 17:23:49 +01:00
parent 63c391593d
commit 2b04362ecc
6 changed files with 121 additions and 48 deletions

View file

@ -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;
}