Remove Navigation2D/3D nodes, and move the navigation map to the world resource
This commit is contained in:
parent
469ac1e415
commit
a9dc53d152
39 changed files with 233 additions and 1012 deletions
|
@ -1,59 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<class name="Navigation2D" inherits="Node2D" version="4.0">
|
|
||||||
<brief_description>
|
|
||||||
2D navigation and pathfinding node.
|
|
||||||
</brief_description>
|
|
||||||
<description>
|
|
||||||
Navigation2D provides navigation and pathfinding within a 2D area, specified as a collection of [NavigationPolygon] resources. These are automatically collected from child [NavigationRegion2D] nodes.
|
|
||||||
</description>
|
|
||||||
<tutorials>
|
|
||||||
<link title="2D Navigation Demo">https://godotengine.org/asset-library/asset/117</link>
|
|
||||||
</tutorials>
|
|
||||||
<methods>
|
|
||||||
<method name="get_closest_point" qualifiers="const">
|
|
||||||
<return type="Vector2">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="to_point" type="Vector2">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Returns the point closest to the provided [code]to_point[/code] on the navigation mesh surface.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_closest_point_owner" qualifiers="const">
|
|
||||||
<return type="RID">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="to_point" type="Vector2">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Returns the owner region RID for the point returned by [method get_closest_point].
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_rid" qualifiers="const">
|
|
||||||
<return type="RID">
|
|
||||||
</return>
|
|
||||||
<description>
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_simple_path" qualifiers="const">
|
|
||||||
<return type="PackedVector2Array">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="start" type="Vector2">
|
|
||||||
</argument>
|
|
||||||
<argument index="1" name="end" type="Vector2">
|
|
||||||
</argument>
|
|
||||||
<argument index="2" name="optimize" type="bool" default="true">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Returns the path between two given points. Points are in local coordinate space. If [code]optimize[/code] is [code]true[/code] (the default), the path is smoothed by merging path segments where possible.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
</methods>
|
|
||||||
<members>
|
|
||||||
<member name="cell_size" type="float" setter="set_cell_size" getter="get_cell_size" default="10.0">
|
|
||||||
</member>
|
|
||||||
<member name="edge_connection_margin" type="float" setter="set_edge_connection_margin" getter="get_edge_connection_margin" default="100.0">
|
|
||||||
</member>
|
|
||||||
</members>
|
|
||||||
<constants>
|
|
||||||
</constants>
|
|
||||||
</class>
|
|
|
@ -1,84 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<class name="Navigation3D" inherits="Node3D" version="4.0">
|
|
||||||
<brief_description>
|
|
||||||
Mesh-based navigation and pathfinding node.
|
|
||||||
</brief_description>
|
|
||||||
<description>
|
|
||||||
Provides navigation and pathfinding within a collection of [NavigationMesh]es. These will be automatically collected from child [NavigationRegion3D] nodes. In addition to basic pathfinding, this class also assists with aligning navigation agents with the meshes they are navigating on.
|
|
||||||
</description>
|
|
||||||
<tutorials>
|
|
||||||
<link title="3D Navmesh Demo">https://godotengine.org/asset-library/asset/124</link>
|
|
||||||
</tutorials>
|
|
||||||
<methods>
|
|
||||||
<method name="get_closest_point" qualifiers="const">
|
|
||||||
<return type="Vector3">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="to_point" type="Vector3">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Returns the point closest to the provided [code]to_point[/code] on the navigation mesh surface.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_closest_point_normal" qualifiers="const">
|
|
||||||
<return type="Vector3">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="to_point" type="Vector3">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Returns the normal for the point returned by [method get_closest_point].
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_closest_point_owner" qualifiers="const">
|
|
||||||
<return type="RID">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="to_point" type="Vector3">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Returns the owner region RID for the point returned by [method get_closest_point].
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_closest_point_to_segment" qualifiers="const">
|
|
||||||
<return type="Vector3">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="start" type="Vector3">
|
|
||||||
</argument>
|
|
||||||
<argument index="1" name="end" type="Vector3">
|
|
||||||
</argument>
|
|
||||||
<argument index="2" name="use_collision" type="bool" default="false">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Returns the closest point between the navigation surface and the segment.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_rid" qualifiers="const">
|
|
||||||
<return type="RID">
|
|
||||||
</return>
|
|
||||||
<description>
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_simple_path" qualifiers="const">
|
|
||||||
<return type="PackedVector3Array">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="start" type="Vector3">
|
|
||||||
</argument>
|
|
||||||
<argument index="1" name="end" type="Vector3">
|
|
||||||
</argument>
|
|
||||||
<argument index="2" name="optimize" type="bool" default="true">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Returns the path between two given points. Points are in local coordinate space. If [code]optimize[/code] is [code]true[/code] (the default), the agent properties associated with each [NavigationMesh] (radius, height, etc.) are considered in the path calculation, otherwise they are ignored.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
</methods>
|
|
||||||
<members>
|
|
||||||
<member name="cell_size" type="float" setter="set_cell_size" getter="get_cell_size" default="0.3">
|
|
||||||
</member>
|
|
||||||
<member name="edge_connection_margin" type="float" setter="set_edge_connection_margin" getter="get_edge_connection_margin" default="5.0">
|
|
||||||
</member>
|
|
||||||
<member name="up_vector" type="Vector3" setter="set_up_vector" getter="get_up_vector" default="Vector3( 0, 1, 0 )">
|
|
||||||
Defines which direction is up. By default, this is [code](0, 1, 0)[/code], which is the world's "up" direction.
|
|
||||||
</member>
|
|
||||||
</members>
|
|
||||||
<constants>
|
|
||||||
</constants>
|
|
||||||
</class>
|
|
|
@ -4,7 +4,7 @@
|
||||||
2D Agent used in navigation for collision avoidance.
|
2D Agent used in navigation for collision avoidance.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
2D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. This can be done by having the agent as a child of a [Navigation2D] node, or using [method set_navigation]. [NavigationAgent2D] is physics safe.
|
2D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. [NavigationAgent2D] is physics safe.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
|
@ -37,13 +37,6 @@
|
||||||
Returns which index the agent is currently on in the navigation path's [PackedVector2Array].
|
Returns which index the agent is currently on in the navigation path's [PackedVector2Array].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_navigation" qualifiers="const">
|
|
||||||
<return type="Node">
|
|
||||||
</return>
|
|
||||||
<description>
|
|
||||||
Returns the [Navigation2D] node that the agent is using for its navigation system.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_next_location">
|
<method name="get_next_location">
|
||||||
<return type="Vector2">
|
<return type="Vector2">
|
||||||
</return>
|
</return>
|
||||||
|
@ -79,15 +72,6 @@
|
||||||
Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location].
|
Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="set_navigation">
|
|
||||||
<return type="void">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="navigation" type="Node">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Sets the [Navigation2D] node used by the agent. Useful when you don't want to make the agent a child of a [Navigation2D] node.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="set_target_location">
|
<method name="set_target_location">
|
||||||
<return type="void">
|
<return type="void">
|
||||||
</return>
|
</return>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
3D Agent used in navigation for collision avoidance.
|
3D Agent used in navigation for collision avoidance.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
3D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. This can be done by having the agent as a child of a [Navigation3D] node, or using [method set_navigation]. [NavigationAgent3D] is physics safe.
|
3D Agent that is used in navigation to reach a location while avoiding static and dynamic obstacles. The dynamic obstacles are avoided using RVO collision avoidance. The agent needs navigation data to work correctly. [NavigationAgent3D] is physics safe.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
|
@ -37,13 +37,6 @@
|
||||||
Returns which index the agent is currently on in the navigation path's [PackedVector3Array].
|
Returns which index the agent is currently on in the navigation path's [PackedVector3Array].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_navigation" qualifiers="const">
|
|
||||||
<return type="Node">
|
|
||||||
</return>
|
|
||||||
<description>
|
|
||||||
Returns the [Navigation3D] node that the agent is using for its navigation system.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_next_location">
|
<method name="get_next_location">
|
||||||
<return type="Vector3">
|
<return type="Vector3">
|
||||||
</return>
|
</return>
|
||||||
|
@ -79,15 +72,6 @@
|
||||||
Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location].
|
Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="set_navigation">
|
|
||||||
<return type="void">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="navigation" type="Node">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Sets the [Navigation3D] node used by the agent. Useful when you don't want to make the agent a child of a [Navigation3D] node.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="set_target_location">
|
<method name="set_target_location">
|
||||||
<return type="void">
|
<return type="void">
|
||||||
</return>
|
</return>
|
||||||
|
|
|
@ -4,27 +4,11 @@
|
||||||
2D Obstacle used in navigation for collision avoidance.
|
2D Obstacle used in navigation for collision avoidance.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
2D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. This can be done by having the obstacle as a child of a [Navigation2D] node, or using [method set_navigation]. [NavigationObstacle2D] is physics safe.
|
2D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. [NavigationObstacle2D] is physics safe.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
<method name="get_navigation" qualifiers="const">
|
|
||||||
<return type="Node">
|
|
||||||
</return>
|
|
||||||
<description>
|
|
||||||
Returns the [Navigation2D] node that the obstacle is using for its navigation system.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="set_navigation">
|
|
||||||
<return type="void">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="navigation" type="Node">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Sets the [Navigation2D] node used by the obstacle. Useful when you don't want to make the obstacle a child of a [Navigation2D] node.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
</methods>
|
</methods>
|
||||||
<constants>
|
<constants>
|
||||||
</constants>
|
</constants>
|
||||||
|
|
|
@ -4,27 +4,11 @@
|
||||||
3D Obstacle used in navigation for collision avoidance.
|
3D Obstacle used in navigation for collision avoidance.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
3D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. This can be done by having the obstacle as a child of a [Navigation3D] node, or using [method set_navigation]. [NavigationObstacle3D] is physics safe.
|
3D Obstacle used in navigation for collision avoidance. The obstacle needs navigation data to work correctly. [NavigationObstacle3D] is physics safe.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
<method name="get_navigation" qualifiers="const">
|
|
||||||
<return type="Node">
|
|
||||||
</return>
|
|
||||||
<description>
|
|
||||||
Returns the [Navigation3D] node that the obstacle is using for its navigation system.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="set_navigation">
|
|
||||||
<return type="void">
|
|
||||||
</return>
|
|
||||||
<argument index="0" name="navigation" type="Node">
|
|
||||||
</argument>
|
|
||||||
<description>
|
|
||||||
Sets the [Navigation3D] node used by the obstacle. Useful when you don't want to make the obstacle a child of a [Navigation3D] node.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
</methods>
|
</methods>
|
||||||
<constants>
|
<constants>
|
||||||
</constants>
|
</constants>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
A region of the navigation map.
|
A region of the navigation map.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
A region of the navigation map. It tells the [Navigation3D] node what can be navigated and what cannot, based on the [NavigationMesh] resource. This should be a child of a [Navigation3D] node (even not a direct child).
|
A region of the navigation map. It tells the [NavigationServer3D] what can be navigated and what cannot, based on its [NavigationMesh] resource.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
|
|
|
@ -1020,6 +1020,14 @@
|
||||||
</member>
|
</member>
|
||||||
<member name="mono/unhandled_exception_policy" type="int" setter="" getter="" default="0">
|
<member name="mono/unhandled_exception_policy" type="int" setter="" getter="" default="0">
|
||||||
</member>
|
</member>
|
||||||
|
<member name="navigation/2d/default_cell_size" type="int" setter="" getter="" default="10">
|
||||||
|
</member>
|
||||||
|
<member name="navigation/2d/default_edge_connection_margin" type="int" setter="" getter="" default="100">
|
||||||
|
</member>
|
||||||
|
<member name="navigation/3d/default_cell_size" type="float" setter="" getter="" default="0.3">
|
||||||
|
</member>
|
||||||
|
<member name="navigation/3d/default_edge_connection_margin" type="float" setter="" getter="" default="5.0">
|
||||||
|
</member>
|
||||||
<member name="network/limits/debugger/max_chars_per_second" type="int" setter="" getter="" default="32768">
|
<member name="network/limits/debugger/max_chars_per_second" type="int" setter="" getter="" default="32768">
|
||||||
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>
|
||||||
|
|
|
@ -272,6 +272,9 @@
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
<members>
|
<members>
|
||||||
|
<member name="bake_navigation" type="bool" setter="set_bake_navigation" getter="is_baking_navigation" default="false">
|
||||||
|
If [code]true[/code], this TileMap bakes a navigation region.
|
||||||
|
</member>
|
||||||
<member name="cell_clip_uv" type="bool" setter="set_clip_uv" getter="get_clip_uv" default="false">
|
<member name="cell_clip_uv" type="bool" setter="set_clip_uv" getter="get_clip_uv" default="false">
|
||||||
If [code]true[/code], the cell's UVs will be clipped.
|
If [code]true[/code], the cell's UVs will be clipped.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
<member name="direct_space_state" type="PhysicsDirectSpaceState2D" setter="" getter="get_direct_space_state">
|
<member name="direct_space_state" type="PhysicsDirectSpaceState2D" setter="" getter="get_direct_space_state">
|
||||||
Direct access to the world's physics 2D space state. Used for querying current and potential collisions. When using multi-threaded physics, access is limited to [code]_physics_process(delta)[/code] in the main thread.
|
Direct access to the world's physics 2D space state. Used for querying current and potential collisions. When using multi-threaded physics, access is limited to [code]_physics_process(delta)[/code] in the main thread.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="navigation_map" type="RID" setter="" getter="get_navigation_map">
|
||||||
|
The [RID] of this world's navigation map. Used by the [NavigationServer2D].
|
||||||
|
</member>
|
||||||
<member name="space" type="RID" setter="" getter="get_space">
|
<member name="space" type="RID" setter="" getter="get_space">
|
||||||
The [RID] of this world's physics space resource. Used by the [PhysicsServer2D] for 2D physics, treating it as both a space and an area.
|
The [RID] of this world's physics space resource. Used by the [PhysicsServer2D] for 2D physics, treating it as both a space and an area.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
<member name="fallback_environment" type="Environment" setter="set_fallback_environment" getter="get_fallback_environment">
|
<member name="fallback_environment" type="Environment" setter="set_fallback_environment" getter="get_fallback_environment">
|
||||||
The World3D's fallback_environment will be used if the World3D's [Environment] fails or is missing.
|
The World3D's fallback_environment will be used if the World3D's [Environment] fails or is missing.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="navigation_map" type="RID" setter="" getter="get_navigation_map">
|
||||||
|
The [RID] of this world's navigation map. Used by the [NavigationServer3D].
|
||||||
|
</member>
|
||||||
<member name="scenario" type="RID" setter="" getter="get_scenario">
|
<member name="scenario" type="RID" setter="" getter="get_scenario">
|
||||||
The World3D's visual scenario.
|
The World3D's visual scenario.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "editor/import/scene_importer_mesh_node_3d.h"
|
#include "editor/import/scene_importer_mesh_node_3d.h"
|
||||||
#include "scene/3d/collision_shape_3d.h"
|
#include "scene/3d/collision_shape_3d.h"
|
||||||
#include "scene/3d/mesh_instance_3d.h"
|
#include "scene/3d/mesh_instance_3d.h"
|
||||||
#include "scene/3d/navigation_3d.h"
|
#include "scene/3d/navigation_region_3d.h"
|
||||||
#include "scene/3d/physics_body_3d.h"
|
#include "scene/3d/physics_body_3d.h"
|
||||||
#include "scene/3d/vehicle_body_3d.h"
|
#include "scene/3d/vehicle_body_3d.h"
|
||||||
#include "scene/animation/animation_player.h"
|
#include "scene/animation/animation_player.h"
|
||||||
|
|
|
@ -31,10 +31,10 @@
|
||||||
#ifndef NAV_REGION_H
|
#ifndef NAV_REGION_H
|
||||||
#define NAV_REGION_H
|
#define NAV_REGION_H
|
||||||
|
|
||||||
#include "nav_rid.h"
|
#include "scene/resources/navigation_mesh.h"
|
||||||
|
|
||||||
|
#include "nav_rid.h"
|
||||||
#include "nav_utils.h"
|
#include "nav_utils.h"
|
||||||
#include "scene/3d/navigation_3d.h"
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -184,6 +184,9 @@
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
<members>
|
<members>
|
||||||
|
<member name="bake_navigation" type="bool" setter="set_bake_navigation" getter="is_baking_navigation" default="false">
|
||||||
|
If [code]true[/code], this GridMap bakes a navigation region.
|
||||||
|
</member>
|
||||||
<member name="cell_center_x" type="bool" setter="set_center_x" getter="get_center_x" default="true">
|
<member name="cell_center_x" type="bool" setter="set_center_x" getter="get_center_x" default="true">
|
||||||
If [code]true[/code], grid items are centered on the X axis.
|
If [code]true[/code], grid items are centered on the X axis.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -179,6 +179,15 @@ bool GridMap::get_collision_layer_bit(int p_bit) const {
|
||||||
return get_collision_layer() & (1 << p_bit);
|
return get_collision_layer() & (1 << p_bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GridMap::set_bake_navigation(bool p_bake_navigation) {
|
||||||
|
bake_navigation = p_bake_navigation;
|
||||||
|
_recreate_octant_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GridMap::is_baking_navigation() {
|
||||||
|
return bake_navigation;
|
||||||
|
}
|
||||||
|
|
||||||
void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) {
|
void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) {
|
||||||
if (!mesh_library.is_null()) {
|
if (!mesh_library.is_null()) {
|
||||||
mesh_library->unregister_owner(this);
|
mesh_library->unregister_owner(this);
|
||||||
|
@ -474,13 +483,14 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
|
||||||
Octant::NavMesh nm;
|
Octant::NavMesh nm;
|
||||||
nm.xform = xform * mesh_library->get_item_navmesh_transform(c.item);
|
nm.xform = xform * mesh_library->get_item_navmesh_transform(c.item);
|
||||||
|
|
||||||
if (navigation) {
|
if (bake_navigation) {
|
||||||
RID region = NavigationServer3D::get_singleton()->region_create();
|
RID region = NavigationServer3D::get_singleton()->region_create();
|
||||||
NavigationServer3D::get_singleton()->region_set_navmesh(region, navmesh);
|
NavigationServer3D::get_singleton()->region_set_navmesh(region, navmesh);
|
||||||
NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * nm.xform);
|
NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * mesh_library->get_item_navmesh_transform(c.item));
|
||||||
NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
|
NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
|
||||||
nm.region = region;
|
nm.region = region;
|
||||||
}
|
}
|
||||||
|
|
||||||
g.navmesh_ids[E->get()] = nm;
|
g.navmesh_ids[E->get()] = nm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,15 +574,16 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) {
|
||||||
RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform());
|
RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (navigation && mesh_library.is_valid()) {
|
if (bake_navigation && mesh_library.is_valid()) {
|
||||||
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
|
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
|
||||||
if (cell_map.has(F->key()) && F->get().region.is_valid() == false) {
|
if (cell_map.has(F->key()) && F->get().region.is_valid() == false) {
|
||||||
Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F->key()].item);
|
Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F->key()].item);
|
||||||
if (nm.is_valid()) {
|
if (nm.is_valid()) {
|
||||||
RID region = NavigationServer3D::get_singleton()->region_create();
|
RID region = NavigationServer3D::get_singleton()->region_create();
|
||||||
NavigationServer3D::get_singleton()->region_set_navmesh(region, nm);
|
NavigationServer3D::get_singleton()->region_set_navmesh(region, nm);
|
||||||
NavigationServer3D::get_singleton()->region_set_transform(region, navigation->get_global_transform() * F->get().xform);
|
NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * F->get().xform);
|
||||||
NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
|
NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
|
||||||
|
|
||||||
F->get().region = region;
|
F->get().region = region;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -594,14 +605,12 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) {
|
||||||
RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID());
|
RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, RID());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (navigation) {
|
|
||||||
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
|
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
|
||||||
if (F->get().region.is_valid()) {
|
if (F->get().region.is_valid()) {
|
||||||
NavigationServer3D::get_singleton()->free(F->get().region);
|
NavigationServer3D::get_singleton()->free(F->get().region);
|
||||||
F->get().region = RID();
|
F->get().region = RID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GridMap::_octant_clean_up(const OctantKey &p_key) {
|
void GridMap::_octant_clean_up(const OctantKey &p_key) {
|
||||||
|
@ -635,16 +644,6 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) {
|
||||||
void GridMap::_notification(int p_what) {
|
void GridMap::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_ENTER_WORLD: {
|
case NOTIFICATION_ENTER_WORLD: {
|
||||||
Node3D *c = this;
|
|
||||||
while (c) {
|
|
||||||
navigation = Object::cast_to<Navigation3D>(c);
|
|
||||||
if (navigation) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = Object::cast_to<Node3D>(c->get_parent());
|
|
||||||
}
|
|
||||||
|
|
||||||
last_transform = get_global_transform();
|
last_transform = get_global_transform();
|
||||||
|
|
||||||
for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
|
for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
|
||||||
|
@ -679,8 +678,6 @@ void GridMap::_notification(int p_what) {
|
||||||
_octant_exit_world(E->key());
|
_octant_exit_world(E->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
navigation = nullptr;
|
|
||||||
|
|
||||||
//_queue_octants_dirty(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS);
|
//_queue_octants_dirty(MAP_DIRTY_INSTANCES|MAP_DIRTY_TRANSFORMS);
|
||||||
//_update_octants_callback();
|
//_update_octants_callback();
|
||||||
//_update_area_instances();
|
//_update_area_instances();
|
||||||
|
@ -785,6 +782,9 @@ void GridMap::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &GridMap::set_collision_layer_bit);
|
ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &GridMap::set_collision_layer_bit);
|
||||||
ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &GridMap::get_collision_layer_bit);
|
ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &GridMap::get_collision_layer_bit);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &GridMap::set_bake_navigation);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_baking_navigation"), &GridMap::is_baking_navigation);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_mesh_library", "mesh_library"), &GridMap::set_mesh_library);
|
ClassDB::bind_method(D_METHOD("set_mesh_library", "mesh_library"), &GridMap::set_mesh_library);
|
||||||
ClassDB::bind_method(D_METHOD("get_mesh_library"), &GridMap::get_mesh_library);
|
ClassDB::bind_method(D_METHOD("get_mesh_library"), &GridMap::get_mesh_library);
|
||||||
|
|
||||||
|
@ -838,6 +838,8 @@ void GridMap::_bind_methods() {
|
||||||
ADD_GROUP("Collision", "collision_");
|
ADD_GROUP("Collision", "collision_");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
|
||||||
|
ADD_GROUP("Navigation", "");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation");
|
||||||
|
|
||||||
BIND_CONSTANT(INVALID_CELL_ITEM);
|
BIND_CONSTANT(INVALID_CELL_ITEM);
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#ifndef GRID_MAP_H
|
#ifndef GRID_MAP_H
|
||||||
#define GRID_MAP_H
|
#define GRID_MAP_H
|
||||||
|
|
||||||
#include "scene/3d/navigation_3d.h"
|
|
||||||
#include "scene/3d/node_3d.h"
|
#include "scene/3d/node_3d.h"
|
||||||
#include "scene/resources/mesh_library.h"
|
#include "scene/resources/mesh_library.h"
|
||||||
#include "scene/resources/multimesh.h"
|
#include "scene/resources/multimesh.h"
|
||||||
|
@ -135,6 +134,7 @@ class GridMap : public Node3D {
|
||||||
|
|
||||||
uint32_t collision_layer = 1;
|
uint32_t collision_layer = 1;
|
||||||
uint32_t collision_mask = 1;
|
uint32_t collision_mask = 1;
|
||||||
|
bool bake_navigation = false;
|
||||||
|
|
||||||
Transform last_transform;
|
Transform last_transform;
|
||||||
|
|
||||||
|
@ -145,7 +145,6 @@ class GridMap : public Node3D {
|
||||||
bool center_y = true;
|
bool center_y = true;
|
||||||
bool center_z = true;
|
bool center_z = true;
|
||||||
float cell_scale = 1.0;
|
float cell_scale = 1.0;
|
||||||
Navigation3D *navigation = nullptr;
|
|
||||||
|
|
||||||
bool clip = false;
|
bool clip = false;
|
||||||
bool clip_above = true;
|
bool clip_above = true;
|
||||||
|
@ -223,6 +222,9 @@ public:
|
||||||
void set_collision_mask_bit(int p_bit, bool p_value);
|
void set_collision_mask_bit(int p_bit, bool p_value);
|
||||||
bool get_collision_mask_bit(int p_bit) const;
|
bool get_collision_mask_bit(int p_bit) const;
|
||||||
|
|
||||||
|
void set_bake_navigation(bool p_bake_navigation);
|
||||||
|
bool is_baking_navigation();
|
||||||
|
|
||||||
void set_mesh_library(const Ref<MeshLibrary> &p_mesh_library);
|
void set_mesh_library(const Ref<MeshLibrary> &p_mesh_library);
|
||||||
Ref<MeshLibrary> get_mesh_library() const;
|
Ref<MeshLibrary> get_mesh_library() const;
|
||||||
|
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* navigation_2d.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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_2d.h"
|
|
||||||
#include "servers/navigation_server_2d.h"
|
|
||||||
|
|
||||||
void Navigation2D::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_rid"), &Navigation2D::get_rid);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true));
|
|
||||||
ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation2D::set_cell_size);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation2D::get_cell_size);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation2D::set_edge_connection_margin);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation2D::get_edge_connection_margin);
|
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size");
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Navigation2D::_notification(int p_what) {
|
|
||||||
switch (p_what) {
|
|
||||||
case NOTIFICATION_READY: {
|
|
||||||
NavigationServer2D::get_singleton()->map_set_active(map, true);
|
|
||||||
} break;
|
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
|
||||||
NavigationServer2D::get_singleton()->map_set_active(map, false);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Navigation2D::set_cell_size(float p_cell_size) {
|
|
||||||
cell_size = p_cell_size;
|
|
||||||
NavigationServer2D::get_singleton()->map_set_cell_size(map, cell_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Navigation2D::set_edge_connection_margin(float p_edge_connection_margin) {
|
|
||||||
edge_connection_margin = p_edge_connection_margin;
|
|
||||||
NavigationServer2D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) const {
|
|
||||||
return NavigationServer2D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) const {
|
|
||||||
return NavigationServer2D::get_singleton()->map_get_closest_point(map, p_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
RID Navigation2D::get_closest_point_owner(const Vector2 &p_point) const {
|
|
||||||
return NavigationServer2D::get_singleton()->map_get_closest_point_owner(map, p_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigation2D::Navigation2D() {
|
|
||||||
map = NavigationServer2D::get_singleton()->map_create();
|
|
||||||
set_cell_size(10); // Ten pixels
|
|
||||||
set_edge_connection_margin(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigation2D::~Navigation2D() {
|
|
||||||
NavigationServer2D::get_singleton()->free(map);
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* navigation_2d.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef NAVIGATION_2D_H
|
|
||||||
#define NAVIGATION_2D_H
|
|
||||||
|
|
||||||
#include "scene/2d/navigation_region_2d.h"
|
|
||||||
#include "scene/2d/node_2d.h"
|
|
||||||
|
|
||||||
class Navigation2D : public Node2D {
|
|
||||||
GDCLASS(Navigation2D, Node2D);
|
|
||||||
|
|
||||||
RID map;
|
|
||||||
real_t cell_size;
|
|
||||||
real_t edge_connection_margin;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
void _notification(int p_what);
|
|
||||||
|
|
||||||
public:
|
|
||||||
RID get_rid() const {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_cell_size(float p_cell_size);
|
|
||||||
float get_cell_size() const {
|
|
||||||
return cell_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_edge_connection_margin(float p_edge_connection_margin);
|
|
||||||
float get_edge_connection_margin() const {
|
|
||||||
return edge_connection_margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<Vector2> get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize = true) const;
|
|
||||||
Vector2 get_closest_point(const Vector2 &p_point) const;
|
|
||||||
RID get_closest_point_owner(const Vector2 &p_point) const;
|
|
||||||
|
|
||||||
Navigation2D();
|
|
||||||
~Navigation2D();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // NAVIGATION_2D_H
|
|
|
@ -32,7 +32,6 @@
|
||||||
|
|
||||||
#include "core/config/engine.h"
|
#include "core/config/engine.h"
|
||||||
#include "core/math/geometry_2d.h"
|
#include "core/math/geometry_2d.h"
|
||||||
#include "scene/2d/navigation_2d.h"
|
|
||||||
#include "servers/navigation_server_2d.h"
|
#include "servers/navigation_server_2d.h"
|
||||||
|
|
||||||
void NavigationAgent2D::_bind_methods() {
|
void NavigationAgent2D::_bind_methods() {
|
||||||
|
@ -42,9 +41,6 @@ void NavigationAgent2D::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent2D::set_radius);
|
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent2D::set_radius);
|
||||||
ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent2D::get_radius);
|
ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent2D::get_radius);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent2D::set_navigation_node);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent2D::get_navigation_node);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent2D::set_neighbor_dist);
|
ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent2D::set_neighbor_dist);
|
||||||
ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent2D::get_neighbor_dist);
|
ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent2D::get_neighbor_dist);
|
||||||
|
|
||||||
|
@ -95,27 +91,10 @@ void NavigationAgent2D::_notification(int p_what) {
|
||||||
|
|
||||||
NavigationServer2D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
|
NavigationServer2D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
|
||||||
|
|
||||||
// Search the navigation node and set it
|
|
||||||
{
|
|
||||||
Navigation2D *nav = nullptr;
|
|
||||||
Node *p = get_parent();
|
|
||||||
while (p != nullptr) {
|
|
||||||
nav = Object::cast_to<Navigation2D>(p);
|
|
||||||
if (nav != nullptr) {
|
|
||||||
p = nullptr;
|
|
||||||
} else {
|
|
||||||
p = p->get_parent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_navigation(nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_physics_process_internal(true);
|
set_physics_process_internal(true);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
agent_parent = nullptr;
|
agent_parent = nullptr;
|
||||||
set_navigation(nullptr);
|
|
||||||
set_physics_process_internal(false);
|
set_physics_process_internal(false);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||||
|
@ -146,25 +125,6 @@ NavigationAgent2D::~NavigationAgent2D() {
|
||||||
agent = RID(); // Pointless
|
agent = RID(); // Pointless
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationAgent2D::set_navigation(Navigation2D *p_nav) {
|
|
||||||
if (navigation == p_nav) {
|
|
||||||
return; // Pointless
|
|
||||||
}
|
|
||||||
|
|
||||||
navigation = p_nav;
|
|
||||||
NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NavigationAgent2D::set_navigation_node(Node *p_nav) {
|
|
||||||
Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
|
|
||||||
ERR_FAIL_COND(nav == nullptr);
|
|
||||||
set_navigation(nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *NavigationAgent2D::get_navigation_node() const {
|
|
||||||
return Object::cast_to<Node>(navigation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NavigationAgent2D::set_target_desired_distance(real_t p_dd) {
|
void NavigationAgent2D::set_target_desired_distance(real_t p_dd) {
|
||||||
target_desired_distance = p_dd;
|
target_desired_distance = p_dd;
|
||||||
}
|
}
|
||||||
|
@ -287,7 +247,7 @@ void NavigationAgent2D::update_navigation() {
|
||||||
if (agent_parent == nullptr) {
|
if (agent_parent == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (navigation == nullptr) {
|
if (!agent_parent->is_inside_tree()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
|
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
|
||||||
|
@ -319,7 +279,7 @@ void NavigationAgent2D::update_navigation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reload_path) {
|
if (reload_path) {
|
||||||
navigation_path = NavigationServer2D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true);
|
navigation_path = NavigationServer2D::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_location, true);
|
||||||
navigation_finished = false;
|
navigation_finished = false;
|
||||||
nav_path_index = 0;
|
nav_path_index = 0;
|
||||||
emit_signal("path_changed");
|
emit_signal("path_changed");
|
||||||
|
|
|
@ -35,13 +35,11 @@
|
||||||
#include "scene/main/node.h"
|
#include "scene/main/node.h"
|
||||||
|
|
||||||
class Node2D;
|
class Node2D;
|
||||||
class Navigation2D;
|
|
||||||
|
|
||||||
class NavigationAgent2D : public Node {
|
class NavigationAgent2D : public Node {
|
||||||
GDCLASS(NavigationAgent2D, Node);
|
GDCLASS(NavigationAgent2D, Node);
|
||||||
|
|
||||||
Node2D *agent_parent = nullptr;
|
Node2D *agent_parent = nullptr;
|
||||||
Navigation2D *navigation = nullptr;
|
|
||||||
|
|
||||||
RID agent;
|
RID agent;
|
||||||
|
|
||||||
|
@ -74,14 +72,6 @@ public:
|
||||||
NavigationAgent2D();
|
NavigationAgent2D();
|
||||||
virtual ~NavigationAgent2D();
|
virtual ~NavigationAgent2D();
|
||||||
|
|
||||||
void set_navigation(Navigation2D *p_nav);
|
|
||||||
const Navigation2D *get_navigation() const {
|
|
||||||
return navigation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_navigation_node(Node *p_nav);
|
|
||||||
Node *get_navigation_node() const;
|
|
||||||
|
|
||||||
RID get_rid() const {
|
RID get_rid() const {
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,48 +31,31 @@
|
||||||
#include "navigation_obstacle_2d.h"
|
#include "navigation_obstacle_2d.h"
|
||||||
|
|
||||||
#include "scene/2d/collision_shape_2d.h"
|
#include "scene/2d/collision_shape_2d.h"
|
||||||
#include "scene/2d/navigation_2d.h"
|
|
||||||
#include "scene/2d/physics_body_2d.h"
|
#include "scene/2d/physics_body_2d.h"
|
||||||
#include "servers/navigation_server_2d.h"
|
#include "servers/navigation_server_2d.h"
|
||||||
|
|
||||||
void NavigationObstacle2D::_bind_methods() {
|
void NavigationObstacle2D::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationObstacle2D::_notification(int p_what) {
|
void NavigationObstacle2D::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_READY: {
|
case NOTIFICATION_READY: {
|
||||||
update_agent_shape();
|
|
||||||
|
|
||||||
// Search the navigation node and set it
|
|
||||||
{
|
|
||||||
Navigation2D *nav = nullptr;
|
|
||||||
Node *p = get_parent();
|
|
||||||
while (p != nullptr) {
|
|
||||||
nav = Object::cast_to<Navigation2D>(p);
|
|
||||||
if (nav != nullptr) {
|
|
||||||
p = nullptr;
|
|
||||||
} else {
|
|
||||||
p = p->get_parent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_navigation(nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_physics_process_internal(true);
|
set_physics_process_internal(true);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
set_navigation(nullptr);
|
|
||||||
set_physics_process_internal(false);
|
set_physics_process_internal(false);
|
||||||
} break;
|
} break;
|
||||||
|
case NOTIFICATION_PARENTED: {
|
||||||
|
parent_node2d = Object::cast_to<Node2D>(get_parent());
|
||||||
|
update_agent_shape();
|
||||||
|
} break;
|
||||||
|
case NOTIFICATION_UNPARENTED: {
|
||||||
|
parent_node2d = nullptr;
|
||||||
|
} break;
|
||||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||||
Node2D *node = Object::cast_to<Node2D>(get_parent());
|
if (parent_node2d) {
|
||||||
if (node) {
|
NavigationServer2D::get_singleton()->agent_set_position(agent, parent_node2d->get_global_transform().get_origin());
|
||||||
NavigationServer2D::get_singleton()->agent_set_position(agent, node->get_global_transform().get_origin());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,25 +69,6 @@ NavigationObstacle2D::~NavigationObstacle2D() {
|
||||||
agent = RID(); // Pointless
|
agent = RID(); // Pointless
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) {
|
|
||||||
if (navigation == p_nav) {
|
|
||||||
return; // Pointless
|
|
||||||
}
|
|
||||||
|
|
||||||
navigation = p_nav;
|
|
||||||
NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NavigationObstacle2D::set_navigation_node(Node *p_nav) {
|
|
||||||
Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav);
|
|
||||||
ERR_FAIL_COND(nav == nullptr);
|
|
||||||
set_navigation(nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *NavigationObstacle2D::get_navigation_node() const {
|
|
||||||
return Object::cast_to<Node>(navigation);
|
|
||||||
}
|
|
||||||
|
|
||||||
String NavigationObstacle2D::get_configuration_warning() const {
|
String NavigationObstacle2D::get_configuration_warning() const {
|
||||||
String warning = Node::get_configuration_warning();
|
String warning = Node::get_configuration_warning();
|
||||||
|
|
||||||
|
@ -119,13 +83,12 @@ String NavigationObstacle2D::get_configuration_warning() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationObstacle2D::update_agent_shape() {
|
void NavigationObstacle2D::update_agent_shape() {
|
||||||
Node *node = get_parent();
|
if (parent_node2d) {
|
||||||
|
|
||||||
// Estimate the radius of this physics body
|
// Estimate the radius of this physics body
|
||||||
real_t radius = 0.0;
|
real_t radius = 0.0;
|
||||||
for (int i(0); i < node->get_child_count(); i++) {
|
for (int i(0); i < parent_node2d->get_child_count(); i++) {
|
||||||
// For each collision shape
|
// For each collision shape
|
||||||
CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(node->get_child(i));
|
CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(parent_node2d->get_child(i));
|
||||||
if (cs) {
|
if (cs) {
|
||||||
// Take the distance between the Body center to the shape center
|
// Take the distance between the Body center to the shape center
|
||||||
real_t r = cs->get_transform().get_origin().length();
|
real_t r = cs->get_transform().get_origin().length();
|
||||||
|
@ -139,11 +102,8 @@ void NavigationObstacle2D::update_agent_shape() {
|
||||||
radius = MAX(radius, r);
|
radius = MAX(radius, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node2D *node_2d = Object::cast_to<Node2D>(node);
|
Vector2 s = parent_node2d->get_global_transform().get_scale();
|
||||||
if (node_2d) {
|
|
||||||
Vector2 s = node_2d->get_global_transform().get_scale();
|
|
||||||
radius *= MAX(s.x, s.y);
|
radius *= MAX(s.x, s.y);
|
||||||
}
|
|
||||||
|
|
||||||
if (radius == 0.0) {
|
if (radius == 0.0) {
|
||||||
radius = 1.0; // Never a 0 radius
|
radius = 1.0; // Never a 0 radius
|
||||||
|
@ -155,4 +115,5 @@ void NavigationObstacle2D::update_agent_shape() {
|
||||||
NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0);
|
NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0);
|
||||||
NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
|
NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
|
||||||
NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0);
|
NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,15 +31,13 @@
|
||||||
#ifndef NAVIGATION_OBSTACLE_2D_H
|
#ifndef NAVIGATION_OBSTACLE_2D_H
|
||||||
#define NAVIGATION_OBSTACLE_2D_H
|
#define NAVIGATION_OBSTACLE_2D_H
|
||||||
|
|
||||||
|
#include "scene/2d/node_2d.h"
|
||||||
#include "scene/main/node.h"
|
#include "scene/main/node.h"
|
||||||
|
|
||||||
class Navigation2D;
|
|
||||||
|
|
||||||
class NavigationObstacle2D : public Node {
|
class NavigationObstacle2D : public Node {
|
||||||
GDCLASS(NavigationObstacle2D, Node);
|
GDCLASS(NavigationObstacle2D, Node);
|
||||||
|
|
||||||
Navigation2D *navigation = nullptr;
|
Node2D *parent_node2d = nullptr;
|
||||||
|
|
||||||
RID agent;
|
RID agent;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -50,14 +48,6 @@ public:
|
||||||
NavigationObstacle2D();
|
NavigationObstacle2D();
|
||||||
virtual ~NavigationObstacle2D();
|
virtual ~NavigationObstacle2D();
|
||||||
|
|
||||||
void set_navigation(Navigation2D *p_nav);
|
|
||||||
const Navigation2D *get_navigation() const {
|
|
||||||
return navigation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_navigation_node(Node *p_nav);
|
|
||||||
Node *get_navigation_node() const;
|
|
||||||
|
|
||||||
RID get_rid() const {
|
RID get_rid() const {
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "core/core_string_names.h"
|
#include "core/core_string_names.h"
|
||||||
#include "core/math/geometry_2d.h"
|
#include "core/math/geometry_2d.h"
|
||||||
#include "core/os/mutex.h"
|
#include "core/os/mutex.h"
|
||||||
#include "navigation_2d.h"
|
|
||||||
#include "servers/navigation_server_2d.h"
|
#include "servers/navigation_server_2d.h"
|
||||||
|
|
||||||
#include "thirdparty/misc/polypartition.h"
|
#include "thirdparty/misc/polypartition.h"
|
||||||
|
@ -366,9 +365,7 @@ void NavigationRegion2D::set_enabled(bool p_enabled) {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
NavigationServer2D::get_singleton()->region_set_map(region, RID());
|
NavigationServer2D::get_singleton()->region_set_map(region, RID());
|
||||||
} else {
|
} else {
|
||||||
if (navigation) {
|
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
|
||||||
NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) {
|
if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) {
|
||||||
|
@ -394,29 +391,15 @@ bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
|
||||||
void NavigationRegion2D::_notification(int p_what) {
|
void NavigationRegion2D::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
Node2D *c = this;
|
|
||||||
while (c) {
|
|
||||||
navigation = Object::cast_to<Navigation2D>(c);
|
|
||||||
if (navigation) {
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
|
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = Object::cast_to<Node2D>(c->get_parent());
|
|
||||||
}
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||||
NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform());
|
NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform());
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
if (navigation) {
|
|
||||||
NavigationServer2D::get_singleton()->region_set_map(region, RID());
|
NavigationServer2D::get_singleton()->region_set_map(region, RID());
|
||||||
}
|
|
||||||
navigation = nullptr;
|
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_DRAW: {
|
case NOTIFICATION_DRAW: {
|
||||||
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) {
|
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) {
|
||||||
|
@ -507,18 +490,8 @@ String NavigationRegion2D::get_configuration_warning() const {
|
||||||
}
|
}
|
||||||
warning += TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon.");
|
warning += TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon.");
|
||||||
}
|
}
|
||||||
const Node2D *c = this;
|
|
||||||
while (c) {
|
|
||||||
if (Object::cast_to<Navigation2D>(c)) {
|
|
||||||
return warning;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = Object::cast_to<Node2D>(c->get_parent());
|
return warning;
|
||||||
}
|
|
||||||
if (!warning.is_empty()) {
|
|
||||||
warning += "\n\n";
|
|
||||||
}
|
|
||||||
return warning + TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationRegion2D::_bind_methods() {
|
void NavigationRegion2D::_bind_methods() {
|
||||||
|
|
|
@ -91,14 +91,11 @@ public:
|
||||||
~NavigationPolygon() {}
|
~NavigationPolygon() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Navigation2D;
|
|
||||||
|
|
||||||
class NavigationRegion2D : public Node2D {
|
class NavigationRegion2D : public Node2D {
|
||||||
GDCLASS(NavigationRegion2D, Node2D);
|
GDCLASS(NavigationRegion2D, Node2D);
|
||||||
|
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
RID region;
|
RID region;
|
||||||
Navigation2D *navigation = nullptr;
|
|
||||||
Ref<NavigationPolygon> navpoly;
|
Ref<NavigationPolygon> navpoly;
|
||||||
|
|
||||||
void _navpoly_changed();
|
void _navpoly_changed();
|
||||||
|
|
|
@ -48,16 +48,6 @@ int TileMap::_get_quadrant_size() const {
|
||||||
void TileMap::_notification(int p_what) {
|
void TileMap::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
Node2D *c = this;
|
|
||||||
while (c) {
|
|
||||||
navigation = Object::cast_to<Navigation2D>(c);
|
|
||||||
if (navigation) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = Object::cast_to<Node2D>(c->get_parent());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_parent) {
|
if (use_parent) {
|
||||||
_clear_quadrants();
|
_clear_quadrants();
|
||||||
collision_parent = Object::cast_to<CollisionObject2D>(get_parent());
|
collision_parent = Object::cast_to<CollisionObject2D>(get_parent());
|
||||||
|
@ -77,12 +67,10 @@ void TileMap::_notification(int p_what) {
|
||||||
_update_quadrant_space(RID());
|
_update_quadrant_space(RID());
|
||||||
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
||||||
Quadrant &q = E->get();
|
Quadrant &q = E->get();
|
||||||
if (navigation) {
|
|
||||||
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
|
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
|
||||||
NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID());
|
NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID());
|
||||||
}
|
}
|
||||||
q.navpoly_ids.clear();
|
q.navpoly_ids.clear();
|
||||||
}
|
|
||||||
|
|
||||||
if (collision_parent) {
|
if (collision_parent) {
|
||||||
collision_parent->remove_shape_owner(q.shape_owner_id);
|
collision_parent->remove_shape_owner(q.shape_owner_id);
|
||||||
|
@ -96,8 +84,6 @@ void TileMap::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
|
|
||||||
collision_parent = nullptr;
|
collision_parent = nullptr;
|
||||||
navigation = nullptr;
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||||
|
@ -135,11 +121,6 @@ void TileMap::_update_quadrant_transform() {
|
||||||
local_transform = get_transform();
|
local_transform = get_transform();
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform2D nav_rel;
|
|
||||||
if (navigation) {
|
|
||||||
nav_rel = get_relative_transform_to_parent(navigation);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
||||||
Quadrant &q = E->get();
|
Quadrant &q = E->get();
|
||||||
Transform2D xform;
|
Transform2D xform;
|
||||||
|
@ -150,9 +131,9 @@ void TileMap::_update_quadrant_transform() {
|
||||||
PhysicsServer2D::get_singleton()->body_set_state(q.body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
|
PhysicsServer2D::get_singleton()->body_set_state(q.body, PhysicsServer2D::BODY_STATE_TRANSFORM, xform);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (navigation) {
|
if (bake_navigation) {
|
||||||
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
|
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
|
||||||
NavigationServer2D::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform);
|
NavigationServer2D::get_singleton()->region_set_transform(F->get().region, F->get().xform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,11 +296,6 @@ void TileMap::update_dirty_quadrants() {
|
||||||
RenderingServer *vs = RenderingServer::get_singleton();
|
RenderingServer *vs = RenderingServer::get_singleton();
|
||||||
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
|
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
|
||||||
Vector2 tofs = get_cell_draw_offset();
|
Vector2 tofs = get_cell_draw_offset();
|
||||||
Transform2D nav_rel;
|
|
||||||
if (navigation) {
|
|
||||||
nav_rel = get_relative_transform_to_parent(navigation);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 qofs;
|
Vector2 qofs;
|
||||||
|
|
||||||
SceneTree *st = SceneTree::get_singleton();
|
SceneTree *st = SceneTree::get_singleton();
|
||||||
|
@ -352,12 +328,10 @@ void TileMap::update_dirty_quadrants() {
|
||||||
}
|
}
|
||||||
int shape_idx = 0;
|
int shape_idx = 0;
|
||||||
|
|
||||||
if (navigation) {
|
|
||||||
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
|
||||||
NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
|
NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
|
||||||
}
|
}
|
||||||
q.navpoly_ids.clear();
|
q.navpoly_ids.clear();
|
||||||
}
|
|
||||||
|
|
||||||
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
|
||||||
RS::get_singleton()->free(E->get().id);
|
RS::get_singleton()->free(E->get().id);
|
||||||
|
@ -579,7 +553,7 @@ void TileMap::update_dirty_quadrants() {
|
||||||
vs->canvas_item_add_set_transform(debug_canvas_item, Transform2D());
|
vs->canvas_item_add_set_transform(debug_canvas_item, Transform2D());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (navigation) {
|
if (bake_navigation) {
|
||||||
Ref<NavigationPolygon> navpoly;
|
Ref<NavigationPolygon> navpoly;
|
||||||
Vector2 npoly_ofs;
|
Vector2 npoly_ofs;
|
||||||
if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
|
if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(c.id) == TileSet::ATLAS_TILE) {
|
||||||
|
@ -596,8 +570,8 @@ void TileMap::update_dirty_quadrants() {
|
||||||
_fix_cell_transform(xform, c, npoly_ofs, s);
|
_fix_cell_transform(xform, c, npoly_ofs, s);
|
||||||
|
|
||||||
RID region = NavigationServer2D::get_singleton()->region_create();
|
RID region = NavigationServer2D::get_singleton()->region_create();
|
||||||
NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
|
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
|
||||||
NavigationServer2D::get_singleton()->region_set_transform(region, nav_rel * xform);
|
NavigationServer2D::get_singleton()->region_set_transform(region, xform);
|
||||||
NavigationServer2D::get_singleton()->region_set_navpoly(region, navpoly);
|
NavigationServer2D::get_singleton()->region_set_navpoly(region, navpoly);
|
||||||
|
|
||||||
Quadrant::NavPoly np;
|
Quadrant::NavPoly np;
|
||||||
|
@ -787,12 +761,10 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
|
||||||
dirty_quadrant_list.remove(&q.dirty_list);
|
dirty_quadrant_list.remove(&q.dirty_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (navigation) {
|
|
||||||
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
|
||||||
NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
|
NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
|
||||||
}
|
}
|
||||||
q.navpoly_ids.clear();
|
q.navpoly_ids.clear();
|
||||||
}
|
|
||||||
|
|
||||||
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
|
||||||
RS::get_singleton()->free(E->get().id);
|
RS::get_singleton()->free(E->get().id);
|
||||||
|
@ -1360,6 +1332,17 @@ float TileMap::get_collision_bounce() const {
|
||||||
return bounce;
|
return bounce;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TileMap::set_bake_navigation(bool p_bake_navigation) {
|
||||||
|
bake_navigation = p_bake_navigation;
|
||||||
|
for (Map<PosKey, Quadrant>::Element *F = quadrant_map.front(); F; F = F->next()) {
|
||||||
|
_make_quadrant_dirty(F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TileMap::is_baking_navigation() {
|
||||||
|
return bake_navigation;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t TileMap::get_collision_layer() const {
|
uint32_t TileMap::get_collision_layer() const {
|
||||||
return collision_layer;
|
return collision_layer;
|
||||||
}
|
}
|
||||||
|
@ -1784,6 +1767,9 @@ void TileMap::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_collision_bounce", "value"), &TileMap::set_collision_bounce);
|
ClassDB::bind_method(D_METHOD("set_collision_bounce", "value"), &TileMap::set_collision_bounce);
|
||||||
ClassDB::bind_method(D_METHOD("get_collision_bounce"), &TileMap::get_collision_bounce);
|
ClassDB::bind_method(D_METHOD("get_collision_bounce"), &TileMap::get_collision_bounce);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_bake_navigation", "bake_navigation"), &TileMap::set_bake_navigation);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_baking_navigation"), &TileMap::is_baking_navigation);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &TileMap::set_occluder_light_mask);
|
ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &TileMap::set_occluder_light_mask);
|
||||||
ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &TileMap::get_occluder_light_mask);
|
ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &TileMap::get_occluder_light_mask);
|
||||||
|
|
||||||
|
@ -1842,6 +1828,9 @@ void TileMap::_bind_methods() {
|
||||||
ADD_GROUP("Occluder", "occluder_");
|
ADD_GROUP("Occluder", "occluder_");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "occluder_light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask");
|
||||||
|
|
||||||
|
ADD_GROUP("Navigation", "");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation");
|
||||||
|
|
||||||
ADD_PROPERTY_DEFAULT("format", FORMAT_1);
|
ADD_PROPERTY_DEFAULT("format", FORMAT_1);
|
||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("settings_changed"));
|
ADD_SIGNAL(MethodInfo("settings_changed"));
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
|
|
||||||
#include "core/templates/self_list.h"
|
#include "core/templates/self_list.h"
|
||||||
#include "core/templates/vset.h"
|
#include "core/templates/vset.h"
|
||||||
#include "scene/2d/navigation_2d.h"
|
|
||||||
#include "scene/2d/node_2d.h"
|
#include "scene/2d/node_2d.h"
|
||||||
#include "scene/resources/tile_set.h"
|
#include "scene/resources/tile_set.h"
|
||||||
|
|
||||||
|
@ -78,7 +77,7 @@ private:
|
||||||
bool use_parent = false;
|
bool use_parent = false;
|
||||||
CollisionObject2D *collision_parent = nullptr;
|
CollisionObject2D *collision_parent = nullptr;
|
||||||
bool use_kinematic = false;
|
bool use_kinematic = false;
|
||||||
Navigation2D *navigation = nullptr;
|
bool bake_navigation = false;
|
||||||
|
|
||||||
union PosKey {
|
union PosKey {
|
||||||
struct {
|
struct {
|
||||||
|
@ -295,6 +294,9 @@ public:
|
||||||
void set_collision_bounce(float p_bounce);
|
void set_collision_bounce(float p_bounce);
|
||||||
float get_collision_bounce() const;
|
float get_collision_bounce() const;
|
||||||
|
|
||||||
|
void set_bake_navigation(bool p_bake_navigation);
|
||||||
|
bool is_baking_navigation();
|
||||||
|
|
||||||
void set_mode(Mode p_mode);
|
void set_mode(Mode p_mode);
|
||||||
Mode get_mode() const;
|
Mode get_mode() const;
|
||||||
|
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* navigation_3d.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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_3d.h"
|
|
||||||
|
|
||||||
#include "servers/navigation_server_3d.h"
|
|
||||||
|
|
||||||
Vector<Vector3> Navigation3D::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) const {
|
|
||||||
return NavigationServer3D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Navigation3D::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const {
|
|
||||||
return NavigationServer3D::get_singleton()->map_get_closest_point_to_segment(map, p_from, p_to, p_use_collision);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Navigation3D::get_closest_point(const Vector3 &p_point) const {
|
|
||||||
return NavigationServer3D::get_singleton()->map_get_closest_point(map, p_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Navigation3D::get_closest_point_normal(const Vector3 &p_point) const {
|
|
||||||
return NavigationServer3D::get_singleton()->map_get_closest_point_normal(map, p_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
RID Navigation3D::get_closest_point_owner(const Vector3 &p_point) const {
|
|
||||||
return NavigationServer3D::get_singleton()->map_get_closest_point_owner(map, p_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Navigation3D::set_up_vector(const Vector3 &p_up) {
|
|
||||||
up = p_up;
|
|
||||||
NavigationServer3D::get_singleton()->map_set_up(map, up);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Navigation3D::get_up_vector() const {
|
|
||||||
return up;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Navigation3D::set_cell_size(float p_cell_size) {
|
|
||||||
cell_size = p_cell_size;
|
|
||||||
NavigationServer3D::get_singleton()->map_set_cell_size(map, cell_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Navigation3D::set_edge_connection_margin(float p_edge_connection_margin) {
|
|
||||||
edge_connection_margin = p_edge_connection_margin;
|
|
||||||
NavigationServer3D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Navigation3D::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_rid"), &Navigation3D::get_rid);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation3D::get_simple_path, DEFVAL(true));
|
|
||||||
ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "start", "end", "use_collision"), &Navigation3D::get_closest_point_to_segment, DEFVAL(false));
|
|
||||||
ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation3D::get_closest_point);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_closest_point_normal", "to_point"), &Navigation3D::get_closest_point_normal);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation3D::get_closest_point_owner);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_up_vector", "up"), &Navigation3D::set_up_vector);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_up_vector"), &Navigation3D::get_up_vector);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation3D::set_cell_size);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation3D::get_cell_size);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation3D::set_edge_connection_margin);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation3D::get_edge_connection_margin);
|
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_vector"), "set_up_vector", "get_up_vector");
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size");
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Navigation3D::_notification(int p_what) {
|
|
||||||
switch (p_what) {
|
|
||||||
case NOTIFICATION_READY: {
|
|
||||||
NavigationServer3D::get_singleton()->map_set_active(map, true);
|
|
||||||
} break;
|
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
|
||||||
NavigationServer3D::get_singleton()->map_set_active(map, false);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigation3D::Navigation3D() {
|
|
||||||
map = NavigationServer3D::get_singleton()->map_create();
|
|
||||||
|
|
||||||
set_cell_size(0.3);
|
|
||||||
set_edge_connection_margin(5.0); // Five meters, depends a lot on the agent's radius
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigation3D::~Navigation3D() {
|
|
||||||
NavigationServer3D::get_singleton()->free(map);
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*************************************************************************/
|
|
||||||
/* navigation_3d.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef NAVIGATION_3D_H
|
|
||||||
#define NAVIGATION_3D_H
|
|
||||||
|
|
||||||
#include "scene/3d/navigation_region_3d.h"
|
|
||||||
#include "scene/3d/node_3d.h"
|
|
||||||
|
|
||||||
class Navigation3D : public Node3D {
|
|
||||||
GDCLASS(Navigation3D, Node3D);
|
|
||||||
|
|
||||||
RID map;
|
|
||||||
|
|
||||||
Vector3 up = Vector3(0, 1, 0);
|
|
||||||
real_t cell_size;
|
|
||||||
real_t edge_connection_margin;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
void _notification(int p_what);
|
|
||||||
|
|
||||||
public:
|
|
||||||
RID get_rid() const {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_up_vector(const Vector3 &p_up);
|
|
||||||
Vector3 get_up_vector() const;
|
|
||||||
|
|
||||||
void set_cell_size(float p_cell_size);
|
|
||||||
float get_cell_size() const {
|
|
||||||
return cell_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_edge_connection_margin(float p_edge_connection_margin);
|
|
||||||
float get_edge_connection_margin() const {
|
|
||||||
return edge_connection_margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<Vector3> get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize = true) const;
|
|
||||||
Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision = false) const;
|
|
||||||
Vector3 get_closest_point(const Vector3 &p_point) const;
|
|
||||||
Vector3 get_closest_point_normal(const Vector3 &p_point) const;
|
|
||||||
RID get_closest_point_owner(const Vector3 &p_point) const;
|
|
||||||
|
|
||||||
Navigation3D();
|
|
||||||
~Navigation3D();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // NAVIGATION_H
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "navigation_agent_3d.h"
|
#include "navigation_agent_3d.h"
|
||||||
|
|
||||||
#include "core/config/engine.h"
|
#include "core/config/engine.h"
|
||||||
#include "scene/3d/navigation_3d.h"
|
|
||||||
#include "servers/navigation_server_3d.h"
|
#include "servers/navigation_server_3d.h"
|
||||||
|
|
||||||
void NavigationAgent3D::_bind_methods() {
|
void NavigationAgent3D::_bind_methods() {
|
||||||
|
@ -47,9 +46,6 @@ void NavigationAgent3D::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_ignore_y", "ignore"), &NavigationAgent3D::set_ignore_y);
|
ClassDB::bind_method(D_METHOD("set_ignore_y", "ignore"), &NavigationAgent3D::set_ignore_y);
|
||||||
ClassDB::bind_method(D_METHOD("get_ignore_y"), &NavigationAgent3D::get_ignore_y);
|
ClassDB::bind_method(D_METHOD("get_ignore_y"), &NavigationAgent3D::get_ignore_y);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent3D::set_navigation_node);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent3D::get_navigation_node);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent3D::set_neighbor_dist);
|
ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent3D::set_neighbor_dist);
|
||||||
ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent3D::get_neighbor_dist);
|
ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent3D::get_neighbor_dist);
|
||||||
|
|
||||||
|
@ -101,28 +97,10 @@ void NavigationAgent3D::_notification(int p_what) {
|
||||||
agent_parent = Object::cast_to<Node3D>(get_parent());
|
agent_parent = Object::cast_to<Node3D>(get_parent());
|
||||||
|
|
||||||
NavigationServer3D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
|
NavigationServer3D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
|
||||||
|
|
||||||
// Search the navigation node and set it
|
|
||||||
{
|
|
||||||
Navigation3D *nav = nullptr;
|
|
||||||
Node *p = get_parent();
|
|
||||||
while (p != nullptr) {
|
|
||||||
nav = Object::cast_to<Navigation3D>(p);
|
|
||||||
if (nav != nullptr) {
|
|
||||||
p = nullptr;
|
|
||||||
} else {
|
|
||||||
p = p->get_parent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_navigation(nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_physics_process_internal(true);
|
set_physics_process_internal(true);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
agent_parent = nullptr;
|
agent_parent = nullptr;
|
||||||
set_navigation(nullptr);
|
|
||||||
set_physics_process_internal(false);
|
set_physics_process_internal(false);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||||
|
@ -154,25 +132,6 @@ NavigationAgent3D::~NavigationAgent3D() {
|
||||||
agent = RID(); // Pointless
|
agent = RID(); // Pointless
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationAgent3D::set_navigation(Navigation3D *p_nav) {
|
|
||||||
if (navigation == p_nav) {
|
|
||||||
return; // Pointless
|
|
||||||
}
|
|
||||||
|
|
||||||
navigation = p_nav;
|
|
||||||
NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NavigationAgent3D::set_navigation_node(Node *p_nav) {
|
|
||||||
Navigation3D *nav = Object::cast_to<Navigation3D>(p_nav);
|
|
||||||
ERR_FAIL_COND(nav == nullptr);
|
|
||||||
set_navigation(nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *NavigationAgent3D::get_navigation_node() const {
|
|
||||||
return Object::cast_to<Node>(navigation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NavigationAgent3D::set_target_desired_distance(real_t p_dd) {
|
void NavigationAgent3D::set_target_desired_distance(real_t p_dd) {
|
||||||
target_desired_distance = p_dd;
|
target_desired_distance = p_dd;
|
||||||
}
|
}
|
||||||
|
@ -303,7 +262,7 @@ void NavigationAgent3D::update_navigation() {
|
||||||
if (agent_parent == nullptr) {
|
if (agent_parent == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (navigation == nullptr) {
|
if (!agent_parent->is_inside_tree()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
|
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
|
||||||
|
@ -337,7 +296,7 @@ void NavigationAgent3D::update_navigation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reload_path) {
|
if (reload_path) {
|
||||||
navigation_path = NavigationServer3D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true);
|
navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true);
|
||||||
navigation_finished = false;
|
navigation_finished = false;
|
||||||
nav_path_index = 0;
|
nav_path_index = 0;
|
||||||
emit_signal("path_changed");
|
emit_signal("path_changed");
|
||||||
|
|
|
@ -35,13 +35,11 @@
|
||||||
#include "scene/main/node.h"
|
#include "scene/main/node.h"
|
||||||
|
|
||||||
class Node3D;
|
class Node3D;
|
||||||
class Navigation3D;
|
|
||||||
|
|
||||||
class NavigationAgent3D : public Node {
|
class NavigationAgent3D : public Node {
|
||||||
GDCLASS(NavigationAgent3D, Node);
|
GDCLASS(NavigationAgent3D, Node);
|
||||||
|
|
||||||
Node3D *agent_parent = nullptr;
|
Node3D *agent_parent = nullptr;
|
||||||
Navigation3D *navigation = nullptr;
|
|
||||||
|
|
||||||
RID agent;
|
RID agent;
|
||||||
|
|
||||||
|
@ -76,14 +74,6 @@ public:
|
||||||
NavigationAgent3D();
|
NavigationAgent3D();
|
||||||
virtual ~NavigationAgent3D();
|
virtual ~NavigationAgent3D();
|
||||||
|
|
||||||
void set_navigation(Navigation3D *p_nav);
|
|
||||||
const Navigation3D *get_navigation() const {
|
|
||||||
return navigation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_navigation_node(Node *p_nav);
|
|
||||||
Node *get_navigation_node() const;
|
|
||||||
|
|
||||||
RID get_rid() const {
|
RID get_rid() const {
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,47 +31,30 @@
|
||||||
#include "navigation_obstacle_3d.h"
|
#include "navigation_obstacle_3d.h"
|
||||||
|
|
||||||
#include "scene/3d/collision_shape_3d.h"
|
#include "scene/3d/collision_shape_3d.h"
|
||||||
#include "scene/3d/navigation_3d.h"
|
|
||||||
#include "scene/3d/physics_body_3d.h"
|
#include "scene/3d/physics_body_3d.h"
|
||||||
#include "servers/navigation_server_3d.h"
|
#include "servers/navigation_server_3d.h"
|
||||||
|
|
||||||
void NavigationObstacle3D::_bind_methods() {
|
void NavigationObstacle3D::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle3D::set_navigation_node);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle3D::get_navigation_node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationObstacle3D::_notification(int p_what) {
|
void NavigationObstacle3D::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_READY: {
|
case NOTIFICATION_READY: {
|
||||||
update_agent_shape();
|
|
||||||
|
|
||||||
// Search the navigation node and set it
|
|
||||||
{
|
|
||||||
Navigation3D *nav = nullptr;
|
|
||||||
Node *p = get_parent();
|
|
||||||
while (p != nullptr) {
|
|
||||||
nav = Object::cast_to<Navigation3D>(p);
|
|
||||||
if (nav != nullptr) {
|
|
||||||
p = nullptr;
|
|
||||||
} else {
|
|
||||||
p = p->get_parent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_navigation(nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_physics_process_internal(true);
|
set_physics_process_internal(true);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
set_navigation(nullptr);
|
|
||||||
set_physics_process_internal(false);
|
set_physics_process_internal(false);
|
||||||
} break;
|
} break;
|
||||||
|
case NOTIFICATION_PARENTED: {
|
||||||
|
parent_node3d = Object::cast_to<Node3D>(get_parent());
|
||||||
|
update_agent_shape();
|
||||||
|
} break;
|
||||||
|
case NOTIFICATION_UNPARENTED: {
|
||||||
|
parent_node3d = nullptr;
|
||||||
|
} break;
|
||||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||||
Node3D *spatial = Object::cast_to<Node3D>(get_parent());
|
if (parent_node3d) {
|
||||||
if (spatial) {
|
NavigationServer3D::get_singleton()->agent_set_position(agent, parent_node3d->get_global_transform().origin);
|
||||||
NavigationServer3D::get_singleton()->agent_set_position(agent, spatial->get_global_transform().origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent());
|
PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent());
|
||||||
if (rigid) {
|
if (rigid) {
|
||||||
|
@ -79,7 +62,7 @@ void NavigationObstacle3D::_notification(int p_what) {
|
||||||
NavigationServer3D::get_singleton()->agent_set_velocity(agent, v);
|
NavigationServer3D::get_singleton()->agent_set_velocity(agent, v);
|
||||||
NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v);
|
NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,29 +76,10 @@ NavigationObstacle3D::~NavigationObstacle3D() {
|
||||||
agent = RID(); // Pointless
|
agent = RID(); // Pointless
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationObstacle3D::set_navigation(Navigation3D *p_nav) {
|
|
||||||
if (navigation == p_nav) {
|
|
||||||
return; // Pointless
|
|
||||||
}
|
|
||||||
|
|
||||||
navigation = p_nav;
|
|
||||||
NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NavigationObstacle3D::set_navigation_node(Node *p_nav) {
|
|
||||||
Navigation3D *nav = Object::cast_to<Navigation3D>(p_nav);
|
|
||||||
ERR_FAIL_COND(nav == nullptr);
|
|
||||||
set_navigation(nav);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *NavigationObstacle3D::get_navigation_node() const {
|
|
||||||
return Object::cast_to<Node>(navigation);
|
|
||||||
}
|
|
||||||
|
|
||||||
String NavigationObstacle3D::get_configuration_warning() const {
|
String NavigationObstacle3D::get_configuration_warning() const {
|
||||||
String warning = Node::get_configuration_warning();
|
String warning = Node::get_configuration_warning();
|
||||||
|
|
||||||
if (!Object::cast_to<Node3D>(get_parent())) {
|
if (!parent_node3d) {
|
||||||
if (!warning.is_empty()) {
|
if (!warning.is_empty()) {
|
||||||
warning += "\n\n";
|
warning += "\n\n";
|
||||||
}
|
}
|
||||||
|
@ -126,13 +90,12 @@ String NavigationObstacle3D::get_configuration_warning() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationObstacle3D::update_agent_shape() {
|
void NavigationObstacle3D::update_agent_shape() {
|
||||||
Node *node = get_parent();
|
if (parent_node3d) {
|
||||||
|
|
||||||
// Estimate the radius of this physics body
|
// Estimate the radius of this physics body
|
||||||
real_t radius = 0.0;
|
real_t radius = 0.0;
|
||||||
for (int i(0); i < node->get_child_count(); i++) {
|
for (int i(0); i < parent_node3d->get_child_count(); i++) {
|
||||||
// For each collision shape
|
// For each collision shape
|
||||||
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(node->get_child(i));
|
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(parent_node3d->get_child(i));
|
||||||
if (cs) {
|
if (cs) {
|
||||||
// Take the distance between the Body center to the shape center
|
// Take the distance between the Body center to the shape center
|
||||||
real_t r = cs->get_transform().origin.length();
|
real_t r = cs->get_transform().origin.length();
|
||||||
|
@ -146,11 +109,9 @@ void NavigationObstacle3D::update_agent_shape() {
|
||||||
radius = MAX(radius, r);
|
radius = MAX(radius, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node3D *spa = Object::cast_to<Node3D>(node);
|
|
||||||
if (spa) {
|
Vector3 s = parent_node3d->get_global_transform().basis.get_scale();
|
||||||
Vector3 s = spa->get_global_transform().basis.get_scale();
|
|
||||||
radius *= MAX(s.x, MAX(s.y, s.z));
|
radius *= MAX(s.x, MAX(s.y, s.z));
|
||||||
}
|
|
||||||
|
|
||||||
if (radius == 0.0) {
|
if (radius == 0.0) {
|
||||||
radius = 1.0; // Never a 0 radius
|
radius = 1.0; // Never a 0 radius
|
||||||
|
@ -162,4 +123,5 @@ void NavigationObstacle3D::update_agent_shape() {
|
||||||
NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0);
|
NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0);
|
||||||
NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
|
NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
|
||||||
NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0);
|
NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,15 +31,13 @@
|
||||||
#ifndef NAVIGATION_OBSTACLE_H
|
#ifndef NAVIGATION_OBSTACLE_H
|
||||||
#define NAVIGATION_OBSTACLE_H
|
#define NAVIGATION_OBSTACLE_H
|
||||||
|
|
||||||
|
#include "scene/3d/node_3d.h"
|
||||||
#include "scene/main/node.h"
|
#include "scene/main/node.h"
|
||||||
|
|
||||||
class Navigation3D;
|
|
||||||
|
|
||||||
class NavigationObstacle3D : public Node {
|
class NavigationObstacle3D : public Node {
|
||||||
GDCLASS(NavigationObstacle3D, Node);
|
GDCLASS(NavigationObstacle3D, Node);
|
||||||
|
|
||||||
Navigation3D *navigation = nullptr;
|
Node3D *parent_node3d = nullptr;
|
||||||
|
|
||||||
RID agent;
|
RID agent;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -50,14 +48,6 @@ public:
|
||||||
NavigationObstacle3D();
|
NavigationObstacle3D();
|
||||||
virtual ~NavigationObstacle3D();
|
virtual ~NavigationObstacle3D();
|
||||||
|
|
||||||
void set_navigation(Navigation3D *p_nav);
|
|
||||||
const Navigation3D *get_navigation() const {
|
|
||||||
return navigation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_navigation_node(Node *p_nav);
|
|
||||||
Node *get_navigation_node() const;
|
|
||||||
|
|
||||||
RID get_rid() const {
|
RID get_rid() const {
|
||||||
return agent;
|
return agent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
|
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
#include "mesh_instance_3d.h"
|
#include "mesh_instance_3d.h"
|
||||||
#include "navigation_3d.h"
|
|
||||||
#include "servers/navigation_server_3d.h"
|
#include "servers/navigation_server_3d.h"
|
||||||
|
|
||||||
void NavigationRegion3D::set_enabled(bool p_enabled) {
|
void NavigationRegion3D::set_enabled(bool p_enabled) {
|
||||||
|
@ -48,9 +47,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
NavigationServer3D::get_singleton()->region_set_map(region, RID());
|
NavigationServer3D::get_singleton()->region_set_map(region, RID());
|
||||||
} else {
|
} else {
|
||||||
if (navigation) {
|
NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
|
||||||
NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_view) {
|
if (debug_view) {
|
||||||
|
@ -74,17 +71,8 @@ bool NavigationRegion3D::is_enabled() const {
|
||||||
void NavigationRegion3D::_notification(int p_what) {
|
void NavigationRegion3D::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
Node3D *c = this;
|
|
||||||
while (c) {
|
|
||||||
navigation = Object::cast_to<Navigation3D>(c);
|
|
||||||
if (navigation) {
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
|
NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = c->get_parent_spatial();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {
|
if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {
|
||||||
|
@ -105,15 +93,12 @@ void NavigationRegion3D::_notification(int p_what) {
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
if (navigation) {
|
|
||||||
NavigationServer3D::get_singleton()->region_set_map(region, RID());
|
NavigationServer3D::get_singleton()->region_set_map(region, RID());
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_view) {
|
if (debug_view) {
|
||||||
debug_view->queue_delete();
|
debug_view->queue_delete();
|
||||||
debug_view = nullptr;
|
debug_view = nullptr;
|
||||||
}
|
}
|
||||||
navigation = nullptr;
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,19 +183,7 @@ String NavigationRegion3D::get_configuration_warning() const {
|
||||||
warning += TTR("A NavigationMesh resource must be set or created for this node to work.");
|
warning += TTR("A NavigationMesh resource must be set or created for this node to work.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const Node3D *c = this;
|
|
||||||
while (c) {
|
|
||||||
if (Object::cast_to<Navigation3D>(c)) {
|
|
||||||
return warning;
|
return warning;
|
||||||
}
|
|
||||||
|
|
||||||
c = Object::cast_to<Node3D>(c->get_parent());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!warning.is_empty()) {
|
|
||||||
warning += "\n\n";
|
|
||||||
}
|
|
||||||
return warning + TTR("NavigationRegion3D must be a child or grandchild to a Navigation3D node. It only provides navigation data.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavigationRegion3D::_bind_methods() {
|
void NavigationRegion3D::_bind_methods() {
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
#include "scene/resources/mesh.h"
|
#include "scene/resources/mesh.h"
|
||||||
#include "scene/resources/navigation_mesh.h"
|
#include "scene/resources/navigation_mesh.h"
|
||||||
|
|
||||||
class Navigation3D;
|
|
||||||
|
|
||||||
class NavigationRegion3D : public Node3D {
|
class NavigationRegion3D : public Node3D {
|
||||||
GDCLASS(NavigationRegion3D, Node3D);
|
GDCLASS(NavigationRegion3D, Node3D);
|
||||||
|
|
||||||
|
@ -44,7 +42,6 @@ class NavigationRegion3D : public Node3D {
|
||||||
RID region;
|
RID region;
|
||||||
Ref<NavigationMesh> navmesh;
|
Ref<NavigationMesh> navmesh;
|
||||||
|
|
||||||
Navigation3D *navigation = nullptr;
|
|
||||||
Node *debug_view = nullptr;
|
Node *debug_view = nullptr;
|
||||||
Thread bake_thread;
|
Thread bake_thread;
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
#include "scene/2d/line_2d.h"
|
#include "scene/2d/line_2d.h"
|
||||||
#include "scene/2d/mesh_instance_2d.h"
|
#include "scene/2d/mesh_instance_2d.h"
|
||||||
#include "scene/2d/multimesh_instance_2d.h"
|
#include "scene/2d/multimesh_instance_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_obstacle_2d.h"
|
#include "scene/2d/navigation_obstacle_2d.h"
|
||||||
#include "scene/2d/parallax_background.h"
|
#include "scene/2d/parallax_background.h"
|
||||||
|
@ -206,7 +205,6 @@
|
||||||
#include "scene/3d/listener_3d.h"
|
#include "scene/3d/listener_3d.h"
|
||||||
#include "scene/3d/mesh_instance_3d.h"
|
#include "scene/3d/mesh_instance_3d.h"
|
||||||
#include "scene/3d/multimesh_instance_3d.h"
|
#include "scene/3d/multimesh_instance_3d.h"
|
||||||
#include "scene/3d/navigation_3d.h"
|
|
||||||
#include "scene/3d/navigation_agent_3d.h"
|
#include "scene/3d/navigation_agent_3d.h"
|
||||||
#include "scene/3d/navigation_obstacle_3d.h"
|
#include "scene/3d/navigation_obstacle_3d.h"
|
||||||
#include "scene/3d/navigation_region_3d.h"
|
#include "scene/3d/navigation_region_3d.h"
|
||||||
|
@ -516,7 +514,6 @@ void register_scene_types() {
|
||||||
ClassDB::register_class<ConeTwistJoint3D>();
|
ClassDB::register_class<ConeTwistJoint3D>();
|
||||||
ClassDB::register_class<Generic6DOFJoint3D>();
|
ClassDB::register_class<Generic6DOFJoint3D>();
|
||||||
|
|
||||||
ClassDB::register_class<Navigation3D>();
|
|
||||||
ClassDB::register_class<NavigationRegion3D>();
|
ClassDB::register_class<NavigationRegion3D>();
|
||||||
ClassDB::register_class<NavigationAgent3D>();
|
ClassDB::register_class<NavigationAgent3D>();
|
||||||
ClassDB::register_class<NavigationObstacle3D>();
|
ClassDB::register_class<NavigationObstacle3D>();
|
||||||
|
@ -793,7 +790,6 @@ void register_scene_types() {
|
||||||
ClassDB::register_class<PathFollow2D>();
|
ClassDB::register_class<PathFollow2D>();
|
||||||
|
|
||||||
ClassDB::register_class<NavigationMesh>();
|
ClassDB::register_class<NavigationMesh>();
|
||||||
ClassDB::register_class<Navigation2D>();
|
|
||||||
ClassDB::register_class<NavigationPolygon>();
|
ClassDB::register_class<NavigationPolygon>();
|
||||||
ClassDB::register_class<NavigationRegion2D>();
|
ClassDB::register_class<NavigationRegion2D>();
|
||||||
ClassDB::register_class<NavigationAgent2D>();
|
ClassDB::register_class<NavigationAgent2D>();
|
||||||
|
@ -814,6 +810,8 @@ void register_scene_types() {
|
||||||
ClassDB::add_compatibility_class("DynamicFont", "Font");
|
ClassDB::add_compatibility_class("DynamicFont", "Font");
|
||||||
ClassDB::add_compatibility_class("DynamicFontData", "FontData");
|
ClassDB::add_compatibility_class("DynamicFontData", "FontData");
|
||||||
ClassDB::add_compatibility_class("ToolButton", "Button");
|
ClassDB::add_compatibility_class("ToolButton", "Button");
|
||||||
|
ClassDB::add_compatibility_class("Navigation3D", "Node3D");
|
||||||
|
ClassDB::add_compatibility_class("Navigation2D", "Node2D");
|
||||||
|
|
||||||
// Renamed in 4.0.
|
// Renamed in 4.0.
|
||||||
// Keep alphabetical ordering to easily locate classes and avoid duplicates.
|
// Keep alphabetical ordering to easily locate classes and avoid duplicates.
|
||||||
|
@ -865,7 +863,6 @@ void register_scene_types() {
|
||||||
ClassDB::add_compatibility_class("Listener", "Listener3D");
|
ClassDB::add_compatibility_class("Listener", "Listener3D");
|
||||||
ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D");
|
ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D");
|
||||||
ClassDB::add_compatibility_class("MultiMeshInstance", "MultiMeshInstance3D");
|
ClassDB::add_compatibility_class("MultiMeshInstance", "MultiMeshInstance3D");
|
||||||
ClassDB::add_compatibility_class("Navigation", "Navigation3D");
|
|
||||||
ClassDB::add_compatibility_class("NavigationAgent", "NavigationAgent3D");
|
ClassDB::add_compatibility_class("NavigationAgent", "NavigationAgent3D");
|
||||||
ClassDB::add_compatibility_class("NavigationMeshInstance", "NavigationRegion3D");
|
ClassDB::add_compatibility_class("NavigationMeshInstance", "NavigationRegion3D");
|
||||||
ClassDB::add_compatibility_class("NavigationObstacle", "NavigationObstacle3D");
|
ClassDB::add_compatibility_class("NavigationObstacle", "NavigationObstacle3D");
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "scene/2d/camera_2d.h"
|
#include "scene/2d/camera_2d.h"
|
||||||
#include "scene/2d/visibility_notifier_2d.h"
|
#include "scene/2d/visibility_notifier_2d.h"
|
||||||
#include "scene/main/window.h"
|
#include "scene/main/window.h"
|
||||||
|
#include "servers/navigation_server_2d.h"
|
||||||
#include "servers/physics_server_2d.h"
|
#include "servers/physics_server_2d.h"
|
||||||
#include "servers/rendering_server.h"
|
#include "servers/rendering_server.h"
|
||||||
|
|
||||||
|
@ -315,14 +316,18 @@ void World2D::_update() {
|
||||||
indexer->_update();
|
indexer->_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
RID World2D::get_canvas() {
|
RID World2D::get_canvas() const {
|
||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
RID World2D::get_space() {
|
RID World2D::get_space() const {
|
||||||
return space;
|
return space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RID World2D::get_navigation_map() const {
|
||||||
|
return navigation_map;
|
||||||
|
}
|
||||||
|
|
||||||
void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
|
void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
|
||||||
for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) {
|
for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) {
|
||||||
r_viewports->push_back(E->key());
|
r_viewports->push_back(E->key());
|
||||||
|
@ -332,11 +337,13 @@ void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
|
||||||
void World2D::_bind_methods() {
|
void World2D::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas);
|
ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas);
|
||||||
ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space);
|
ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_navigation_map"), &World2D::get_navigation_map);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World2D::get_direct_space_state);
|
ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World2D::get_direct_space_state);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "canvas", PROPERTY_HINT_NONE, "", 0), "", "get_canvas");
|
ADD_PROPERTY(PropertyInfo(Variant::RID, "canvas", PROPERTY_HINT_NONE, "", 0), "", "get_canvas");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
|
ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", 0), "", "get_navigation_map");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState2D", 0), "", "get_direct_space_state");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState2D", 0), "", "get_direct_space_state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,9 +353,9 @@ PhysicsDirectSpaceState2D *World2D::get_direct_space_state() {
|
||||||
|
|
||||||
World2D::World2D() {
|
World2D::World2D() {
|
||||||
canvas = RenderingServer::get_singleton()->canvas_create();
|
canvas = RenderingServer::get_singleton()->canvas_create();
|
||||||
space = PhysicsServer2D::get_singleton()->space_create();
|
|
||||||
|
|
||||||
//set space2D to be more friendly with pixels than meters, by adjusting some constants
|
// Create and configure space2D to be more friendly with pixels than meters
|
||||||
|
space = PhysicsServer2D::get_singleton()->space_create();
|
||||||
PhysicsServer2D::get_singleton()->space_set_active(space, true);
|
PhysicsServer2D::get_singleton()->space_set_active(space, true);
|
||||||
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98));
|
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98));
|
||||||
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1)));
|
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1)));
|
||||||
|
@ -356,11 +363,19 @@ World2D::World2D() {
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
|
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
|
||||||
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0));
|
PhysicsServer2D::get_singleton()->area_set_param(space, PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0));
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
|
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
|
||||||
|
|
||||||
|
// Create and configure the navigation_map to be more friendly with pixels than meters.
|
||||||
|
navigation_map = NavigationServer2D::get_singleton()->map_create();
|
||||||
|
NavigationServer2D::get_singleton()->map_set_active(navigation_map, true);
|
||||||
|
NavigationServer2D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 10));
|
||||||
|
NavigationServer2D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 100));
|
||||||
|
|
||||||
indexer = memnew(SpatialIndexer2D);
|
indexer = memnew(SpatialIndexer2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
World2D::~World2D() {
|
World2D::~World2D() {
|
||||||
RenderingServer::get_singleton()->free(canvas);
|
RenderingServer::get_singleton()->free(canvas);
|
||||||
PhysicsServer2D::get_singleton()->free(space);
|
PhysicsServer2D::get_singleton()->free(space);
|
||||||
|
NavigationServer2D::get_singleton()->free(navigation_map);
|
||||||
memdelete(indexer);
|
memdelete(indexer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ class World2D : public Resource {
|
||||||
|
|
||||||
RID canvas;
|
RID canvas;
|
||||||
RID space;
|
RID space;
|
||||||
|
RID navigation_map;
|
||||||
|
|
||||||
SpatialIndexer2D *indexer;
|
SpatialIndexer2D *indexer;
|
||||||
|
|
||||||
|
@ -63,8 +64,9 @@ protected:
|
||||||
void _update();
|
void _update();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RID get_canvas();
|
RID get_canvas() const;
|
||||||
RID get_space();
|
RID get_space() const;
|
||||||
|
RID get_navigation_map() const;
|
||||||
|
|
||||||
PhysicsDirectSpaceState2D *get_direct_space_state();
|
PhysicsDirectSpaceState2D *get_direct_space_state();
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "scene/3d/camera_3d.h"
|
#include "scene/3d/camera_3d.h"
|
||||||
#include "scene/3d/visibility_notifier_3d.h"
|
#include "scene/3d/visibility_notifier_3d.h"
|
||||||
#include "scene/scene_string_names.h"
|
#include "scene/scene_string_names.h"
|
||||||
|
#include "servers/navigation_server_3d.h"
|
||||||
|
|
||||||
struct SpatialIndexer {
|
struct SpatialIndexer {
|
||||||
Octree<VisibilityNotifier3D> octree;
|
Octree<VisibilityNotifier3D> octree;
|
||||||
|
@ -243,6 +244,10 @@ RID World3D::get_space() const {
|
||||||
return space;
|
return space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RID World3D::get_navigation_map() const {
|
||||||
|
return navigation_map;
|
||||||
|
}
|
||||||
|
|
||||||
RID World3D::get_scenario() const {
|
RID World3D::get_scenario() const {
|
||||||
return scenario;
|
return scenario;
|
||||||
}
|
}
|
||||||
|
@ -310,6 +315,7 @@ void World3D::get_camera_list(List<Camera3D *> *r_cameras) {
|
||||||
|
|
||||||
void World3D::_bind_methods() {
|
void World3D::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_space"), &World3D::get_space);
|
ClassDB::bind_method(D_METHOD("get_space"), &World3D::get_space);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_navigation_map"), &World3D::get_navigation_map);
|
||||||
ClassDB::bind_method(D_METHOD("get_scenario"), &World3D::get_scenario);
|
ClassDB::bind_method(D_METHOD("get_scenario"), &World3D::get_scenario);
|
||||||
ClassDB::bind_method(D_METHOD("set_environment", "env"), &World3D::set_environment);
|
ClassDB::bind_method(D_METHOD("set_environment", "env"), &World3D::set_environment);
|
||||||
ClassDB::bind_method(D_METHOD("get_environment"), &World3D::get_environment);
|
ClassDB::bind_method(D_METHOD("get_environment"), &World3D::get_environment);
|
||||||
|
@ -322,6 +328,7 @@ void World3D::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
|
ADD_PROPERTY(PropertyInfo(Variant::RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::RID, "navigation_map", PROPERTY_HINT_NONE, "", 0), "", "get_navigation_map");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario");
|
ADD_PROPERTY(PropertyInfo(Variant::RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState3D", 0), "", "get_direct_space_state");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState3D", 0), "", "get_direct_space_state");
|
||||||
}
|
}
|
||||||
|
@ -338,6 +345,11 @@ World3D::World3D() {
|
||||||
PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1));
|
PhysicsServer3D::get_singleton()->area_set_param(space, PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1));
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
|
ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"));
|
||||||
|
|
||||||
|
navigation_map = NavigationServer3D::get_singleton()->map_create();
|
||||||
|
NavigationServer3D::get_singleton()->map_set_active(navigation_map, true);
|
||||||
|
NavigationServer3D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/3d/default_cell_size", 0.3));
|
||||||
|
NavigationServer3D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/3d/default_edge_connection_margin", 5.0)); // Five meters, depends a lot on the agent's radius
|
||||||
|
|
||||||
#ifdef _3D_DISABLED
|
#ifdef _3D_DISABLED
|
||||||
indexer = nullptr;
|
indexer = nullptr;
|
||||||
#else
|
#else
|
||||||
|
@ -348,6 +360,7 @@ World3D::World3D() {
|
||||||
World3D::~World3D() {
|
World3D::~World3D() {
|
||||||
PhysicsServer3D::get_singleton()->free(space);
|
PhysicsServer3D::get_singleton()->free(space);
|
||||||
RenderingServer::get_singleton()->free(scenario);
|
RenderingServer::get_singleton()->free(scenario);
|
||||||
|
NavigationServer3D::get_singleton()->free(navigation_map);
|
||||||
|
|
||||||
#ifndef _3D_DISABLED
|
#ifndef _3D_DISABLED
|
||||||
memdelete(indexer);
|
memdelete(indexer);
|
||||||
|
|
|
@ -46,6 +46,7 @@ class World3D : public Resource {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RID space;
|
RID space;
|
||||||
|
RID navigation_map;
|
||||||
RID scenario;
|
RID scenario;
|
||||||
SpatialIndexer *indexer;
|
SpatialIndexer *indexer;
|
||||||
Ref<Environment> environment;
|
Ref<Environment> environment;
|
||||||
|
@ -70,6 +71,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RID get_space() const;
|
RID get_space() const;
|
||||||
|
RID get_navigation_map() const;
|
||||||
RID get_scenario() const;
|
RID get_scenario() const;
|
||||||
|
|
||||||
void set_environment(const Ref<Environment> &p_environment);
|
void set_environment(const Ref<Environment> &p_environment);
|
||||||
|
|
Loading…
Reference in a new issue