feat: WIP improved turns on path modifier
This commit is contained in:
parent
f057254396
commit
9ea66df220
3 changed files with 46 additions and 27 deletions
|
|
@ -262,7 +262,7 @@ void TerrainModifierPath::_notification(int what) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float TerrainModifierPath::evaluate_line(Vector3 a, bool a_end, Vector3 b, bool b_end, Vector2 world_coordinate, float &out_dot, float &out_distance) {
|
float TerrainModifierPath::evaluate_line(Vector3 a, bool a_end, Vector3 b, bool b_end, Vector2 world_coordinate, float &out_dot, float &out_distance, float &out_percentage) {
|
||||||
Vector2 a2{ a.x, a.z }, b2{ b.x, b.z };
|
Vector2 a2{ a.x, a.z }, b2{ b.x, b.z };
|
||||||
Vector2 const relative_coordinate{ world_coordinate - a2 };
|
Vector2 const relative_coordinate{ world_coordinate - a2 };
|
||||||
Vector2 const difference2{ b2 - a2 };
|
Vector2 const difference2{ b2 - a2 };
|
||||||
|
|
@ -272,10 +272,11 @@ float TerrainModifierPath::evaluate_line(Vector3 a, bool a_end, Vector3 b, bool
|
||||||
Vector2 const right{ -difference.z, difference.x };
|
Vector2 const right{ -difference.z, difference.x };
|
||||||
out_dot = right.normalized().dot(relative_coordinate);
|
out_dot = right.normalized().dot(relative_coordinate);
|
||||||
out_distance = world_coordinate.distance_to({ closest_on_line.x, closest_on_line.z });
|
out_distance = world_coordinate.distance_to({ closest_on_line.x, closest_on_line.z });
|
||||||
if (a_end) {
|
out_percentage = w;
|
||||||
|
if (!a_end) {
|
||||||
w = w > 0 ? w : 0;
|
w = w > 0 ? w : 0;
|
||||||
}
|
}
|
||||||
if (b_end) {
|
if (!b_end) {
|
||||||
w = w < 1 ? w : 1;
|
w = w < 1 ? w : 1;
|
||||||
}
|
}
|
||||||
return a.y + (b.y - a.y) * w;
|
return a.y + (b.y - a.y) * w;
|
||||||
|
|
@ -287,30 +288,45 @@ float TerrainModifierPath::evaluate_at(Vector2 world_coordinate, float before) {
|
||||||
this->lock.unlock_shared();
|
this->lock.unlock_shared();
|
||||||
return before;
|
return before;
|
||||||
}
|
}
|
||||||
float const max_distance{ this->curve_left->get_max_domain() > this->curve_right->get_max_domain() ? this->curve_left->get_max_domain() : this->curve_right->get_max_domain() };
|
float out_score{ 0.f };
|
||||||
float out_score{ -INFINITY };
|
float out_delta{ 0.f };
|
||||||
float out_height{ 0 };
|
|
||||||
long const count{ this->closed ? this->points.size() : this->points.size() - 1 };
|
long const count{ this->closed ? this->points.size() : this->points.size() - 1 };
|
||||||
for (int i{ 0 }; i < count; i++) {
|
for (int i{ 0 }; i < count; i++) {
|
||||||
float dot, distance;
|
Vector3 const ipos{ this->points[i] };
|
||||||
float const height{ evaluate_line(this->points[i], !this->closed && i == 0, this->points[Math::wrapi(i + 1, 0, this->points.size())], !this->closed && i == count - 1, world_coordinate, dot, distance) };
|
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 const left{ this->curve_left->sample(distance) };
|
float const left{ this->curve_left->sample(distance) };
|
||||||
float const right{ this->curve_right->sample(distance) };
|
float const right{ this->curve_right->sample(distance) };
|
||||||
float const ndot{ dot / distance };
|
float const ndot{ dot / distance };
|
||||||
float separation{ ndot / 2.f + 0.5f };
|
float separation{ ndot / 2.f + 0.5f };
|
||||||
if (closed || (i > 0 && i < count - 1)) {
|
float turn{ ndot };
|
||||||
|
Vector3 const right_direction{ (this->points[Math::wrapi(i + 1, 0, this->points.size())] - ipos).cross({ 0, 1, 0 }) };
|
||||||
|
if (!is_end && percentage >= 1.f) {
|
||||||
|
turn = (this->points[Math::wrapi(i + 2, 0, this->points.size())] - ipos).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);
|
||||||
|
separation = turn <= 0 ? 0 : 1;
|
||||||
|
} else if (!is_start && !is_end) {
|
||||||
separation = Math::round(separation);
|
separation = Math::round(separation);
|
||||||
}
|
}
|
||||||
float const weight{ left * (1 - separation) + right * separation };
|
if (turn / turn == dot / dot) {
|
||||||
float const blended_height{ Math::lerp(before, height, weight) };
|
float const weight{ left * (1 - separation) + right * separation };
|
||||||
float const score{ weight - (1 - Math::abs(ndot)) * 2.f - (distance / max_distance) };
|
float const blended_height{ Math::lerp(before, height, weight) };
|
||||||
if (score > out_score) {
|
float const delta{ blended_height - before };
|
||||||
out_score = score;
|
float const score{ weight };
|
||||||
out_height = blended_height;
|
if (score > out_score) {
|
||||||
|
out_score = score;
|
||||||
|
out_delta = delta * score;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->lock.unlock_shared();
|
this->lock.unlock_shared();
|
||||||
return out_height;
|
if (out_score == 0.f) {
|
||||||
|
return before;
|
||||||
|
}
|
||||||
|
return before + (out_delta / out_score);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerrainModifierPath::path_changed() {
|
void TerrainModifierPath::path_changed() {
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ class TerrainModifierPath : public TerrainModifier {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int what);
|
void _notification(int what);
|
||||||
float evaluate_line(Vector3 a, bool a_end, Vector3 b, bool b_end, Vector2 world_coordinate, float &out_dot, float &out_distance);
|
float evaluate_line(Vector3 a, bool a_end, Vector3 b, bool b_end, Vector2 world_coordinate, float &out_dot, float &out_distance, float &out_percentage);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
float evaluate_at(Vector2 world_coordinate, float before) override;
|
float evaluate_at(Vector2 world_coordinate, float before) override;
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ sky = SubResource("Sky_w3uoq")
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_kbmr5"]
|
[sub_resource type="Curve" id="Curve_kbmr5"]
|
||||||
_limits = [0.0, 1.0, 0.0, 100.0]
|
_limits = [0.0, 1.0, 0.0, 100.0]
|
||||||
_data = [Vector2(0, 1), 0.0, -0.0015643721, 0, 0, Vector2(60.370926, 0.60930693), -0.018071167, -0.018071167, 0, 0, Vector2(100, 0), 0.0, 0.0, 0, 0]
|
_data = [Vector2(0, 1), 0.0, -0.030682996, 0, 0, Vector2(100, 0), 0.0, 0.0, 0, 0]
|
||||||
point_count = 3
|
point_count = 2
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_w3uoq"]
|
[sub_resource type="Curve" id="Curve_w3uoq"]
|
||||||
_limits = [0.0, 1.0, 0.0, 101.07341]
|
_limits = [0.0, 1.0, 0.0, 101.07341]
|
||||||
|
|
@ -40,30 +40,33 @@ chunk_size = 100
|
||||||
thread_count = 5
|
thread_count = 5
|
||||||
|
|
||||||
[node name="TerrainModifierPath" type="TerrainModifierPath" parent="Terrain" unique_id=462259542]
|
[node name="TerrainModifierPath" type="TerrainModifierPath" parent="Terrain" unique_id=462259542]
|
||||||
transform = Transform3D(2.7896824, 0, 0, 0, 1, 0, 0, 0, 3.9856973, 188.70874, 151.32993, 528.5824)
|
transform = Transform3D(1.9138145, 0, 0, 0, 0.6860331, 0, 0, 0, 2.7343204, 190.712, 125.888245, 634.1432)
|
||||||
curve_left = SubResource("Curve_kbmr5")
|
curve_left = SubResource("Curve_kbmr5")
|
||||||
curve_right = SubResource("Curve_w3uoq")
|
curve_right = SubResource("Curve_w3uoq")
|
||||||
|
|
||||||
[node name="TerrainModifierPathPoint" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=1975236067]
|
[node name="TerrainModifierPathPoint" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=1975236067]
|
||||||
transform = Transform3D(0.9999999, 0, 0, 0, 1, 0, 0, 0, 0.9999999, -6.678116, -33.99875, -74.15768)
|
transform = Transform3D(0.9999999, 0, 0, 0, 1, 0, 0, 0, 0.99999976, -5.4521523, -33.998764, -98.341095)
|
||||||
|
|
||||||
[node name="TerrainModifierPathPoint5" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=2007122252]
|
[node name="TerrainModifierPathPoint5" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=2007122252]
|
||||||
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 41.63815, 4.6532288, -38.86402)
|
transform = Transform3D(0.9999999, 0, 0, 0, 1, 0, 0, 0, 0.9999999, 33.986214, 4.6532135, -47.78543)
|
||||||
|
|
||||||
[node name="TerrainModifierPathPoint2" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=88875414]
|
[node name="TerrainModifierPathPoint2" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=88875414]
|
||||||
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 4.2666435, -27.249336, 5.506424)
|
transform = Transform3D(0.9999999, 0, 0, 0, 1, 0, 0, 0, 0.9999999, -45.605103, -77.62694, -7.8362274)
|
||||||
|
|
||||||
[node name="TerrainModifierPathPoint3" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=910243114]
|
[node name="TerrainModifierPathPoint3" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=910243114]
|
||||||
transform = Transform3D(-0.08673841, 0, 0.9962309, 0, 1, 0, -0.9962308, 0, -0.08673839, 77.83667, 84.083954, 12.383522)
|
transform = Transform3D(-0.08673841, 0, 0.9962309, 0, 1, 0, -0.99623066, 0, -0.0867384, 51.146767, 185.18083, 46.93416)
|
||||||
|
|
||||||
[node name="TerrainModifierPathPoint4" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=738726374]
|
[node name="TerrainModifierPathPoint4" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=738726374]
|
||||||
transform = Transform3D(-0.08673839, 0, 0.9962309, 0, 1, 0, -0.9962308, 0, -0.08673841, 124.05687, -50.373947, -21.531578)
|
transform = Transform3D(-0.5568029, 0, 0.8306443, 0, 1, 0, -0.83064425, 0, -0.556803, 181.23196, -50.373947, -56.57155)
|
||||||
|
|
||||||
[node name="TerrainModifierPathPoint6" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=868243973]
|
[node name="TerrainModifierPathPoint6" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=868243973]
|
||||||
transform = Transform3D(-0.08673839, 0, 0.9962309, 0, 1, 0, -0.99623066, 0, -0.08673841, 163.78015, -50.373917, 24.09636)
|
transform = Transform3D(-0.5568028, 0, 0.8306443, 0, 1, 0, -0.830644, 0, -0.55680287, 206.74478, -50.373917, 13.438446)
|
||||||
|
|
||||||
[node name="TerrainModifierPathPoint7" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=601656436]
|
[node name="TerrainModifierPathPoint7" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=601656436]
|
||||||
transform = Transform3D(-0.08673839, 0, 0.9962309, 0, 1, 0, -0.99623054, 0, -0.08673841, 106.59272, 12.878235, 75.88286)
|
transform = Transform3D(-0.5568028, 0, 0.8306443, 0, 1, 0, -0.8306439, 0, -0.55680287, 192.3706, 12.87825, 78.11276)
|
||||||
|
|
||||||
|
[node name="TerrainModifierPathPoint8" type="TerrainModifierPathPoint" parent="Terrain/TerrainModifierPath" unique_id=300006660]
|
||||||
|
transform = Transform3D(-0.5568028, 0, 0.8306443, 0, 1, 0, -0.8306439, 0, -0.55680287, 289.17203, 36.37845, 54.197342)
|
||||||
|
|
||||||
[node name="TerrainModifierDistance8" type="TerrainModifierDistance" parent="Terrain" unique_id=1993490768]
|
[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)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 784.91595, 251.11382, 135.92102)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue