1
0
Fork 0

Merge pull request #114742 from kleonc/tile_navigation_preserve_winding_order

Preserve winding order for transformed tiles' navigation polygons
This commit is contained in:
Rémi Verschelde 2026-01-10 23:48:16 +01:00
commit ab6bbf1c59
No known key found for this signature in database
GPG Key ID: C3336907360768E1
4 changed files with 26 additions and 31 deletions

View File

@ -444,10 +444,10 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
if (baking_rect.has_area() && border_size > 0.0) {
Vector2 baking_rect_offset = p_navigation_mesh->get_baking_rect_offset();
const int rect_begin_x = baking_rect.position[0] + baking_rect_offset.x + border_size;
const int rect_begin_y = baking_rect.position[1] + baking_rect_offset.y + border_size;
const int rect_end_x = baking_rect.position[0] + baking_rect.size[0] + baking_rect_offset.x - border_size;
const int rect_end_y = baking_rect.position[1] + baking_rect.size[1] + baking_rect_offset.y - border_size;
const double rect_begin_x = baking_rect.position[0] + baking_rect_offset.x + border_size;
const double rect_begin_y = baking_rect.position[1] + baking_rect_offset.y + border_size;
const double rect_end_x = baking_rect.position[0] + baking_rect.size[0] + baking_rect_offset.x - border_size;
const double rect_end_y = baking_rect.position[1] + baking_rect.size[1] + baking_rect_offset.y - border_size;
RectD clipper_rect = RectD(rect_begin_x, rect_begin_y, rect_end_x, rect_end_y);

View File

@ -3565,16 +3565,7 @@ void TileMapLayer::navmesh_parse_source_geometry(const Ref<NavigationPolygon> &p
continue;
}
Vector<Vector2> traversable_outline;
traversable_outline.resize(navigation_polygon_outline.size());
const Vector2 *navigation_polygon_outline_ptr = navigation_polygon_outline.ptr();
Vector2 *traversable_outline_ptrw = traversable_outline.ptrw();
for (int traversable_outline_index = 0; traversable_outline_index < traversable_outline.size(); traversable_outline_index++) {
traversable_outline_ptrw[traversable_outline_index] = tile_transform_offset.xform(navigation_polygon_outline_ptr[traversable_outline_index]);
}
Vector<Vector2> traversable_outline = tile_transform_offset.xform(navigation_polygon_outline);
p_source_geometry_data->_add_traversable_outline(traversable_outline);
}
}
@ -3598,16 +3589,7 @@ void TileMapLayer::navmesh_parse_source_geometry(const Ref<NavigationPolygon> &p
collision_polygon_points = TileData::get_transformed_vertices(collision_polygon_points, flip_h, flip_v, transpose);
}
Vector<Vector2> obstruction_outline;
obstruction_outline.resize(collision_polygon_points.size());
const Vector2 *collision_polygon_points_ptr = collision_polygon_points.ptr();
Vector2 *obstruction_outline_ptrw = obstruction_outline.ptrw();
for (int obstruction_outline_index = 0; obstruction_outline_index < obstruction_outline.size(); obstruction_outline_index++) {
obstruction_outline_ptrw[obstruction_outline_index] = tile_transform_offset.xform(collision_polygon_points_ptr[obstruction_outline_index]);
}
Vector<Vector2> obstruction_outline = tile_transform_offset.xform(collision_polygon_points);
p_source_geometry_data->_add_obstruction_outline(obstruction_outline);
}
}

View File

@ -6594,7 +6594,19 @@ Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_f
Ref<NavigationPolygon> transformed_polygon;
transformed_polygon.instantiate();
PackedVector2Array new_points = get_transformed_vertices(layer_tile_data.navigation_polygon->get_vertices(), p_flip_h, p_flip_v, p_transpose);
// Winding order:
// - Preserve for outlines.
// - If there are no polygons provided, preserve for vertices.
// - If there are polygons provided, preserve for polygons, don't preserve for vertices (so the vertex order is unchanged and polygons don't need reindexing).
Vector<Vector<int>> new_polygons = layer_tile_data.navigation_polygon->get_polygons();
if ((p_flip_h != p_flip_v) != p_transpose) {
for (Vector<int> &polygon : new_polygons) {
polygon.reverse();
}
}
PackedVector2Array new_points = get_transformed_vertices(layer_tile_data.navigation_polygon->get_vertices(), p_flip_h, p_flip_v, p_transpose, new_polygons.is_empty());
const Vector<Vector<Vector2>> outlines = layer_tile_data.navigation_polygon->get_outlines();
int outline_count = outlines.size();
@ -6603,10 +6615,10 @@ Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_f
new_outlines.resize(outline_count);
for (int i = 0; i < outline_count; i++) {
new_outlines.write[i] = get_transformed_vertices(outlines[i], p_flip_h, p_flip_v, p_transpose);
new_outlines.write[i] = get_transformed_vertices(outlines[i], p_flip_h, p_flip_v, p_transpose, true);
}
transformed_polygon->set_data(new_points, layer_tile_data.navigation_polygon->get_polygons(), new_outlines);
transformed_polygon->set_data(new_points, new_polygons, new_outlines);
layer_tile_data.transformed_navigation_polygon[key] = transformed_polygon;
return transformed_polygon;
@ -6657,14 +6669,15 @@ Variant TileData::get_custom_data_by_layer_id(int p_layer_id) const {
return custom_data[p_layer_id];
}
PackedVector2Array TileData::get_transformed_vertices(const PackedVector2Array &p_vertices, bool p_flip_h, bool p_flip_v, bool p_transpose) {
PackedVector2Array TileData::get_transformed_vertices(const PackedVector2Array &p_vertices, bool p_flip_h, bool p_flip_v, bool p_transpose, bool p_preserve_winding_order) {
const Vector2 *r = p_vertices.ptr();
int size = p_vertices.size();
PackedVector2Array new_points;
new_points.resize(size);
new_points.resize_uninitialized(size);
Vector2 *w = new_points.ptrw();
bool reverse_vertex_order = p_preserve_winding_order && ((p_flip_h != p_flip_v) != p_transpose);
for (int i = 0; i < size; i++) {
Vector2 v;
if (p_transpose) {
@ -6679,7 +6692,7 @@ PackedVector2Array TileData::get_transformed_vertices(const PackedVector2Array &
if (p_flip_v) {
v.y *= -1;
}
w[i] = v;
w[reverse_vertex_order ? (size - 1 - i) : i] = v;
}
return new_points;
}

View File

@ -1029,7 +1029,7 @@ public:
Variant get_custom_data_by_layer_id(int p_layer_id) const;
// Polygons.
static PackedVector2Array get_transformed_vertices(const PackedVector2Array &p_vertices, bool p_flip_h, bool p_flip_v, bool p_transpose);
static PackedVector2Array get_transformed_vertices(const PackedVector2Array &p_vertices, bool p_flip_h, bool p_flip_v, bool p_transpose, bool p_preserve_winding_order = false);
};
VARIANT_ENUM_CAST(TileSet::CellNeighbor);