chore: adjusted terrain modifier logic
This commit is contained in:
parent
7a2ed4a785
commit
a214291c2f
2 changed files with 62 additions and 89 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue