mirror of https://github.com/godotengine/godot
Merge pull request #114742 from kleonc/tile_navigation_preserve_winding_order
Preserve winding order for transformed tiles' navigation polygons
This commit is contained in:
commit
ab6bbf1c59
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue