mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-30 21:09:19 +01:00
Backported from godot4: Added node for Navigation links .
- DarkKilauea
3dd59013f4
This commit is contained in:
parent
f6e65112d7
commit
0438c3cc3f
@ -133,6 +133,117 @@
|
|||||||
Returns all created navigation map [RID]s on the NavigationServer. This returns both 2D and 3D created navigation maps as there is technically no distinction between them.
|
Returns all created navigation map [RID]s on the NavigationServer. This returns both 2D and 3D created navigation maps as there is technically no distinction between them.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="link_create" qualifiers="const">
|
||||||
|
<return type="RID" />
|
||||||
|
<description>
|
||||||
|
Create a new link between two locations on a map.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_end_location" qualifiers="const">
|
||||||
|
<return type="Vector2" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the ending location of this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_enter_cost" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the [code]enter_cost[/code] of this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_map" qualifiers="const">
|
||||||
|
<return type="RID" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the navigation map [RID] the requested [code]link[/code] is currently assigned to.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_navigation_layers" qualifiers="const">
|
||||||
|
<return type="int" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the navigation layers for this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_start_location" qualifiers="const">
|
||||||
|
<return type="Vector2" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the starting location of this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_travel_cost" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the [code]travel_cost[/code] of this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_is_bidirectional" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns whether this [code]link[/code] can be travelled in both directions.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_bidirectional" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="bidirectional" type="bool" />
|
||||||
|
<description>
|
||||||
|
Sets whether this [code]link[/code] can be travelled in both directions.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_end_location" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="location" type="Vector2" />
|
||||||
|
<description>
|
||||||
|
Sets the exit location for the [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_enter_cost" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="enter_cost" type="float" />
|
||||||
|
<description>
|
||||||
|
Sets the [code]enter_cost[/code] for this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_map" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="map" type="RID" />
|
||||||
|
<description>
|
||||||
|
Sets the navigation map [RID] for the link.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_navigation_layers" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="navigation_layers" type="int" />
|
||||||
|
<description>
|
||||||
|
Set the links's navigation layers. This allows selecting links from a path request (when using [method NavigationServer2D.map_get_path]).
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_start_location" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="location" type="Vector2" />
|
||||||
|
<description>
|
||||||
|
Sets the entry location for this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_travel_cost" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="travel_cost" type="float" />
|
||||||
|
<description>
|
||||||
|
Sets the [code]travel_cost[/code] for this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="map_create" qualifiers="const">
|
<method name="map_create" qualifiers="const">
|
||||||
<return type="RID" />
|
<return type="RID" />
|
||||||
<description>
|
<description>
|
||||||
@ -193,6 +304,20 @@
|
|||||||
Returns the edge connection margin of the map. The edge connection margin is a distance used to connect two regions.
|
Returns the edge connection margin of the map. The edge connection margin is a distance used to connect two regions.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="map_get_link_connection_radius" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="map" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the link connection radius of the map. This distance is the maximum range any link will search for navigation mesh polygons to connect to.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="map_get_links" qualifiers="const">
|
||||||
|
<return type="RID[]" />
|
||||||
|
<param index="0" name="map" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns all navigation link [RID]s that are currently assigned to the requested navigation [code]map[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="map_get_path" qualifiers="const">
|
<method name="map_get_path" qualifiers="const">
|
||||||
<return type="PoolVector2Array" />
|
<return type="PoolVector2Array" />
|
||||||
<argument index="0" name="map" type="RID" />
|
<argument index="0" name="map" type="RID" />
|
||||||
@ -258,6 +383,14 @@
|
|||||||
Queries a path in a given navigation map. Start and target position and other parameters are defined through [NavigationPathQueryParameters2D]. Updates the provided [NavigationPathQueryResult2D] result object with the path among other results requested by the query.
|
Queries a path in a given navigation map. Start and target position and other parameters are defined through [NavigationPathQueryParameters2D]. Updates the provided [NavigationPathQueryResult2D] result object with the path among other results requested by the query.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="map_set_link_connection_radius" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="map" type="RID" />
|
||||||
|
<param index="1" name="radius" type="float" />
|
||||||
|
<description>
|
||||||
|
Set the map's link connection radius used to connect links to navigation polygons.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="region_create" qualifiers="const">
|
<method name="region_create" qualifiers="const">
|
||||||
<return type="RID" />
|
<return type="RID" />
|
||||||
<description>
|
<description>
|
||||||
|
82
doc/classes/NavigationLink2D.xml
Normal file
82
doc/classes/NavigationLink2D.xml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<class name="NavigationLink2D" inherits="Node2D" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
|
||||||
|
<brief_description>
|
||||||
|
A link between two positions on [NavigationRegion2D]s that agents can be routed through.
|
||||||
|
</brief_description>
|
||||||
|
<description>
|
||||||
|
A link between two positions on [NavigationRegion2D]s that agents can be routed through. These positions can be on the same [NavigationRegion2D] or on two different ones. Links are useful to express navigation methods other than traveling along the surface of the navigation polygon, such as ziplines, teleporters, or gaps that can be jumped across.
|
||||||
|
</description>
|
||||||
|
<tutorials>
|
||||||
|
<link title="Using NavigationLinks">$DOCS_URL/tutorials/navigation/navigation_using_navigationlinks.html</link>
|
||||||
|
</tutorials>
|
||||||
|
<methods>
|
||||||
|
<method name="get_global_end_position" qualifiers="const">
|
||||||
|
<return type="Vector2" />
|
||||||
|
<description>
|
||||||
|
Returns the [member end_position] that is relative to the link as a global position.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="get_global_start_position" qualifiers="const">
|
||||||
|
<return type="Vector2" />
|
||||||
|
<description>
|
||||||
|
Returns the [member start_position] that is relative to the link as a global position.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="get_navigation_layer_value" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="layer_number" type="int" />
|
||||||
|
<description>
|
||||||
|
Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [param layer_number] between 1 and 32.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="set_global_end_position">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="position" type="Vector2" />
|
||||||
|
<description>
|
||||||
|
Sets the [member end_position] that is relative to the link from a global [param position].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="set_global_start_position">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="position" type="Vector2" />
|
||||||
|
<description>
|
||||||
|
Sets the [member start_position] that is relative to the link from a global [param position].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="set_navigation_layer_value">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="layer_number" type="int" />
|
||||||
|
<param index="1" name="value" type="bool" />
|
||||||
|
<description>
|
||||||
|
Based on [param value], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [param layer_number] between 1 and 32.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
</methods>
|
||||||
|
<members>
|
||||||
|
<member name="bidirectional" type="bool" setter="set_bidirectional" getter="is_bidirectional" default="true">
|
||||||
|
Whether this link can be traveled in both directions or only from [member start_position] to [member end_position].
|
||||||
|
</member>
|
||||||
|
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
|
||||||
|
Whether this link is currently active. If [code]false[/code], [method NavigationServer2D.map_get_path] will ignore this link.
|
||||||
|
</member>
|
||||||
|
<member name="end_position" type="Vector2" setter="set_end_position" getter="get_end_position" default="Vector2(0, 0)">
|
||||||
|
Ending position of the link.
|
||||||
|
This position will search out the nearest polygon in the navigation mesh to attach to.
|
||||||
|
The distance the link will search is controlled by [method NavigationServer2D.map_set_link_connection_radius].
|
||||||
|
</member>
|
||||||
|
<member name="enter_cost" type="float" setter="set_enter_cost" getter="get_enter_cost" default="0.0">
|
||||||
|
When pathfinding enters this link from another regions navigation mesh the [member enter_cost] value is added to the path distance for determining the shortest path.
|
||||||
|
</member>
|
||||||
|
<member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1">
|
||||||
|
A bitfield determining all navigation layers the link belongs to. These navigation layers will be checked when requesting a path with [method NavigationServer2D.map_get_path].
|
||||||
|
</member>
|
||||||
|
<member name="start_position" type="Vector2" setter="set_start_position" getter="get_start_position" default="Vector2(0, 0)">
|
||||||
|
Starting position of the link.
|
||||||
|
This position will search out the nearest polygon in the navigation mesh to attach to.
|
||||||
|
The distance the link will search is controlled by [method NavigationServer2D.map_set_link_connection_radius].
|
||||||
|
</member>
|
||||||
|
<member name="travel_cost" type="float" setter="set_travel_cost" getter="get_travel_cost" default="1.0">
|
||||||
|
When pathfinding moves along the link the traveled distance is multiplied with [member travel_cost] for determining the shortest path.
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</class>
|
82
doc/classes/NavigationLink3D.xml
Normal file
82
doc/classes/NavigationLink3D.xml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<class name="NavigationLink3D" inherits="Node3D" is_experimental="true" version="4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
|
||||||
|
<brief_description>
|
||||||
|
A link between two positions on [NavigationRegion3D]s that agents can be routed through.
|
||||||
|
</brief_description>
|
||||||
|
<description>
|
||||||
|
A link between two positions on [NavigationRegion3D]s that agents can be routed through. These positions can be on the same [NavigationRegion3D] or on two different ones. Links are useful to express navigation methods other than traveling along the surface of the navigation mesh, such as ziplines, teleporters, or gaps that can be jumped across.
|
||||||
|
</description>
|
||||||
|
<tutorials>
|
||||||
|
<link title="Using NavigationLinks">$DOCS_URL/tutorials/navigation/navigation_using_navigationlinks.html</link>
|
||||||
|
</tutorials>
|
||||||
|
<methods>
|
||||||
|
<method name="get_global_end_position" qualifiers="const">
|
||||||
|
<return type="Vector3" />
|
||||||
|
<description>
|
||||||
|
Returns the [member end_position] that is relative to the link as a global position.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="get_global_start_position" qualifiers="const">
|
||||||
|
<return type="Vector3" />
|
||||||
|
<description>
|
||||||
|
Returns the [member start_position] that is relative to the link as a global position.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="get_navigation_layer_value" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="layer_number" type="int" />
|
||||||
|
<description>
|
||||||
|
Returns whether or not the specified layer of the [member navigation_layers] bitmask is enabled, given a [param layer_number] between 1 and 32.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="set_global_end_position">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="position" type="Vector3" />
|
||||||
|
<description>
|
||||||
|
Sets the [member end_position] that is relative to the link from a global [param position].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="set_global_start_position">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="position" type="Vector3" />
|
||||||
|
<description>
|
||||||
|
Sets the [member start_position] that is relative to the link from a global [param position].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="set_navigation_layer_value">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="layer_number" type="int" />
|
||||||
|
<param index="1" name="value" type="bool" />
|
||||||
|
<description>
|
||||||
|
Based on [param value], enables or disables the specified layer in the [member navigation_layers] bitmask, given a [param layer_number] between 1 and 32.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
</methods>
|
||||||
|
<members>
|
||||||
|
<member name="bidirectional" type="bool" setter="set_bidirectional" getter="is_bidirectional" default="true">
|
||||||
|
Whether this link can be traveled in both directions or only from [member start_position] to [member end_position].
|
||||||
|
</member>
|
||||||
|
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
|
||||||
|
Whether this link is currently active. If [code]false[/code], [method NavigationServer3D.map_get_path] will ignore this link.
|
||||||
|
</member>
|
||||||
|
<member name="end_position" type="Vector3" setter="set_end_position" getter="get_end_position" default="Vector3(0, 0, 0)">
|
||||||
|
Ending position of the link.
|
||||||
|
This position will search out the nearest polygon in the navigation mesh to attach to.
|
||||||
|
The distance the link will search is controlled by [method NavigationServer3D.map_set_link_connection_radius].
|
||||||
|
</member>
|
||||||
|
<member name="enter_cost" type="float" setter="set_enter_cost" getter="get_enter_cost" default="0.0">
|
||||||
|
When pathfinding enters this link from another regions navigation mesh the [member enter_cost] value is added to the path distance for determining the shortest path.
|
||||||
|
</member>
|
||||||
|
<member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1">
|
||||||
|
A bitfield determining all navigation layers the link belongs to. These navigation layers will be checked when requesting a path with [method NavigationServer3D.map_get_path].
|
||||||
|
</member>
|
||||||
|
<member name="start_position" type="Vector3" setter="set_start_position" getter="get_start_position" default="Vector3(0, 0, 0)">
|
||||||
|
Starting position of the link.
|
||||||
|
This position will search out the nearest polygon in the navigation mesh to attach to.
|
||||||
|
The distance the link will search is controlled by [method NavigationServer3D.map_set_link_connection_radius].
|
||||||
|
</member>
|
||||||
|
<member name="travel_cost" type="float" setter="set_travel_cost" getter="get_travel_cost" default="1.0">
|
||||||
|
When pathfinding moves along the link the traveled distance is multiplied with [member travel_cost] for determining the shortest path.
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</class>
|
@ -133,6 +133,117 @@
|
|||||||
Returns all created navigation map [RID]s on the NavigationServer. This returns both 2D and 3D created navigation maps as there is technically no distinction between them.
|
Returns all created navigation map [RID]s on the NavigationServer. This returns both 2D and 3D created navigation maps as there is technically no distinction between them.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="link_create" qualifiers="const">
|
||||||
|
<return type="RID" />
|
||||||
|
<description>
|
||||||
|
Create a new link between two locations on a map.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_end_location" qualifiers="const">
|
||||||
|
<return type="Vector3" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the ending location of this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_enter_cost" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the [code]enter_cost[/code] of this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_map" qualifiers="const">
|
||||||
|
<return type="RID" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the navigation map [RID] the requested [code]link[/code] is currently assigned to.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_navigation_layers" qualifiers="const">
|
||||||
|
<return type="int" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the navigation layers for this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_start_location" qualifiers="const">
|
||||||
|
<return type="Vector3" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the starting location of this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_get_travel_cost" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the [code]travel_cost[/code] of this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_is_bidirectional" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns whether this [code]link[/code] can be travelled in both directions.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_bidirectional" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="bidirectional" type="bool" />
|
||||||
|
<description>
|
||||||
|
Sets whether this [code]link[/code] can be travelled in both directions.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_end_location" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="location" type="Vector3" />
|
||||||
|
<description>
|
||||||
|
Sets the exit location for the [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_enter_cost" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="enter_cost" type="float" />
|
||||||
|
<description>
|
||||||
|
Sets the [code]enter_cost[/code] for this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_map" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="map" type="RID" />
|
||||||
|
<description>
|
||||||
|
Sets the navigation map [RID] for the link.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_navigation_layers" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="navigation_layers" type="int" />
|
||||||
|
<description>
|
||||||
|
Set the links's navigation layers. This allows selecting links from a path request (when using [method NavigationServer3D.map_get_path]).
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_start_location" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="location" type="Vector3" />
|
||||||
|
<description>
|
||||||
|
Sets the entry location for this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="link_set_travel_cost" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="link" type="RID" />
|
||||||
|
<param index="1" name="travel_cost" type="float" />
|
||||||
|
<description>
|
||||||
|
Sets the [code]travel_cost[/code] for this [code]link[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="map_create" qualifiers="const">
|
<method name="map_create" qualifiers="const">
|
||||||
<return type="RID" />
|
<return type="RID" />
|
||||||
<description>
|
<description>
|
||||||
@ -211,6 +322,20 @@
|
|||||||
Returns the edge connection margin of the map. This distance is the minimum vertex distance needed to connect two edges from different regions.
|
Returns the edge connection margin of the map. This distance is the minimum vertex distance needed to connect two edges from different regions.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="map_get_link_connection_radius" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="map" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns the link connection radius of the map. This distance is the maximum range any link will search for navigation mesh polygons to connect to.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="map_get_links" qualifiers="const">
|
||||||
|
<return type="RID[]" />
|
||||||
|
<param index="0" name="map" type="RID" />
|
||||||
|
<description>
|
||||||
|
Returns all navigation link [RID]s that are currently assigned to the requested navigation [code]map[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="map_get_path" qualifiers="const">
|
<method name="map_get_path" qualifiers="const">
|
||||||
<return type="PoolVector3Array" />
|
<return type="PoolVector3Array" />
|
||||||
<argument index="0" name="map" type="RID" />
|
<argument index="0" name="map" type="RID" />
|
||||||
@ -275,6 +400,14 @@
|
|||||||
Set the map edge connection margin used to weld the compatible region edges.
|
Set the map edge connection margin used to weld the compatible region edges.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="map_set_link_connection_radius" qualifiers="const">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="map" type="RID" />
|
||||||
|
<param index="1" name="radius" type="float" />
|
||||||
|
<description>
|
||||||
|
Set the map's link connection radius used to connect links to navigation polygons.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="map_set_up" qualifiers="const">
|
<method name="map_set_up" qualifiers="const">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<argument index="0" name="map" type="RID" />
|
<argument index="0" name="map" type="RID" />
|
||||||
|
@ -547,6 +547,12 @@
|
|||||||
<member name="debug/shapes/navigation/enable_geometry_face_random_color" type="bool" setter="" getter="" default="true">
|
<member name="debug/shapes/navigation/enable_geometry_face_random_color" type="bool" setter="" getter="" default="true">
|
||||||
If enabled, colorizes each navigation mesh polygon face with a random color when "Visible Navigation" is enabled in the Debug menu.
|
If enabled, colorizes each navigation mesh polygon face with a random color when "Visible Navigation" is enabled in the Debug menu.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="debug/shapes/navigation/enable_link_connections" type="bool" setter="" getter="" default="true">
|
||||||
|
If enabled, displays navigation link connections when "Visible Navigation" is enabled in the Debug menu.
|
||||||
|
</member>
|
||||||
|
<member name="debug/shapes/navigation/enable_link_connections_xray" type="bool" setter="" getter="" default="true">
|
||||||
|
If enabled, displays navigation link connections through geometry when "Visible Navigation" is enabled in the Debug menu.
|
||||||
|
</member>
|
||||||
<member name="debug/shapes/navigation/geometry_edge_color" type="Color" setter="" getter="" default="Color(0.5, 1, 1, 1)">
|
<member name="debug/shapes/navigation/geometry_edge_color" type="Color" setter="" getter="" default="Color(0.5, 1, 1, 1)">
|
||||||
Color to display enabled navigation mesh polygon edges, visible when "Visible Navigation" is enabled in the Debug menu.
|
Color to display enabled navigation mesh polygon edges, visible when "Visible Navigation" is enabled in the Debug menu.
|
||||||
</member>
|
</member>
|
||||||
@ -559,6 +565,12 @@
|
|||||||
<member name="debug/shapes/navigation/geometry_face_disabled_color" type="Color" setter="" getter="" default="Color(0.5, 0.5, 0.5, 0.4)">
|
<member name="debug/shapes/navigation/geometry_face_disabled_color" type="Color" setter="" getter="" default="Color(0.5, 0.5, 0.5, 0.4)">
|
||||||
Color to display disabled navigation mesh polygon faces, visible when "Visible Navigation" is enabled in the Debug menu.
|
Color to display disabled navigation mesh polygon faces, visible when "Visible Navigation" is enabled in the Debug menu.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="debug/shapes/navigation/link_connection_color" type="Color" setter="" getter="" default="Color(1, 0.5, 1, 1)">
|
||||||
|
Color to use to display navigation link connections, visible when "Visible Navigation" is enabled in the Debug menu.
|
||||||
|
</member>
|
||||||
|
<member name="debug/shapes/navigation/link_connection_disabled_color" type="Color" setter="" getter="" default="Color(0.5, 0.5, 0.5, 1)">
|
||||||
|
Color to use to display disabled navigation link connections, visible when "Visible Navigation" is enabled in the Debug menu.
|
||||||
|
</member>
|
||||||
<member name="navigation/baking/generator/navigation_mesh_generator" type="String" setter="" getter="" default=""DEFAULT"">
|
<member name="navigation/baking/generator/navigation_mesh_generator" type="String" setter="" getter="" default=""DEFAULT"">
|
||||||
Sets which navigation mesh generator to use to bake navigation meshes and parse source geometry from the scene.
|
Sets which navigation mesh generator to use to bake navigation meshes and parse source geometry from the scene.
|
||||||
"DEFAULT" and "GodotNavigationMeshGenerator" are the same, as there is currently no alternative navigation mesh generator implemented.
|
"DEFAULT" and "GodotNavigationMeshGenerator" are the same, as there is currently no alternative navigation mesh generator implemented.
|
||||||
@ -1363,6 +1375,9 @@
|
|||||||
<member name="navigation/2d/default_edge_connection_margin" type="float" setter="" getter="" default="1.0">
|
<member name="navigation/2d/default_edge_connection_margin" type="float" setter="" getter="" default="1.0">
|
||||||
Default edge connection margin for 2D navigation maps. See [method Navigation2DServer.map_set_edge_connection_margin].
|
Default edge connection margin for 2D navigation maps. See [method Navigation2DServer.map_set_edge_connection_margin].
|
||||||
</member>
|
</member>
|
||||||
|
<member name="navigation/2d/default_link_connection_radius" type="int" setter="" getter="" default="4">
|
||||||
|
Default link connection radius for 2D navigation maps. See [method NavigationServer2D.map_set_link_connection_radius].
|
||||||
|
</member>
|
||||||
<member name="navigation/3d/default_cell_height" type="float" setter="" getter="" default="0.25">
|
<member name="navigation/3d/default_cell_height" type="float" setter="" getter="" default="0.25">
|
||||||
Default cell height for 3D navigation maps. See [method NavigationServer.map_set_cell_height].
|
Default cell height for 3D navigation maps. See [method NavigationServer.map_set_cell_height].
|
||||||
</member>
|
</member>
|
||||||
@ -1375,6 +1390,9 @@
|
|||||||
<member name="navigation/3d/default_map_up" type="Vector3" setter="" getter="" default="Vector3( 0, 1, 0 )">
|
<member name="navigation/3d/default_map_up" type="Vector3" setter="" getter="" default="Vector3( 0, 1, 0 )">
|
||||||
Default map up vector for 3D navigation maps. See [method NavigationServer.map_set_up].
|
Default map up vector for 3D navigation maps. See [method NavigationServer.map_set_up].
|
||||||
</member>
|
</member>
|
||||||
|
<member name="navigation/3d/default_link_connection_radius" type="float" setter="" getter="" default="1.0">
|
||||||
|
Default link connection radius for 3D navigation maps. See [method NavigationServer3D.map_set_link_connection_radius].
|
||||||
|
</member>
|
||||||
<member name="network/limits/debugger_stdout/max_chars_per_second" type="int" setter="" getter="" default="2048">
|
<member name="network/limits/debugger_stdout/max_chars_per_second" type="int" setter="" getter="" default="2048">
|
||||||
Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
|
Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
|
||||||
</member>
|
</member>
|
||||||
|
@ -126,6 +126,7 @@
|
|||||||
#include "editor/plugins/mesh_editor_plugin.h"
|
#include "editor/plugins/mesh_editor_plugin.h"
|
||||||
#include "editor/plugins/mesh_instance_editor_plugin.h"
|
#include "editor/plugins/mesh_instance_editor_plugin.h"
|
||||||
#include "editor/plugins/multimesh_editor_plugin.h"
|
#include "editor/plugins/multimesh_editor_plugin.h"
|
||||||
|
#include "editor/plugins/navigation_link_2d_editor_plugin.h"
|
||||||
#include "editor/plugins/packed_scene_editor_plugin.h"
|
#include "editor/plugins/packed_scene_editor_plugin.h"
|
||||||
#include "editor/plugins/path_2d_editor_plugin.h"
|
#include "editor/plugins/path_2d_editor_plugin.h"
|
||||||
#include "editor/plugins/path_editor_plugin.h"
|
#include "editor/plugins/path_editor_plugin.h"
|
||||||
@ -7015,6 +7016,7 @@ EditorNode::EditorNode() {
|
|||||||
add_editor_plugin(memnew(Path2DEditorPlugin(this)));
|
add_editor_plugin(memnew(Path2DEditorPlugin(this)));
|
||||||
add_editor_plugin(memnew(PathEditorPlugin(this)));
|
add_editor_plugin(memnew(PathEditorPlugin(this)));
|
||||||
add_editor_plugin(memnew(Line2DEditorPlugin(this)));
|
add_editor_plugin(memnew(Line2DEditorPlugin(this)));
|
||||||
|
add_editor_plugin(memnew(NavigationLink2DEditorPlugin));
|
||||||
add_editor_plugin(memnew(Polygon2DEditorPlugin(this)));
|
add_editor_plugin(memnew(Polygon2DEditorPlugin(this)));
|
||||||
add_editor_plugin(memnew(LightOccluder2DEditorPlugin(this)));
|
add_editor_plugin(memnew(LightOccluder2DEditorPlugin(this)));
|
||||||
add_editor_plugin(memnew(GradientEditorPlugin(this)));
|
add_editor_plugin(memnew(GradientEditorPlugin(this)));
|
||||||
|
1
editor/icons/icon_navigation_link_2d.svg
Normal file
1
editor/icons/icon_navigation_link_2d.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h3.2a3.25 3.25 0 0 1-.2-5l5-5a3.25 3.25 0 0 1 5 .2V2a1 1 0 0 0-1-1zm7.15 6.65a2 2 0 0 1 1.207.207l1.25-1.25a1 1 0 0 1 1.75 1.75l-2 2a1 1 0 0 1-1.5 0 .5.5 0 0 0-.707.707 2 2 0 0 0 2.914 0l2-2A2 2 0 0 0 10.9 5.9zm1.628 4.628a2 2 0 0 1-1.207-.207l-1.25 1.25a1.237 1.237 0 0 1-1.75-1.75l2-2a1 1 0 0 1 1.5 0 .5.5 0 0 0 .707-.707 2 2 0 0 0-2.914 0l-2 2a2.237 2.237 0 0 0 3.164 3.164z" fill="#8ea6f4"/></svg>
|
After Width: | Height: | Size: 529 B |
1
editor/icons/icon_navigation_link_3d.svg
Normal file
1
editor/icons/icon_navigation_link_3d.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h3.2a3.25 3.25 0 0 1-.2-5l5-5a3.25 3.25 0 0 1 5 .2V2a1 1 0 0 0-1-1zm7.15 6.65a2 2 0 0 1 1.207.207l1.25-1.25a1 1 0 0 1 1.75 1.75l-2 2a1 1 0 0 1-1.5 0 .5.5 0 0 0-.707.707 2 2 0 0 0 2.914 0l2-2A2 2 0 0 0 10.9 5.9zm1.628 4.628a2 2 0 0 1-1.207-.207l-1.25 1.25a1.237 1.237 0 0 1-1.75-1.75l2-2a1 1 0 0 1 1.5 0 .5.5 0 0 0 .707-.707 2 2 0 0 0-2.914 0l-2 2a2.237 2.237 0 0 0 3.164 3.164z" fill="#fc7d7d"/></svg>
|
After Width: | Height: | Size: 529 B |
202
editor/plugins/navigation_link_2d_editor_plugin.cpp
Normal file
202
editor/plugins/navigation_link_2d_editor_plugin.cpp
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* navigation_link_2d_editor_plugin.cpp */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "navigation_link_2d_editor_plugin.h"
|
||||||
|
|
||||||
|
#include "canvas_item_editor_plugin.h"
|
||||||
|
#include "editor/editor_node.h"
|
||||||
|
#include "editor/editor_settings.h"
|
||||||
|
#include "core/object/undo_redo.h"
|
||||||
|
#include "servers/navigation_server.h"
|
||||||
|
|
||||||
|
void NavigationLink2DEditor::_notification(int p_what) {
|
||||||
|
switch (p_what) {
|
||||||
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
|
get_tree()->connect("node_removed", this, "_node_removed");
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
get_tree()->disconnect("node_removed", this, "_node_removed");
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2DEditor::_node_removed(Node *p_node) {
|
||||||
|
if (p_node == node) {
|
||||||
|
node = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2DEditor::_bind_methods() {
|
||||||
|
ClassDB::bind_method("_node_removed", &NavigationLink2DEditor::_node_removed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavigationLink2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
|
||||||
|
if (!node || !node->is_visible_in_tree()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
|
||||||
|
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
|
||||||
|
|
||||||
|
Ref<InputEventMouseButton> mb = p_event;
|
||||||
|
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) {
|
||||||
|
if (mb->is_pressed()) {
|
||||||
|
// Start position
|
||||||
|
if (xform.xform(node->get_start_position()).distance_to(mb->get_position()) < grab_threshold) {
|
||||||
|
start_grabbed = true;
|
||||||
|
original_start_position = node->get_start_position();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
start_grabbed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End position
|
||||||
|
if (xform.xform(node->get_end_position()).distance_to(mb->get_position()) < grab_threshold) {
|
||||||
|
end_grabbed = true;
|
||||||
|
original_end_position = node->get_end_position();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
end_grabbed = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
|
||||||
|
|
||||||
|
if (start_grabbed) {
|
||||||
|
undo_redo->create_action(TTR("Set start_position"));
|
||||||
|
undo_redo->add_do_method(node, "set_start_position", node->get_start_position());
|
||||||
|
undo_redo->add_do_method(canvas_item_editor, "update_viewport");
|
||||||
|
undo_redo->add_undo_method(node, "set_start_position", original_start_position);
|
||||||
|
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
||||||
|
undo_redo->commit_action();
|
||||||
|
|
||||||
|
start_grabbed = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_grabbed) {
|
||||||
|
undo_redo->create_action(TTR("Set end_position"));
|
||||||
|
undo_redo->add_do_method(node, "set_end_position", node->get_end_position());
|
||||||
|
undo_redo->add_do_method(canvas_item_editor, "update_viewport");
|
||||||
|
undo_redo->add_undo_method(node, "set_end_position", original_end_position);
|
||||||
|
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
|
||||||
|
undo_redo->commit_action();
|
||||||
|
|
||||||
|
end_grabbed = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<InputEventMouseMotion> mm = p_event;
|
||||||
|
if (mm.is_valid()) {
|
||||||
|
Vector2 point = canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position()));
|
||||||
|
point = node->get_global_transform().affine_inverse().xform(point);
|
||||||
|
|
||||||
|
if (start_grabbed) {
|
||||||
|
node->set_start_position(point);
|
||||||
|
canvas_item_editor->update_viewport();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_grabbed) {
|
||||||
|
node->set_end_position(point);
|
||||||
|
canvas_item_editor->update_viewport();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
||||||
|
if (!node || !node->is_visible_in_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform2D gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
|
||||||
|
Vector2 global_start_position = gt.xform(node->get_start_position());
|
||||||
|
Vector2 global_end_position = gt.xform(node->get_end_position());
|
||||||
|
|
||||||
|
// Only drawing the handles here, since the debug rendering will fill in the rest.
|
||||||
|
const Ref<Texture> handle = get_theme_icon("EditorHandle", "EditorIcons");
|
||||||
|
p_overlay->draw_texture(handle, global_start_position - handle->get_size() / 2);
|
||||||
|
p_overlay->draw_texture(handle, global_end_position - handle->get_size() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2DEditor::edit(NavigationLink2D *p_node) {
|
||||||
|
if (!canvas_item_editor) {
|
||||||
|
canvas_item_editor = CanvasItemEditor::get_singleton();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_node) {
|
||||||
|
node = p_node;
|
||||||
|
} else {
|
||||||
|
node = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas_item_editor->update_viewport();
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationLink2DEditor::NavigationLink2DEditor() {
|
||||||
|
canvas_item_editor = nullptr;
|
||||||
|
node = nullptr;
|
||||||
|
start_grabbed = false;
|
||||||
|
end_grabbed = false;
|
||||||
|
}
|
||||||
|
NavigationLink2DEditor::~NavigationLink2DEditor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
void NavigationLink2DEditorPlugin::edit(Object *p_object) {
|
||||||
|
editor->edit(Object::cast_to<NavigationLink2D>(p_object));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavigationLink2DEditorPlugin::handles(Object *p_object) const {
|
||||||
|
return Object::cast_to<NavigationLink2D>(p_object) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2DEditorPlugin::make_visible(bool p_visible) {
|
||||||
|
if (!p_visible) {
|
||||||
|
edit(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationLink2DEditorPlugin::NavigationLink2DEditorPlugin() {
|
||||||
|
editor = memnew(NavigationLink2DEditor);
|
||||||
|
EditorNode::get_singleton()->get_gui_base()->add_child(editor);
|
||||||
|
}
|
84
editor/plugins/navigation_link_2d_editor_plugin.h
Normal file
84
editor/plugins/navigation_link_2d_editor_plugin.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
#ifndef NAVIGATION_LINK_2D_EDITOR_PLUGIN_H
|
||||||
|
#define NAVIGATION_LINK_2D_EDITOR_PLUGIN_H
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/* navigation_link_2d_editor_plugin.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "editor/editor_plugin.h"
|
||||||
|
#include "scene/2d/navigation_link_2d.h"
|
||||||
|
|
||||||
|
class CanvasItemEditor;
|
||||||
|
|
||||||
|
class NavigationLink2DEditor : public Control {
|
||||||
|
GDCLASS(NavigationLink2DEditor, Control);
|
||||||
|
|
||||||
|
CanvasItemEditor *canvas_item_editor;
|
||||||
|
NavigationLink2D *node;
|
||||||
|
|
||||||
|
bool start_grabbed;
|
||||||
|
Vector2 original_start_position;
|
||||||
|
|
||||||
|
bool end_grabbed;
|
||||||
|
Vector2 original_end_position;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _notification(int p_what);
|
||||||
|
void _node_removed(Node *p_node);
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
|
||||||
|
void forward_canvas_draw_over_viewport(Control *p_overlay);
|
||||||
|
void edit(NavigationLink2D *p_node);
|
||||||
|
|
||||||
|
NavigationLink2DEditor();
|
||||||
|
~NavigationLink2DEditor();
|
||||||
|
};
|
||||||
|
|
||||||
|
class NavigationLink2DEditorPlugin : public EditorPlugin {
|
||||||
|
GDCLASS(NavigationLink2DEditorPlugin, EditorPlugin);
|
||||||
|
|
||||||
|
NavigationLink2DEditor *editor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) override { return editor->forward_canvas_gui_input(p_event); }
|
||||||
|
virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override { editor->forward_canvas_draw_over_viewport(p_overlay); }
|
||||||
|
|
||||||
|
virtual String get_name() const override { return "NavigationLink2D"; }
|
||||||
|
bool has_main_screen() const override { return false; }
|
||||||
|
virtual void edit(Object *p_object) override;
|
||||||
|
virtual bool handles(Object *p_object) const override;
|
||||||
|
virtual void make_visible(bool p_visible) override;
|
||||||
|
|
||||||
|
NavigationLink2DEditorPlugin();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAVIGATION_LINK_2D_EDITOR_PLUGIN_H
|
@ -7059,6 +7059,7 @@ void SpatialEditor::_register_all_gizmos() {
|
|||||||
add_gizmo_plugin(Ref<CollisionObjectGizmoPlugin>(memnew(CollisionObjectGizmoPlugin)));
|
add_gizmo_plugin(Ref<CollisionObjectGizmoPlugin>(memnew(CollisionObjectGizmoPlugin)));
|
||||||
add_gizmo_plugin(Ref<CollisionShapeSpatialGizmoPlugin>(memnew(CollisionShapeSpatialGizmoPlugin)));
|
add_gizmo_plugin(Ref<CollisionShapeSpatialGizmoPlugin>(memnew(CollisionShapeSpatialGizmoPlugin)));
|
||||||
add_gizmo_plugin(Ref<CollisionPolygonSpatialGizmoPlugin>(memnew(CollisionPolygonSpatialGizmoPlugin)));
|
add_gizmo_plugin(Ref<CollisionPolygonSpatialGizmoPlugin>(memnew(CollisionPolygonSpatialGizmoPlugin)));
|
||||||
|
add_gizmo_plugin(Ref<NavigationLink3DGizmoPlugin>(memnew(NavigationLink3DGizmoPlugin)));
|
||||||
add_gizmo_plugin(Ref<NavigationMeshSpatialGizmoPlugin>(memnew(NavigationMeshSpatialGizmoPlugin)));
|
add_gizmo_plugin(Ref<NavigationMeshSpatialGizmoPlugin>(memnew(NavigationMeshSpatialGizmoPlugin)));
|
||||||
add_gizmo_plugin(Ref<JointSpatialGizmoPlugin>(memnew(JointSpatialGizmoPlugin)));
|
add_gizmo_plugin(Ref<JointSpatialGizmoPlugin>(memnew(JointSpatialGizmoPlugin)));
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
#include "scene/3d/light.h"
|
#include "scene/3d/light.h"
|
||||||
#include "scene/3d/listener.h"
|
#include "scene/3d/listener.h"
|
||||||
#include "scene/3d/mesh_instance.h"
|
#include "scene/3d/mesh_instance.h"
|
||||||
|
#include "scene/3d/navigation_link_3d.h"
|
||||||
#include "scene/3d/navigation_mesh_instance.h"
|
#include "scene/3d/navigation_mesh_instance.h"
|
||||||
#include "scene/3d/occluder.h"
|
#include "scene/3d/occluder.h"
|
||||||
#include "scene/3d/physics_body.h"
|
#include "scene/3d/physics_body.h"
|
||||||
@ -3716,6 +3717,175 @@ void NavigationMeshSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////
|
||||||
|
|
||||||
|
NavigationLink3DGizmoPlugin::NavigationLink3DGizmoPlugin() {
|
||||||
|
create_material("navigation_link_material", NavigationServer::get_singleton()->get_debug_navigation_link_connection_color());
|
||||||
|
create_material("navigation_link_material_disabled", NavigationServer::get_singleton()->get_debug_navigation_link_connection_disabled_color());
|
||||||
|
create_handle_material("handles");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavigationLink3DGizmoPlugin::has_gizmo(Spatial *p_spatial) {
|
||||||
|
return Object::cast_to<NavigationLink3D>(p_spatial) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
String NavigationLink3DGizmoPlugin::get_gizmo_name() const {
|
||||||
|
return "NavigationLink3D";
|
||||||
|
}
|
||||||
|
|
||||||
|
int NavigationLink3DGizmoPlugin::get_priority() const {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3DGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
|
||||||
|
NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node());
|
||||||
|
|
||||||
|
RID nav_map = link->get_world_3d()->get_navigation_map();
|
||||||
|
real_t search_radius = NavigationServer::get_singleton()->map_get_link_connection_radius(nav_map);
|
||||||
|
Vector3 up_vector = NavigationServer::get_singleton()->map_get_up(nav_map);
|
||||||
|
Vector3::Axis up_axis = static_cast<Vector3::Axis>(up_vector.max_axis());
|
||||||
|
|
||||||
|
Vector3 start_location = link->get_start_position();
|
||||||
|
Vector3 end_location = link->get_end_position();
|
||||||
|
|
||||||
|
Ref<Material> link_material = get_material("navigation_link_material", p_gizmo);
|
||||||
|
Ref<Material> link_material_disabled = get_material("navigation_link_material_disabled", p_gizmo);
|
||||||
|
Ref<Material> handles_material = get_material("handles");
|
||||||
|
|
||||||
|
p_gizmo->clear();
|
||||||
|
|
||||||
|
// Draw line between the points.
|
||||||
|
Vector<Vector3> lines;
|
||||||
|
lines.push_back(start_location);
|
||||||
|
lines.push_back(end_location);
|
||||||
|
|
||||||
|
// Draw start location search radius
|
||||||
|
for (int i = 0; i < 30; i++) {
|
||||||
|
// Create a circle
|
||||||
|
const float ra = Math::deg2rad((float)(i * 12));
|
||||||
|
const float rb = Math::deg2rad((float)((i + 1) * 12));
|
||||||
|
const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * search_radius;
|
||||||
|
const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * search_radius;
|
||||||
|
|
||||||
|
// Draw axis-aligned circle
|
||||||
|
switch (up_axis) {
|
||||||
|
case Vector3::AXIS_X:
|
||||||
|
lines.push_back(start_location + Vector3(0, a.x, a.y));
|
||||||
|
lines.push_back(start_location + Vector3(0, b.x, b.y));
|
||||||
|
break;
|
||||||
|
case Vector3::AXIS_Y:
|
||||||
|
lines.push_back(start_location + Vector3(a.x, 0, a.y));
|
||||||
|
lines.push_back(start_location + Vector3(b.x, 0, b.y));
|
||||||
|
break;
|
||||||
|
case Vector3::AXIS_Z:
|
||||||
|
lines.push_back(start_location + Vector3(a.x, a.y, 0));
|
||||||
|
lines.push_back(start_location + Vector3(b.x, b.y, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw end location search radius
|
||||||
|
for (int i = 0; i < 30; i++) {
|
||||||
|
// Create a circle
|
||||||
|
const float ra = Math::deg2rad((float)(i * 12));
|
||||||
|
const float rb = Math::deg2rad((float)((i + 1) * 12));
|
||||||
|
const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * search_radius;
|
||||||
|
const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * search_radius;
|
||||||
|
|
||||||
|
// Draw axis-aligned circle
|
||||||
|
switch (up_axis) {
|
||||||
|
case Vector3::AXIS_X:
|
||||||
|
lines.push_back(end_location + Vector3(0, a.x, a.y));
|
||||||
|
lines.push_back(end_location + Vector3(0, b.x, b.y));
|
||||||
|
break;
|
||||||
|
case Vector3::AXIS_Y:
|
||||||
|
lines.push_back(end_location + Vector3(a.x, 0, a.y));
|
||||||
|
lines.push_back(end_location + Vector3(b.x, 0, b.y));
|
||||||
|
break;
|
||||||
|
case Vector3::AXIS_Z:
|
||||||
|
lines.push_back(end_location + Vector3(a.x, a.y, 0));
|
||||||
|
lines.push_back(end_location + Vector3(b.x, b.y, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_gizmo->add_lines(lines, link->is_enabled() ? link_material : link_material_disabled);
|
||||||
|
p_gizmo->add_collision_segments(lines);
|
||||||
|
|
||||||
|
Vector<Vector3> handles;
|
||||||
|
handles.push_back(start_location);
|
||||||
|
handles.push_back(end_location);
|
||||||
|
p_gizmo->add_handles(handles, handles_material);
|
||||||
|
}
|
||||||
|
|
||||||
|
String NavigationLink3DGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary) const {
|
||||||
|
return p_id == 0 ? TTR("Start Location") : TTR("End Location");
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant NavigationLink3DGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary) const {
|
||||||
|
NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node());
|
||||||
|
return p_id == 0 ? link->get_start_position() : link->get_end_position();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3DGizmoPlugin::set_handle(const EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary, Camera *p_camera, const Point2 &p_point) {
|
||||||
|
NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node());
|
||||||
|
|
||||||
|
Transform gt = link->get_global_transform();
|
||||||
|
Transform gi = gt.affine_inverse();
|
||||||
|
|
||||||
|
Transform ct = p_camera->get_global_transform();
|
||||||
|
Vector3 cam_dir = ct.basis.get_column(Vector3::AXIS_Z);
|
||||||
|
|
||||||
|
Vector3 ray_from = p_camera->project_ray_origin(p_point);
|
||||||
|
Vector3 ray_dir = p_camera->project_ray_normal(p_point);
|
||||||
|
|
||||||
|
Vector3 location = p_id == 0 ? link->get_start_position() : link->get_end_position();
|
||||||
|
Plane move_plane = Plane(cam_dir, gt.xform(location));
|
||||||
|
|
||||||
|
Vector3 intersection;
|
||||||
|
if (!move_plane.intersects_ray(ray_from, ray_dir, &intersection)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SpatialEditor::get_singleton()->is_snap_enabled()) {
|
||||||
|
double snap = SpatialEditor::get_singleton()->get_translate_snap();
|
||||||
|
intersection.snap(Vector3(snap, snap, snap));
|
||||||
|
}
|
||||||
|
|
||||||
|
location = gi.xform(intersection);
|
||||||
|
if (p_id == 0) {
|
||||||
|
link->set_start_position(location);
|
||||||
|
} else if (p_id == 1) {
|
||||||
|
link->set_end_position(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3DGizmoPlugin::commit_handle(const EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
|
||||||
|
NavigationLink3D *link = Object::cast_to<NavigationLink3D>(p_gizmo->get_spatial_node());
|
||||||
|
|
||||||
|
if (p_cancel) {
|
||||||
|
if (p_id == 0) {
|
||||||
|
link->set_start_position(p_restore);
|
||||||
|
} else {
|
||||||
|
link->set_end_position(p_restore);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UndoRedo *ur = EditorNode::get_undo_redo();
|
||||||
|
if (p_id == 0) {
|
||||||
|
ur->create_action(TTR("Change Start Location"));
|
||||||
|
ur->add_do_method(link, "set_start_position", link->get_start_position());
|
||||||
|
ur->add_undo_method(link, "set_start_position", p_restore);
|
||||||
|
} else {
|
||||||
|
ur->create_action(TTR("Change End Location"));
|
||||||
|
ur->add_do_method(link, "set_end_position", link->get_end_position());
|
||||||
|
ur->add_undo_method(link, "set_end_position", p_restore);
|
||||||
|
}
|
||||||
|
|
||||||
|
ur->commit_action();
|
||||||
|
}
|
||||||
|
|
||||||
//////
|
//////
|
||||||
|
|
||||||
#define BODY_A_RADIUS 0.25
|
#define BODY_A_RADIUS 0.25
|
||||||
|
@ -509,6 +509,23 @@ public:
|
|||||||
NavigationMeshSpatialGizmoPlugin();
|
NavigationMeshSpatialGizmoPlugin();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NavigationLink3DGizmoPlugin : public EditorSpatialGizmoPlugin {
|
||||||
|
GDCLASS(NavigationLink3DGizmoPlugin, EditorSpatialGizmoPlugin);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool has_gizmo(Spatial *p_spatial);
|
||||||
|
String get_gizmo_name() const;
|
||||||
|
int get_priority() const;
|
||||||
|
void redraw(EditorSpatialGizmo *p_gizmo);
|
||||||
|
|
||||||
|
String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary) const;
|
||||||
|
Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary) const;
|
||||||
|
void set_handle(const EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary, Camera *p_camera, const Point2 &p_point);
|
||||||
|
void commit_handle(const EditorSpatialGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false);
|
||||||
|
|
||||||
|
NavigationLink3DGizmoPlugin();
|
||||||
|
};
|
||||||
|
|
||||||
class JointGizmosDrawer {
|
class JointGizmosDrawer {
|
||||||
public:
|
public:
|
||||||
static Basis look_body(const Transform &p_joint_transform, const Transform &p_body_transform);
|
static Basis look_body(const Transform &p_joint_transform, const Transform &p_body_transform);
|
||||||
|
75
modules/navigation/nav_base.h
Normal file
75
modules/navigation/nav_base.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
#ifndef NAV_BASE_H
|
||||||
|
#define NAV_BASE_H
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/* nav_base.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "nav_rid.h"
|
||||||
|
#include "nav_utils.h"
|
||||||
|
#include "servers/navigation/navigation_utilities.h"
|
||||||
|
|
||||||
|
class NavMap;
|
||||||
|
|
||||||
|
class NavBase : public NavRid {
|
||||||
|
protected:
|
||||||
|
uint32_t navigation_layers;
|
||||||
|
real_t enter_cost;
|
||||||
|
real_t travel_cost;
|
||||||
|
ObjectID owner_id;
|
||||||
|
NavigationUtilities::PathSegmentType type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NavigationUtilities::PathSegmentType get_type() const { return type; }
|
||||||
|
|
||||||
|
virtual void set_use_edge_connections(bool p_enabled) {}
|
||||||
|
virtual bool get_use_edge_connections() const { return false; }
|
||||||
|
|
||||||
|
void set_navigation_layers(uint32_t p_navigation_layers) { navigation_layers = p_navigation_layers; }
|
||||||
|
uint32_t get_navigation_layers() const { return navigation_layers; }
|
||||||
|
|
||||||
|
void set_enter_cost(real_t p_enter_cost) { enter_cost = MAX(p_enter_cost, 0.0); }
|
||||||
|
real_t get_enter_cost() const { return enter_cost; }
|
||||||
|
|
||||||
|
void set_travel_cost(real_t p_travel_cost) { travel_cost = MAX(p_travel_cost, 0.0); }
|
||||||
|
real_t get_travel_cost() const { return travel_cost; }
|
||||||
|
|
||||||
|
void set_owner_id(ObjectID p_owner_id) { owner_id = p_owner_id; }
|
||||||
|
ObjectID get_owner_id() const { return owner_id; }
|
||||||
|
|
||||||
|
NavBase() {
|
||||||
|
navigation_layers = 1;
|
||||||
|
enter_cost = 0.0;
|
||||||
|
travel_cost = 1.0;
|
||||||
|
};
|
||||||
|
virtual ~NavBase(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAV_BASE_H
|
72
modules/navigation/nav_link.cpp
Normal file
72
modules/navigation/nav_link.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* nav_link.cpp */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "nav_link.h"
|
||||||
|
|
||||||
|
#include "nav_map.h"
|
||||||
|
|
||||||
|
void NavLink::set_map(NavMap *p_map) {
|
||||||
|
if (map == p_map) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
map = p_map;
|
||||||
|
link_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavLink::set_bidirectional(bool p_bidirectional) {
|
||||||
|
if (bidirectional == p_bidirectional) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bidirectional = p_bidirectional;
|
||||||
|
link_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavLink::set_start_position(const Vector3 p_position) {
|
||||||
|
if (start_position == p_position) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
start_position = p_position;
|
||||||
|
link_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavLink::set_end_position(const Vector3 p_position) {
|
||||||
|
if (end_position == p_position) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
end_position = p_position;
|
||||||
|
link_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavLink::check_dirty() {
|
||||||
|
const bool was_dirty = link_dirty;
|
||||||
|
|
||||||
|
link_dirty = false;
|
||||||
|
return was_dirty;
|
||||||
|
}
|
77
modules/navigation/nav_link.h
Normal file
77
modules/navigation/nav_link.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
#ifndef NAV_LINK_H
|
||||||
|
#define NAV_LINK_H
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/* nav_link.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "nav_base.h"
|
||||||
|
#include "nav_utils.h"
|
||||||
|
|
||||||
|
class NavLink : public NavBase {
|
||||||
|
NavMap *map;
|
||||||
|
bool bidirectional;
|
||||||
|
Vector3 start_position;
|
||||||
|
Vector3 end_position;
|
||||||
|
|
||||||
|
bool link_dirty;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NavLink() {
|
||||||
|
type = NavigationUtilities::PathSegmentType::PATH_SEGMENT_TYPE_LINK;
|
||||||
|
map = nullptr;
|
||||||
|
bidirectional = true;
|
||||||
|
link_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_map(NavMap *p_map);
|
||||||
|
NavMap *get_map() const {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_bidirectional(bool p_bidirectional);
|
||||||
|
bool is_bidirectional() const {
|
||||||
|
return bidirectional;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_start_position(Vector3 p_position);
|
||||||
|
Vector3 get_start_position() const {
|
||||||
|
return start_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_end_position(Vector3 p_position);
|
||||||
|
Vector3 get_end_position() const {
|
||||||
|
return end_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_dirty();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAV_LINK_H
|
@ -31,6 +31,7 @@
|
|||||||
#include "nav_map.h"
|
#include "nav_map.h"
|
||||||
|
|
||||||
#include "core/os/threaded_array_processor.h"
|
#include "core/os/threaded_array_processor.h"
|
||||||
|
#include "nav_link.h"
|
||||||
#include "nav_region.h"
|
#include "nav_region.h"
|
||||||
#include "rvo_agent.h"
|
#include "rvo_agent.h"
|
||||||
#include "scene/resources/mesh.h"
|
#include "scene/resources/mesh.h"
|
||||||
@ -59,6 +60,11 @@ void NavMap::set_edge_connection_margin(float p_edge_connection_margin) {
|
|||||||
regenerate_links = true;
|
regenerate_links = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavMap::set_link_connection_radius(float p_link_connection_radius) {
|
||||||
|
link_connection_radius = p_link_connection_radius;
|
||||||
|
regenerate_links = true;
|
||||||
|
}
|
||||||
|
|
||||||
gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const {
|
gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const {
|
||||||
const int x = static_cast<int>(Math::round(p_pos.x / cell_size));
|
const int x = static_cast<int>(Math::round(p_pos.x / cell_size));
|
||||||
const int y = static_cast<int>(Math::round(p_pos.y / cell_height));
|
const int y = static_cast<int>(Math::round(p_pos.y / cell_height));
|
||||||
@ -165,17 +171,17 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
|
|||||||
}
|
}
|
||||||
|
|
||||||
const gd::NavigationPoly &least_cost_poly = navigation_polys[least_cost_id];
|
const gd::NavigationPoly &least_cost_poly = navigation_polys[least_cost_id];
|
||||||
float region_enter_cost = 0.0;
|
float poly_enter_cost = 0.0;
|
||||||
float region_travel_cost = least_cost_poly.poly->owner->get_travel_cost();
|
float poly_travel_cost = least_cost_poly.poly->owner->get_travel_cost();
|
||||||
|
|
||||||
if (prev_least_cost_id != -1 && !(navigation_polys[prev_least_cost_id].poly->owner->get_self() == least_cost_poly.poly->owner->get_self())) {
|
if (prev_least_cost_id != -1 && !(navigation_polys[prev_least_cost_id].poly->owner->get_self() == least_cost_poly.poly->owner->get_self())) {
|
||||||
region_enter_cost = least_cost_poly.poly->owner->get_enter_cost();
|
poly_enter_cost = least_cost_poly.poly->owner->get_enter_cost();
|
||||||
}
|
}
|
||||||
prev_least_cost_id = least_cost_id;
|
prev_least_cost_id = least_cost_id;
|
||||||
|
|
||||||
Vector3 pathway[2] = { connection.pathway_start, connection.pathway_end };
|
Vector3 pathway[2] = { connection.pathway_start, connection.pathway_end };
|
||||||
const Vector3 new_entry = Geometry::get_closest_point_to_segment(least_cost_poly.entry, pathway);
|
const Vector3 new_entry = Geometry::get_closest_point_to_segment(least_cost_poly.entry, pathway);
|
||||||
const float new_distance = (least_cost_poly.entry.distance_to(new_entry) * region_travel_cost) + region_enter_cost + least_cost_poly.traveled_distance;
|
const float new_distance = (least_cost_poly.entry.distance_to(new_entry) * poly_travel_cost) + poly_enter_cost + least_cost_poly.traveled_distance;
|
||||||
|
|
||||||
int64_t already_visited_polygon_index = navigation_polys.find(gd::NavigationPoly(connection.polygon));
|
int64_t already_visited_polygon_index = navigation_polys.find(gd::NavigationPoly(connection.polygon));
|
||||||
|
|
||||||
@ -368,10 +374,15 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
|
|||||||
// Add mid points
|
// Add mid points
|
||||||
int np_id = least_cost_id;
|
int np_id = least_cost_id;
|
||||||
while (np_id != -1 && navigation_polys[np_id].back_navigation_poly_id != -1) {
|
while (np_id != -1 && navigation_polys[np_id].back_navigation_poly_id != -1) {
|
||||||
int prev = navigation_polys[np_id].back_navigation_edge;
|
if (navigation_polys[np_id].back_navigation_edge != -1) {
|
||||||
int prev_n = (navigation_polys[np_id].back_navigation_edge + 1) % navigation_polys[np_id].poly->points.size();
|
int prev = navigation_polys[np_id].back_navigation_edge;
|
||||||
Vector3 point = (navigation_polys[np_id].poly->points[prev].pos + navigation_polys[np_id].poly->points[prev_n].pos) * 0.5;
|
int prev_n = (navigation_polys[np_id].back_navigation_edge + 1) % navigation_polys[np_id].poly->points.size();
|
||||||
path.push_back(point);
|
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);
|
||||||
|
} else {
|
||||||
|
path.push_back(navigation_polys[np_id].entry);
|
||||||
|
}
|
||||||
|
|
||||||
np_id = navigation_polys[np_id].back_navigation_poly_id;
|
np_id = navigation_polys[np_id].back_navigation_poly_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,6 +494,19 @@ void NavMap::remove_region(NavRegion *p_region) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavMap::add_link(NavLink *p_link) {
|
||||||
|
links.push_back(p_link);
|
||||||
|
regenerate_links = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavMap::remove_link(NavLink *p_link) {
|
||||||
|
int64_t link_index = links.find(p_link);
|
||||||
|
if (link_index != -1) {
|
||||||
|
links.remove_unordered(link_index);
|
||||||
|
regenerate_links = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool NavMap::has_agent(RvoAgent *agent) const {
|
bool NavMap::has_agent(RvoAgent *agent) const {
|
||||||
return (agents.find(agent) != -1);
|
return (agents.find(agent) != -1);
|
||||||
}
|
}
|
||||||
@ -537,6 +561,12 @@ void NavMap::sync() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint32_t l = 0; l < links.size(); l++) {
|
||||||
|
if (links[l]->check_dirty()) {
|
||||||
|
regenerate_links = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (regenerate_links) {
|
if (regenerate_links) {
|
||||||
// Remove regions connections.
|
// Remove regions connections.
|
||||||
for (uint32_t r = 0; r < regions.size(); r++) {
|
for (uint32_t r = 0; r < regions.size(); r++) {
|
||||||
@ -668,7 +698,121 @@ void NavMap::sync() {
|
|||||||
free_edge.polygon->edges[free_edge.edge].connections.push_back(new_connection);
|
free_edge.polygon->edges[free_edge.edge].connections.push_back(new_connection);
|
||||||
|
|
||||||
// Add the connection to the region_connection map.
|
// Add the connection to the region_connection map.
|
||||||
free_edge.polygon->owner->get_connections().push_back(new_connection);
|
((NavRegion *)free_edge.polygon->owner)->get_connections().push_back(new_connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t link_poly_idx = 0;
|
||||||
|
link_polygons.resize(links.size());
|
||||||
|
|
||||||
|
// Search for polygons within range of a nav link.
|
||||||
|
for (uint32_t l = 0; l < links.size(); l++) {
|
||||||
|
const NavLink *link = links[l];
|
||||||
|
const Vector3 start = link->get_start_position();
|
||||||
|
const Vector3 end = link->get_end_position();
|
||||||
|
|
||||||
|
gd::Polygon *closest_start_polygon = nullptr;
|
||||||
|
real_t closest_start_distance = link_connection_radius;
|
||||||
|
Vector3 closest_start_point;
|
||||||
|
|
||||||
|
gd::Polygon *closest_end_polygon = nullptr;
|
||||||
|
real_t closest_end_distance = link_connection_radius;
|
||||||
|
Vector3 closest_end_point;
|
||||||
|
|
||||||
|
// Create link to any polygons within the search radius of the start point.
|
||||||
|
for (uint32_t start_index = 0; start_index < polygons.size(); start_index++) {
|
||||||
|
gd::Polygon &start_poly = polygons[start_index];
|
||||||
|
|
||||||
|
// For each face check the distance to the start
|
||||||
|
for (uint32_t start_point_id = 2; start_point_id < start_poly.points.size(); start_point_id += 1) {
|
||||||
|
const Face3 start_face(start_poly.points[0].pos, start_poly.points[start_point_id - 1].pos, start_poly.points[start_point_id].pos);
|
||||||
|
const Vector3 start_point = start_face.get_closest_point_to(start);
|
||||||
|
const real_t start_distance = start_point.distance_to(start);
|
||||||
|
|
||||||
|
// Pick the polygon that is within our radius and is closer than anything we've seen yet.
|
||||||
|
if (start_distance <= link_connection_radius && start_distance < closest_start_distance) {
|
||||||
|
closest_start_distance = start_distance;
|
||||||
|
closest_start_point = start_point;
|
||||||
|
closest_start_polygon = &start_poly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find any polygons within the search radius of the end point.
|
||||||
|
for (uint32_t end_index = 0; end_index < polygons.size(); end_index++) {
|
||||||
|
gd::Polygon &end_poly = polygons[end_index];
|
||||||
|
|
||||||
|
// For each face check the distance to the end
|
||||||
|
for (uint32_t end_point_id = 2; end_point_id < end_poly.points.size(); end_point_id += 1) {
|
||||||
|
const Face3 end_face(end_poly.points[0].pos, end_poly.points[end_point_id - 1].pos, end_poly.points[end_point_id].pos);
|
||||||
|
const Vector3 end_point = end_face.get_closest_point_to(end);
|
||||||
|
const real_t end_distance = end_point.distance_to(end);
|
||||||
|
|
||||||
|
// Pick the polygon that is within our radius and is closer than anything we've seen yet.
|
||||||
|
if (end_distance <= link_connection_radius && end_distance < closest_end_distance) {
|
||||||
|
closest_end_distance = end_distance;
|
||||||
|
closest_end_point = end_point;
|
||||||
|
closest_end_polygon = &end_poly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have both a start and end point, then create a synthetic polygon to route through.
|
||||||
|
if (closest_start_polygon && closest_end_polygon) {
|
||||||
|
gd::Polygon &new_polygon = link_polygons[link_poly_idx++];
|
||||||
|
new_polygon.owner = const_cast<NavLink *>(link);
|
||||||
|
|
||||||
|
new_polygon.edges.clear();
|
||||||
|
new_polygon.edges.resize(4);
|
||||||
|
new_polygon.points.clear();
|
||||||
|
new_polygon.points.reserve(4);
|
||||||
|
|
||||||
|
// Build a set of vertices that create a thin polygon going from the start to the end point.
|
||||||
|
new_polygon.points.push_back({ closest_start_point, get_point_key(closest_start_point) });
|
||||||
|
new_polygon.points.push_back({ closest_start_point, get_point_key(closest_start_point) });
|
||||||
|
new_polygon.points.push_back({ closest_end_point, get_point_key(closest_end_point) });
|
||||||
|
new_polygon.points.push_back({ closest_end_point, get_point_key(closest_end_point) });
|
||||||
|
|
||||||
|
Vector3 center;
|
||||||
|
for (int p = 0; p < 4; ++p) {
|
||||||
|
center += new_polygon.points[p].pos;
|
||||||
|
}
|
||||||
|
new_polygon.center = center / real_t(new_polygon.points.size());
|
||||||
|
new_polygon.clockwise = true;
|
||||||
|
|
||||||
|
// Setup connections to go forward in the link.
|
||||||
|
{
|
||||||
|
gd::Edge::Connection entry_connection;
|
||||||
|
entry_connection.polygon = &new_polygon;
|
||||||
|
entry_connection.edge = -1;
|
||||||
|
entry_connection.pathway_start = new_polygon.points[0].pos;
|
||||||
|
entry_connection.pathway_end = new_polygon.points[1].pos;
|
||||||
|
closest_start_polygon->edges[0].connections.push_back(entry_connection);
|
||||||
|
|
||||||
|
gd::Edge::Connection exit_connection;
|
||||||
|
exit_connection.polygon = closest_end_polygon;
|
||||||
|
exit_connection.edge = -1;
|
||||||
|
exit_connection.pathway_start = new_polygon.points[2].pos;
|
||||||
|
exit_connection.pathway_end = new_polygon.points[3].pos;
|
||||||
|
new_polygon.edges[2].connections.push_back(exit_connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the link is bi-directional, create connections from the end to the start.
|
||||||
|
if (link->is_bidirectional()) {
|
||||||
|
gd::Edge::Connection entry_connection;
|
||||||
|
entry_connection.polygon = &new_polygon;
|
||||||
|
entry_connection.edge = -1;
|
||||||
|
entry_connection.pathway_start = new_polygon.points[2].pos;
|
||||||
|
entry_connection.pathway_end = new_polygon.points[3].pos;
|
||||||
|
closest_end_polygon->edges[0].connections.push_back(entry_connection);
|
||||||
|
|
||||||
|
gd::Edge::Connection exit_connection;
|
||||||
|
exit_connection.polygon = closest_start_polygon;
|
||||||
|
exit_connection.edge = -1;
|
||||||
|
exit_connection.pathway_start = new_polygon.points[0].pos;
|
||||||
|
exit_connection.pathway_end = new_polygon.points[1].pos;
|
||||||
|
new_polygon.edges[0].connections.push_back(exit_connection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,6 +914,7 @@ NavMap::NavMap() {
|
|||||||
agents_dirty = false;
|
agents_dirty = false;
|
||||||
deltatime = 0.0;
|
deltatime = 0.0;
|
||||||
map_update_id = 0;
|
map_update_id = 0;
|
||||||
|
link_connection_radius = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NavMap::~NavMap() {
|
NavMap::~NavMap() {
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
#include <KdTree.h>
|
#include <KdTree.h>
|
||||||
|
|
||||||
|
class NavLink;
|
||||||
class NavRegion;
|
class NavRegion;
|
||||||
class RvoAgent;
|
class RvoAgent;
|
||||||
class NavRegion;
|
class NavRegion;
|
||||||
@ -56,11 +57,19 @@ class NavMap : public NavRid {
|
|||||||
/// This value is used to detect the near edges to connect.
|
/// This value is used to detect the near edges to connect.
|
||||||
real_t edge_connection_margin;
|
real_t edge_connection_margin;
|
||||||
|
|
||||||
|
/// This value is used to limit how far links search to find polygons to connect to.
|
||||||
|
real_t link_connection_radius;
|
||||||
|
|
||||||
bool regenerate_polygons;
|
bool regenerate_polygons;
|
||||||
bool regenerate_links;
|
bool regenerate_links;
|
||||||
|
|
||||||
|
/// Map regions
|
||||||
LocalVector<NavRegion *> regions;
|
LocalVector<NavRegion *> regions;
|
||||||
|
|
||||||
|
/// Map links
|
||||||
|
LocalVector<NavLink *> links;
|
||||||
|
LocalVector<gd::Polygon> link_polygons;
|
||||||
|
|
||||||
/// Map polygons
|
/// Map polygons
|
||||||
LocalVector<gd::Polygon> polygons;
|
LocalVector<gd::Polygon> polygons;
|
||||||
|
|
||||||
@ -111,6 +120,11 @@ public:
|
|||||||
return edge_connection_margin;
|
return edge_connection_margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_link_connection_radius(float p_link_connection_radius);
|
||||||
|
float get_link_connection_radius() const {
|
||||||
|
return link_connection_radius;
|
||||||
|
}
|
||||||
|
|
||||||
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 = 1) const;
|
||||||
@ -126,6 +140,12 @@ public:
|
|||||||
return regions;
|
return regions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_link(NavLink *p_link);
|
||||||
|
void remove_link(NavLink *p_link);
|
||||||
|
const LocalVector<NavLink *> &get_links() const {
|
||||||
|
return links;
|
||||||
|
}
|
||||||
|
|
||||||
bool has_agent(RvoAgent *agent) const;
|
bool has_agent(RvoAgent *agent) const;
|
||||||
void add_agent(RvoAgent *agent);
|
void add_agent(RvoAgent *agent);
|
||||||
void remove_agent(RvoAgent *agent);
|
void remove_agent(RvoAgent *agent);
|
||||||
|
@ -41,14 +41,6 @@ void NavRegion::set_map(NavMap *p_map) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavRegion::set_navigation_layers(uint32_t p_navigation_layers) {
|
|
||||||
navigation_layers = p_navigation_layers;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t NavRegion::get_navigation_layers() const {
|
|
||||||
return navigation_layers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NavRegion::set_transform(Transform p_transform) {
|
void NavRegion::set_transform(Transform p_transform) {
|
||||||
transform = p_transform;
|
transform = p_transform;
|
||||||
polygons_dirty = true;
|
polygons_dirty = true;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#ifndef NAV_REGION_H
|
#ifndef NAV_REGION_H
|
||||||
#define NAV_REGION_H
|
#define NAV_REGION_H
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* nav_region.h */
|
/* nav_region.h */
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
@ -30,24 +31,16 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#include "nav_rid.h"
|
#include "nav_base.h"
|
||||||
|
|
||||||
#include "nav_utils.h"
|
#include "nav_utils.h"
|
||||||
#include "scene/3d/navigation.h"
|
#include "scene/3d/navigation.h"
|
||||||
#include "scene/resources/navigation_mesh.h"
|
#include "scene/resources/navigation_mesh.h"
|
||||||
|
|
||||||
#include <vector>
|
class NavRegion : public NavBase {
|
||||||
|
|
||||||
class NavMap;
|
|
||||||
class NavRegion;
|
|
||||||
|
|
||||||
class NavRegion : public NavRid {
|
|
||||||
NavMap *map;
|
NavMap *map;
|
||||||
Transform transform;
|
Transform transform;
|
||||||
Ref<NavigationMesh> mesh;
|
Ref<NavigationMesh> mesh;
|
||||||
uint32_t navigation_layers;
|
|
||||||
float enter_cost;
|
|
||||||
float travel_cost;
|
|
||||||
Vector<gd::Edge::Connection> connections;
|
Vector<gd::Edge::Connection> connections;
|
||||||
|
|
||||||
bool polygons_dirty;
|
bool polygons_dirty;
|
||||||
@ -65,15 +58,6 @@ public:
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_enter_cost(float p_enter_cost) { enter_cost = MAX(p_enter_cost, 0.0); }
|
|
||||||
float get_enter_cost() const { return enter_cost; }
|
|
||||||
|
|
||||||
void set_travel_cost(float p_travel_cost) { travel_cost = MAX(p_travel_cost, 0.0); }
|
|
||||||
float get_travel_cost() const { return travel_cost; }
|
|
||||||
|
|
||||||
void set_navigation_layers(uint32_t p_navigation_layers);
|
|
||||||
uint32_t get_navigation_layers() const;
|
|
||||||
|
|
||||||
void set_transform(Transform transform);
|
void set_transform(Transform transform);
|
||||||
const Transform &get_transform() const {
|
const Transform &get_transform() const {
|
||||||
return transform;
|
return transform;
|
||||||
|
@ -33,9 +33,7 @@
|
|||||||
#include "core/math/vector3.h"
|
#include "core/math/vector3.h"
|
||||||
#include "core/containers/rid.h"
|
#include "core/containers/rid.h"
|
||||||
|
|
||||||
#include <vector>
|
class NavBase;
|
||||||
|
|
||||||
class NavRegion;
|
|
||||||
|
|
||||||
namespace gd {
|
namespace gd {
|
||||||
struct Polygon;
|
struct Polygon;
|
||||||
@ -73,14 +71,18 @@ struct Point {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Edge {
|
struct Edge {
|
||||||
/// This edge ID
|
|
||||||
int this_edge;
|
|
||||||
|
|
||||||
/// The gateway in the edge, as, in some case, the whole edge might not be navigable.
|
/// The gateway in the edge, as, in some case, the whole edge might not be navigable.
|
||||||
struct Connection {
|
struct Connection {
|
||||||
|
/// Polygon that this connection leads to.
|
||||||
Polygon *polygon;
|
Polygon *polygon;
|
||||||
|
|
||||||
|
/// Edge of the source polygon where this connection starts from.
|
||||||
int edge;
|
int edge;
|
||||||
|
|
||||||
|
/// Point on the edge where the gateway leading to the poly starts.
|
||||||
Vector3 pathway_start;
|
Vector3 pathway_start;
|
||||||
|
|
||||||
|
/// Point on the edge where the gateway leading to the poly ends.
|
||||||
Vector3 pathway_end;
|
Vector3 pathway_end;
|
||||||
|
|
||||||
Connection() {
|
Connection() {
|
||||||
@ -89,20 +91,21 @@ struct Edge {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Connections from this edge to other polygons.
|
||||||
Vector<Connection> connections;
|
Vector<Connection> connections;
|
||||||
|
|
||||||
Edge() {
|
Edge() {
|
||||||
this_edge = -1;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Polygon {
|
struct Polygon {
|
||||||
NavRegion *owner;
|
/// Navigation region or link that contains this polygon.
|
||||||
|
NavBase *owner;
|
||||||
|
|
||||||
/// The points of this `Polygon`
|
/// The points of this `Polygon`
|
||||||
LocalVector<Point> points;
|
LocalVector<Point> points;
|
||||||
|
|
||||||
/// Are the points clockwise ?
|
/// Are the points clockwise?
|
||||||
bool clockwise;
|
bool clockwise;
|
||||||
|
|
||||||
/// The edges of this `Polygon`
|
/// The edges of this `Polygon`
|
||||||
@ -123,7 +126,7 @@ struct NavigationPoly {
|
|||||||
|
|
||||||
/// Those 4 variables are used to travel the path backwards.
|
/// Those 4 variables are used to travel the path backwards.
|
||||||
int back_navigation_poly_id;
|
int back_navigation_poly_id;
|
||||||
uint32_t back_navigation_edge;
|
int back_navigation_edge;
|
||||||
Vector3 back_navigation_edge_pathway_start;
|
Vector3 back_navigation_edge_pathway_start;
|
||||||
Vector3 back_navigation_edge_pathway_end;
|
Vector3 back_navigation_edge_pathway_end;
|
||||||
|
|
||||||
@ -141,7 +144,7 @@ struct NavigationPoly {
|
|||||||
back_navigation_poly_id = -1;
|
back_navigation_poly_id = -1;
|
||||||
back_navigation_edge = UINT32_MAX;
|
back_navigation_edge = UINT32_MAX;
|
||||||
|
|
||||||
back_navigation_edge = 0;
|
back_navigation_edge = -1;
|
||||||
traveled_distance = 0.0;
|
traveled_distance = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,12 @@
|
|||||||
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0)); \
|
return NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FORWARD_1_R_C(CONV_R, FUNC_NAME, T_0, D_0, CONV_0) \
|
||||||
|
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0) \
|
||||||
|
const { \
|
||||||
|
return CONV_R(NavigationServer::get_singleton()->FUNC_NAME(CONV_0(D_0))); \
|
||||||
|
}
|
||||||
|
|
||||||
#define FORWARD_2_C(FUNC_NAME, T_0, D_0, T_1, D_1, CONV_0, CONV_1) \
|
#define FORWARD_2_C(FUNC_NAME, T_0, D_0, T_1, D_1, CONV_0, CONV_1) \
|
||||||
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1) \
|
PandemoniumNavigation2DServer::FUNC_NAME(T_0 D_0, T_1 D_1) \
|
||||||
const { \
|
const { \
|
||||||
@ -194,6 +200,8 @@ PandemoniumNavigation2DServer::~PandemoniumNavigation2DServer() {
|
|||||||
|
|
||||||
Array FORWARD_0_C(get_maps);
|
Array FORWARD_0_C(get_maps);
|
||||||
|
|
||||||
|
Array FORWARD_1_C(map_get_links, RID, p_map, rid_to_rid);
|
||||||
|
|
||||||
Array FORWARD_1_C(map_get_regions, RID, p_map, rid_to_rid);
|
Array FORWARD_1_C(map_get_regions, RID, p_map, rid_to_rid);
|
||||||
|
|
||||||
Array FORWARD_1_C(map_get_agents, RID, p_map, rid_to_rid);
|
Array FORWARD_1_C(map_get_agents, RID, p_map, rid_to_rid);
|
||||||
@ -221,6 +229,9 @@ real_t FORWARD_1_C(map_get_cell_height, RID, p_map, rid_to_rid);
|
|||||||
void FORWARD_2_C(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin, rid_to_rid, real_to_real);
|
void FORWARD_2_C(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin, rid_to_rid, real_to_real);
|
||||||
real_t FORWARD_1_C(map_get_edge_connection_margin, RID, p_map, rid_to_rid);
|
real_t FORWARD_1_C(map_get_edge_connection_margin, RID, p_map, rid_to_rid);
|
||||||
|
|
||||||
|
void FORWARD_2_C(map_set_link_connection_radius, RID, p_map, real_t, p_connection_radius, rid_to_rid, real_to_real);
|
||||||
|
real_t FORWARD_1_C(map_get_link_connection_radius, RID, p_map, rid_to_rid);
|
||||||
|
|
||||||
Vector<Vector2> FORWARD_5_R_C(vector_v3_to_v2, map_get_path, RID, p_map, Vector2, p_origin, Vector2, p_destination, bool, p_optimize, uint32_t, p_navigation_layers, rid_to_rid, v2_to_v3, v2_to_v3, bool_to_bool, uint32_to_uint32);
|
Vector<Vector2> FORWARD_5_R_C(vector_v3_to_v2, map_get_path, RID, p_map, Vector2, p_origin, Vector2, p_destination, bool, p_optimize, uint32_t, p_navigation_layers, rid_to_rid, v2_to_v3, v2_to_v3, bool_to_bool, uint32_to_uint32);
|
||||||
|
|
||||||
Vector2 FORWARD_2_R_C(v3_to_v2, map_get_closest_point, RID, p_map, const Vector2 &, p_point, rid_to_rid, v2_to_v3);
|
Vector2 FORWARD_2_R_C(v3_to_v2, map_get_closest_point, RID, p_map, const Vector2 &, p_point, rid_to_rid, v2_to_v3);
|
||||||
@ -247,6 +258,23 @@ int FORWARD_1_C(region_get_connections_count, RID, p_region, rid_to_rid);
|
|||||||
Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_start, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int);
|
Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_start, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int);
|
||||||
Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_end, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int);
|
Vector2 FORWARD_2_R_C(v3_to_v2, region_get_connection_pathway_end, RID, p_region, int, p_connection_id, rid_to_rid, int_to_int);
|
||||||
|
|
||||||
|
RID FORWARD_0_C(link_create);
|
||||||
|
|
||||||
|
void FORWARD_2_C(link_set_map, RID, p_link, RID, p_map, rid_to_rid, rid_to_rid);
|
||||||
|
RID FORWARD_1_C(link_get_map, RID, p_link, rid_to_rid);
|
||||||
|
void FORWARD_2_C(link_set_bidirectional, RID, p_link, bool, p_bidirectional, rid_to_rid, bool_to_bool);
|
||||||
|
bool FORWARD_1_C(link_is_bidirectional, RID, p_link, rid_to_rid);
|
||||||
|
void FORWARD_2_C(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers, rid_to_rid, uint32_to_uint32);
|
||||||
|
uint32_t FORWARD_1_C(link_get_navigation_layers, RID, p_link, rid_to_rid);
|
||||||
|
void FORWARD_2_C(link_set_start_location, RID, p_link, Vector2, p_location, rid_to_rid, v2_to_v3);
|
||||||
|
Vector2 FORWARD_1_R_C(v3_to_v2, link_get_start_location, RID, p_link, rid_to_rid);
|
||||||
|
void FORWARD_2_C(link_set_end_location, RID, p_link, Vector2, p_location, rid_to_rid, v2_to_v3);
|
||||||
|
Vector2 FORWARD_1_R_C(v3_to_v2, link_get_end_location, RID, p_link, rid_to_rid);
|
||||||
|
void FORWARD_2_C(link_set_enter_cost, RID, p_link, real_t, p_enter_cost, rid_to_rid, real_to_real);
|
||||||
|
real_t FORWARD_1_C(link_get_enter_cost, RID, p_link, rid_to_rid);
|
||||||
|
void FORWARD_2_C(link_set_travel_cost, RID, p_link, real_t, p_travel_cost, rid_to_rid, real_to_real);
|
||||||
|
real_t FORWARD_1_C(link_get_travel_cost, RID, p_link, rid_to_rid);
|
||||||
|
|
||||||
RID PandemoniumNavigation2DServer::agent_create() const {
|
RID PandemoniumNavigation2DServer::agent_create() const {
|
||||||
RID agent = NavigationServer::get_singleton()->agent_create();
|
RID agent = NavigationServer::get_singleton()->agent_create();
|
||||||
NavigationServer::get_singleton()->agent_set_ignore_y(agent, true);
|
NavigationServer::get_singleton()->agent_set_ignore_y(agent, true);
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#include "core/object/object.h"
|
|
||||||
#include "core/containers/rid.h"
|
#include "core/containers/rid.h"
|
||||||
|
#include "core/object/object.h"
|
||||||
#include "scene/resources/navigation_polygon.h"
|
#include "scene/resources/navigation_polygon.h"
|
||||||
#include "servers/navigation_2d_server.h"
|
#include "servers/navigation_2d_server.h"
|
||||||
|
|
||||||
@ -73,12 +73,19 @@ public:
|
|||||||
/// Returns the edge connection margin of this map.
|
/// Returns the edge connection margin of this map.
|
||||||
virtual real_t map_get_edge_connection_margin(RID p_map) const;
|
virtual real_t map_get_edge_connection_margin(RID p_map) const;
|
||||||
|
|
||||||
|
/// Set the map link connection radius used to attach links to the nav mesh.
|
||||||
|
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) const;
|
||||||
|
|
||||||
|
/// Returns the link connection radius of this map.
|
||||||
|
virtual real_t map_get_link_connection_radius(RID p_map) const;
|
||||||
|
|
||||||
/// Returns the navigation path to reach the destination from the origin.
|
/// Returns the navigation path to reach the destination from the origin.
|
||||||
virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const;
|
virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const;
|
||||||
|
|
||||||
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const;
|
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const;
|
||||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const;
|
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const;
|
||||||
|
|
||||||
|
virtual Array map_get_links(RID p_map) const;
|
||||||
virtual Array map_get_regions(RID p_map) const;
|
virtual Array map_get_regions(RID p_map) const;
|
||||||
virtual Array map_get_agents(RID p_map) const;
|
virtual Array map_get_agents(RID p_map) const;
|
||||||
|
|
||||||
@ -116,6 +123,37 @@ public:
|
|||||||
virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const;
|
virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const;
|
||||||
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const;
|
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const;
|
||||||
|
|
||||||
|
/// Creates a new link between locations in the nav map.
|
||||||
|
virtual RID link_create() const;
|
||||||
|
|
||||||
|
/// Set the map of this link.
|
||||||
|
virtual void link_set_map(RID p_link, RID p_map) const;
|
||||||
|
virtual RID link_get_map(RID p_link) const;
|
||||||
|
|
||||||
|
/// Set whether this link travels in both directions.
|
||||||
|
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) const;
|
||||||
|
virtual bool link_is_bidirectional(RID p_link) const;
|
||||||
|
|
||||||
|
/// Set the link's layers.
|
||||||
|
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) const;
|
||||||
|
virtual uint32_t link_get_navigation_layers(RID p_link) const;
|
||||||
|
|
||||||
|
/// Set the start location of the link.
|
||||||
|
virtual void link_set_start_location(RID p_link, Vector2 p_location) const;
|
||||||
|
virtual Vector2 link_get_start_location(RID p_link) const;
|
||||||
|
|
||||||
|
/// Set the end location of the link.
|
||||||
|
virtual void link_set_end_location(RID p_link, Vector2 p_location) const;
|
||||||
|
virtual Vector2 link_get_end_location(RID p_link) const;
|
||||||
|
|
||||||
|
/// Set the enter cost of the link.
|
||||||
|
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) const;
|
||||||
|
virtual real_t link_get_enter_cost(RID p_link) const;
|
||||||
|
|
||||||
|
/// Set the travel cost of the link.
|
||||||
|
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) const;
|
||||||
|
virtual real_t link_get_travel_cost(RID p_link) const;
|
||||||
|
|
||||||
/// Creates the agent.
|
/// Creates the agent.
|
||||||
virtual RID agent_create() const;
|
virtual RID agent_create() const;
|
||||||
|
|
||||||
|
@ -228,6 +228,20 @@ real_t PandemoniumNavigationServer::map_get_edge_connection_margin(RID p_map) co
|
|||||||
return map->get_edge_connection_margin();
|
return map->get_edge_connection_margin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COMMAND_2(map_set_link_connection_radius, RID, p_map, real_t, p_connection_radius) {
|
||||||
|
NavMap *map = map_owner.getornull(p_map);
|
||||||
|
ERR_FAIL_COND(map == nullptr);
|
||||||
|
|
||||||
|
map->set_link_connection_radius(p_connection_radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
real_t PandemoniumNavigationServer::map_get_link_connection_radius(RID p_map) const {
|
||||||
|
const NavMap *map = map_owner.getornull(p_map);
|
||||||
|
ERR_FAIL_COND_V(map == nullptr, 0);
|
||||||
|
|
||||||
|
return map->get_link_connection_radius();
|
||||||
|
}
|
||||||
|
|
||||||
Vector<Vector3> PandemoniumNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const {
|
Vector<Vector3> PandemoniumNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const {
|
||||||
const NavMap *map = map_owner.getornull(p_map);
|
const NavMap *map = map_owner.getornull(p_map);
|
||||||
ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>());
|
ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>());
|
||||||
@ -263,6 +277,20 @@ RID PandemoniumNavigationServer::map_get_closest_point_owner(RID p_map, const Ve
|
|||||||
return map->get_closest_point_owner(p_point);
|
return map->get_closest_point_owner(p_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array PandemoniumNavigationServer::map_get_links(RID p_map) const {
|
||||||
|
Array link_rids;
|
||||||
|
const NavMap *map = map_owner.getornull(p_map);
|
||||||
|
ERR_FAIL_COND_V(map == nullptr, link_rids);
|
||||||
|
|
||||||
|
const LocalVector<NavLink *> links = map->get_links();
|
||||||
|
link_rids.resize(links.size());
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < links.size(); i++) {
|
||||||
|
link_rids[i] = links[i]->get_self();
|
||||||
|
}
|
||||||
|
return link_rids;
|
||||||
|
}
|
||||||
|
|
||||||
Array PandemoniumNavigationServer::map_get_regions(RID p_map) const {
|
Array PandemoniumNavigationServer::map_get_regions(RID p_map) const {
|
||||||
Array regions_rids;
|
Array regions_rids;
|
||||||
const NavMap *map = map_owner.getornull(p_map);
|
const NavMap *map = map_owner.getornull(p_map);
|
||||||
@ -434,6 +462,131 @@ Vector3 PandemoniumNavigationServer::region_get_connection_pathway_end(RID p_reg
|
|||||||
return region->get_connection_pathway_end(p_connection_id);
|
return region->get_connection_pathway_end(p_connection_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RID PandemoniumNavigationServer::link_create() const {
|
||||||
|
PandemoniumNavigationServer *mut_this = const_cast<PandemoniumNavigationServer *>(this);
|
||||||
|
MutexLock lock(mut_this->operations_mutex);
|
||||||
|
NavLink *link = memnew(NavLink);
|
||||||
|
RID rid = link_owner.make_rid(link);
|
||||||
|
link->set_self(rid);
|
||||||
|
return rid;
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND_2(link_set_map, RID, p_link, RID, p_map) {
|
||||||
|
NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND(link == nullptr);
|
||||||
|
|
||||||
|
if (link->get_map() != nullptr) {
|
||||||
|
if (link->get_map()->get_self() == p_map) {
|
||||||
|
return; // Pointless
|
||||||
|
}
|
||||||
|
|
||||||
|
link->get_map()->remove_link(link);
|
||||||
|
link->set_map(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_map.is_valid()) {
|
||||||
|
NavMap *map = map_owner.getornull(p_map);
|
||||||
|
ERR_FAIL_COND(map == nullptr);
|
||||||
|
|
||||||
|
map->add_link(link);
|
||||||
|
link->set_map(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RID PandemoniumNavigationServer::link_get_map(const RID p_link) const {
|
||||||
|
const NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND_V(link == nullptr, RID());
|
||||||
|
|
||||||
|
if (link->get_map()) {
|
||||||
|
return link->get_map()->get_self();
|
||||||
|
}
|
||||||
|
return RID();
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional) {
|
||||||
|
NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND(link == nullptr);
|
||||||
|
|
||||||
|
link->set_bidirectional(p_bidirectional);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PandemoniumNavigationServer::link_is_bidirectional(RID p_link) const {
|
||||||
|
const NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND_V(link == nullptr, false);
|
||||||
|
|
||||||
|
return link->is_bidirectional();
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers) {
|
||||||
|
NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND(link == nullptr);
|
||||||
|
|
||||||
|
link->set_navigation_layers(p_navigation_layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PandemoniumNavigationServer::link_get_navigation_layers(const RID p_link) const {
|
||||||
|
const NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND_V(link == nullptr, 0);
|
||||||
|
|
||||||
|
return link->get_navigation_layers();
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND_2(link_set_start_location, RID, p_link, Vector3, p_location) {
|
||||||
|
NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND(link == nullptr);
|
||||||
|
|
||||||
|
link->set_start_position(p_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 PandemoniumNavigationServer::link_get_start_location(RID p_link) const {
|
||||||
|
const NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND_V(link == nullptr, Vector3());
|
||||||
|
|
||||||
|
return link->get_start_position();
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND_2(link_set_end_location, RID, p_link, Vector3, p_location) {
|
||||||
|
NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND(link == nullptr);
|
||||||
|
|
||||||
|
link->set_end_position(p_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 PandemoniumNavigationServer::link_get_end_location(RID p_link) const {
|
||||||
|
const NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND_V(link == nullptr, Vector3());
|
||||||
|
|
||||||
|
return link->get_end_position();
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND_2(link_set_enter_cost, RID, p_link, real_t, p_enter_cost) {
|
||||||
|
NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND(link == nullptr);
|
||||||
|
|
||||||
|
link->set_enter_cost(p_enter_cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
real_t PandemoniumNavigationServer::link_get_enter_cost(const RID p_link) const {
|
||||||
|
const NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND_V(link == nullptr, 0);
|
||||||
|
|
||||||
|
return link->get_enter_cost();
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMAND_2(link_set_travel_cost, RID, p_link, real_t, p_travel_cost) {
|
||||||
|
NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND(link == nullptr);
|
||||||
|
|
||||||
|
link->set_travel_cost(p_travel_cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
real_t PandemoniumNavigationServer::link_get_travel_cost(const RID p_link) const {
|
||||||
|
const NavLink *link = link_owner.getornull(p_link);
|
||||||
|
ERR_FAIL_COND_V(link == nullptr, 0);
|
||||||
|
|
||||||
|
return link->get_travel_cost();
|
||||||
|
}
|
||||||
|
|
||||||
RID PandemoniumNavigationServer::agent_create() const {
|
RID PandemoniumNavigationServer::agent_create() const {
|
||||||
PandemoniumNavigationServer *mut_this = const_cast<PandemoniumNavigationServer *>(this);
|
PandemoniumNavigationServer *mut_this = const_cast<PandemoniumNavigationServer *>(this);
|
||||||
MutexLock lock(mut_this->operations_mutex);
|
MutexLock lock(mut_this->operations_mutex);
|
||||||
@ -571,6 +724,13 @@ COMMAND_1(free, RID, p_object) {
|
|||||||
regions[i]->set_map(nullptr);
|
regions[i]->set_map(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Removes any assigned links
|
||||||
|
LocalVector<NavLink *> links = map->get_links();
|
||||||
|
for (uint32_t i = 0; i < links.size(); i++) {
|
||||||
|
map->remove_link(links[i]);
|
||||||
|
links[i]->set_map(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove any assigned agent
|
// Remove any assigned agent
|
||||||
LocalVector<RvoAgent *> agents = map->get_agents();
|
LocalVector<RvoAgent *> agents = map->get_agents();
|
||||||
for (uint32_t i = 0; i < agents.size(); i++) {
|
for (uint32_t i = 0; i < agents.size(); i++) {
|
||||||
@ -596,6 +756,17 @@ COMMAND_1(free, RID, p_object) {
|
|||||||
region_owner.free(p_object);
|
region_owner.free(p_object);
|
||||||
memdelete(region);
|
memdelete(region);
|
||||||
|
|
||||||
|
} else if (link_owner.owns(p_object)) {
|
||||||
|
NavLink *link = link_owner.getornull(p_object);
|
||||||
|
|
||||||
|
// Removes this link from the map if assigned
|
||||||
|
if (link->get_map() != nullptr) {
|
||||||
|
link->get_map()->remove_link(link);
|
||||||
|
link->set_map(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
link_owner.free(p_object);
|
||||||
|
|
||||||
} else if (agent_owner.owns(p_object)) {
|
} else if (agent_owner.owns(p_object)) {
|
||||||
RvoAgent *agent = agent_owner.getornull(p_object);
|
RvoAgent *agent = agent_owner.getornull(p_object);
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#include "servers/navigation_server.h"
|
#include "servers/navigation_server.h"
|
||||||
|
|
||||||
#include "core/containers/rid.h"
|
#include "core/containers/rid.h"
|
||||||
|
|
||||||
|
#include "nav_link.h"
|
||||||
#include "nav_map.h"
|
#include "nav_map.h"
|
||||||
#include "nav_region.h"
|
#include "nav_region.h"
|
||||||
#include "rvo_agent.h"
|
#include "rvo_agent.h"
|
||||||
@ -68,6 +70,7 @@ class PandemoniumNavigationServer : public NavigationServer {
|
|||||||
|
|
||||||
LocalVector<SetCommand *> commands;
|
LocalVector<SetCommand *> commands;
|
||||||
|
|
||||||
|
mutable RID_Owner<NavLink> link_owner;
|
||||||
mutable RID_Owner<NavMap> map_owner;
|
mutable RID_Owner<NavMap> map_owner;
|
||||||
mutable RID_Owner<NavRegion> region_owner;
|
mutable RID_Owner<NavRegion> region_owner;
|
||||||
mutable RID_Owner<RvoAgent> agent_owner;
|
mutable RID_Owner<RvoAgent> agent_owner;
|
||||||
@ -100,6 +103,9 @@ public:
|
|||||||
COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin);
|
COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin);
|
||||||
virtual real_t map_get_edge_connection_margin(RID p_map) const;
|
virtual real_t map_get_edge_connection_margin(RID p_map) const;
|
||||||
|
|
||||||
|
COMMAND_2(map_set_link_connection_radius, RID, p_map, real_t, p_connection_radius);
|
||||||
|
virtual real_t map_get_link_connection_radius(RID p_map) const;
|
||||||
|
|
||||||
virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers = 1) const;
|
virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers = 1) const;
|
||||||
|
|
||||||
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const;
|
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const;
|
||||||
@ -107,6 +113,7 @@ public:
|
|||||||
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const;
|
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const;
|
||||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const;
|
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const;
|
||||||
|
|
||||||
|
virtual Array map_get_links(RID p_map) const;
|
||||||
virtual Array map_get_regions(RID p_map) const;
|
virtual Array map_get_regions(RID p_map) const;
|
||||||
virtual Array map_get_agents(RID p_map) const;
|
virtual Array map_get_agents(RID p_map) const;
|
||||||
|
|
||||||
@ -132,6 +139,22 @@ public:
|
|||||||
virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const;
|
virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const;
|
||||||
virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const;
|
virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const;
|
||||||
|
|
||||||
|
virtual RID link_create() const;
|
||||||
|
COMMAND_2(link_set_map, RID, p_link, RID, p_map);
|
||||||
|
virtual RID link_get_map(RID p_link) const;
|
||||||
|
COMMAND_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional);
|
||||||
|
virtual bool link_is_bidirectional(RID p_link) const;
|
||||||
|
COMMAND_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers);
|
||||||
|
virtual uint32_t link_get_navigation_layers(RID p_link) const;
|
||||||
|
COMMAND_2(link_set_start_location, RID, p_link, Vector3, p_location);
|
||||||
|
virtual Vector3 link_get_start_location(RID p_link) const;
|
||||||
|
COMMAND_2(link_set_end_location, RID, p_link, Vector3, p_location);
|
||||||
|
virtual Vector3 link_get_end_location(RID p_link) const;
|
||||||
|
COMMAND_2(link_set_enter_cost, RID, p_link, real_t, p_enter_cost);
|
||||||
|
virtual real_t link_get_enter_cost(RID p_link) const;
|
||||||
|
COMMAND_2(link_set_travel_cost, RID, p_link, real_t, p_travel_cost);
|
||||||
|
virtual real_t link_get_travel_cost(RID p_link) const;
|
||||||
|
|
||||||
virtual RID agent_create() const;
|
virtual RID agent_create() const;
|
||||||
COMMAND_2(agent_set_map, RID, p_agent, RID, p_map);
|
COMMAND_2(agent_set_map, RID, p_agent, RID, p_map);
|
||||||
virtual RID agent_get_map(RID p_agent) const;
|
virtual RID agent_get_map(RID p_agent) const;
|
||||||
|
@ -20,9 +20,15 @@ public:
|
|||||||
virtual real_t map_get_cell_height(RID p_map) const { return 0; }
|
virtual real_t map_get_cell_height(RID p_map) const { return 0; }
|
||||||
virtual void map_set_edge_connection_margin(RID p_map, real_t p_connection_margin) const {}
|
virtual void map_set_edge_connection_margin(RID p_map, real_t p_connection_margin) const {}
|
||||||
virtual real_t map_get_edge_connection_margin(RID p_map) const { return 0; }
|
virtual real_t map_get_edge_connection_margin(RID p_map) const { return 0; }
|
||||||
|
|
||||||
|
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) const {}
|
||||||
|
virtual real_t map_get_link_connection_radius(RID p_map) const { return 0; }
|
||||||
|
|
||||||
virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const { return Vector<Vector2>(); }
|
virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const { return Vector<Vector2>(); }
|
||||||
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const { return Vector2(); }
|
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const { return Vector2(); }
|
||||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const { return RID(); }
|
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const { return RID(); }
|
||||||
|
|
||||||
|
virtual Array map_get_links(RID p_map) const { return Array(); }
|
||||||
virtual Array map_get_regions(RID p_map) const { return Array(); }
|
virtual Array map_get_regions(RID p_map) const { return Array(); }
|
||||||
virtual Array map_get_agents(RID p_map) const { return Array(); }
|
virtual Array map_get_agents(RID p_map) const { return Array(); }
|
||||||
virtual void map_force_update(RID p_map) {}
|
virtual void map_force_update(RID p_map) {}
|
||||||
@ -43,6 +49,22 @@ public:
|
|||||||
virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const { return Vector2(); }
|
virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const { return Vector2(); }
|
||||||
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const { return Vector2(); }
|
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const { return Vector2(); }
|
||||||
|
|
||||||
|
virtual RID link_create() const { return RID(); }
|
||||||
|
virtual void link_set_map(RID p_link, RID p_map) const {}
|
||||||
|
virtual RID link_get_map(RID p_link) const { return RID(); }
|
||||||
|
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) const {}
|
||||||
|
virtual bool link_is_bidirectional(RID p_link) const { return false; }
|
||||||
|
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) const {}
|
||||||
|
virtual uint32_t link_get_navigation_layers(RID p_link) const { return 0; }
|
||||||
|
virtual void link_set_start_location(RID p_link, Vector2 p_location) const {}
|
||||||
|
virtual Vector2 link_get_start_location(RID p_link) const { return Vector2(); }
|
||||||
|
virtual void link_set_end_location(RID p_link, Vector2 p_location) const {}
|
||||||
|
virtual Vector2 link_get_end_location(RID p_link) const { return Vector2(); }
|
||||||
|
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) const {}
|
||||||
|
virtual real_t link_get_enter_cost(RID p_link) const { return 0; }
|
||||||
|
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) const {}
|
||||||
|
virtual real_t link_get_travel_cost(RID p_link) const { return 0; }
|
||||||
|
|
||||||
virtual RID agent_create() const { return RID(); }
|
virtual RID agent_create() const { return RID(); }
|
||||||
virtual void agent_set_map(RID p_agent, RID p_map) const {}
|
virtual void agent_set_map(RID p_agent, RID p_map) const {}
|
||||||
virtual RID agent_get_map(RID p_agent) const { return RID(); }
|
virtual RID agent_get_map(RID p_agent) const { return RID(); }
|
||||||
|
@ -21,11 +21,16 @@ public:
|
|||||||
virtual real_t map_get_cell_height(RID p_map) const { return 0; }
|
virtual real_t map_get_cell_height(RID p_map) const { return 0; }
|
||||||
virtual void map_set_edge_connection_margin(RID p_map, real_t p_connection_margin) const {}
|
virtual void map_set_edge_connection_margin(RID p_map, real_t p_connection_margin) const {}
|
||||||
virtual real_t map_get_edge_connection_margin(RID p_map) const { return 0; }
|
virtual real_t map_get_edge_connection_margin(RID p_map) const { return 0; }
|
||||||
|
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) const {}
|
||||||
|
virtual real_t map_get_link_connection_radius(RID p_map) const { return 0; }
|
||||||
|
|
||||||
virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const { return Vector<Vector3>(); }
|
virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const { return Vector<Vector3>(); }
|
||||||
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const { return Vector3(); }
|
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const { return Vector3(); }
|
||||||
virtual Vector3 map_get_closest_point(RID p_map, const Vector3 &p_point) const { return Vector3(); }
|
virtual Vector3 map_get_closest_point(RID p_map, const Vector3 &p_point) const { return Vector3(); }
|
||||||
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const { return Vector3(); }
|
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const { return Vector3(); }
|
||||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const { return RID(); }
|
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const { return RID(); }
|
||||||
|
|
||||||
|
virtual Array map_get_links(RID p_map) const { return Array(); }
|
||||||
virtual Array map_get_regions(RID p_map) const { return Array(); }
|
virtual Array map_get_regions(RID p_map) const { return Array(); }
|
||||||
virtual Array map_get_agents(RID p_map) const { return Array(); }
|
virtual Array map_get_agents(RID p_map) const { return Array(); }
|
||||||
virtual void map_force_update(RID p_map) {}
|
virtual void map_force_update(RID p_map) {}
|
||||||
@ -46,6 +51,22 @@ public:
|
|||||||
virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const { return Vector3(); }
|
virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const { return Vector3(); }
|
||||||
virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const { return Vector3(); }
|
virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const { return Vector3(); }
|
||||||
|
|
||||||
|
virtual RID link_create() const { return RID(); }
|
||||||
|
virtual void link_set_map(RID p_link, RID p_map) const {}
|
||||||
|
virtual RID link_get_map(RID p_link) const { return RID(); }
|
||||||
|
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) const {}
|
||||||
|
virtual bool link_is_bidirectional(RID p_link) const { return false; }
|
||||||
|
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) const {}
|
||||||
|
virtual uint32_t link_get_navigation_layers(RID p_link) const { return 0; }
|
||||||
|
virtual void link_set_start_location(RID p_link, Vector3 p_location) const {}
|
||||||
|
virtual Vector3 link_get_start_location(RID p_link) const { return Vector3(); }
|
||||||
|
virtual void link_set_end_location(RID p_link, Vector3 p_location) const {}
|
||||||
|
virtual Vector3 link_get_end_location(RID p_link) const { return Vector3(); }
|
||||||
|
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) const {}
|
||||||
|
virtual real_t link_get_enter_cost(RID p_link) const { return 0; }
|
||||||
|
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) const {}
|
||||||
|
virtual real_t link_get_travel_cost(RID p_link) const { return 0; }
|
||||||
|
|
||||||
virtual RID agent_create() const { return RID(); }
|
virtual RID agent_create() const { return RID(); }
|
||||||
virtual void agent_set_map(RID p_agent, RID p_map) const {}
|
virtual void agent_set_map(RID p_agent, RID p_map) const {}
|
||||||
virtual RID agent_get_map(RID p_agent) const { return RID(); }
|
virtual RID agent_get_map(RID p_agent) const { return RID(); }
|
||||||
|
344
scene/2d/navigation_link_2d.cpp
Normal file
344
scene/2d/navigation_link_2d.cpp
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* navigation_link_2d.cpp */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "navigation_link_2d.h"
|
||||||
|
|
||||||
|
#include "core/config/engine.h"
|
||||||
|
#include "core/math/geometry.h"
|
||||||
|
#include "scene/resources/world_2d.h"
|
||||||
|
#include "servers/navigation_2d_server.h"
|
||||||
|
#include "servers/navigation_server.h"
|
||||||
|
|
||||||
|
void NavigationLink2D::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationLink2D::set_enabled);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationLink2D::is_enabled);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_bidirectional", "bidirectional"), &NavigationLink2D::set_bidirectional);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_bidirectional"), &NavigationLink2D::is_bidirectional);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationLink2D::set_navigation_layers);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationLink2D::get_navigation_layers);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationLink2D::set_navigation_layer_value);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationLink2D::get_navigation_layer_value);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_start_position", "position"), &NavigationLink2D::set_start_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationLink2D::get_start_position);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink2D::set_end_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink2D::get_end_position);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_global_start_position", "position"), &NavigationLink2D::set_global_start_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_global_start_position"), &NavigationLink2D::get_global_start_position);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_global_end_position", "position"), &NavigationLink2D::set_global_end_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_global_end_position"), &NavigationLink2D::get_global_end_position);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink2D::set_enter_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink2D::get_enter_cost);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_travel_cost", "travel_cost"), &NavigationLink2D::set_travel_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_travel_cost"), &NavigationLink2D::get_travel_cost);
|
||||||
|
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bidirectional"), "set_bidirectional", "is_bidirectional");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "start_position"), "set_start_position", "get_start_position");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "end_position"), "set_end_position", "get_end_position");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "enter_cost"), "set_enter_cost", "get_enter_cost");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "travel_cost"), "set_travel_cost", "get_travel_cost");
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::_notification(int p_what) {
|
||||||
|
switch (p_what) {
|
||||||
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
|
if (enabled) {
|
||||||
|
Navigation2DServer::get_singleton()->link_set_map(link, get_world_2d()->get_navigation_map());
|
||||||
|
}
|
||||||
|
current_global_transform = get_global_transform();
|
||||||
|
Navigation2DServer::get_singleton()->link_set_start_location(link, current_global_transform.xform(start_position));
|
||||||
|
Navigation2DServer::get_singleton()->link_set_end_location(link, current_global_transform.xform(end_position));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||||
|
set_physics_process_internal(true);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||||
|
set_physics_process_internal(false);
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
Transform2D new_global_transform = get_global_transform();
|
||||||
|
if (current_global_transform != new_global_transform) {
|
||||||
|
current_global_transform = new_global_transform;
|
||||||
|
Navigation2DServer::get_singleton()->link_set_start_location(link, current_global_transform.xform(start_position));
|
||||||
|
Navigation2DServer::get_singleton()->link_set_end_location(link, current_global_transform.xform(end_position));
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
Navigation2DServer::get_singleton()->link_set_map(link, RID());
|
||||||
|
} break;
|
||||||
|
case NOTIFICATION_DRAW: {
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_enabled())) {
|
||||||
|
Color color;
|
||||||
|
if (enabled) {
|
||||||
|
color = Navigation2DServer::get_singleton()->get_debug_navigation_link_connection_color();
|
||||||
|
} else {
|
||||||
|
color = Navigation2DServer::get_singleton()->get_debug_navigation_link_connection_disabled_color();
|
||||||
|
}
|
||||||
|
|
||||||
|
real_t radius = Navigation2DServer::get_singleton()->map_get_link_connection_radius(get_world_2d()->get_navigation_map());
|
||||||
|
|
||||||
|
draw_line(get_start_position(), get_end_position(), color);
|
||||||
|
draw_arc(get_start_position(), radius, 0, Math_TAU, 10, color);
|
||||||
|
draw_arc(get_end_position(), radius, 0, Math_TAU, 10, color);
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
Rect2 NavigationLink2D::_edit_get_rect() const {
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return Rect2();
|
||||||
|
}
|
||||||
|
|
||||||
|
real_t radius = Navigation2DServer::get_singleton()->map_get_link_connection_radius(get_world_2d()->get_navigation_map());
|
||||||
|
|
||||||
|
Rect2 rect(get_start_position(), Size2());
|
||||||
|
rect.expand_to(get_end_position());
|
||||||
|
rect.grow_by(radius);
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavigationLink2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
|
||||||
|
Point2 segment[2] = { get_start_position(), get_end_position() };
|
||||||
|
|
||||||
|
Vector2 closest_point = Geometry::get_closest_point_to_segment_2d(p_point, segment);
|
||||||
|
return p_point.distance_to(closest_point) < p_tolerance;
|
||||||
|
}
|
||||||
|
#endif // TOOLS_ENABLED
|
||||||
|
|
||||||
|
void NavigationLink2D::set_enabled(bool p_enabled) {
|
||||||
|
if (enabled == p_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled = p_enabled;
|
||||||
|
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enabled) {
|
||||||
|
Navigation2DServer::get_singleton()->link_set_map(link, RID());
|
||||||
|
} else {
|
||||||
|
Navigation2DServer::get_singleton()->link_set_map(link, get_world_2d()->get_navigation_map());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_enabled()) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::set_bidirectional(bool p_bidirectional) {
|
||||||
|
if (bidirectional == p_bidirectional) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bidirectional = p_bidirectional;
|
||||||
|
|
||||||
|
Navigation2DServer::get_singleton()->link_set_bidirectional(link, bidirectional);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::set_navigation_layers(uint32_t p_navigation_layers) {
|
||||||
|
if (navigation_layers == p_navigation_layers) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigation_layers = p_navigation_layers;
|
||||||
|
|
||||||
|
Navigation2DServer::get_singleton()->link_set_navigation_layers(link, navigation_layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::set_navigation_layer_value(int p_layer_number, bool p_value) {
|
||||||
|
ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||||
|
ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||||
|
|
||||||
|
uint32_t _navigation_layers = get_navigation_layers();
|
||||||
|
|
||||||
|
if (p_value) {
|
||||||
|
_navigation_layers |= 1 << (p_layer_number - 1);
|
||||||
|
} else {
|
||||||
|
_navigation_layers &= ~(1 << (p_layer_number - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
set_navigation_layers(_navigation_layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavigationLink2D::get_navigation_layer_value(int p_layer_number) const {
|
||||||
|
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||||
|
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||||
|
|
||||||
|
return get_navigation_layers() & (1 << (p_layer_number - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::set_start_position(Vector2 p_position) {
|
||||||
|
if (start_position.is_equal_approx(p_position)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_position = p_position;
|
||||||
|
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigation2DServer::get_singleton()->link_set_start_location(link, current_global_transform.xform(start_position));
|
||||||
|
|
||||||
|
update_configuration_warning();
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_enabled()) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::set_end_position(Vector2 p_position) {
|
||||||
|
if (end_position.is_equal_approx(p_position)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
end_position = p_position;
|
||||||
|
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigation2DServer::get_singleton()->link_set_end_location(link, current_global_transform.xform(end_position));
|
||||||
|
|
||||||
|
update_configuration_warning();
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (Engine::get_singleton()->is_editor_hint() || Navigation2DServer::get_singleton()->get_debug_enabled()) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::set_global_start_position(Vector2 p_position) {
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
set_start_position(to_local(p_position));
|
||||||
|
} else {
|
||||||
|
set_start_position(p_position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 NavigationLink2D::get_global_start_position() const {
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
return to_global(start_position);
|
||||||
|
} else {
|
||||||
|
return start_position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::set_global_end_position(Vector2 p_position) {
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
set_end_position(to_local(p_position));
|
||||||
|
} else {
|
||||||
|
set_end_position(p_position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 NavigationLink2D::get_global_end_position() const {
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
return to_global(end_position);
|
||||||
|
} else {
|
||||||
|
return end_position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::set_enter_cost(real_t p_enter_cost) {
|
||||||
|
ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive.");
|
||||||
|
if (Math::is_equal_approx(enter_cost, p_enter_cost)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enter_cost = p_enter_cost;
|
||||||
|
|
||||||
|
Navigation2DServer::get_singleton()->link_set_enter_cost(link, enter_cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink2D::set_travel_cost(real_t p_travel_cost) {
|
||||||
|
ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive.");
|
||||||
|
if (Math::is_equal_approx(travel_cost, p_travel_cost)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
travel_cost = p_travel_cost;
|
||||||
|
|
||||||
|
Navigation2DServer::get_singleton()->link_set_travel_cost(link, travel_cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
String NavigationLink2D::get_configuration_warning() const {
|
||||||
|
String warnings = Node::get_configuration_warning();
|
||||||
|
|
||||||
|
if (start_position.is_equal_approx(end_position)) {
|
||||||
|
warnings += RTR("NavigationLink2D start position should be different than the end position to be useful.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return warnings;
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationLink2D::NavigationLink2D() {
|
||||||
|
enabled = true;
|
||||||
|
bidirectional = true;
|
||||||
|
navigation_layers = 1;
|
||||||
|
enter_cost = 0.0;
|
||||||
|
travel_cost = 1.0;
|
||||||
|
|
||||||
|
link = Navigation2DServer::get_singleton()->link_create();
|
||||||
|
//Navigation2DServer::get_singleton()->link_set_owner_id(link, get_instance_id());
|
||||||
|
|
||||||
|
set_notify_transform(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationLink2D::~NavigationLink2D() {
|
||||||
|
ERR_FAIL_NULL(Navigation2DServer::get_singleton());
|
||||||
|
Navigation2DServer::get_singleton()->free(link);
|
||||||
|
link = RID();
|
||||||
|
}
|
96
scene/2d/navigation_link_2d.h
Normal file
96
scene/2d/navigation_link_2d.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#ifndef NAVIGATION_LINK_2D_H
|
||||||
|
#define NAVIGATION_LINK_2D_H
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/* navigation_link_2d.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "scene/2d/node_2d.h"
|
||||||
|
|
||||||
|
class NavigationLink2D : public Node2D {
|
||||||
|
GDCLASS(NavigationLink2D, Node2D);
|
||||||
|
|
||||||
|
bool enabled;
|
||||||
|
RID link;
|
||||||
|
bool bidirectional;
|
||||||
|
uint32_t navigation_layers;
|
||||||
|
Vector2 end_position;
|
||||||
|
Vector2 start_position;
|
||||||
|
real_t enter_cost;
|
||||||
|
real_t travel_cost;
|
||||||
|
|
||||||
|
Transform2D current_global_transform;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
void _notification(int p_what);
|
||||||
|
|
||||||
|
public:
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
virtual Rect2 _edit_get_rect() const;
|
||||||
|
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void set_enabled(bool p_enabled);
|
||||||
|
bool is_enabled() const { return enabled; }
|
||||||
|
|
||||||
|
void set_bidirectional(bool p_bidirectional);
|
||||||
|
bool is_bidirectional() const { return bidirectional; }
|
||||||
|
|
||||||
|
void set_navigation_layers(uint32_t p_navigation_layers);
|
||||||
|
uint32_t get_navigation_layers() const { return navigation_layers; }
|
||||||
|
|
||||||
|
void set_navigation_layer_value(int p_layer_number, bool p_value);
|
||||||
|
bool get_navigation_layer_value(int p_layer_number) const;
|
||||||
|
|
||||||
|
void set_start_position(Vector2 p_position);
|
||||||
|
Vector2 get_start_position() const { return start_position; }
|
||||||
|
|
||||||
|
void set_end_position(Vector2 p_position);
|
||||||
|
Vector2 get_end_position() const { return end_position; }
|
||||||
|
|
||||||
|
void set_global_start_position(Vector2 p_position);
|
||||||
|
Vector2 get_global_start_position() const;
|
||||||
|
|
||||||
|
void set_global_end_position(Vector2 p_position);
|
||||||
|
Vector2 get_global_end_position() const;
|
||||||
|
|
||||||
|
void set_enter_cost(real_t p_enter_cost);
|
||||||
|
real_t get_enter_cost() const { return enter_cost; }
|
||||||
|
|
||||||
|
void set_travel_cost(real_t p_travel_cost);
|
||||||
|
real_t get_travel_cost() const { return travel_cost; }
|
||||||
|
|
||||||
|
String get_configuration_warning() const;
|
||||||
|
|
||||||
|
NavigationLink2D();
|
||||||
|
~NavigationLink2D();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAVIGATION_LINK_2D_H
|
442
scene/3d/navigation_link_3d.cpp
Normal file
442
scene/3d/navigation_link_3d.cpp
Normal file
@ -0,0 +1,442 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* navigation_link_3d.cpp */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "navigation_link_3d.h"
|
||||||
|
|
||||||
|
#include "core/config/engine.h"
|
||||||
|
#include "scene/resources/mesh.h"
|
||||||
|
#include "scene/resources/world_3d.h"
|
||||||
|
#include "mesh_instance.h"
|
||||||
|
#include "servers/navigation_server.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
void NavigationLink3D::_update_debug_mesh() {
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
// don't update inside Editor as node 3d gizmo takes care of this
|
||||||
|
// as collisions and selections for Editor Viewport need to be updated
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NavigationServer::get_singleton()->get_debug_enabled()) {
|
||||||
|
if (debug_instance.is_valid()) {
|
||||||
|
RS::get_singleton()->instance_set_visible(debug_instance, false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!debug_instance.is_valid()) {
|
||||||
|
debug_instance = RenderingServer::get_singleton()->instance_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!debug_mesh.is_valid()) {
|
||||||
|
debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
|
||||||
|
}
|
||||||
|
|
||||||
|
RID nav_map = get_world_3d()->get_navigation_map();
|
||||||
|
real_t search_radius = NavigationServer::get_singleton()->map_get_link_connection_radius(nav_map);
|
||||||
|
Vector3 up_vector = NavigationServer::get_singleton()->map_get_up(nav_map);
|
||||||
|
Vector3::Axis up_axis = static_cast<Vector3::Axis>(up_vector.max_axis());
|
||||||
|
|
||||||
|
debug_mesh->clear_surfaces();
|
||||||
|
|
||||||
|
Vector<Vector3> lines;
|
||||||
|
|
||||||
|
// Draw line between the points.
|
||||||
|
lines.push_back(start_position);
|
||||||
|
lines.push_back(end_position);
|
||||||
|
|
||||||
|
// Draw start position search radius
|
||||||
|
for (int i = 0; i < 30; i++) {
|
||||||
|
// Create a circle
|
||||||
|
const float ra = Math::deg2rad((float)(i * 12));
|
||||||
|
const float rb = Math::deg2rad((float)((i + 1) * 12));
|
||||||
|
const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * search_radius;
|
||||||
|
const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * search_radius;
|
||||||
|
|
||||||
|
// Draw axis-aligned circle
|
||||||
|
switch (up_axis) {
|
||||||
|
case Vector3::AXIS_X:
|
||||||
|
lines.push_back(start_position + Vector3(0, a.x, a.y));
|
||||||
|
lines.push_back(start_position + Vector3(0, b.x, b.y));
|
||||||
|
break;
|
||||||
|
case Vector3::AXIS_Y:
|
||||||
|
lines.push_back(start_position + Vector3(a.x, 0, a.y));
|
||||||
|
lines.push_back(start_position + Vector3(b.x, 0, b.y));
|
||||||
|
break;
|
||||||
|
case Vector3::AXIS_Z:
|
||||||
|
lines.push_back(start_position + Vector3(a.x, a.y, 0));
|
||||||
|
lines.push_back(start_position + Vector3(b.x, b.y, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw end position search radius
|
||||||
|
for (int i = 0; i < 30; i++) {
|
||||||
|
// Create a circle
|
||||||
|
const float ra = Math::deg2rad((float)(i * 12));
|
||||||
|
const float rb = Math::deg2rad((float)((i + 1) * 12));
|
||||||
|
const Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * search_radius;
|
||||||
|
const Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * search_radius;
|
||||||
|
|
||||||
|
// Draw axis-aligned circle
|
||||||
|
switch (up_axis) {
|
||||||
|
case Vector3::AXIS_X:
|
||||||
|
lines.push_back(end_position + Vector3(0, a.x, a.y));
|
||||||
|
lines.push_back(end_position + Vector3(0, b.x, b.y));
|
||||||
|
break;
|
||||||
|
case Vector3::AXIS_Y:
|
||||||
|
lines.push_back(end_position + Vector3(a.x, 0, a.y));
|
||||||
|
lines.push_back(end_position + Vector3(b.x, 0, b.y));
|
||||||
|
break;
|
||||||
|
case Vector3::AXIS_Z:
|
||||||
|
lines.push_back(end_position + Vector3(a.x, a.y, 0));
|
||||||
|
lines.push_back(end_position + Vector3(b.x, b.y, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Array mesh_array;
|
||||||
|
mesh_array.resize(Mesh::ARRAY_MAX);
|
||||||
|
mesh_array[Mesh::ARRAY_VERTEX] = lines;
|
||||||
|
|
||||||
|
debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, mesh_array);
|
||||||
|
|
||||||
|
RS::get_singleton()->instance_set_base(debug_instance, debug_mesh->get_rid());
|
||||||
|
RS::get_singleton()->instance_set_scenario(debug_instance, get_world_3d()->get_scenario());
|
||||||
|
RS::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree());
|
||||||
|
|
||||||
|
Ref<SpatialMaterial> link_material = NavigationServer::get_singleton_mut()->get_debug_navigation_link_connections_material();
|
||||||
|
Ref<SpatialMaterial> disabled_link_material = NavigationServer::get_singleton_mut()->get_debug_navigation_link_connections_disabled_material();
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
RS::get_singleton()->instance_set_surface_material(debug_instance, 0, link_material->get_rid());
|
||||||
|
} else {
|
||||||
|
RS::get_singleton()->instance_set_surface_material(debug_instance, 0, disabled_link_material->get_rid());
|
||||||
|
}
|
||||||
|
|
||||||
|
RS::get_singleton()->instance_set_transform(debug_instance, current_global_transform);
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
|
void NavigationLink3D::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationLink3D::set_enabled);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationLink3D::is_enabled);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_bidirectional", "bidirectional"), &NavigationLink3D::set_bidirectional);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_bidirectional"), &NavigationLink3D::is_bidirectional);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationLink3D::set_navigation_layers);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationLink3D::get_navigation_layers);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationLink3D::set_navigation_layer_value);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationLink3D::get_navigation_layer_value);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_start_position", "position"), &NavigationLink3D::set_start_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_start_position"), &NavigationLink3D::get_start_position);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_end_position", "position"), &NavigationLink3D::set_end_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_end_position"), &NavigationLink3D::get_end_position);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_global_start_position", "position"), &NavigationLink3D::set_global_start_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_global_start_position"), &NavigationLink3D::get_global_start_position);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_global_end_position", "position"), &NavigationLink3D::set_global_end_position);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_global_end_position"), &NavigationLink3D::get_global_end_position);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationLink3D::set_enter_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationLink3D::get_enter_cost);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_travel_cost", "travel_cost"), &NavigationLink3D::set_travel_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_travel_cost"), &NavigationLink3D::get_travel_cost);
|
||||||
|
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bidirectional"), "set_bidirectional", "is_bidirectional");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "start_position"), "set_start_position", "get_start_position");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "end_position"), "set_end_position", "get_end_position");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "enter_cost"), "set_enter_cost", "get_enter_cost");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "travel_cost"), "set_travel_cost", "get_travel_cost");
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::_notification(int p_what) {
|
||||||
|
switch (p_what) {
|
||||||
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
|
if (enabled) {
|
||||||
|
NavigationServer::get_singleton()->link_set_map(link, get_world_3d()->get_navigation_map());
|
||||||
|
}
|
||||||
|
current_global_transform = get_global_transform();
|
||||||
|
NavigationServer::get_singleton()->link_set_start_location(link, current_global_transform.xform(start_position));
|
||||||
|
NavigationServer::get_singleton()->link_set_end_location(link, current_global_transform.xform(end_position));
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
_update_debug_mesh();
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||||
|
set_physics_process_internal(true);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||||
|
set_physics_process_internal(false);
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
Transform new_global_transform = get_global_transform();
|
||||||
|
if (current_global_transform != new_global_transform) {
|
||||||
|
current_global_transform = new_global_transform;
|
||||||
|
NavigationServer::get_singleton()->link_set_start_location(link, current_global_transform.xform(start_position));
|
||||||
|
NavigationServer::get_singleton()->link_set_end_location(link, current_global_transform.xform(end_position));
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (debug_instance.is_valid()) {
|
||||||
|
RS::get_singleton()->instance_set_transform(debug_instance, current_global_transform);
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
NavigationServer::get_singleton()->link_set_map(link, RID());
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (debug_instance.is_valid()) {
|
||||||
|
RS::get_singleton()->instance_set_scenario(debug_instance, RID());
|
||||||
|
RS::get_singleton()->instance_set_visible(debug_instance, false);
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationLink3D::NavigationLink3D() {
|
||||||
|
link = NavigationServer::get_singleton()->link_create();
|
||||||
|
//NavigationServer::get_singleton()->link_set_owner_id(link, get_instance_id());
|
||||||
|
|
||||||
|
set_notify_transform(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationLink3D::~NavigationLink3D() {
|
||||||
|
ERR_FAIL_NULL(NavigationServer::get_singleton());
|
||||||
|
NavigationServer::get_singleton()->free(link);
|
||||||
|
link = RID();
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
ERR_FAIL_NULL(RenderingServer::get_singleton());
|
||||||
|
if (debug_instance.is_valid()) {
|
||||||
|
RenderingServer::get_singleton()->free(debug_instance);
|
||||||
|
}
|
||||||
|
if (debug_mesh.is_valid()) {
|
||||||
|
RenderingServer::get_singleton()->free(debug_mesh->get_rid());
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_enabled(bool p_enabled) {
|
||||||
|
if (enabled == p_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled = p_enabled;
|
||||||
|
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
NavigationServer::get_singleton()->link_set_map(link, get_world_3d()->get_navigation_map());
|
||||||
|
} else {
|
||||||
|
NavigationServer::get_singleton()->link_set_map(link, RID());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (debug_instance.is_valid() && debug_mesh.is_valid()) {
|
||||||
|
if (enabled) {
|
||||||
|
Ref<SpatialMaterial> link_material = NavigationServer::get_singleton_mut()->get_debug_navigation_link_connections_material();
|
||||||
|
RS::get_singleton()->instance_set_surface_material(debug_instance, 0, link_material->get_rid());
|
||||||
|
} else {
|
||||||
|
Ref<SpatialMaterial> disabled_link_material = NavigationServer::get_singleton_mut()->get_debug_navigation_link_connections_disabled_material();
|
||||||
|
RS::get_singleton()->instance_set_surface_material(debug_instance, 0, disabled_link_material->get_rid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
|
update_gizmos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_bidirectional(bool p_bidirectional) {
|
||||||
|
if (bidirectional == p_bidirectional) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bidirectional = p_bidirectional;
|
||||||
|
|
||||||
|
NavigationServer::get_singleton()->link_set_bidirectional(link, bidirectional);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_navigation_layers(uint32_t p_navigation_layers) {
|
||||||
|
if (navigation_layers == p_navigation_layers) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigation_layers = p_navigation_layers;
|
||||||
|
|
||||||
|
NavigationServer::get_singleton()->link_set_navigation_layers(link, navigation_layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_navigation_layer_value(int p_layer_number, bool p_value) {
|
||||||
|
ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||||
|
ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||||
|
|
||||||
|
uint32_t _navigation_layers = get_navigation_layers();
|
||||||
|
|
||||||
|
if (p_value) {
|
||||||
|
_navigation_layers |= 1 << (p_layer_number - 1);
|
||||||
|
} else {
|
||||||
|
_navigation_layers &= ~(1 << (p_layer_number - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
set_navigation_layers(_navigation_layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavigationLink3D::get_navigation_layer_value(int p_layer_number) const {
|
||||||
|
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||||
|
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
|
||||||
|
|
||||||
|
return get_navigation_layers() & (1 << (p_layer_number - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_start_position(Vector3 p_position) {
|
||||||
|
if (start_position.is_equal_approx(p_position)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_position = p_position;
|
||||||
|
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationServer::get_singleton()->link_set_start_location(link, current_global_transform.xform(start_position));
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
_update_debug_mesh();
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
|
update_gizmos();
|
||||||
|
update_configuration_warning();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_end_position(Vector3 p_position) {
|
||||||
|
if (end_position.is_equal_approx(p_position)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
end_position = p_position;
|
||||||
|
|
||||||
|
if (!is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationServer::get_singleton()->link_set_end_location(link, current_global_transform.xform(end_position));
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
_update_debug_mesh();
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
|
update_gizmos();
|
||||||
|
update_configuration_warning();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_global_start_position(Vector3 p_position) {
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
set_start_position(to_local(p_position));
|
||||||
|
} else {
|
||||||
|
set_start_position(p_position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 NavigationLink3D::get_global_start_position() const {
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
return to_global(start_position);
|
||||||
|
} else {
|
||||||
|
return start_position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_global_end_position(Vector3 p_position) {
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
set_end_position(to_local(p_position));
|
||||||
|
} else {
|
||||||
|
set_end_position(p_position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 NavigationLink3D::get_global_end_position() const {
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
return to_global(end_position);
|
||||||
|
} else {
|
||||||
|
return end_position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_enter_cost(real_t p_enter_cost) {
|
||||||
|
ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive.");
|
||||||
|
if (Math::is_equal_approx(enter_cost, p_enter_cost)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enter_cost = p_enter_cost;
|
||||||
|
|
||||||
|
NavigationServer::get_singleton()->link_set_enter_cost(link, enter_cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationLink3D::set_travel_cost(real_t p_travel_cost) {
|
||||||
|
ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive.");
|
||||||
|
if (Math::is_equal_approx(travel_cost, p_travel_cost)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
travel_cost = p_travel_cost;
|
||||||
|
|
||||||
|
NavigationServer::get_singleton()->link_set_travel_cost(link, travel_cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
String NavigationLink3D::get_configuration_warning() const {
|
||||||
|
String warnings = Node::get_configuration_warning();
|
||||||
|
|
||||||
|
if (start_position.is_equal_approx(end_position)) {
|
||||||
|
warnings += RTR("NavigationLink3D start position should be different than the end position to be useful.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return warnings;
|
||||||
|
}
|
98
scene/3d/navigation_link_3d.h
Normal file
98
scene/3d/navigation_link_3d.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#ifndef NAVIGATION_LINK_3D_H
|
||||||
|
#define NAVIGATION_LINK_3D_H
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/* navigation_link_3d.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "scene/3d/spatial.h"
|
||||||
|
|
||||||
|
class NavigationLink3D : public Spatial {
|
||||||
|
GDCLASS(NavigationLink3D, Spatial);
|
||||||
|
|
||||||
|
bool enabled = true;
|
||||||
|
RID link;
|
||||||
|
bool bidirectional = true;
|
||||||
|
uint32_t navigation_layers = 1;
|
||||||
|
Vector3 end_position;
|
||||||
|
Vector3 start_position;
|
||||||
|
real_t enter_cost = 0.0;
|
||||||
|
real_t travel_cost = 1.0;
|
||||||
|
|
||||||
|
Transform current_global_transform;
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
RID debug_instance;
|
||||||
|
Ref<ArrayMesh> debug_mesh;
|
||||||
|
|
||||||
|
void _update_debug_mesh();
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
void _notification(int p_what);
|
||||||
|
|
||||||
|
public:
|
||||||
|
NavigationLink3D();
|
||||||
|
~NavigationLink3D();
|
||||||
|
|
||||||
|
void set_enabled(bool p_enabled);
|
||||||
|
bool is_enabled() const { return enabled; }
|
||||||
|
|
||||||
|
void set_bidirectional(bool p_bidirectional);
|
||||||
|
bool is_bidirectional() const { return bidirectional; }
|
||||||
|
|
||||||
|
void set_navigation_layers(uint32_t p_navigation_layers);
|
||||||
|
uint32_t get_navigation_layers() const { return navigation_layers; }
|
||||||
|
|
||||||
|
void set_navigation_layer_value(int p_layer_number, bool p_value);
|
||||||
|
bool get_navigation_layer_value(int p_layer_number) const;
|
||||||
|
|
||||||
|
void set_start_position(Vector3 p_position);
|
||||||
|
Vector3 get_start_position() const { return start_position; }
|
||||||
|
|
||||||
|
void set_end_position(Vector3 p_position);
|
||||||
|
Vector3 get_end_position() const { return end_position; }
|
||||||
|
|
||||||
|
void set_global_start_position(Vector3 p_position);
|
||||||
|
Vector3 get_global_start_position() const;
|
||||||
|
|
||||||
|
void set_global_end_position(Vector3 p_position);
|
||||||
|
Vector3 get_global_end_position() const;
|
||||||
|
|
||||||
|
void set_enter_cost(real_t p_enter_cost);
|
||||||
|
real_t get_enter_cost() const { return enter_cost; }
|
||||||
|
|
||||||
|
void set_travel_cost(real_t p_travel_cost);
|
||||||
|
real_t get_travel_cost() const { return travel_cost; }
|
||||||
|
|
||||||
|
String get_configuration_warning() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAVIGATION_LINK_3D_H
|
@ -54,6 +54,7 @@
|
|||||||
#include "scene/2d/navigation_2d.h"
|
#include "scene/2d/navigation_2d.h"
|
||||||
#include "scene/2d/navigation_agent_2d.h"
|
#include "scene/2d/navigation_agent_2d.h"
|
||||||
#include "scene/2d/navigation_geometry_parser_2d.h"
|
#include "scene/2d/navigation_geometry_parser_2d.h"
|
||||||
|
#include "scene/2d/navigation_link_2d.h"
|
||||||
#include "scene/2d/navigation_obstacle_2d.h"
|
#include "scene/2d/navigation_obstacle_2d.h"
|
||||||
#include "scene/2d/navigation_polygon_instance.h"
|
#include "scene/2d/navigation_polygon_instance.h"
|
||||||
#include "scene/2d/parallax_background.h"
|
#include "scene/2d/parallax_background.h"
|
||||||
@ -199,6 +200,7 @@
|
|||||||
#include "scene/3d/navigation.h"
|
#include "scene/3d/navigation.h"
|
||||||
#include "scene/3d/navigation_agent.h"
|
#include "scene/3d/navigation_agent.h"
|
||||||
#include "scene/3d/navigation_geometry_parser_3d.h"
|
#include "scene/3d/navigation_geometry_parser_3d.h"
|
||||||
|
#include "scene/3d/navigation_link_3d.h"
|
||||||
#include "scene/3d/navigation_mesh_instance.h"
|
#include "scene/3d/navigation_mesh_instance.h"
|
||||||
#include "scene/3d/navigation_obstacle.h"
|
#include "scene/3d/navigation_obstacle.h"
|
||||||
#include "scene/3d/occluder.h"
|
#include "scene/3d/occluder.h"
|
||||||
@ -499,6 +501,7 @@ void register_scene_types() {
|
|||||||
ClassDB::register_class<NavigationMeshInstance>();
|
ClassDB::register_class<NavigationMeshInstance>();
|
||||||
ClassDB::register_class<NavigationAgent>();
|
ClassDB::register_class<NavigationAgent>();
|
||||||
ClassDB::register_class<NavigationObstacle>();
|
ClassDB::register_class<NavigationObstacle>();
|
||||||
|
ClassDB::register_class<NavigationLink3D>();
|
||||||
|
|
||||||
OS::get_singleton()->yield(); //may take time to init
|
OS::get_singleton()->yield(); //may take time to init
|
||||||
|
|
||||||
@ -689,6 +692,7 @@ void register_scene_types() {
|
|||||||
ClassDB::register_class<NavigationPolygonInstance>();
|
ClassDB::register_class<NavigationPolygonInstance>();
|
||||||
ClassDB::register_class<NavigationAgent2D>();
|
ClassDB::register_class<NavigationAgent2D>();
|
||||||
ClassDB::register_class<NavigationObstacle2D>();
|
ClassDB::register_class<NavigationObstacle2D>();
|
||||||
|
ClassDB::register_class<NavigationLink2D>();
|
||||||
|
|
||||||
ClassDB::register_class<NavigationMeshSourceGeometryData2D>();
|
ClassDB::register_class<NavigationMeshSourceGeometryData2D>();
|
||||||
ClassDB::register_class<NavigationGeometryParser2D>();
|
ClassDB::register_class<NavigationGeometryParser2D>();
|
||||||
|
@ -384,6 +384,7 @@ World2D::World2D() {
|
|||||||
Navigation2DServer::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 1.0));
|
Navigation2DServer::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 1.0));
|
||||||
Navigation2DServer::get_singleton()->map_set_cell_height(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_height", 1.0));
|
Navigation2DServer::get_singleton()->map_set_cell_height(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_height", 1.0));
|
||||||
Navigation2DServer::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 1.0));
|
Navigation2DServer::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 1.0));
|
||||||
|
Navigation2DServer::get_singleton()->map_set_link_connection_radius(navigation_map, GLOBAL_DEF("navigation/2d/default_link_connection_radius", 4));
|
||||||
|
|
||||||
indexer = memnew(SpatialIndexer2D);
|
indexer = memnew(SpatialIndexer2D);
|
||||||
}
|
}
|
||||||
|
@ -364,6 +364,7 @@ World3D::World3D() {
|
|||||||
NavigationServer::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_size", 0.25));
|
NavigationServer::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_size", 0.25));
|
||||||
NavigationServer::get_singleton()->map_set_cell_height(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_height", 0.25));
|
NavigationServer::get_singleton()->map_set_cell_height(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_height", 0.25));
|
||||||
NavigationServer::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/3d/default_edge_connection_margin", 0.25));
|
NavigationServer::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/3d/default_edge_connection_margin", 0.25));
|
||||||
|
NavigationServer::get_singleton()->map_set_link_connection_radius(navigation_map, GLOBAL_DEF("navigation/3d/default_link_connection_radius", 1.0));
|
||||||
|
|
||||||
#ifdef _3D_DISABLED
|
#ifdef _3D_DISABLED
|
||||||
indexer = NULL;
|
indexer = NULL;
|
||||||
|
@ -49,10 +49,13 @@ void Navigation2DServer::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("map_get_cell_height", "map"), &Navigation2DServer::map_get_cell_size);
|
ClassDB::bind_method(D_METHOD("map_get_cell_height", "map"), &Navigation2DServer::map_get_cell_size);
|
||||||
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &Navigation2DServer::map_set_edge_connection_margin);
|
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &Navigation2DServer::map_set_edge_connection_margin);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &Navigation2DServer::map_get_edge_connection_margin);
|
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &Navigation2DServer::map_get_edge_connection_margin);
|
||||||
|
ClassDB::bind_method(D_METHOD("map_set_link_connection_radius", "map", "radius"), &Navigation2DServer::map_set_link_connection_radius);
|
||||||
|
ClassDB::bind_method(D_METHOD("map_get_link_connection_radius", "map"), &Navigation2DServer::map_get_link_connection_radius);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &Navigation2DServer::map_get_path, 1);
|
ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &Navigation2DServer::map_get_path, 1);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &Navigation2DServer::map_get_closest_point);
|
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &Navigation2DServer::map_get_closest_point);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &Navigation2DServer::map_get_closest_point_owner);
|
ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &Navigation2DServer::map_get_closest_point_owner);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("map_get_links", "map"), &Navigation2DServer::map_get_links);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &Navigation2DServer::map_get_regions);
|
ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &Navigation2DServer::map_get_regions);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &Navigation2DServer::map_get_agents);
|
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &Navigation2DServer::map_get_agents);
|
||||||
ClassDB::bind_method(D_METHOD("map_force_update", "map"), &Navigation2DServer::map_force_update);
|
ClassDB::bind_method(D_METHOD("map_force_update", "map"), &Navigation2DServer::map_force_update);
|
||||||
@ -73,6 +76,22 @@ void Navigation2DServer::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &Navigation2DServer::region_get_connection_pathway_start);
|
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &Navigation2DServer::region_get_connection_pathway_start);
|
||||||
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &Navigation2DServer::region_get_connection_pathway_end);
|
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &Navigation2DServer::region_get_connection_pathway_end);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("link_create"), &Navigation2DServer::link_create);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &Navigation2DServer::link_set_map);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_map", "link"), &Navigation2DServer::link_get_map);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_bidirectional", "link", "bidirectional"), &Navigation2DServer::link_set_bidirectional);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &Navigation2DServer::link_is_bidirectional);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &Navigation2DServer::link_set_navigation_layers);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_navigation_layers", "link"), &Navigation2DServer::link_get_navigation_layers);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_start_location", "link", "location"), &Navigation2DServer::link_set_start_location);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_start_location", "link"), &Navigation2DServer::link_get_start_location);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_end_location", "link", "location"), &Navigation2DServer::link_set_end_location);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_end_location", "link"), &Navigation2DServer::link_get_end_location);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_enter_cost", "link", "enter_cost"), &Navigation2DServer::link_set_enter_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &Navigation2DServer::link_get_enter_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &Navigation2DServer::link_set_travel_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_travel_cost", "link"), &Navigation2DServer::link_get_travel_cost);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("agent_create"), &Navigation2DServer::agent_create);
|
ClassDB::bind_method(D_METHOD("agent_create"), &Navigation2DServer::agent_create);
|
||||||
ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &Navigation2DServer::agent_set_map);
|
ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &Navigation2DServer::agent_set_map);
|
||||||
ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &Navigation2DServer::agent_get_map);
|
ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &Navigation2DServer::agent_get_map);
|
||||||
@ -112,6 +131,29 @@ Navigation2DServer::~Navigation2DServer() {
|
|||||||
singleton = nullptr;
|
singleton = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
void Navigation2DServer::set_debug_enabled(bool p_enabled) {
|
||||||
|
NavigationServer::get_singleton_mut()->set_debug_enabled(p_enabled);
|
||||||
|
}
|
||||||
|
bool Navigation2DServer::get_debug_enabled() const {
|
||||||
|
return NavigationServer::get_singleton()->get_debug_enabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Navigation2DServer::set_debug_navigation_link_connection_color(const Color &p_color) {
|
||||||
|
NavigationServer::get_singleton_mut()->set_debug_navigation_link_connection_color(p_color);
|
||||||
|
}
|
||||||
|
Color Navigation2DServer::get_debug_navigation_link_connection_color() const {
|
||||||
|
return NavigationServer::get_singleton()->get_debug_navigation_link_connection_color();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Navigation2DServer::set_debug_navigation_link_connection_disabled_color(const Color &p_color) {
|
||||||
|
NavigationServer::get_singleton_mut()->set_debug_navigation_link_connection_disabled_color(p_color);
|
||||||
|
}
|
||||||
|
Color Navigation2DServer::get_debug_navigation_link_connection_disabled_color() const {
|
||||||
|
return NavigationServer::get_singleton()->get_debug_navigation_link_connection_disabled_color();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Vector<Navigation2DServerManager::ClassInfo> Navigation2DServerManager::navigation_servers;
|
Vector<Navigation2DServerManager::ClassInfo> Navigation2DServerManager::navigation_servers;
|
||||||
int Navigation2DServerManager::default_server_id = -1;
|
int Navigation2DServerManager::default_server_id = -1;
|
||||||
int Navigation2DServerManager::default_server_priority = -1;
|
int Navigation2DServerManager::default_server_priority = -1;
|
||||||
|
@ -84,12 +84,19 @@ public:
|
|||||||
/// Returns the edge connection margin of this map.
|
/// Returns the edge connection margin of this map.
|
||||||
virtual real_t map_get_edge_connection_margin(RID p_map) const = 0;
|
virtual real_t map_get_edge_connection_margin(RID p_map) const = 0;
|
||||||
|
|
||||||
|
/// Set the map link connection radius used to attach links to the nav mesh.
|
||||||
|
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) const = 0;
|
||||||
|
|
||||||
|
/// Returns the link connection radius of this map.
|
||||||
|
virtual real_t map_get_link_connection_radius(RID p_map) const = 0;
|
||||||
|
|
||||||
/// Returns the navigation path to reach the destination from the origin.
|
/// Returns the navigation path to reach the destination from the origin.
|
||||||
virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const = 0;
|
virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const = 0;
|
||||||
|
|
||||||
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const = 0;
|
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const = 0;
|
||||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const = 0;
|
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const = 0;
|
||||||
|
|
||||||
|
virtual Array map_get_links(RID p_map) const = 0;
|
||||||
virtual Array map_get_regions(RID p_map) const = 0;
|
virtual Array map_get_regions(RID p_map) const = 0;
|
||||||
virtual Array map_get_agents(RID p_map) const = 0;
|
virtual Array map_get_agents(RID p_map) const = 0;
|
||||||
|
|
||||||
@ -127,6 +134,37 @@ public:
|
|||||||
virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const = 0;
|
virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const = 0;
|
||||||
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const = 0;
|
virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const = 0;
|
||||||
|
|
||||||
|
/// Creates a new link between locations in the nav map.
|
||||||
|
virtual RID link_create() const = 0;
|
||||||
|
|
||||||
|
/// Set the map of this link.
|
||||||
|
virtual void link_set_map(RID p_link, RID p_map) const = 0;
|
||||||
|
virtual RID link_get_map(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set whether this link travels in both directions.
|
||||||
|
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) const = 0;
|
||||||
|
virtual bool link_is_bidirectional(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the link's layers.
|
||||||
|
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) const = 0;
|
||||||
|
virtual uint32_t link_get_navigation_layers(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the start location of the link.
|
||||||
|
virtual void link_set_start_location(RID p_link, Vector2 p_location) const = 0;
|
||||||
|
virtual Vector2 link_get_start_location(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the end location of the link.
|
||||||
|
virtual void link_set_end_location(RID p_link, Vector2 p_location) const = 0;
|
||||||
|
virtual Vector2 link_get_end_location(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the enter cost of the link.
|
||||||
|
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) const = 0;
|
||||||
|
virtual real_t link_get_enter_cost(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the travel cost of the link.
|
||||||
|
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) const = 0;
|
||||||
|
virtual real_t link_get_travel_cost(RID p_link) const = 0;
|
||||||
|
|
||||||
/// Creates the agent.
|
/// Creates the agent.
|
||||||
virtual RID agent_create() const = 0;
|
virtual RID agent_create() const = 0;
|
||||||
|
|
||||||
@ -199,6 +237,17 @@ public:
|
|||||||
|
|
||||||
Navigation2DServer();
|
Navigation2DServer();
|
||||||
virtual ~Navigation2DServer();
|
virtual ~Navigation2DServer();
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
void set_debug_enabled(bool p_enabled);
|
||||||
|
bool get_debug_enabled() const;
|
||||||
|
|
||||||
|
void set_debug_navigation_link_connection_color(const Color &p_color);
|
||||||
|
Color get_debug_navigation_link_connection_color() const;
|
||||||
|
|
||||||
|
void set_debug_navigation_link_connection_disabled_color(const Color &p_color);
|
||||||
|
Color get_debug_navigation_link_connection_disabled_color() const;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Navigation2DServer *(*CreateNavigation2DServerCallback)();
|
typedef Navigation2DServer *(*CreateNavigation2DServerCallback)();
|
||||||
|
@ -60,12 +60,15 @@ void NavigationServer::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("map_get_cell_height", "map"), &NavigationServer::map_get_cell_height);
|
ClassDB::bind_method(D_METHOD("map_get_cell_height", "map"), &NavigationServer::map_get_cell_height);
|
||||||
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &NavigationServer::map_set_edge_connection_margin);
|
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &NavigationServer::map_set_edge_connection_margin);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &NavigationServer::map_get_edge_connection_margin);
|
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &NavigationServer::map_get_edge_connection_margin);
|
||||||
|
ClassDB::bind_method(D_METHOD("map_set_link_connection_radius", "map", "radius"), &NavigationServer::map_set_link_connection_radius);
|
||||||
|
ClassDB::bind_method(D_METHOD("map_get_link_connection_radius", "map"), &NavigationServer::map_get_link_connection_radius);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &NavigationServer::map_get_path, 1);
|
ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &NavigationServer::map_get_path, 1);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_closest_point_to_segment", "map", "start", "end", "use_collision"), &NavigationServer::map_get_closest_point_to_segment, false);
|
ClassDB::bind_method(D_METHOD("map_get_closest_point_to_segment", "map", "start", "end", "use_collision"), &NavigationServer::map_get_closest_point_to_segment, false);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer::map_get_closest_point);
|
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer::map_get_closest_point);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_closest_point_normal", "map", "to_point"), &NavigationServer::map_get_closest_point_normal);
|
ClassDB::bind_method(D_METHOD("map_get_closest_point_normal", "map", "to_point"), &NavigationServer::map_get_closest_point_normal);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer::map_get_closest_point_owner);
|
ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer::map_get_closest_point_owner);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("map_get_links", "map"), &NavigationServer::map_get_links);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer::map_get_regions);
|
ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer::map_get_regions);
|
||||||
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer::map_get_agents);
|
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer::map_get_agents);
|
||||||
ClassDB::bind_method(D_METHOD("map_force_update", "map"), &NavigationServer::map_force_update);
|
ClassDB::bind_method(D_METHOD("map_force_update", "map"), &NavigationServer::map_force_update);
|
||||||
@ -91,6 +94,22 @@ void NavigationServer::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &NavigationServer::region_get_connection_pathway_start);
|
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_start", "region", "connection"), &NavigationServer::region_get_connection_pathway_start);
|
||||||
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer::region_get_connection_pathway_end);
|
ClassDB::bind_method(D_METHOD("region_get_connection_pathway_end", "region", "connection"), &NavigationServer::region_get_connection_pathway_end);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("link_create"), &NavigationServer::link_create);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_map", "link", "map"), &NavigationServer::link_set_map);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_map", "link"), &NavigationServer::link_get_map);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_bidirectional", "link", "bidirectional"), &NavigationServer::link_set_bidirectional);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &NavigationServer::link_is_bidirectional);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &NavigationServer::link_set_navigation_layers);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_navigation_layers", "link"), &NavigationServer::link_get_navigation_layers);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_start_location", "link", "location"), &NavigationServer::link_set_start_location);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_start_location", "link"), &NavigationServer::link_get_start_location);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_end_location", "link", "location"), &NavigationServer::link_set_end_location);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_end_location", "link"), &NavigationServer::link_get_end_location);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_enter_cost", "link", "enter_cost"), &NavigationServer::link_set_enter_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &NavigationServer::link_get_enter_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &NavigationServer::link_set_travel_cost);
|
||||||
|
ClassDB::bind_method(D_METHOD("link_get_travel_cost", "link"), &NavigationServer::link_get_travel_cost);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer::agent_create);
|
ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer::agent_create);
|
||||||
ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer::agent_set_map);
|
ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer::agent_set_map);
|
||||||
ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer::agent_get_map);
|
ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer::agent_get_map);
|
||||||
@ -138,11 +157,16 @@ NavigationServer::NavigationServer() {
|
|||||||
_debug_navigation_geometry_face_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_color", Color(0.5, 1.0, 1.0, 0.4));
|
_debug_navigation_geometry_face_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_color", Color(0.5, 1.0, 1.0, 0.4));
|
||||||
_debug_navigation_geometry_edge_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_edge_disabled_color", Color(0.5, 0.5, 0.5, 1.0));
|
_debug_navigation_geometry_edge_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_edge_disabled_color", Color(0.5, 0.5, 0.5, 1.0));
|
||||||
_debug_navigation_geometry_face_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_disabled_color", Color(0.5, 0.5, 0.5, 0.4));
|
_debug_navigation_geometry_face_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_disabled_color", Color(0.5, 0.5, 0.5, 0.4));
|
||||||
|
_debug_navigation_link_connection_color = GLOBAL_DEF("debug/shapes/navigation/link_connection_color", Color(1.0, 0.5, 1.0, 1.0));
|
||||||
|
_debug_navigation_link_connection_disabled_color = GLOBAL_DEF("debug/shapes/navigation/link_connection_disabled_color", Color(0.5, 0.5, 0.5, 1.0));
|
||||||
|
|
||||||
_debug_navigation_enable_edge_connections = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections", true);
|
_debug_navigation_enable_edge_connections = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections", true);
|
||||||
_debug_navigation_enable_edge_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections_xray", true);
|
_debug_navigation_enable_edge_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections_xray", true);
|
||||||
_debug_navigation_enable_edge_lines = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines", true);
|
_debug_navigation_enable_edge_lines = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines", true);
|
||||||
_debug_navigation_enable_edge_lines_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines_xray", true);
|
_debug_navigation_enable_edge_lines_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_lines_xray", true);
|
||||||
_debug_navigation_enable_geometry_face_random_color = GLOBAL_DEF("debug/shapes/navigation/enable_geometry_face_random_color", true);
|
_debug_navigation_enable_geometry_face_random_color = GLOBAL_DEF("debug/shapes/navigation/enable_geometry_face_random_color", true);
|
||||||
|
_debug_navigation_enable_link_connections = GLOBAL_DEF("debug/shapes/navigation/enable_link_connections", true);
|
||||||
|
_debug_navigation_enable_link_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_link_connections_xray", true);
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +288,42 @@ Ref<SpatialMaterial> NavigationServer::get_debug_navigation_edge_connections_mat
|
|||||||
return _debug_navigation_edge_connections_material;
|
return _debug_navigation_edge_connections_material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<SpatialMaterial> NavigationServer::get_debug_navigation_link_connections_material() {
|
||||||
|
if (_debug_navigation_link_connections_material.is_valid()) {
|
||||||
|
return _debug_navigation_link_connections_material;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<SpatialMaterial> material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
|
||||||
|
material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
|
||||||
|
|
||||||
|
material->set_albedo(_debug_navigation_link_connection_color);
|
||||||
|
if (_debug_navigation_enable_link_connections_xray) {
|
||||||
|
material->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, true);
|
||||||
|
}
|
||||||
|
material->set_render_priority(SpatialMaterial::RENDER_PRIORITY_MAX - 2);
|
||||||
|
|
||||||
|
_debug_navigation_link_connections_material = material;
|
||||||
|
return _debug_navigation_link_connections_material;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<SpatialMaterial> NavigationServer::get_debug_navigation_link_connections_disabled_material() {
|
||||||
|
if (_debug_navigation_link_connections_disabled_material.is_valid()) {
|
||||||
|
return _debug_navigation_link_connections_disabled_material;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<SpatialMaterial> material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
|
||||||
|
material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
|
||||||
|
|
||||||
|
material->set_albedo(_debug_navigation_link_connection_disabled_color);
|
||||||
|
if (_debug_navigation_enable_link_connections_xray) {
|
||||||
|
material->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, true);
|
||||||
|
}
|
||||||
|
material->set_render_priority(SpatialMaterial::RENDER_PRIORITY_MAX - 2);
|
||||||
|
|
||||||
|
_debug_navigation_link_connections_disabled_material = material;
|
||||||
|
return _debug_navigation_link_connections_disabled_material;
|
||||||
|
}
|
||||||
|
|
||||||
void NavigationServer::set_debug_navigation_edge_connection_color(const Color &p_color) {
|
void NavigationServer::set_debug_navigation_edge_connection_color(const Color &p_color) {
|
||||||
_debug_navigation_edge_connection_color = p_color;
|
_debug_navigation_edge_connection_color = p_color;
|
||||||
if (_debug_navigation_edge_connections_material.is_valid()) {
|
if (_debug_navigation_edge_connections_material.is_valid()) {
|
||||||
@ -319,6 +379,28 @@ Color NavigationServer::get_debug_navigation_geometry_face_disabled_color() cons
|
|||||||
return _debug_navigation_geometry_face_disabled_color;
|
return _debug_navigation_geometry_face_disabled_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigationServer::set_debug_navigation_link_connection_color(const Color &p_color) {
|
||||||
|
_debug_navigation_link_connection_color = p_color;
|
||||||
|
if (_debug_navigation_link_connections_material.is_valid()) {
|
||||||
|
_debug_navigation_link_connections_material->set_albedo(_debug_navigation_link_connection_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Color NavigationServer::get_debug_navigation_link_connection_color() const {
|
||||||
|
return _debug_navigation_link_connection_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationServer::set_debug_navigation_link_connection_disabled_color(const Color &p_color) {
|
||||||
|
_debug_navigation_link_connection_disabled_color = p_color;
|
||||||
|
if (_debug_navigation_link_connections_disabled_material.is_valid()) {
|
||||||
|
_debug_navigation_link_connections_disabled_material->set_albedo(_debug_navigation_link_connection_disabled_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Color NavigationServer::get_debug_navigation_link_connection_disabled_color() const {
|
||||||
|
return _debug_navigation_link_connection_disabled_color;
|
||||||
|
}
|
||||||
|
|
||||||
void NavigationServer::set_debug_navigation_enable_edge_connections(const bool p_value) {
|
void NavigationServer::set_debug_navigation_enable_edge_connections(const bool p_value) {
|
||||||
_debug_navigation_enable_edge_connections = p_value;
|
_debug_navigation_enable_edge_connections = p_value;
|
||||||
_debug_dirty = true;
|
_debug_dirty = true;
|
||||||
@ -371,6 +453,27 @@ bool NavigationServer::get_debug_navigation_enable_geometry_face_random_color()
|
|||||||
return _debug_navigation_enable_geometry_face_random_color;
|
return _debug_navigation_enable_geometry_face_random_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigationServer::set_debug_navigation_enable_link_connections(const bool p_value) {
|
||||||
|
_debug_navigation_enable_link_connections = p_value;
|
||||||
|
_debug_dirty = true;
|
||||||
|
call_deferred("_emit_navigation_debug_changed_signal");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavigationServer::get_debug_navigation_enable_link_connections() const {
|
||||||
|
return _debug_navigation_enable_link_connections;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigationServer::set_debug_navigation_enable_link_connections_xray(const bool p_value) {
|
||||||
|
_debug_navigation_enable_link_connections_xray = p_value;
|
||||||
|
if (_debug_navigation_link_connections_material.is_valid()) {
|
||||||
|
_debug_navigation_link_connections_material->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, _debug_navigation_enable_link_connections_xray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NavigationServer::get_debug_navigation_enable_link_connections_xray() const {
|
||||||
|
return _debug_navigation_enable_link_connections_xray;
|
||||||
|
}
|
||||||
|
|
||||||
void NavigationServer::set_debug_enabled(bool p_enabled) {
|
void NavigationServer::set_debug_enabled(bool p_enabled) {
|
||||||
if (_debug_enabled != p_enabled) {
|
if (_debug_enabled != p_enabled) {
|
||||||
_debug_dirty = true;
|
_debug_dirty = true;
|
||||||
|
@ -98,6 +98,12 @@ public:
|
|||||||
/// Returns the edge connection margin of this map.
|
/// Returns the edge connection margin of this map.
|
||||||
virtual real_t map_get_edge_connection_margin(RID p_map) const = 0;
|
virtual real_t map_get_edge_connection_margin(RID p_map) const = 0;
|
||||||
|
|
||||||
|
/// Set the map link connection radius used to attach links to the nav mesh.
|
||||||
|
virtual void map_set_link_connection_radius(RID p_map, real_t p_connection_radius) const = 0;
|
||||||
|
|
||||||
|
/// Returns the link connection radius of this map.
|
||||||
|
virtual real_t map_get_link_connection_radius(RID p_map) const = 0;
|
||||||
|
|
||||||
/// Returns the navigation path to reach the destination from the origin.
|
/// Returns the navigation path to reach the destination from the origin.
|
||||||
virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const = 0;
|
virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const = 0;
|
||||||
|
|
||||||
@ -106,6 +112,7 @@ public:
|
|||||||
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const = 0;
|
virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const = 0;
|
||||||
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const = 0;
|
virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const = 0;
|
||||||
|
|
||||||
|
virtual Array map_get_links(RID p_map) const = 0;
|
||||||
virtual Array map_get_regions(RID p_map) const = 0;
|
virtual Array map_get_regions(RID p_map) const = 0;
|
||||||
virtual Array map_get_agents(RID p_map) const = 0;
|
virtual Array map_get_agents(RID p_map) const = 0;
|
||||||
|
|
||||||
@ -143,6 +150,37 @@ public:
|
|||||||
virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const = 0;
|
virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const = 0;
|
||||||
virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const = 0;
|
virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const = 0;
|
||||||
|
|
||||||
|
/// Creates a new link between locations in the nav map.
|
||||||
|
virtual RID link_create() const = 0;
|
||||||
|
|
||||||
|
/// Set the map of this link.
|
||||||
|
virtual void link_set_map(RID p_link, RID p_map) const = 0;
|
||||||
|
virtual RID link_get_map(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set whether this link travels in both directions.
|
||||||
|
virtual void link_set_bidirectional(RID p_link, bool p_bidirectional) const = 0;
|
||||||
|
virtual bool link_is_bidirectional(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the link's layers.
|
||||||
|
virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) const = 0;
|
||||||
|
virtual uint32_t link_get_navigation_layers(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the start location of the link.
|
||||||
|
virtual void link_set_start_location(RID p_link, Vector3 p_location) const = 0;
|
||||||
|
virtual Vector3 link_get_start_location(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the end location of the link.
|
||||||
|
virtual void link_set_end_location(RID p_link, Vector3 p_location) const = 0;
|
||||||
|
virtual Vector3 link_get_end_location(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the enter cost of the link.
|
||||||
|
virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) const = 0;
|
||||||
|
virtual real_t link_get_enter_cost(RID p_link) const = 0;
|
||||||
|
|
||||||
|
/// Set the travel cost of the link.
|
||||||
|
virtual void link_set_travel_cost(RID p_link, real_t p_travel_cost) const = 0;
|
||||||
|
virtual real_t link_get_travel_cost(RID p_link) const = 0;
|
||||||
|
|
||||||
/// Creates the agent.
|
/// Creates the agent.
|
||||||
virtual RID agent_create() const = 0;
|
virtual RID agent_create() const = 0;
|
||||||
|
|
||||||
@ -245,6 +283,12 @@ public:
|
|||||||
void set_debug_navigation_geometry_face_disabled_color(const Color &p_color);
|
void set_debug_navigation_geometry_face_disabled_color(const Color &p_color);
|
||||||
Color get_debug_navigation_geometry_face_disabled_color() const;
|
Color get_debug_navigation_geometry_face_disabled_color() const;
|
||||||
|
|
||||||
|
void set_debug_navigation_link_connection_color(const Color &p_color);
|
||||||
|
Color get_debug_navigation_link_connection_color() const;
|
||||||
|
|
||||||
|
void set_debug_navigation_link_connection_disabled_color(const Color &p_color);
|
||||||
|
Color get_debug_navigation_link_connection_disabled_color() const;
|
||||||
|
|
||||||
void set_debug_navigation_enable_edge_connections(const bool p_value);
|
void set_debug_navigation_enable_edge_connections(const bool p_value);
|
||||||
bool get_debug_navigation_enable_edge_connections() const;
|
bool get_debug_navigation_enable_edge_connections() const;
|
||||||
|
|
||||||
@ -260,11 +304,19 @@ public:
|
|||||||
void set_debug_navigation_enable_geometry_face_random_color(const bool p_value);
|
void set_debug_navigation_enable_geometry_face_random_color(const bool p_value);
|
||||||
bool get_debug_navigation_enable_geometry_face_random_color() const;
|
bool get_debug_navigation_enable_geometry_face_random_color() const;
|
||||||
|
|
||||||
|
void set_debug_navigation_enable_link_connections(const bool p_value);
|
||||||
|
bool get_debug_navigation_enable_link_connections() const;
|
||||||
|
|
||||||
|
void set_debug_navigation_enable_link_connections_xray(const bool p_value);
|
||||||
|
bool get_debug_navigation_enable_link_connections_xray() const;
|
||||||
|
|
||||||
Ref<SpatialMaterial> get_debug_navigation_geometry_face_material();
|
Ref<SpatialMaterial> get_debug_navigation_geometry_face_material();
|
||||||
Ref<SpatialMaterial> get_debug_navigation_geometry_edge_material();
|
Ref<SpatialMaterial> get_debug_navigation_geometry_edge_material();
|
||||||
Ref<SpatialMaterial> get_debug_navigation_geometry_face_disabled_material();
|
Ref<SpatialMaterial> get_debug_navigation_geometry_face_disabled_material();
|
||||||
Ref<SpatialMaterial> get_debug_navigation_geometry_edge_disabled_material();
|
Ref<SpatialMaterial> get_debug_navigation_geometry_edge_disabled_material();
|
||||||
Ref<SpatialMaterial> get_debug_navigation_edge_connections_material();
|
Ref<SpatialMaterial> get_debug_navigation_edge_connections_material();
|
||||||
|
Ref<SpatialMaterial> get_debug_navigation_link_connections_material();
|
||||||
|
Ref<SpatialMaterial> get_debug_navigation_link_connections_disabled_material();
|
||||||
|
|
||||||
void _emit_navigation_debug_changed_signal();
|
void _emit_navigation_debug_changed_signal();
|
||||||
|
|
||||||
@ -277,17 +329,24 @@ protected:
|
|||||||
Color _debug_navigation_geometry_face_color;
|
Color _debug_navigation_geometry_face_color;
|
||||||
Color _debug_navigation_geometry_edge_disabled_color;
|
Color _debug_navigation_geometry_edge_disabled_color;
|
||||||
Color _debug_navigation_geometry_face_disabled_color;
|
Color _debug_navigation_geometry_face_disabled_color;
|
||||||
|
Color _debug_navigation_link_connection_color;
|
||||||
|
Color _debug_navigation_link_connection_disabled_color;
|
||||||
|
|
||||||
bool _debug_navigation_enable_edge_connections;
|
bool _debug_navigation_enable_edge_connections;
|
||||||
bool _debug_navigation_enable_edge_connections_xray;
|
bool _debug_navigation_enable_edge_connections_xray;
|
||||||
bool _debug_navigation_enable_edge_lines;
|
bool _debug_navigation_enable_edge_lines;
|
||||||
bool _debug_navigation_enable_edge_lines_xray;
|
bool _debug_navigation_enable_edge_lines_xray;
|
||||||
bool _debug_navigation_enable_geometry_face_random_color;
|
bool _debug_navigation_enable_geometry_face_random_color;
|
||||||
|
bool _debug_navigation_enable_link_connections;
|
||||||
|
bool _debug_navigation_enable_link_connections_xray;
|
||||||
|
|
||||||
Ref<SpatialMaterial> _debug_navigation_geometry_edge_material;
|
Ref<SpatialMaterial> _debug_navigation_geometry_edge_material;
|
||||||
Ref<SpatialMaterial> _debug_navigation_geometry_face_material;
|
Ref<SpatialMaterial> _debug_navigation_geometry_face_material;
|
||||||
Ref<SpatialMaterial> _debug_navigation_geometry_edge_disabled_material;
|
Ref<SpatialMaterial> _debug_navigation_geometry_edge_disabled_material;
|
||||||
Ref<SpatialMaterial> _debug_navigation_geometry_face_disabled_material;
|
Ref<SpatialMaterial> _debug_navigation_geometry_face_disabled_material;
|
||||||
Ref<SpatialMaterial> _debug_navigation_edge_connections_material;
|
Ref<SpatialMaterial> _debug_navigation_edge_connections_material;
|
||||||
|
Ref<SpatialMaterial> _debug_navigation_link_connections_material;
|
||||||
|
Ref<SpatialMaterial> _debug_navigation_link_connections_disabled_material;
|
||||||
|
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user