chore: adjusted terrain modifier logic

This commit is contained in:
Sara Gerretsen 2026-03-03 12:54:35 +01:00
parent 7a2ed4a785
commit a214291c2f
2 changed files with 62 additions and 89 deletions

View file

@ -3,6 +3,7 @@
#include "core/math/math_funcs.h"
#include "core/variant/variant.h"
#include "macros.h"
#include "scene/main/node.h"
#include "terrain/terrain.h"
#include <algorithm>
@ -269,6 +270,9 @@ void TerrainModifierPath::_notification(int what) {
}
}
return;
case NOTIFICATION_CHILD_ORDER_CHANGED:
path_changed();
return;
}
}
@ -284,10 +288,10 @@ float TerrainModifierPath::evaluate_line(Vector3 a, bool a_end, Vector3 b, bool
out_distance = world_coordinate.distance_to({ closest_on_line.x, closest_on_line.z });
out_percentage = w;
if (!a_end) {
w = w > 0 ? w : 0;
w = w < 0 ? 0 : w;
}
if (!b_end) {
w = w < 1 ? w : 1;
w = w > 1 ? 1 : w;
}
return a.y + (b.y - a.y) * w;
}
@ -307,26 +311,30 @@ float TerrainModifierPath::evaluate_at(Vector2 world_coordinate, float before) {
long const count{ this->closed ? this->points.size() : this->points.size() - 1 };
for (int i{ 0 }; i < count; i++) {
Vector3 const ipos{ this->points[i] };
Vector3 const next_pos{ this->points[Math::wrapi(i + 1, 0, this->points.size())] };
float dot, distance, percentage;
bool const is_start{ !this->closed && i == 0 }, is_end{ !this->closed && i == count - 1 };
float const height{ evaluate_line(ipos, is_start, this->points[Math::wrapi(i + 1, 0, this->points.size())], is_end, world_coordinate, dot, distance, percentage) };
float height{ evaluate_line(ipos, is_start, next_pos, is_end, world_coordinate, dot, distance, percentage) };
float const left{ this->curve_left_buffer->sample(distance) };
float const right{ right_curve->sample(distance) };
float const ndot{ dot / distance };
float separation{ ndot / 2.f + 0.5f };
float turn{ 0.f };
Vector3 const right_direction{ (this->points[Math::wrapi(i + 1, 0, this->points.size())] - ipos).normalized().cross({ 0, 1, 0 }) };
Vector3 const right_direction{ (next_pos - ipos).normalized().cross({ 0, 1, 0 }) };
Vector3 turn_vector{ 0, 0, 0 };
if (!is_end && percentage >= 1.f) {
turn = (this->points[Math::wrapi(i + 2, 0, this->points.size())] - ipos).dot(right_direction);
turn_vector = this->points[Math::wrapi(i + 2, 0, this->points.size())] - next_pos;
turn = (turn_vector).dot(right_direction);
separation = turn >= 0 ? 0 : 1;
} else if (!is_start && percentage <= 0.f) {
turn = (this->points[Math::wrapi(i - 1, 0, this->points.size())] - ipos).dot(right_direction);
turn_vector = this->points[Math::wrapi(i - 1, 0, this->points.size())] - ipos;
turn = (turn_vector).dot(right_direction);
separation = turn >= 0 ? 0 : 1;
} else if (!is_start && !is_end) {
separation = Math::round(separation);
turn = -dot;
}
if ((percentage > 0.f && percentage < 1.f) || Math::abs(turn) / turn != Math::abs(dot) / dot) {
if ((percentage > -Math::abs(turn) && percentage < 1.f + Math::abs(turn)) || Math::abs(turn) / turn != Math::abs(dot) / dot) {
float const weight{ left * (1 - separation) + right * separation };
float const blended_height{ Math::lerp(before, height, weight) };
float const delta{ blended_height - before };
@ -345,6 +353,9 @@ float TerrainModifierPath::evaluate_at(Vector2 world_coordinate, float before) {
}
void TerrainModifierPath::path_changed() {
if (!is_inside_tree()) {
return;
}
this->lock.lock_exclusive();
this->points.clear();
this->min_height = INFINITY;

View file

@ -12,25 +12,15 @@ sky_material = SubResource("ProceduralSkyMaterial_kbmr5")
background_mode = 2
sky = SubResource("Sky_w3uoq")
[sub_resource type="Curve" id="Curve_kbmr5"]
_limits = [0.0, 1.0, 0.0, 100.0]
_data = [Vector2(0, 1), 0.0, -0.019399326, 0, 0, Vector2(43.078506, 0.46632487), -0.02627238, -0.02627238, 0, 0, Vector2(100, 0), 0.0, 0.0, 0, 0]
point_count = 3
[sub_resource type="Curve" id="Curve_w3uoq"]
_limits = [0.0, 1.0, 0.0, 101.07341]
_data = [Vector2(0, 1), 0.0, -0.009893799, 0, 1, Vector2(101.07341, 0), -0.009893799, 0.0, 1, 0]
_limits = [0.0, 1.0, 0.0, 300.0]
_data = [Vector2(0, 1), 0.0, -0.00018586064, 0, 0, Vector2(300, 0), 0.0, 0.0, 0, 0]
point_count = 2
[sub_resource type="Curve" id="Curve_chm2y"]
[sub_resource type="Curve" id="Curve_kbmr5"]
_limits = [0.0, 1.0, 0.0, 300.0]
_data = [Vector2(0, 1), -0.005856493, -0.00037566788, 0, 0, Vector2(103.49251, 0.80491185), -0.0043557375, -0.0043557375, 0, 0, Vector2(300, 0), 0.00031304389, -0.05797184, 0, 0]
point_count = 3
[sub_resource type="Curve" id="Curve_o3i6r"]
_limits = [0.0, 1.0, 0.0, 5.0]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1.215907, 1), 0.0, 0.0, 0, 0, Vector2(1.8194687, 0), 0.0, 0.0, 0, 0]
point_count = 3
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(69.40413, 0.8155421), -0.008522048, -0.008522048, 0, 0, Vector2(124.08008, 0.34781557), -0.0070376517, -0.0070376517, 0, 0, Vector2(244.43303, 0), 0.00011380972, 0.0, 0, 0]
point_count = 4
[sub_resource type="BoxMesh" id="BoxMesh_kbmr5"]
@ -44,78 +34,50 @@ side_length = 1000
chunk_size = 100
thread_count = 5
[node name="TerrainModifierPath" type="TerrainModifierPath" parent="Terrain" unique_id=462259542]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 377.77588, 108.75322, 652.4378)
[node name="TerrainModifierPath2" type="TerrainModifierPath" parent="Terrain" unique_id=645020759]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 251.12363, 255.25969, 182.0507)
gizmo_extents = 100.0
curve_left = SubResource("Curve_w3uoq")
[node name="TerrainModifierPathPoint" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=59754729]
gizmo_extents = 50.0
[node name="TerrainModifierPathPoint5" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=460239910]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 101.51407, -59.121643, -89.72089)
gizmo_extents = 50.0
[node name="TerrainModifierPathPoint2" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=94753507]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 274.68933, -82.27042, -75.669815)
gizmo_extents = 50.0
[node name="TerrainModifierPathPoint4" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=473450276]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 437.1725, -161.30762, -75.669815)
gizmo_extents = 50.0
[node name="TerrainModifierPathPoint3" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=1474399635]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 595.01825, -141.92302, 42.69197)
gizmo_extents = 50.0
[node name="TerrainModifierPath" type="TerrainModifierPath" parent="Terrain" unique_id=314094590]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1033.4109, 14.052078, 504.81018)
gizmo_extents = 100.0
curve_left = SubResource("Curve_kbmr5")
curve_right = SubResource("Curve_w3uoq")
[node name="TerrainModifierPathPoint" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=1975236067]
transform = Transform3D(0.9999999, 0, 0, 0, 1, 0, 0, 0, 0.99999976, -180.28406, -81.73056, -295.60077)
gizmo_extents = 10.0
[node name="TerrainModifierPathPoint" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=183585959]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -33.743713, 0)
gizmo_extents = 50.0
[node name="TerrainModifierPathPoint5" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=2007122252]
transform = Transform3D(0.9999999, 0, 0, 0, 1, 0, 0, 0, 0.9999999, -117.323944, -72.07858, -209.4972)
gizmo_extents = 10.0
[node name="TerrainModifierPathPoint2" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=597094982]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -287.58557, -82.655075, -121.09625)
gizmo_extents = 50.0
[node name="TerrainModifierPathPoint2" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=88875414]
transform = Transform3D(0.9999999, 0, 0, 0, 1, 0, 0, 0, 0.9999999, -186.47693, -104.63211, -100.22473)
gizmo_extents = 10.0
[node name="TerrainModifierPathPoint3" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=225558441]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -762.8348, -186.70262, 158.77417)
gizmo_extents = 50.0
[node name="TerrainModifierPathPoint3" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=910243114]
transform = Transform3D(0.9999996, 0, 0, 0, 1, 0, 0, 0, 0.9999998, -72.87836, -24.743164, -14.561768)
gizmo_extents = 10.0
[node name="TerrainModifierPathPoint4" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=738726374]
transform = Transform3D(0.99999976, 0, 0, 0, 1, 0, 0, 0, 0.99999976, 69.492004, -25.579193, -103.737305)
gizmo_extents = 10.0
[node name="TerrainModifierPathPoint6" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=868243973]
transform = Transform3D(0.9999994, 0, 0, 0, 1, 0, 0, 0, 0.9999997, 191.05371, -25.255402, -19.047241)
gizmo_extents = 10.0
[node name="TerrainModifierPathPoint7" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=601656436]
transform = Transform3D(0.99999934, 0, 0, 0, 1, 0, 0, 0, 0.9999997, 160.64337, -4.200287, 123.704346)
gizmo_extents = 10.0
[node name="TerrainModifierPathPoint8" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=300006660]
transform = Transform3D(0.99999934, 0, 0, 0, 1, 0, 0, 0, 0.9999997, 271.10236, -19.105774, 225.51074)
gizmo_extents = 10.0
[node name="TerrainModifierDistance8" type="TerrainModifierDistance" parent="Terrain" unique_id=1993490768]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 784.91595, 251.11382, 135.92102)
distance_weight_curve = SubResource("Curve_chm2y")
[node name="TerrainModifierPath2" type="TerrainModifierPath" parent="Terrain" unique_id=515690726]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 368.5579, 8.567036, 412.4803)
curve_left = SubResource("Curve_o3i6r")
[node name="TerrainModifierPathPoint7" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=283037782]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 30.025024, -9.3514, -37.19107)
gizmo_extents = 1.0
[node name="TerrainModifierPathPoint6" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=1696432484]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12.917389, -11.265772, -41.447937)
gizmo_extents = 1.0
[node name="TerrainModifierPathPoint" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=870583505]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.7605286, -11.487162, -33.974182)
gizmo_extents = 1.0
[node name="TerrainModifierPathPoint2" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=2085062411]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -17.681885, -12.115929, -8.841034)
gizmo_extents = 1.0
[node name="TerrainModifierPathPoint3" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=1608777346]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21.356476, -12.387854, 8.474121)
gizmo_extents = 1.0
[node name="TerrainModifierPathPoint4" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=2089784013]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.419983, -10.32972, 16.345459)
gizmo_extents = 1.0
[node name="TerrainModifierPathPoint5" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath2" unique_id=732306824]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.16311646, -8.924315, 20.998108)
gizmo_extents = 1.0
[node name="TerrainModifierPathPoint4" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=423129060]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1223.7019, -259.18048, 0)
gizmo_extents = 50.0
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1089775425]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 352.22195, 0, 401.61105)