Add support for emitting a signal when entering a NavLink

This commit is contained in:
Josh Jones 2022-10-05 17:24:45 -06:00
parent 0bb94df247
commit 5d8ba2b2d1
27 changed files with 607 additions and 33 deletions

View file

@ -28,6 +28,12 @@
Returns which index the agent is currently on in the navigation path's [PackedVector2Array]. Returns which index the agent is currently on in the navigation path's [PackedVector2Array].
</description> </description>
</method> </method>
<method name="get_current_navigation_result" qualifiers="const">
<return type="NavigationPathQueryResult2D" />
<description>
Returns the path query result for the path the agent is currently following.
</description>
</method>
<method name="get_final_location"> <method name="get_final_location">
<return type="Vector2" /> <return type="Vector2" />
<description> <description>
@ -122,6 +128,9 @@
<member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="3.0"> <member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="3.0">
The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path. The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path.
</member> </member>
<member name="path_metadata_flags" type="int" setter="set_path_metadata_flags" getter="get_path_metadata_flags" enum="NavigationPathQueryParameters2D.PathMetadataFlags" default="7">
Additional information to return with the navigation path.
</member>
<member name="radius" type="float" setter="set_radius" getter="get_radius" default="10.0"> <member name="radius" type="float" setter="set_radius" getter="get_radius" default="10.0">
The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_distance]). The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_distance]).
Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size. Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size.
@ -137,6 +146,17 @@
</member> </member>
</members> </members>
<signals> <signals>
<signal name="link_reached">
<param index="0" name="details" type="Dictionary" />
<description>
Notifies when a navigation link has been reached.
The details dictionary may contain the following keys depending on the value of [member path_metadata_flags]:
- [code]location[/code]: The start location of the link that was reached.
- [code]type[/code]: Always [constant NavigationPathQueryResult2D.PATH_SEGMENT_TYPE_LINK].
- [code]rid[/code]: The [RID] of the link.
- [code]owner[/code]: The object which manages the link (usually [NavigationLink2D]).
</description>
</signal>
<signal name="navigation_finished"> <signal name="navigation_finished">
<description> <description>
Notifies when the final location is reached. Notifies when the final location is reached.
@ -158,5 +178,16 @@
Notifies when the collision avoidance velocity is calculated. Emitted by [method set_velocity]. Only emitted when [member avoidance_enabled] is true. Notifies when the collision avoidance velocity is calculated. Emitted by [method set_velocity]. Only emitted when [member avoidance_enabled] is true.
</description> </description>
</signal> </signal>
<signal name="waypoint_reached">
<param index="0" name="details" type="Dictionary" />
<description>
Notifies when a waypoint along the path has been reached.
The details dictionary may contain the following keys depending on the value of [member path_metadata_flags]:
- [code]location[/code]: The location of the waypoint that was reached.
- [code]type[/code]: The type of navigation primitive (region or link) that contains this waypoint.
- [code]rid[/code]: The [RID] of the containing navigation primitive (region or link).
- [code]owner[/code]: The object which manages the containing navigation primitive (region or link).
</description>
</signal>
</signals> </signals>
</class> </class>

View file

@ -28,6 +28,12 @@
Returns which index the agent is currently on in the navigation path's [PackedVector3Array]. Returns which index the agent is currently on in the navigation path's [PackedVector3Array].
</description> </description>
</method> </method>
<method name="get_current_navigation_result" qualifiers="const">
<return type="NavigationPathQueryResult3D" />
<description>
Returns the path query result for the path the agent is currently following.
</description>
</method>
<method name="get_final_location"> <method name="get_final_location">
<return type="Vector3" /> <return type="Vector3" />
<description> <description>
@ -128,6 +134,9 @@
<member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="3.0"> <member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="3.0">
The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path. The maximum distance the agent is allowed away from the ideal path to the final location. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path.
</member> </member>
<member name="path_metadata_flags" type="int" setter="set_path_metadata_flags" getter="get_path_metadata_flags" enum="NavigationPathQueryParameters3D.PathMetadataFlags" default="7">
Additional information to return with the navigation path.
</member>
<member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0"> <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0">
The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_distance]). The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_distance]).
Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size. Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size.
@ -143,6 +152,17 @@
</member> </member>
</members> </members>
<signals> <signals>
<signal name="link_reached">
<param index="0" name="details" type="Dictionary" />
<description>
Notifies when a navigation link has been reached.
The details dictionary may contain the following keys depending on the value of [member path_metadata_flags]:
- [code]location[/code]: The start location of the link that was reached.
- [code]type[/code]: Always [constant NavigationPathQueryResult3D.PATH_SEGMENT_TYPE_LINK].
- [code]rid[/code]: The [RID] of the link.
- [code]owner[/code]: The object which manages the link (usually [NavigationLink3D]).
</description>
</signal>
<signal name="navigation_finished"> <signal name="navigation_finished">
<description> <description>
Notifies when the final location is reached. Notifies when the final location is reached.
@ -164,5 +184,16 @@
Notifies when the collision avoidance velocity is calculated. Emitted by [method set_velocity]. Only emitted when [member avoidance_enabled] is true. Notifies when the collision avoidance velocity is calculated. Emitted by [method set_velocity]. Only emitted when [member avoidance_enabled] is true.
</description> </description>
</signal> </signal>
<signal name="waypoint_reached">
<param index="0" name="details" type="Dictionary" />
<description>
Notifies when a waypoint along the path has been reached.
The details dictionary may contain the following keys depending on the value of [member path_metadata_flags]:
- [code]location[/code]: The location of the waypoint that was reached.
- [code]type[/code]: The type of navigation primitive (region or link) that contains this waypoint.
- [code]rid[/code]: The [RID] of the containing navigation primitive (region or link).
- [code]owner[/code]: The object which manages the containing navigation primitive (region or link).
</description>
</signal>
</signals> </signals>
</class> </class>

View file

@ -12,6 +12,9 @@
<member name="map" type="RID" setter="set_map" getter="get_map"> <member name="map" type="RID" setter="set_map" getter="get_map">
The navigation [code]map[/code] [RID] used in the path query. The navigation [code]map[/code] [RID] used in the path query.
</member> </member>
<member name="metadata_flags" type="int" setter="set_metadata_flags" getter="get_metadata_flags" enum="NavigationPathQueryParameters2D.PathMetadataFlags" default="7">
Additional information to include with the navigation path.
</member>
<member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1"> <member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1">
The navigation layers the query will use (as a bitmask). The navigation layers the query will use (as a bitmask).
</member> </member>
@ -38,5 +41,20 @@
<constant name="PATH_POSTPROCESSING_EDGECENTERED" value="1" enum="PathPostProcessing"> <constant name="PATH_POSTPROCESSING_EDGECENTERED" value="1" enum="PathPostProcessing">
Centers every path position in the middle of the traveled navigation mesh polygon edge. This creates better paths for tile- or gridbased layouts that restrict the movement to the cells center. Centers every path position in the middle of the traveled navigation mesh polygon edge. This creates better paths for tile- or gridbased layouts that restrict the movement to the cells center.
</constant> </constant>
<constant name="PATH_METADATA_INCLUDE_NONE" value="0" enum="PathMetadataFlags" is_bitfield="true">
Don't include any additional metadata about the returned path.
</constant>
<constant name="PATH_METADATA_INCLUDE_TYPES" value="1" enum="PathMetadataFlags" is_bitfield="true">
Include the type of navigation primitive (region or link) that each point of the path goes through.
</constant>
<constant name="PATH_METADATA_INCLUDE_RIDS" value="2" enum="PathMetadataFlags" is_bitfield="true">
Include the [RID]s of the regions and links that each point of the path goes through.
</constant>
<constant name="PATH_METADATA_INCLUDE_OWNERS" value="4" enum="PathMetadataFlags" is_bitfield="true">
Include the [code]ObjectID[/code]s of the [Object]s which manage the regions and links each point of the path goes through.
</constant>
<constant name="PATH_METADATA_INCLUDE_ALL" value="7" enum="PathMetadataFlags" is_bitfield="true">
Include all available metadata about the returned path.
</constant>
</constants> </constants>
</class> </class>

View file

@ -12,6 +12,9 @@
<member name="map" type="RID" setter="set_map" getter="get_map"> <member name="map" type="RID" setter="set_map" getter="get_map">
The navigation [code]map[/code] [RID] used in the path query. The navigation [code]map[/code] [RID] used in the path query.
</member> </member>
<member name="metadata_flags" type="int" setter="set_metadata_flags" getter="get_metadata_flags" enum="NavigationPathQueryParameters3D.PathMetadataFlags" default="7">
Additional information to include with the navigation path.
</member>
<member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1"> <member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1">
The navigation layers the query will use (as a bitmask). The navigation layers the query will use (as a bitmask).
</member> </member>
@ -38,5 +41,20 @@
<constant name="PATH_POSTPROCESSING_EDGECENTERED" value="1" enum="PathPostProcessing"> <constant name="PATH_POSTPROCESSING_EDGECENTERED" value="1" enum="PathPostProcessing">
Centers every path position in the middle of the traveled navigation mesh polygon edge. This creates better paths for tile- or gridbased layouts that restrict the movement to the cells center. Centers every path position in the middle of the traveled navigation mesh polygon edge. This creates better paths for tile- or gridbased layouts that restrict the movement to the cells center.
</constant> </constant>
<constant name="PATH_METADATA_INCLUDE_NONE" value="0" enum="PathMetadataFlags" is_bitfield="true">
Don't include any additional metadata about the returned path.
</constant>
<constant name="PATH_METADATA_INCLUDE_TYPES" value="1" enum="PathMetadataFlags" is_bitfield="true">
Include the type of navigation primitive (region or link) that each point of the path goes through.
</constant>
<constant name="PATH_METADATA_INCLUDE_RIDS" value="2" enum="PathMetadataFlags" is_bitfield="true">
Include the [RID]s of the regions and links that each point of the path goes through.
</constant>
<constant name="PATH_METADATA_INCLUDE_OWNERS" value="4" enum="PathMetadataFlags" is_bitfield="true">
Include the [code]ObjectID[/code]s of the [Object]s which manage the regions and links each point of the path goes through.
</constant>
<constant name="PATH_METADATA_INCLUDE_ALL" value="7" enum="PathMetadataFlags" is_bitfield="true">
Include all available metadata about the returned path.
</constant>
</constants> </constants>
</class> </class>

View file

@ -20,5 +20,22 @@
<member name="path" type="PackedVector2Array" setter="set_path" getter="get_path" default="PackedVector2Array()"> <member name="path" type="PackedVector2Array" setter="set_path" getter="get_path" default="PackedVector2Array()">
The resulting path array from the navigation query. All path array positions are in global coordinates. Without customized query parameters this is the same path as returned by [method NavigationServer2D.map_get_path]. The resulting path array from the navigation query. All path array positions are in global coordinates. Without customized query parameters this is the same path as returned by [method NavigationServer2D.map_get_path].
</member> </member>
<member name="path_owner_ids" type="PackedInt64Array" setter="set_path_owner_ids" getter="get_path_owner_ids" default="PackedInt64Array()">
The [code]ObjectID[/code]s of the [Object]s which manage the regions and links each point of the path goes through.
</member>
<member name="path_rids" type="RID[]" setter="set_path_rids" getter="get_path_rids" default="[]">
The [RID]s of the regions and links that each point of the path goes through.
</member>
<member name="path_types" type="PackedInt32Array" setter="set_path_types" getter="get_path_types" default="PackedInt32Array()">
The type of navigation primitive (region or link) that each point of the path goes through.
</member>
</members> </members>
<constants>
<constant name="PATH_SEGMENT_TYPE_REGION" value="0" enum="PathSegmentType">
This segment of the path goes through a region.
</constant>
<constant name="PATH_SEGMENT_TYPE_LINK" value="1" enum="PathSegmentType">
This segment of the path goes through a link.
</constant>
</constants>
</class> </class>

View file

@ -20,5 +20,22 @@
<member name="path" type="PackedVector3Array" setter="set_path" getter="get_path" default="PackedVector3Array()"> <member name="path" type="PackedVector3Array" setter="set_path" getter="get_path" default="PackedVector3Array()">
The resulting path array from the navigation query. All path array positions are in global coordinates. Without customized query parameters this is the same path as returned by [method NavigationServer3D.map_get_path]. The resulting path array from the navigation query. All path array positions are in global coordinates. Without customized query parameters this is the same path as returned by [method NavigationServer3D.map_get_path].
</member> </member>
<member name="path_owner_ids" type="PackedInt64Array" setter="set_path_owner_ids" getter="get_path_owner_ids" default="PackedInt64Array()">
The [code]ObjectID[/code]s of the [Object]s which manage the regions and links each point of the path goes through.
</member>
<member name="path_rids" type="RID[]" setter="set_path_rids" getter="get_path_rids" default="[]">
The [RID]s of the regions and links that each point of the path goes through.
</member>
<member name="path_types" type="PackedInt32Array" setter="set_path_types" getter="get_path_types" default="PackedInt32Array()">
The type of navigation primitive (region or link) that each point of the path goes through.
</member>
</members> </members>
<constants>
<constant name="PATH_SEGMENT_TYPE_REGION" value="0" enum="PathSegmentType">
This segment of the path goes through a region.
</constant>
<constant name="PATH_SEGMENT_TYPE_LINK" value="1" enum="PathSegmentType">
This segment of the path goes through a link.
</constant>
</constants>
</class> </class>

View file

@ -36,6 +36,8 @@
#include "navigation_mesh_generator.h" #include "navigation_mesh_generator.h"
#endif #endif
using namespace NavigationUtilities;
/// Creates a struct for each function and a function that once called creates /// Creates a struct for each function and a function that once called creates
/// an instance of that struct with the submitted parameters. /// an instance of that struct with the submitted parameters.
/// Then, that struct is stored in an array; the `sync` function consume that array. /// Then, that struct is stored in an array; the `sync` function consume that array.
@ -228,7 +230,7 @@ Vector<Vector3> GodotNavigationServer::map_get_path(RID p_map, Vector3 p_origin,
const NavMap *map = map_owner.get_or_null(p_map); const NavMap *map = map_owner.get_or_null(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>()); ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>());
return map->get_path(p_origin, p_destination, p_optimize, p_navigation_layers); return map->get_path(p_origin, p_destination, p_optimize, p_navigation_layers, nullptr, nullptr, nullptr);
} }
Vector3 GodotNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const { Vector3 GodotNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
@ -838,20 +840,34 @@ void GodotNavigationServer::process(real_t p_delta_time) {
} }
} }
NavigationUtilities::PathQueryResult GodotNavigationServer::_query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const { PathQueryResult GodotNavigationServer::_query_path(const PathQueryParameters &p_parameters) const {
NavigationUtilities::PathQueryResult r_query_result; PathQueryResult r_query_result;
const NavMap *map = map_owner.get_or_null(p_parameters.map); const NavMap *map = map_owner.get_or_null(p_parameters.map);
ERR_FAIL_COND_V(map == nullptr, r_query_result); ERR_FAIL_COND_V(map == nullptr, r_query_result);
// run the pathfinding // run the pathfinding
if (p_parameters.pathfinding_algorithm == NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR) { if (p_parameters.pathfinding_algorithm == PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR) {
// while postprocessing is still part of map.get_path() need to check and route it here for the correct "optimize" post-processing // while postprocessing is still part of map.get_path() need to check and route it here for the correct "optimize" post-processing
if (p_parameters.path_postprocessing == NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL) { if (p_parameters.path_postprocessing == PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL) {
r_query_result.path = map->get_path(p_parameters.start_position, p_parameters.target_position, true, p_parameters.navigation_layers); r_query_result.path = map->get_path(
} else if (p_parameters.path_postprocessing == NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED) { p_parameters.start_position,
r_query_result.path = map->get_path(p_parameters.start_position, p_parameters.target_position, false, p_parameters.navigation_layers); p_parameters.target_position,
true,
p_parameters.navigation_layers,
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_TYPES) ? &r_query_result.path_types : nullptr,
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_RIDS) ? &r_query_result.path_rids : nullptr,
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_OWNERS) ? &r_query_result.path_owner_ids : nullptr);
} else if (p_parameters.path_postprocessing == PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED) {
r_query_result.path = map->get_path(
p_parameters.start_position,
p_parameters.target_position,
false,
p_parameters.navigation_layers,
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_TYPES) ? &r_query_result.path_types : nullptr,
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_RIDS) ? &r_query_result.path_rids : nullptr,
p_parameters.metadata_flags.has_flag(PathMetadataFlags::PATH_INCLUDE_OWNERS) ? &r_query_result.path_owner_ids : nullptr);
} }
} else { } else {
return r_query_result; return r_query_result;

View file

@ -33,6 +33,7 @@
#include "nav_rid.h" #include "nav_rid.h"
#include "nav_utils.h" #include "nav_utils.h"
#include "servers/navigation/navigation_utilities.h"
class NavMap; class NavMap;
@ -42,8 +43,11 @@ protected:
float enter_cost = 0.0; float enter_cost = 0.0;
float travel_cost = 1.0; float travel_cost = 1.0;
ObjectID owner_id; ObjectID owner_id;
NavigationUtilities::PathSegmentType type;
public: public:
NavigationUtilities::PathSegmentType get_type() const { return type; }
void set_navigation_layers(uint32_t p_navigation_layers) { navigation_layers = p_navigation_layers; } void set_navigation_layers(uint32_t p_navigation_layers) { navigation_layers = p_navigation_layers; }
uint32_t get_navigation_layers() const { return navigation_layers; } uint32_t get_navigation_layers() const { return navigation_layers; }

View file

@ -43,6 +43,10 @@ class NavLink : public NavBase {
bool link_dirty = true; bool link_dirty = true;
public: public:
NavLink() {
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK;
}
void set_map(NavMap *p_map); void set_map(NavMap *p_map);
NavMap *get_map() const { NavMap *get_map() const {
return map; return map;

View file

@ -38,6 +38,18 @@
#define THREE_POINTS_CROSS_PRODUCT(m_a, m_b, m_c) (((m_c) - (m_a)).cross((m_b) - (m_a))) #define THREE_POINTS_CROSS_PRODUCT(m_a, m_b, m_c) (((m_c) - (m_a)).cross((m_b) - (m_a)))
// Helper macro
#define APPEND_METADATA(poly) \
if (r_path_types) { \
r_path_types->push_back(poly->owner->get_type()); \
} \
if (r_path_rids) { \
r_path_rids->push_back(poly->owner->get_self()); \
} \
if (r_path_owners) { \
r_path_owners->push_back(poly->owner->get_owner_id()); \
}
void NavMap::set_up(Vector3 p_up) { void NavMap::set_up(Vector3 p_up) {
up = p_up; up = p_up;
regenerate_polygons = true; regenerate_polygons = true;
@ -71,7 +83,18 @@ gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const {
return p; return p;
} }
Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers) const { Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers, Vector<int32_t> *r_path_types, TypedArray<RID> *r_path_rids, Vector<int64_t> *r_path_owners) const {
// Clear metadata outputs.
if (r_path_types) {
r_path_types->clear();
}
if (r_path_rids) {
r_path_rids->clear();
}
if (r_path_owners) {
r_path_owners->clear();
}
// Find the start poly and the end poly on this map. // Find the start poly and the end poly on this map.
const gd::Polygon *begin_poly = nullptr; const gd::Polygon *begin_poly = nullptr;
const gd::Polygon *end_poly = nullptr; const gd::Polygon *end_poly = nullptr;
@ -115,6 +138,24 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
return Vector<Vector3>(); return Vector<Vector3>();
} }
if (begin_poly == end_poly) { if (begin_poly == end_poly) {
if (r_path_types) {
r_path_types->resize(2);
r_path_types->write[0] = begin_poly->owner->get_type();
r_path_types->write[1] = end_poly->owner->get_type();
}
if (r_path_rids) {
r_path_rids->resize(2);
(*r_path_rids)[0] = begin_poly->owner->get_self();
(*r_path_rids)[1] = end_poly->owner->get_self();
}
if (r_path_owners) {
r_path_owners->resize(2);
r_path_owners->write[0] = begin_poly->owner->get_owner_id();
r_path_owners->write[1] = end_poly->owner->get_owner_id();
}
Vector<Vector3> path; Vector<Vector3> path;
path.resize(2); path.resize(2);
path.write[0] = begin_point; path.write[0] = begin_point;
@ -296,6 +337,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
gd::NavigationPoly *p = apex_poly; gd::NavigationPoly *p = apex_poly;
path.push_back(end_point); path.push_back(end_point);
APPEND_METADATA(end_poly);
while (p) { while (p) {
// Set left and right points of the pathway between polygons. // Set left and right points of the pathway between polygons.
@ -312,7 +354,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
left_poly = p; left_poly = p;
left_portal = left; left_portal = left;
} else { } else {
clip_path(navigation_polys, path, apex_poly, right_portal, right_poly); clip_path(navigation_polys, path, apex_poly, right_portal, right_poly, r_path_types, r_path_rids, r_path_owners);
apex_point = right_portal; apex_point = right_portal;
p = right_poly; p = right_poly;
@ -320,7 +362,9 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
apex_poly = p; apex_poly = p;
left_portal = apex_point; left_portal = apex_point;
right_portal = apex_point; right_portal = apex_point;
path.push_back(apex_point); path.push_back(apex_point);
APPEND_METADATA(apex_poly->poly);
skip = true; skip = true;
} }
} }
@ -331,7 +375,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
right_poly = p; right_poly = p;
right_portal = right; right_portal = right;
} else { } else {
clip_path(navigation_polys, path, apex_poly, left_portal, left_poly); clip_path(navigation_polys, path, apex_poly, left_portal, left_poly, r_path_types, r_path_rids, r_path_owners);
apex_point = left_portal; apex_point = left_portal;
p = left_poly; p = left_poly;
@ -339,7 +383,9 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
apex_poly = p; apex_poly = p;
right_portal = apex_point; right_portal = apex_point;
left_portal = apex_point; left_portal = apex_point;
path.push_back(apex_point); path.push_back(apex_point);
APPEND_METADATA(apex_poly->poly);
} }
} }
@ -355,12 +401,23 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
// If the last point is not the begin point, add it to the list. // If the last point is not the begin point, add it to the list.
if (path[path.size() - 1] != begin_point) { if (path[path.size() - 1] != begin_point) {
path.push_back(begin_point); path.push_back(begin_point);
APPEND_METADATA(begin_poly);
} }
path.reverse(); path.reverse();
if (r_path_types) {
r_path_types->reverse();
}
if (r_path_rids) {
r_path_rids->reverse();
}
if (r_path_owners) {
r_path_owners->reverse();
}
} else { } else {
path.push_back(end_point); path.push_back(end_point);
APPEND_METADATA(end_poly);
// Add mid points // Add mid points
int np_id = least_cost_id; int np_id = least_cost_id;
@ -369,18 +426,37 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
int prev = navigation_polys[np_id].back_navigation_edge; int prev = navigation_polys[np_id].back_navigation_edge;
int prev_n = (navigation_polys[np_id].back_navigation_edge + 1) % navigation_polys[np_id].poly->points.size(); int prev_n = (navigation_polys[np_id].back_navigation_edge + 1) % navigation_polys[np_id].poly->points.size();
Vector3 point = (navigation_polys[np_id].poly->points[prev].pos + navigation_polys[np_id].poly->points[prev_n].pos) * 0.5; Vector3 point = (navigation_polys[np_id].poly->points[prev].pos + navigation_polys[np_id].poly->points[prev_n].pos) * 0.5;
path.push_back(point); path.push_back(point);
APPEND_METADATA(navigation_polys[np_id].poly);
} else { } else {
path.push_back(navigation_polys[np_id].entry); path.push_back(navigation_polys[np_id].entry);
APPEND_METADATA(navigation_polys[np_id].poly);
} }
np_id = navigation_polys[np_id].back_navigation_poly_id; np_id = navigation_polys[np_id].back_navigation_poly_id;
} }
path.push_back(begin_point); path.push_back(begin_point);
APPEND_METADATA(begin_poly);
path.reverse(); path.reverse();
if (r_path_types) {
r_path_types->reverse();
}
if (r_path_rids) {
r_path_rids->reverse();
}
if (r_path_owners) {
r_path_owners->reverse();
}
} }
// Ensure post conditions (path arrays MUST match in size).
CRASH_COND(r_path_types && path.size() != r_path_types->size());
CRASH_COND(r_path_rids && path.size() != r_path_rids->size());
CRASH_COND(r_path_owners && path.size() != r_path_owners->size());
return path; return path;
} }
@ -837,7 +913,7 @@ void NavMap::dispatch_callbacks() {
} }
} }
void NavMap::clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const { void NavMap::clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly, Vector<int32_t> *r_path_types, TypedArray<RID> *r_path_rids, Vector<int64_t> *r_path_owners) const {
Vector3 from = path[path.size() - 1]; Vector3 from = path[path.size() - 1];
if (from.is_equal_approx(p_to_point)) { if (from.is_equal_approx(p_to_point)) {
@ -863,6 +939,7 @@ void NavMap::clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys
if (cut_plane.intersects_segment(pathway_start, pathway_end, &inters)) { if (cut_plane.intersects_segment(pathway_start, pathway_end, &inters)) {
if (!inters.is_equal_approx(p_to_point) && !inters.is_equal_approx(path[path.size() - 1])) { if (!inters.is_equal_approx(p_to_point) && !inters.is_equal_approx(path[path.size() - 1])) {
path.push_back(inters); path.push_back(inters);
APPEND_METADATA(from_poly->poly);
} }
} }
} }

View file

@ -115,7 +115,7 @@ public:
gd::PointKey get_point_key(const Vector3 &p_pos) const; gd::PointKey get_point_key(const Vector3 &p_pos) const;
Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const; Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers, Vector<int32_t> *r_path_types, TypedArray<RID> *r_path_rids, Vector<int64_t> *r_path_owners) const;
Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const; Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const;
Vector3 get_closest_point(const Vector3 &p_point) const; Vector3 get_closest_point(const Vector3 &p_point) const;
Vector3 get_closest_point_normal(const Vector3 &p_point) const; Vector3 get_closest_point_normal(const Vector3 &p_point) const;
@ -154,7 +154,7 @@ public:
private: private:
void compute_single_step(uint32_t index, RvoAgent **agent); void compute_single_step(uint32_t index, RvoAgent **agent);
void clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const; void clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly, Vector<int32_t> *r_path_types, TypedArray<RID> *r_path_rids, Vector<int64_t> *r_path_owners) const;
}; };
#endif // NAV_MAP_H #endif // NAV_MAP_H

View file

@ -48,7 +48,9 @@ class NavRegion : public NavBase {
LocalVector<gd::Polygon> polygons; LocalVector<gd::Polygon> polygons;
public: public:
NavRegion() {} NavRegion() {
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_REGION;
}
void scratch_polygons() { void scratch_polygons() {
polygons_dirty = true; polygons_dirty = true;

View file

@ -70,6 +70,9 @@ void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationAgent2D::set_navigation_layer_value); ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationAgent2D::set_navigation_layer_value);
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationAgent2D::get_navigation_layer_value); ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationAgent2D::get_navigation_layer_value);
ClassDB::bind_method(D_METHOD("set_path_metadata_flags", "flags"), &NavigationAgent2D::set_path_metadata_flags);
ClassDB::bind_method(D_METHOD("get_path_metadata_flags"), &NavigationAgent2D::get_path_metadata_flags);
ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent2D::set_navigation_map); ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent2D::set_navigation_map);
ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent2D::get_navigation_map); ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent2D::get_navigation_map);
@ -79,6 +82,7 @@ void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent2D::get_next_location); ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent2D::get_next_location);
ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent2D::distance_to_target); ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent2D::distance_to_target);
ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent2D::set_velocity); ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent2D::set_velocity);
ClassDB::bind_method(D_METHOD("get_current_navigation_result"), &NavigationAgent2D::get_current_navigation_result);
ClassDB::bind_method(D_METHOD("get_current_navigation_path"), &NavigationAgent2D::get_current_navigation_path); ClassDB::bind_method(D_METHOD("get_current_navigation_path"), &NavigationAgent2D::get_current_navigation_path);
ClassDB::bind_method(D_METHOD("get_current_navigation_path_index"), &NavigationAgent2D::get_current_navigation_path_index); ClassDB::bind_method(D_METHOD("get_current_navigation_path_index"), &NavigationAgent2D::get_current_navigation_path_index);
ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent2D::is_target_reached); ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent2D::is_target_reached);
@ -94,6 +98,7 @@ void NavigationAgent2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:px"), "set_target_desired_distance", "get_target_desired_distance"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:px"), "set_target_desired_distance", "get_target_desired_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1,suffix:px"), "set_path_max_distance", "get_path_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1,suffix:px"), "set_path_max_distance", "get_path_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
ADD_GROUP("Avoidance", ""); ADD_GROUP("Avoidance", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
@ -105,6 +110,8 @@ void NavigationAgent2D::_bind_methods() {
ADD_SIGNAL(MethodInfo("path_changed")); ADD_SIGNAL(MethodInfo("path_changed"));
ADD_SIGNAL(MethodInfo("target_reached")); ADD_SIGNAL(MethodInfo("target_reached"));
ADD_SIGNAL(MethodInfo("waypoint_reached", PropertyInfo(Variant::DICTIONARY, "details")));
ADD_SIGNAL(MethodInfo("link_reached", PropertyInfo(Variant::DICTIONARY, "details")));
ADD_SIGNAL(MethodInfo("navigation_finished")); ADD_SIGNAL(MethodInfo("navigation_finished"));
ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR2, "safe_velocity"))); ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR2, "safe_velocity")));
} }
@ -256,6 +263,14 @@ bool NavigationAgent2D::get_navigation_layer_value(int p_layer_number) const {
return get_navigation_layers() & (1 << (p_layer_number - 1)); return get_navigation_layers() & (1 << (p_layer_number - 1));
} }
void NavigationAgent2D::set_path_metadata_flags(BitField<NavigationPathQueryParameters2D::PathMetadataFlags> p_path_metadata_flags) {
if (path_metadata_flags == p_path_metadata_flags) {
return;
}
path_metadata_flags = p_path_metadata_flags;
}
void NavigationAgent2D::set_navigation_map(RID p_navigation_map) { void NavigationAgent2D::set_navigation_map(RID p_navigation_map) {
map_override = p_navigation_map; map_override = p_navigation_map;
NavigationServer2D::get_singleton()->agent_set_map(agent, map_override); NavigationServer2D::get_singleton()->agent_set_map(agent, map_override);
@ -333,10 +348,6 @@ Vector2 NavigationAgent2D::get_next_location() {
} }
} }
const Vector<Vector2> &NavigationAgent2D::get_current_navigation_path() const {
return navigation_result->get_path();
}
real_t NavigationAgent2D::distance_to_target() const { real_t NavigationAgent2D::distance_to_target() const {
ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent."); ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent.");
return agent_parent->get_global_position().distance_to(target_location); return agent_parent->get_global_position().distance_to(target_location);
@ -436,6 +447,7 @@ void NavigationAgent2D::update_navigation() {
navigation_query->set_start_position(origin); navigation_query->set_start_position(origin);
navigation_query->set_target_position(target_location); navigation_query->set_target_position(target_location);
navigation_query->set_navigation_layers(navigation_layers); navigation_query->set_navigation_layers(navigation_layers);
navigation_query->set_metadata_flags(path_metadata_flags);
if (map_override.is_valid()) { if (map_override.is_valid()) {
navigation_query->set_map(map_override); navigation_query->set_map(map_override);
@ -457,8 +469,52 @@ void NavigationAgent2D::update_navigation() {
if (navigation_finished == false) { if (navigation_finished == false) {
// Advances to the next far away location. // Advances to the next far away location.
const Vector<Vector2> &navigation_path = navigation_result->get_path(); const Vector<Vector2> &navigation_path = navigation_result->get_path();
const Vector<int32_t> &navigation_path_types = navigation_result->get_path_types();
const TypedArray<RID> &navigation_path_rids = navigation_result->get_path_rids();
const Vector<int64_t> &navigation_path_owners = navigation_result->get_path_owner_ids();
while (origin.distance_to(navigation_path[navigation_path_index]) < path_desired_distance) { while (origin.distance_to(navigation_path[navigation_path_index]) < path_desired_distance) {
Dictionary details;
const Vector2 waypoint = navigation_path[navigation_path_index];
details[SNAME("location")] = waypoint;
int waypoint_type = -1;
if (path_metadata_flags.has_flag(NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_TYPES)) {
const NavigationPathQueryResult2D::PathSegmentType type = NavigationPathQueryResult2D::PathSegmentType(navigation_path_types[navigation_path_index]);
details[SNAME("type")] = type;
waypoint_type = type;
}
if (path_metadata_flags.has_flag(NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_RIDS)) {
details[SNAME("rid")] = navigation_path_rids[navigation_path_index];
}
if (path_metadata_flags.has_flag(NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_OWNERS)) {
const ObjectID waypoint_owner_id = ObjectID(navigation_path_owners[navigation_path_index]);
// Get a reference to the owning object.
Object *owner = nullptr;
if (waypoint_owner_id.is_valid()) {
owner = ObjectDB::get_instance(waypoint_owner_id);
}
details[SNAME("owner")] = owner;
}
// Emit a signal for the waypoint
emit_signal(SNAME("waypoint_reached"), details);
// Emit a signal if we've reached a navigation link
if (waypoint_type == NavigationPathQueryResult2D::PATH_SEGMENT_TYPE_LINK) {
emit_signal(SNAME("link_reached"), details);
}
// Move to the next waypoint on the list
navigation_path_index += 1; navigation_path_index += 1;
// Check to see if we've finished our route
if (navigation_path_index == navigation_path.size()) { if (navigation_path_index == navigation_path.size()) {
_check_distance_to_target(); _check_distance_to_target();
navigation_path_index -= 1; navigation_path_index -= 1;

View file

@ -32,10 +32,10 @@
#define NAVIGATION_AGENT_2D_H #define NAVIGATION_AGENT_2D_H
#include "scene/main/node.h" #include "scene/main/node.h"
#include "servers/navigation/navigation_path_query_parameters_2d.h"
#include "servers/navigation/navigation_path_query_result_2d.h"
class Node2D; class Node2D;
class NavigationPathQueryParameters2D;
class NavigationPathQueryResult2D;
class NavigationAgent2D : public Node { class NavigationAgent2D : public Node {
GDCLASS(NavigationAgent2D, Node); GDCLASS(NavigationAgent2D, Node);
@ -48,6 +48,7 @@ class NavigationAgent2D : public Node {
bool avoidance_enabled = false; bool avoidance_enabled = false;
uint32_t navigation_layers = 1; uint32_t navigation_layers = 1;
BitField<NavigationPathQueryParameters2D::PathMetadataFlags> path_metadata_flags = NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_ALL;
real_t path_desired_distance = 1.0; real_t path_desired_distance = 1.0;
real_t target_desired_distance = 1.0; real_t target_desired_distance = 1.0;
@ -95,6 +96,11 @@ public:
void set_navigation_layer_value(int p_layer_number, bool p_value); void set_navigation_layer_value(int p_layer_number, bool p_value);
bool get_navigation_layer_value(int p_layer_number) const; bool get_navigation_layer_value(int p_layer_number) const;
void set_path_metadata_flags(BitField<NavigationPathQueryParameters2D::PathMetadataFlags> p_flags);
BitField<NavigationPathQueryParameters2D::PathMetadataFlags> get_path_metadata_flags() const {
return path_metadata_flags;
}
void set_navigation_map(RID p_navigation_map); void set_navigation_map(RID p_navigation_map);
RID get_navigation_map() const; RID get_navigation_map() const;
@ -141,8 +147,12 @@ public:
Vector2 get_next_location(); Vector2 get_next_location();
const Vector<Vector2> &get_current_navigation_path() const; Ref<NavigationPathQueryResult2D> get_current_navigation_result() const {
return navigation_result;
}
const Vector<Vector2> &get_current_navigation_path() const {
return navigation_result->get_path();
}
int get_current_navigation_path_index() const { int get_current_navigation_path_index() const {
return navigation_path_index; return navigation_path_index;
} }

View file

@ -74,6 +74,9 @@ void NavigationAgent3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationAgent3D::set_navigation_layer_value); ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationAgent3D::set_navigation_layer_value);
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationAgent3D::get_navigation_layer_value); ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationAgent3D::get_navigation_layer_value);
ClassDB::bind_method(D_METHOD("set_path_metadata_flags", "flags"), &NavigationAgent3D::set_path_metadata_flags);
ClassDB::bind_method(D_METHOD("get_path_metadata_flags"), &NavigationAgent3D::get_path_metadata_flags);
ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent3D::set_navigation_map); ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent3D::set_navigation_map);
ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent3D::get_navigation_map); ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent3D::get_navigation_map);
@ -83,6 +86,7 @@ void NavigationAgent3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent3D::get_next_location); ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent3D::get_next_location);
ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent3D::distance_to_target); ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent3D::distance_to_target);
ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent3D::set_velocity); ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent3D::set_velocity);
ClassDB::bind_method(D_METHOD("get_current_navigation_result"), &NavigationAgent3D::get_current_navigation_result);
ClassDB::bind_method(D_METHOD("get_current_navigation_path"), &NavigationAgent3D::get_current_navigation_path); ClassDB::bind_method(D_METHOD("get_current_navigation_path"), &NavigationAgent3D::get_current_navigation_path);
ClassDB::bind_method(D_METHOD("get_current_navigation_path_index"), &NavigationAgent3D::get_current_navigation_path_index); ClassDB::bind_method(D_METHOD("get_current_navigation_path_index"), &NavigationAgent3D::get_current_navigation_path_index);
ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent3D::is_target_reached); ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent3D::is_target_reached);
@ -99,6 +103,7 @@ void NavigationAgent3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,suffix:m"), "set_agent_height_offset", "get_agent_height_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,suffix:m"), "set_agent_height_offset", "get_agent_height_offset");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1,suffix:m"), "set_path_max_distance", "get_path_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1,suffix:m"), "set_path_max_distance", "get_path_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
ADD_GROUP("Avoidance", ""); ADD_GROUP("Avoidance", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
@ -111,6 +116,8 @@ void NavigationAgent3D::_bind_methods() {
ADD_SIGNAL(MethodInfo("path_changed")); ADD_SIGNAL(MethodInfo("path_changed"));
ADD_SIGNAL(MethodInfo("target_reached")); ADD_SIGNAL(MethodInfo("target_reached"));
ADD_SIGNAL(MethodInfo("waypoint_reached", PropertyInfo(Variant::DICTIONARY, "details")));
ADD_SIGNAL(MethodInfo("link_reached", PropertyInfo(Variant::DICTIONARY, "details")));
ADD_SIGNAL(MethodInfo("navigation_finished")); ADD_SIGNAL(MethodInfo("navigation_finished"));
ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity"))); ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity")));
} }
@ -263,6 +270,14 @@ bool NavigationAgent3D::get_navigation_layer_value(int p_layer_number) const {
return get_navigation_layers() & (1 << (p_layer_number - 1)); return get_navigation_layers() & (1 << (p_layer_number - 1));
} }
void NavigationAgent3D::set_path_metadata_flags(BitField<NavigationPathQueryParameters3D::PathMetadataFlags> p_path_metadata_flags) {
if (path_metadata_flags == p_path_metadata_flags) {
return;
}
path_metadata_flags = p_path_metadata_flags;
}
void NavigationAgent3D::set_navigation_map(RID p_navigation_map) { void NavigationAgent3D::set_navigation_map(RID p_navigation_map) {
map_override = p_navigation_map; map_override = p_navigation_map;
NavigationServer3D::get_singleton()->agent_set_map(agent, map_override); NavigationServer3D::get_singleton()->agent_set_map(agent, map_override);
@ -349,10 +364,6 @@ Vector3 NavigationAgent3D::get_next_location() {
} }
} }
const Vector<Vector3> &NavigationAgent3D::get_current_navigation_path() const {
return navigation_result->get_path();
}
real_t NavigationAgent3D::distance_to_target() const { real_t NavigationAgent3D::distance_to_target() const {
ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent."); ERR_FAIL_COND_V_MSG(agent_parent == nullptr, 0.0, "The agent has no parent.");
return agent_parent->get_global_transform().origin.distance_to(target_location); return agent_parent->get_global_transform().origin.distance_to(target_location);
@ -453,6 +464,7 @@ void NavigationAgent3D::update_navigation() {
navigation_query->set_start_position(origin); navigation_query->set_start_position(origin);
navigation_query->set_target_position(target_location); navigation_query->set_target_position(target_location);
navigation_query->set_navigation_layers(navigation_layers); navigation_query->set_navigation_layers(navigation_layers);
navigation_query->set_metadata_flags(path_metadata_flags);
if (map_override.is_valid()) { if (map_override.is_valid()) {
navigation_query->set_map(map_override); navigation_query->set_map(map_override);
@ -474,8 +486,52 @@ void NavigationAgent3D::update_navigation() {
if (navigation_finished == false) { if (navigation_finished == false) {
// Advances to the next far away location. // Advances to the next far away location.
const Vector<Vector3> &navigation_path = navigation_result->get_path(); const Vector<Vector3> &navigation_path = navigation_result->get_path();
const Vector<int32_t> &navigation_path_types = navigation_result->get_path_types();
const TypedArray<RID> &navigation_path_rids = navigation_result->get_path_rids();
const Vector<int64_t> &navigation_path_owners = navigation_result->get_path_owner_ids();
while (origin.distance_to(navigation_path[navigation_path_index] - Vector3(0, navigation_height_offset, 0)) < path_desired_distance) { while (origin.distance_to(navigation_path[navigation_path_index] - Vector3(0, navigation_height_offset, 0)) < path_desired_distance) {
Dictionary details;
const Vector3 waypoint = navigation_path[navigation_path_index];
details[SNAME("location")] = waypoint;
int waypoint_type = -1;
if (path_metadata_flags.has_flag(NavigationPathQueryParameters3D::PathMetadataFlags::PATH_METADATA_INCLUDE_TYPES)) {
const NavigationPathQueryResult3D::PathSegmentType type = NavigationPathQueryResult3D::PathSegmentType(navigation_path_types[navigation_path_index]);
details[SNAME("type")] = type;
waypoint_type = type;
}
if (path_metadata_flags.has_flag(NavigationPathQueryParameters3D::PathMetadataFlags::PATH_METADATA_INCLUDE_RIDS)) {
details[SNAME("rid")] = navigation_path_rids[navigation_path_index];
}
if (path_metadata_flags.has_flag(NavigationPathQueryParameters3D::PathMetadataFlags::PATH_METADATA_INCLUDE_OWNERS)) {
const ObjectID waypoint_owner_id = ObjectID(navigation_path_owners[navigation_path_index]);
// Get a reference to the owning object.
Object *owner = nullptr;
if (waypoint_owner_id.is_valid()) {
owner = ObjectDB::get_instance(waypoint_owner_id);
}
details[SNAME("owner")] = owner;
}
// Emit a signal for the waypoint
emit_signal(SNAME("waypoint_reached"), details);
// Emit a signal if we've reached a navigation link
if (waypoint_type == NavigationPathQueryResult3D::PATH_SEGMENT_TYPE_LINK) {
emit_signal(SNAME("link_reached"), details);
}
// Move to the next waypoint on the list
navigation_path_index += 1; navigation_path_index += 1;
// Check to see if we've finished our route
if (navigation_path_index == navigation_path.size()) { if (navigation_path_index == navigation_path.size()) {
_check_distance_to_target(); _check_distance_to_target();
navigation_path_index -= 1; navigation_path_index -= 1;

View file

@ -32,10 +32,10 @@
#define NAVIGATION_AGENT_3D_H #define NAVIGATION_AGENT_3D_H
#include "scene/main/node.h" #include "scene/main/node.h"
#include "servers/navigation/navigation_path_query_parameters_3d.h"
#include "servers/navigation/navigation_path_query_result_3d.h"
class Node3D; class Node3D;
class NavigationPathQueryParameters3D;
class NavigationPathQueryResult3D;
class NavigationAgent3D : public Node { class NavigationAgent3D : public Node {
GDCLASS(NavigationAgent3D, Node); GDCLASS(NavigationAgent3D, Node);
@ -48,6 +48,7 @@ class NavigationAgent3D : public Node {
bool avoidance_enabled = false; bool avoidance_enabled = false;
uint32_t navigation_layers = 1; uint32_t navigation_layers = 1;
BitField<NavigationPathQueryParameters3D::PathMetadataFlags> path_metadata_flags = NavigationPathQueryParameters3D::PathMetadataFlags::PATH_METADATA_INCLUDE_ALL;
real_t path_desired_distance = 1.0; real_t path_desired_distance = 1.0;
real_t target_desired_distance = 1.0; real_t target_desired_distance = 1.0;
@ -97,6 +98,11 @@ public:
void set_navigation_layer_value(int p_layer_number, bool p_value); void set_navigation_layer_value(int p_layer_number, bool p_value);
bool get_navigation_layer_value(int p_layer_number) const; bool get_navigation_layer_value(int p_layer_number) const;
void set_path_metadata_flags(BitField<NavigationPathQueryParameters3D::PathMetadataFlags> p_flags);
BitField<NavigationPathQueryParameters3D::PathMetadataFlags> get_path_metadata_flags() const {
return path_metadata_flags;
}
void set_navigation_map(RID p_navigation_map); void set_navigation_map(RID p_navigation_map);
RID get_navigation_map() const; RID get_navigation_map() const;
@ -153,8 +159,12 @@ public:
Vector3 get_next_location(); Vector3 get_next_location();
const Vector<Vector3> &get_current_navigation_path() const; Ref<NavigationPathQueryResult3D> get_current_navigation_result() const {
return navigation_result;
}
const Vector<Vector3> &get_current_navigation_path() const {
return navigation_result->get_path();
}
int get_current_navigation_path_index() const { int get_current_navigation_path_index() const {
return navigation_path_index; return navigation_path_index;
} }

View file

@ -105,11 +105,19 @@ Vector2 NavigationPathQueryParameters2D::get_target_position() const {
void NavigationPathQueryParameters2D::set_navigation_layers(uint32_t p_navigation_layers) { void NavigationPathQueryParameters2D::set_navigation_layers(uint32_t p_navigation_layers) {
parameters.navigation_layers = p_navigation_layers; parameters.navigation_layers = p_navigation_layers;
}; }
uint32_t NavigationPathQueryParameters2D::get_navigation_layers() const { uint32_t NavigationPathQueryParameters2D::get_navigation_layers() const {
return parameters.navigation_layers; return parameters.navigation_layers;
}; }
void NavigationPathQueryParameters2D::set_metadata_flags(BitField<NavigationPathQueryParameters2D::PathMetadataFlags> p_flags) {
parameters.metadata_flags = (int64_t)p_flags;
}
BitField<NavigationPathQueryParameters2D::PathMetadataFlags> NavigationPathQueryParameters2D::get_metadata_flags() const {
return (int64_t)parameters.metadata_flags;
}
void NavigationPathQueryParameters2D::_bind_methods() { void NavigationPathQueryParameters2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters2D::set_pathfinding_algorithm); ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters2D::set_pathfinding_algorithm);
@ -130,15 +138,25 @@ void NavigationPathQueryParameters2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationPathQueryParameters2D::set_navigation_layers); ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationPathQueryParameters2D::set_navigation_layers);
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationPathQueryParameters2D::get_navigation_layers); ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationPathQueryParameters2D::get_navigation_layers);
ClassDB::bind_method(D_METHOD("set_metadata_flags", "flags"), &NavigationPathQueryParameters2D::set_metadata_flags);
ClassDB::bind_method(D_METHOD("get_metadata_flags"), &NavigationPathQueryParameters2D::get_metadata_flags);
ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map"); ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_position"), "set_start_position", "get_start_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_position"), "set_start_position", "get_start_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm"); ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing"); ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
ADD_PROPERTY(PropertyInfo(Variant::INT, "metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_metadata_flags", "get_metadata_flags");
BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR); BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR);
BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_CORRIDORFUNNEL); BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_CORRIDORFUNNEL);
BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_EDGECENTERED); BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_EDGECENTERED);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_NONE);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_TYPES);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_RIDS);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_OWNERS);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_ALL);
} }

View file

@ -52,6 +52,14 @@ public:
PATH_POSTPROCESSING_EDGECENTERED, PATH_POSTPROCESSING_EDGECENTERED,
}; };
enum PathMetadataFlags {
PATH_METADATA_INCLUDE_NONE = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_NONE,
PATH_METADATA_INCLUDE_TYPES = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_TYPES,
PATH_METADATA_INCLUDE_RIDS = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_RIDS,
PATH_METADATA_INCLUDE_OWNERS = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_OWNERS,
PATH_METADATA_INCLUDE_ALL = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_ALL
};
const NavigationUtilities::PathQueryParameters &get_parameters() const { return parameters; } const NavigationUtilities::PathQueryParameters &get_parameters() const { return parameters; }
void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm); void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm);
@ -71,9 +79,13 @@ public:
void set_navigation_layers(uint32_t p_navigation_layers); void set_navigation_layers(uint32_t p_navigation_layers);
uint32_t get_navigation_layers() const; uint32_t get_navigation_layers() const;
void set_metadata_flags(BitField<NavigationPathQueryParameters2D::PathMetadataFlags> p_flags);
BitField<NavigationPathQueryParameters2D::PathMetadataFlags> get_metadata_flags() const;
}; };
VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathfindingAlgorithm); VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathfindingAlgorithm);
VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathPostProcessing); VARIANT_ENUM_CAST(NavigationPathQueryParameters2D::PathPostProcessing);
VARIANT_BITFIELD_CAST(NavigationPathQueryParameters2D::PathMetadataFlags);
#endif // NAVIGATION_PATH_QUERY_PARAMETERS_2D_H #endif // NAVIGATION_PATH_QUERY_PARAMETERS_2D_H

View file

@ -111,6 +111,14 @@ uint32_t NavigationPathQueryParameters3D::get_navigation_layers() const {
return parameters.navigation_layers; return parameters.navigation_layers;
} }
void NavigationPathQueryParameters3D::set_metadata_flags(BitField<NavigationPathQueryParameters3D::PathMetadataFlags> p_flags) {
parameters.metadata_flags = (int64_t)p_flags;
}
BitField<NavigationPathQueryParameters3D::PathMetadataFlags> NavigationPathQueryParameters3D::get_metadata_flags() const {
return (int64_t)parameters.metadata_flags;
}
void NavigationPathQueryParameters3D::_bind_methods() { void NavigationPathQueryParameters3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters3D::set_pathfinding_algorithm); ClassDB::bind_method(D_METHOD("set_pathfinding_algorithm", "pathfinding_algorithm"), &NavigationPathQueryParameters3D::set_pathfinding_algorithm);
ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationPathQueryParameters3D::get_pathfinding_algorithm); ClassDB::bind_method(D_METHOD("get_pathfinding_algorithm"), &NavigationPathQueryParameters3D::get_pathfinding_algorithm);
@ -130,15 +138,25 @@ void NavigationPathQueryParameters3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationPathQueryParameters3D::set_navigation_layers); ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationPathQueryParameters3D::set_navigation_layers);
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationPathQueryParameters3D::get_navigation_layers); ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationPathQueryParameters3D::get_navigation_layers);
ClassDB::bind_method(D_METHOD("set_metadata_flags", "flags"), &NavigationPathQueryParameters3D::set_metadata_flags);
ClassDB::bind_method(D_METHOD("get_metadata_flags"), &NavigationPathQueryParameters3D::get_metadata_flags);
ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map"); ADD_PROPERTY(PropertyInfo(Variant::RID, "map"), "set_map", "get_map");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_position"), "set_start_position", "get_start_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_position"), "set_start_position", "get_start_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm"); ADD_PROPERTY(PropertyInfo(Variant::INT, "pathfinding_algorithm", PROPERTY_HINT_ENUM, "AStar"), "set_pathfinding_algorithm", "get_pathfinding_algorithm");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing"); ADD_PROPERTY(PropertyInfo(Variant::INT, "path_postprocessing", PROPERTY_HINT_ENUM, "Corridorfunnel,Edgecentered"), "set_path_postprocessing", "get_path_postprocessing");
ADD_PROPERTY(PropertyInfo(Variant::INT, "metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_metadata_flags", "get_metadata_flags");
BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR); BIND_ENUM_CONSTANT(PATHFINDING_ALGORITHM_ASTAR);
BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_CORRIDORFUNNEL); BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_CORRIDORFUNNEL);
BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_EDGECENTERED); BIND_ENUM_CONSTANT(PATH_POSTPROCESSING_EDGECENTERED);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_NONE);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_TYPES);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_RIDS);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_OWNERS);
BIND_BITFIELD_FLAG(PATH_METADATA_INCLUDE_ALL);
} }

View file

@ -52,6 +52,14 @@ public:
PATH_POSTPROCESSING_EDGECENTERED, PATH_POSTPROCESSING_EDGECENTERED,
}; };
enum PathMetadataFlags {
PATH_METADATA_INCLUDE_NONE = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_NONE,
PATH_METADATA_INCLUDE_TYPES = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_TYPES,
PATH_METADATA_INCLUDE_RIDS = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_RIDS,
PATH_METADATA_INCLUDE_OWNERS = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_OWNERS,
PATH_METADATA_INCLUDE_ALL = NavigationUtilities::PathMetadataFlags::PATH_INCLUDE_ALL
};
const NavigationUtilities::PathQueryParameters &get_parameters() const { return parameters; } const NavigationUtilities::PathQueryParameters &get_parameters() const { return parameters; }
void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm); void set_pathfinding_algorithm(const PathfindingAlgorithm p_pathfinding_algorithm);
@ -71,9 +79,13 @@ public:
void set_navigation_layers(uint32_t p_navigation_layers); void set_navigation_layers(uint32_t p_navigation_layers);
uint32_t get_navigation_layers() const; uint32_t get_navigation_layers() const;
void set_metadata_flags(BitField<NavigationPathQueryParameters3D::PathMetadataFlags> p_flags);
BitField<NavigationPathQueryParameters3D::PathMetadataFlags> get_metadata_flags() const;
}; };
VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathfindingAlgorithm); VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathfindingAlgorithm);
VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathPostProcessing); VARIANT_ENUM_CAST(NavigationPathQueryParameters3D::PathPostProcessing);
VARIANT_BITFIELD_CAST(NavigationPathQueryParameters3D::PathMetadataFlags);
#endif // NAVIGATION_PATH_QUERY_PARAMETERS_3D_H #endif // NAVIGATION_PATH_QUERY_PARAMETERS_3D_H

View file

@ -38,15 +38,57 @@ const Vector<Vector2> &NavigationPathQueryResult2D::get_path() const {
return path; return path;
} }
void NavigationPathQueryResult2D::set_path_types(const Vector<int32_t> &p_path_types) {
path_types = p_path_types;
}
const Vector<int32_t> &NavigationPathQueryResult2D::get_path_types() const {
return path_types;
}
void NavigationPathQueryResult2D::set_path_rids(const TypedArray<RID> &p_path_rids) {
path_rids = p_path_rids;
}
TypedArray<RID> NavigationPathQueryResult2D::get_path_rids() const {
return path_rids;
}
void NavigationPathQueryResult2D::set_path_owner_ids(const Vector<int64_t> &p_path_owner_ids) {
path_owner_ids = p_path_owner_ids;
}
const Vector<int64_t> &NavigationPathQueryResult2D::get_path_owner_ids() const {
return path_owner_ids;
}
void NavigationPathQueryResult2D::reset() { void NavigationPathQueryResult2D::reset() {
path.clear(); path.clear();
path_types.clear();
path_rids.clear();
path_owner_ids.clear();
} }
void NavigationPathQueryResult2D::_bind_methods() { void NavigationPathQueryResult2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult2D::set_path); ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult2D::set_path);
ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult2D::get_path); ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult2D::get_path);
ClassDB::bind_method(D_METHOD("set_path_types", "path_types"), &NavigationPathQueryResult2D::set_path_types);
ClassDB::bind_method(D_METHOD("get_path_types"), &NavigationPathQueryResult2D::get_path_types);
ClassDB::bind_method(D_METHOD("set_path_rids", "path_rids"), &NavigationPathQueryResult2D::set_path_rids);
ClassDB::bind_method(D_METHOD("get_path_rids"), &NavigationPathQueryResult2D::get_path_rids);
ClassDB::bind_method(D_METHOD("set_path_owner_ids", "path_owner_ids"), &NavigationPathQueryResult2D::set_path_owner_ids);
ClassDB::bind_method(D_METHOD("get_path_owner_ids"), &NavigationPathQueryResult2D::get_path_owner_ids);
ClassDB::bind_method(D_METHOD("reset"), &NavigationPathQueryResult2D::reset); ClassDB::bind_method(D_METHOD("reset"), &NavigationPathQueryResult2D::reset);
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "path"), "set_path", "get_path"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "path"), "set_path", "get_path");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "path_types"), "set_path_types", "get_path_types");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "path_rids", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_path_rids", "get_path_rids");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT64_ARRAY, "path_owner_ids"), "set_path_owner_ids", "get_path_owner_ids");
BIND_ENUM_CONSTANT(PATH_SEGMENT_TYPE_REGION);
BIND_ENUM_CONSTANT(PATH_SEGMENT_TYPE_LINK);
} }

View file

@ -38,15 +38,34 @@ class NavigationPathQueryResult2D : public RefCounted {
GDCLASS(NavigationPathQueryResult2D, RefCounted); GDCLASS(NavigationPathQueryResult2D, RefCounted);
Vector<Vector2> path; Vector<Vector2> path;
Vector<int32_t> path_types;
TypedArray<RID> path_rids;
Vector<int64_t> path_owner_ids;
protected: protected:
static void _bind_methods(); static void _bind_methods();
public: public:
enum PathSegmentType {
PATH_SEGMENT_TYPE_REGION = 0,
PATH_SEGMENT_TYPE_LINK = 1,
};
void set_path(const Vector<Vector2> &p_path); void set_path(const Vector<Vector2> &p_path);
const Vector<Vector2> &get_path() const; const Vector<Vector2> &get_path() const;
void set_path_types(const Vector<int32_t> &p_path_types);
const Vector<int32_t> &get_path_types() const;
void set_path_rids(const TypedArray<RID> &p_path_rids);
TypedArray<RID> get_path_rids() const;
void set_path_owner_ids(const Vector<int64_t> &p_path_owner_ids);
const Vector<int64_t> &get_path_owner_ids() const;
void reset(); void reset();
}; };
VARIANT_ENUM_CAST(NavigationPathQueryResult2D::PathSegmentType);
#endif // NAVIGATION_PATH_QUERY_RESULT_2D_H #endif // NAVIGATION_PATH_QUERY_RESULT_2D_H

View file

@ -38,15 +38,57 @@ const Vector<Vector3> &NavigationPathQueryResult3D::get_path() const {
return path; return path;
} }
void NavigationPathQueryResult3D::set_path_types(const Vector<int32_t> &p_path_types) {
path_types = p_path_types;
}
const Vector<int32_t> &NavigationPathQueryResult3D::get_path_types() const {
return path_types;
}
void NavigationPathQueryResult3D::set_path_rids(const TypedArray<RID> &p_path_rids) {
path_rids = p_path_rids;
}
TypedArray<RID> NavigationPathQueryResult3D::get_path_rids() const {
return path_rids;
}
void NavigationPathQueryResult3D::set_path_owner_ids(const Vector<int64_t> &p_path_owner_ids) {
path_owner_ids = p_path_owner_ids;
}
const Vector<int64_t> &NavigationPathQueryResult3D::get_path_owner_ids() const {
return path_owner_ids;
}
void NavigationPathQueryResult3D::reset() { void NavigationPathQueryResult3D::reset() {
path.clear(); path.clear();
path_types.clear();
path_rids.clear();
path_owner_ids.clear();
} }
void NavigationPathQueryResult3D::_bind_methods() { void NavigationPathQueryResult3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult3D::set_path); ClassDB::bind_method(D_METHOD("set_path", "path"), &NavigationPathQueryResult3D::set_path);
ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult3D::get_path); ClassDB::bind_method(D_METHOD("get_path"), &NavigationPathQueryResult3D::get_path);
ClassDB::bind_method(D_METHOD("set_path_types", "path_types"), &NavigationPathQueryResult3D::set_path_types);
ClassDB::bind_method(D_METHOD("get_path_types"), &NavigationPathQueryResult3D::get_path_types);
ClassDB::bind_method(D_METHOD("set_path_rids", "path_rids"), &NavigationPathQueryResult3D::set_path_rids);
ClassDB::bind_method(D_METHOD("get_path_rids"), &NavigationPathQueryResult3D::get_path_rids);
ClassDB::bind_method(D_METHOD("set_path_owner_ids", "path_owner_ids"), &NavigationPathQueryResult3D::set_path_owner_ids);
ClassDB::bind_method(D_METHOD("get_path_owner_ids"), &NavigationPathQueryResult3D::get_path_owner_ids);
ClassDB::bind_method(D_METHOD("reset"), &NavigationPathQueryResult3D::reset); ClassDB::bind_method(D_METHOD("reset"), &NavigationPathQueryResult3D::reset);
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "path"), "set_path", "get_path"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "path"), "set_path", "get_path");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "path_types"), "set_path_types", "get_path_types");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "path_rids", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_path_rids", "get_path_rids");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT64_ARRAY, "path_owner_ids"), "set_path_owner_ids", "get_path_owner_ids");
BIND_ENUM_CONSTANT(PATH_SEGMENT_TYPE_REGION);
BIND_ENUM_CONSTANT(PATH_SEGMENT_TYPE_LINK);
} }

View file

@ -32,21 +32,41 @@
#define NAVIGATION_PATH_QUERY_RESULT_3D_H #define NAVIGATION_PATH_QUERY_RESULT_3D_H
#include "core/object/ref_counted.h" #include "core/object/ref_counted.h"
#include "core/variant/typed_array.h"
#include "servers/navigation/navigation_utilities.h" #include "servers/navigation/navigation_utilities.h"
class NavigationPathQueryResult3D : public RefCounted { class NavigationPathQueryResult3D : public RefCounted {
GDCLASS(NavigationPathQueryResult3D, RefCounted); GDCLASS(NavigationPathQueryResult3D, RefCounted);
Vector<Vector3> path; Vector<Vector3> path;
Vector<int32_t> path_types;
TypedArray<RID> path_rids;
Vector<int64_t> path_owner_ids;
protected: protected:
static void _bind_methods(); static void _bind_methods();
public: public:
enum PathSegmentType {
PATH_SEGMENT_TYPE_REGION = 0,
PATH_SEGMENT_TYPE_LINK = 1,
};
void set_path(const Vector<Vector3> &p_path); void set_path(const Vector<Vector3> &p_path);
const Vector<Vector3> &get_path() const; const Vector<Vector3> &get_path() const;
void set_path_types(const Vector<int32_t> &p_path_types);
const Vector<int32_t> &get_path_types() const;
void set_path_rids(const TypedArray<RID> &p_path_rids);
TypedArray<RID> get_path_rids() const;
void set_path_owner_ids(const Vector<int64_t> &p_path_owner_ids);
const Vector<int64_t> &get_path_owner_ids() const;
void reset(); void reset();
}; };
VARIANT_ENUM_CAST(NavigationPathQueryResult3D::PathSegmentType);
#endif // NAVIGATION_PATH_QUERY_RESULT_3D_H #endif // NAVIGATION_PATH_QUERY_RESULT_3D_H

View file

@ -32,6 +32,7 @@
#define NAVIGATION_UTILITIES_H #define NAVIGATION_UTILITIES_H
#include "core/math/vector3.h" #include "core/math/vector3.h"
#include "core/variant/typed_array.h"
namespace NavigationUtilities { namespace NavigationUtilities {
@ -44,6 +45,19 @@ enum PathPostProcessing {
PATH_POSTPROCESSING_EDGECENTERED, PATH_POSTPROCESSING_EDGECENTERED,
}; };
enum PathSegmentType {
PATH_SEGMENT_TYPE_REGION = 0,
PATH_SEGMENT_TYPE_LINK
};
enum PathMetadataFlags {
PATH_INCLUDE_NONE = 0,
PATH_INCLUDE_TYPES = 1,
PATH_INCLUDE_RIDS = 2,
PATH_INCLUDE_OWNERS = 4,
PATH_INCLUDE_ALL = PATH_INCLUDE_TYPES | PATH_INCLUDE_RIDS | PATH_INCLUDE_OWNERS
};
struct PathQueryParameters { struct PathQueryParameters {
PathfindingAlgorithm pathfinding_algorithm = PATHFINDING_ALGORITHM_ASTAR; PathfindingAlgorithm pathfinding_algorithm = PATHFINDING_ALGORITHM_ASTAR;
PathPostProcessing path_postprocessing = PATH_POSTPROCESSING_CORRIDORFUNNEL; PathPostProcessing path_postprocessing = PATH_POSTPROCESSING_CORRIDORFUNNEL;
@ -51,10 +65,14 @@ struct PathQueryParameters {
Vector3 start_position; Vector3 start_position;
Vector3 target_position; Vector3 target_position;
uint32_t navigation_layers = 1; uint32_t navigation_layers = 1;
BitField<PathMetadataFlags> metadata_flags = PATH_INCLUDE_ALL;
}; };
struct PathQueryResult { struct PathQueryResult {
Vector<Vector3> path; Vector<Vector3> path;
Vector<int32_t> path_types;
TypedArray<RID> path_rids;
Vector<int64_t> path_owner_ids;
}; };
} //namespace NavigationUtilities } //namespace NavigationUtilities

View file

@ -427,4 +427,7 @@ void NavigationServer2D::query_path(const Ref<NavigationPathQueryParameters2D> &
const NavigationUtilities::PathQueryResult _query_result = NavigationServer3D::get_singleton()->_query_path(p_query_parameters->get_parameters()); const NavigationUtilities::PathQueryResult _query_result = NavigationServer3D::get_singleton()->_query_path(p_query_parameters->get_parameters());
p_query_result->set_path(vector_v3_to_v2(_query_result.path)); p_query_result->set_path(vector_v3_to_v2(_query_result.path));
p_query_result->set_path_types(_query_result.path_types);
p_query_result->set_path_rids(_query_result.path_rids);
p_query_result->set_path_owner_ids(_query_result.path_owner_ids);
} }

View file

@ -491,4 +491,7 @@ void NavigationServer3D::query_path(const Ref<NavigationPathQueryParameters3D> &
const NavigationUtilities::PathQueryResult _query_result = _query_path(p_query_parameters->get_parameters()); const NavigationUtilities::PathQueryResult _query_result = _query_path(p_query_parameters->get_parameters());
p_query_result->set_path(_query_result.path); p_query_result->set_path(_query_result.path);
p_query_result->set_path_types(_query_result.path_types);
p_query_result->set_path_rids(_query_result.path_rids);
p_query_result->set_path_owner_ids(_query_result.path_owner_ids);
} }