Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NavigationPolygon border_size property for tile baking #87961

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/classes/NavigationPolygon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,16 @@
<member name="agent_radius" type="float" setter="set_agent_radius" getter="get_agent_radius" default="10.0">
The distance to erode/shrink the walkable surface when baking the navigation mesh.
</member>
<member name="baking_rect" type="Rect2" setter="set_baking_rect" getter="get_baking_rect" default="Rect2(0, 0, 0, 0)">
If the baking [Rect2] has an area the navigation mesh baking will be restricted to its enclosing area.
</member>
<member name="baking_rect_offset" type="Vector2" setter="set_baking_rect_offset" getter="get_baking_rect_offset" default="Vector2(0, 0)">
The position offset applied to the [member baking_rect] [Rect2].
</member>
<member name="border_size" type="float" setter="set_border_size" getter="get_border_size" default="0.0">
The size of the non-navigable border around the bake bounding area defined by the [member baking_rect] [Rect2].
In conjunction with the [member baking_rect] the border size can be used to bake tile aligned navigation meshes without the tile edges being shrunk by [member agent_radius].
</member>
<member name="cell_size" type="float" setter="set_cell_size" getter="get_cell_size" default="1.0">
The cell size used to rasterize the navigation mesh vertices. Must match with the cell size on the navigation map.
</member>
Expand Down
38 changes: 38 additions & 0 deletions modules/navigation/nav_mesh_generator_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -738,9 +738,13 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
Paths64 traversable_polygon_paths;
Paths64 obstruction_polygon_paths;

traversable_polygon_paths.reserve(outline_count + traversable_outlines.size());
obstruction_polygon_paths.reserve(obstruction_outlines.size());

for (int i = 0; i < outline_count; i++) {
const Vector<Vector2> &traversable_outline = p_navigation_mesh->get_outline(i);
Path64 subject_path;
subject_path.reserve(traversable_outline.size());
for (const Vector2 &traversable_point : traversable_outline) {
const Point64 &point = Point64(traversable_point.x, traversable_point.y);
subject_path.push_back(point);
Expand All @@ -750,6 +754,7 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation

for (const Vector<Vector2> &traversable_outline : traversable_outlines) {
Path64 subject_path;
subject_path.reserve(traversable_outline.size());
for (const Vector2 &traversable_point : traversable_outline) {
const Point64 &point = Point64(traversable_point.x, traversable_point.y);
subject_path.push_back(point);
Expand All @@ -759,13 +764,30 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation

for (const Vector<Vector2> &obstruction_outline : obstruction_outlines) {
Path64 clip_path;
clip_path.reserve(obstruction_outline.size());
for (const Vector2 &obstruction_point : obstruction_outline) {
const Point64 &point = Point64(obstruction_point.x, obstruction_point.y);
clip_path.push_back(point);
}
obstruction_polygon_paths.push_back(clip_path);
}

Rect2 baking_rect = p_navigation_mesh->get_baking_rect();
if (baking_rect.has_area()) {
Vector2 baking_rect_offset = p_navigation_mesh->get_baking_rect_offset();

const int rect_begin_x = baking_rect.position[0] + baking_rect_offset.x;
const int rect_begin_y = baking_rect.position[1] + baking_rect_offset.y;
const int rect_end_x = baking_rect.position[0] + baking_rect.size[0] + baking_rect_offset.x;
const int rect_end_y = baking_rect.position[1] + baking_rect.size[1] + baking_rect_offset.y;

Rect64 clipper_rect = Rect64(rect_begin_x, rect_begin_y, rect_end_x, rect_end_y);
RectClip rect_clip = RectClip(clipper_rect);

traversable_polygon_paths = rect_clip.Execute(traversable_polygon_paths);
obstruction_polygon_paths = rect_clip.Execute(obstruction_polygon_paths);
}

Paths64 path_solution;

// first merge all traversable polygons according to user specified fill rule
Expand All @@ -782,6 +804,21 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
}
//path_solution = RamerDouglasPeucker(path_solution, 0.025); //

real_t border_size = p_navigation_mesh->get_border_size();
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;

Rect64 clipper_rect = Rect64(rect_begin_x, rect_begin_y, rect_end_x, rect_end_y);
RectClip rect_clip = RectClip(clipper_rect);

path_solution = rect_clip.Execute(path_solution);
}

Vector<Vector<Vector2>> new_baked_outlines;

for (const Path64 &scaled_path : path_solution) {
Expand All @@ -799,6 +836,7 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation
}

Paths64 polygon_paths;
polygon_paths.reserve(new_baked_outlines.size());

for (const Vector<Vector2> &baked_outline : new_baked_outlines) {
Path64 polygon_path;
Expand Down
39 changes: 39 additions & 0 deletions scene/resources/navigation_polygon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,15 @@ real_t NavigationPolygon::get_cell_size() const {
return cell_size;
}

void NavigationPolygon::set_border_size(real_t p_value) {
ERR_FAIL_COND(p_value < 0.0);
border_size = p_value;
smix8 marked this conversation as resolved.
Show resolved Hide resolved
}

real_t NavigationPolygon::get_border_size() const {
return border_size;
}

void NavigationPolygon::set_parsed_geometry_type(ParsedGeometryType p_geometry_type) {
ERR_FAIL_INDEX(p_geometry_type, PARSED_GEOMETRY_MAX);
parsed_geometry_type = p_geometry_type;
Expand Down Expand Up @@ -410,6 +419,24 @@ real_t NavigationPolygon::get_agent_radius() const {
return agent_radius;
}

void NavigationPolygon::set_baking_rect(const Rect2 &p_rect) {
baking_rect = p_rect;
emit_changed();
}

Rect2 NavigationPolygon::get_baking_rect() const {
return baking_rect;
}

void NavigationPolygon::set_baking_rect_offset(const Vector2 &p_rect_offset) {
baking_rect_offset = p_rect_offset;
emit_changed();
}

Vector2 NavigationPolygon::get_baking_rect_offset() const {
return baking_rect_offset;
}

void NavigationPolygon::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationPolygon::set_vertices);
ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationPolygon::get_vertices);
Expand Down Expand Up @@ -440,6 +467,9 @@ void NavigationPolygon::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &NavigationPolygon::set_cell_size);
ClassDB::bind_method(D_METHOD("get_cell_size"), &NavigationPolygon::get_cell_size);

ClassDB::bind_method(D_METHOD("set_border_size", "border_size"), &NavigationPolygon::set_border_size);
ClassDB::bind_method(D_METHOD("get_border_size"), &NavigationPolygon::get_border_size);

ClassDB::bind_method(D_METHOD("set_parsed_geometry_type", "geometry_type"), &NavigationPolygon::set_parsed_geometry_type);
ClassDB::bind_method(D_METHOD("get_parsed_geometry_type"), &NavigationPolygon::get_parsed_geometry_type);

Expand All @@ -458,6 +488,11 @@ void NavigationPolygon::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_agent_radius", "agent_radius"), &NavigationPolygon::set_agent_radius);
ClassDB::bind_method(D_METHOD("get_agent_radius"), &NavigationPolygon::get_agent_radius);

ClassDB::bind_method(D_METHOD("set_baking_rect", "rect"), &NavigationPolygon::set_baking_rect);
ClassDB::bind_method(D_METHOD("get_baking_rect"), &NavigationPolygon::get_baking_rect);
ClassDB::bind_method(D_METHOD("set_baking_rect_offset", "rect_offset"), &NavigationPolygon::set_baking_rect_offset);
ClassDB::bind_method(D_METHOD("get_baking_rect_offset"), &NavigationPolygon::get_baking_rect_offset);

ClassDB::bind_method(D_METHOD("clear"), &NavigationPolygon::clear);

ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices");
Expand All @@ -473,8 +508,12 @@ void NavigationPolygon::_bind_methods() {
ADD_PROPERTY_DEFAULT("source_geometry_group_name", StringName("navigation_polygon_source_geometry_group"));
ADD_GROUP("Cells", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size", PROPERTY_HINT_RANGE, "1.0,50.0,1.0,or_greater,suffix:px"), "set_cell_size", "get_cell_size");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "border_size", PROPERTY_HINT_RANGE, "0.0,500.0,1.0,or_greater,suffix:px"), "set_border_size", "get_border_size");
ADD_GROUP("Agents", "agent_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_radius", PROPERTY_HINT_RANGE, "0.0,500.0,0.01,or_greater,suffix:px"), "set_agent_radius", "get_agent_radius");
ADD_GROUP("Filters", "");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "baking_rect"), "set_baking_rect", "get_baking_rect");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "baking_rect_offset"), "set_baking_rect_offset", "get_baking_rect_offset");

BIND_ENUM_CONSTANT(PARSED_GEOMETRY_MESH_INSTANCES);
BIND_ENUM_CONSTANT(PARSED_GEOMETRY_STATIC_COLLIDERS);
Expand Down
13 changes: 13 additions & 0 deletions scene/resources/navigation_polygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ class NavigationPolygon : public Resource {
Ref<NavigationMesh> navigation_mesh;

real_t cell_size = 1.0f; // Must match ProjectSettings default 2D cell_size.
real_t border_size = 0.0f;

Rect2 baking_rect;
Vector2 baking_rect_offset;

protected:
static void _bind_methods();
Expand Down Expand Up @@ -138,6 +142,15 @@ class NavigationPolygon : public Resource {
void set_cell_size(real_t p_cell_size);
real_t get_cell_size() const;

void set_border_size(real_t p_value);
real_t get_border_size() const;

void set_baking_rect(const Rect2 &p_rect);
Rect2 get_baking_rect() const;

void set_baking_rect_offset(const Vector2 &p_rect_offset);
Vector2 get_baking_rect_offset() const;

void clear();

NavigationPolygon();
Expand Down
Loading