summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/camera_2d.cpp7
-rw-r--r--scene/2d/camera_2d.h2
-rw-r--r--scene/2d/light_2d.cpp7
-rw-r--r--scene/2d/light_2d.h1
-rw-r--r--scene/2d/navigation_2d.cpp92
-rw-r--r--scene/2d/navigation_2d.h71
-rw-r--r--scene/2d/navigation_agent_2d.cpp45
-rw-r--r--scene/2d/navigation_agent_2d.h15
-rw-r--r--scene/2d/navigation_obstacle_2d.cpp113
-rw-r--r--scene/2d/navigation_obstacle_2d.h14
-rw-r--r--scene/2d/navigation_region_2d.cpp49
-rw-r--r--scene/2d/navigation_region_2d.h6
-rw-r--r--scene/2d/polygon_2d.cpp2
-rw-r--r--scene/2d/polygon_2d.h5
-rw-r--r--scene/2d/ray_cast_2d.cpp43
-rw-r--r--scene/2d/tile_map.cpp73
-rw-r--r--scene/2d/tile_map.h6
-rw-r--r--scene/3d/decal.cpp2
-rw-r--r--scene/3d/decal.h5
-rw-r--r--scene/3d/light_3d.cpp2
-rw-r--r--scene/3d/navigation_3d.cpp117
-rw-r--r--scene/3d/navigation_3d.h78
-rw-r--r--scene/3d/navigation_agent_3d.cpp45
-rw-r--r--scene/3d/navigation_agent_3d.h10
-rw-r--r--scene/3d/navigation_obstacle_3d.cpp130
-rw-r--r--scene/3d/navigation_obstacle_3d.h14
-rw-r--r--scene/3d/navigation_region_3d.cpp49
-rw-r--r--scene/3d/navigation_region_3d.h6
-rw-r--r--scene/3d/sprite_3d.cpp2
-rw-r--r--scene/3d/vehicle_body_3d.cpp2
-rw-r--r--scene/gui/color_picker.cpp90
-rw-r--r--scene/gui/color_picker.h1
-rw-r--r--scene/gui/label.cpp5
-rw-r--r--scene/gui/line_edit.cpp8
-rw-r--r--scene/gui/line_edit.h6
-rw-r--r--scene/gui/rich_text_label.cpp7
-rw-r--r--scene/gui/rich_text_label.h5
-rw-r--r--scene/gui/spin_box.cpp17
-rw-r--r--scene/gui/spin_box.h1
-rw-r--r--scene/gui/text_edit.cpp13
-rw-r--r--scene/main/canvas_layer.cpp2
-rw-r--r--scene/main/canvas_layer.h5
-rw-r--r--scene/main/node.cpp27
-rw-r--r--scene/main/node.h6
-rw-r--r--scene/register_scene_types.cpp9
-rw-r--r--scene/resources/camera_effects.cpp2
-rw-r--r--scene/resources/camera_effects.h5
-rw-r--r--scene/resources/default_theme/bar_arrow.pngbin0 -> 208 bytes
-rw-r--r--scene/resources/default_theme/default_theme.cpp3
-rw-r--r--scene/resources/default_theme/theme_data.h4
-rw-r--r--scene/resources/style_box.cpp7
-rw-r--r--scene/resources/style_box.h1
-rw-r--r--scene/resources/world_2d.cpp23
-rw-r--r--scene/resources/world_2d.h6
-rw-r--r--scene/resources/world_3d.cpp13
-rw-r--r--scene/resources/world_3d.h2
56 files changed, 425 insertions, 856 deletions
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index c5ac4e1a05..9030cc4263 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -569,6 +569,7 @@ void Camera2D::_set_old_smoothing(float p_enable) {
void Camera2D::set_enable_follow_smoothing(bool p_enabled) {
smoothing_enabled = p_enabled;
+ notify_property_list_changed();
}
bool Camera2D::is_follow_smoothing_enabled() const {
@@ -642,6 +643,12 @@ bool Camera2D::is_margin_drawing_enabled() const {
return margin_drawing_enabled;
}
+void Camera2D::_validate_property(PropertyInfo &property) const {
+ if (!smoothing_enabled && property.name == "smoothing_speed") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Camera2D::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &Camera2D::get_offset);
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 252d2686fc..220e208eb0 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -97,8 +97,10 @@ protected:
protected:
virtual Transform2D get_camera_transform();
+
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_offset(const Vector2 &p_offset);
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 15fcb08422..58e15e3cca 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -159,6 +159,7 @@ int Light2D::get_item_shadow_cull_mask() const {
void Light2D::set_shadow_enabled(bool p_enabled) {
shadow = p_enabled;
RS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light, shadow);
+ notify_property_list_changed();
}
bool Light2D::is_shadow_enabled() const {
@@ -221,6 +222,12 @@ float Light2D::get_shadow_smooth() const {
return shadow_smooth;
}
+void Light2D::_validate_property(PropertyInfo &property) const {
+ if (!shadow && (property.name == "shadow_color" || property.name == "shadow_filter" || property.name == "shadow_filter_smooth" || property.name == "shadow_item_cull_mask")) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void Light2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Light2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &Light2D::is_enabled);
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index 4279baf15b..de8a2bb6d0 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -77,6 +77,7 @@ protected:
_FORCE_INLINE_ RID _get_light() const { return canvas_light; }
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_enabled(bool p_enabled);
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
deleted file mode 100644
index bec5ee7984..0000000000
--- a/scene/2d/navigation_2d.cpp
+++ /dev/null
@@ -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);
-}
diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h
deleted file mode 100644
index 12847e52ac..0000000000
--- a/scene/2d/navigation_2d.h
+++ /dev/null
@@ -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
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 534e31b1f2..064fcc91a4 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -32,7 +32,6 @@
#include "core/config/engine.h"
#include "core/math/geometry_2d.h"
-#include "scene/2d/navigation_2d.h"
#include "servers/navigation_server_2d.h"
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("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("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");
- // 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);
} break;
case NOTIFICATION_EXIT_TREE: {
agent_parent = nullptr;
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -146,23 +125,13 @@ NavigationAgent2D::~NavigationAgent2D() {
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);
+void NavigationAgent2D::set_navigable_layers(uint32_t p_layers) {
+ navigable_layers = p_layers;
+ update_navigation();
}
-Node *NavigationAgent2D::get_navigation_node() const {
- return Object::cast_to<Node>(navigation);
+uint32_t NavigationAgent2D::get_navigable_layers() const {
+ return navigable_layers;
}
void NavigationAgent2D::set_target_desired_distance(real_t p_dd) {
@@ -287,7 +256,7 @@ void NavigationAgent2D::update_navigation() {
if (agent_parent == nullptr) {
return;
}
- if (navigation == nullptr) {
+ if (!agent_parent->is_inside_tree()) {
return;
}
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
@@ -319,7 +288,7 @@ void NavigationAgent2D::update_navigation() {
}
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, navigable_layers);
navigation_finished = false;
nav_path_index = 0;
emit_signal("path_changed");
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 6b7da4a5f2..153ede8cec 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -35,16 +35,16 @@
#include "scene/main/node.h"
class Node2D;
-class Navigation2D;
class NavigationAgent2D : public Node {
GDCLASS(NavigationAgent2D, Node);
Node2D *agent_parent = nullptr;
- Navigation2D *navigation = nullptr;
RID agent;
+ uint32_t navigable_layers = 1;
+
real_t target_desired_distance = 1.0;
real_t radius;
real_t neighbor_dist;
@@ -74,18 +74,13 @@ public:
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 {
return agent;
}
+ void set_navigable_layers(uint32_t p_layers);
+ uint32_t get_navigable_layers() const;
+
void set_target_desired_distance(real_t p_dd);
real_t get_target_desired_distance() const {
return target_desired_distance;
diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp
index 7e1aefe5e2..965e2b6dc1 100644
--- a/scene/2d/navigation_obstacle_2d.cpp
+++ b/scene/2d/navigation_obstacle_2d.cpp
@@ -31,48 +31,31 @@
#include "navigation_obstacle_2d.h"
#include "scene/2d/collision_shape_2d.h"
-#include "scene/2d/navigation_2d.h"
#include "scene/2d/physics_body_2d.h"
#include "servers/navigation_server_2d.h"
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) {
switch (p_what) {
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);
} break;
case NOTIFICATION_EXIT_TREE: {
- set_navigation(nullptr);
set_physics_process_internal(false);
} 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: {
- Node2D *node = Object::cast_to<Node2D>(get_parent());
- if (node) {
- NavigationServer2D::get_singleton()->agent_set_position(agent, node->get_global_transform().get_origin());
+ if (parent_node2d) {
+ NavigationServer2D::get_singleton()->agent_set_position(agent, parent_node2d->get_global_transform().get_origin());
}
-
} break;
}
}
@@ -86,25 +69,6 @@ NavigationObstacle2D::~NavigationObstacle2D() {
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 warning = Node::get_configuration_warning();
@@ -119,40 +83,37 @@ String NavigationObstacle2D::get_configuration_warning() const {
}
void NavigationObstacle2D::update_agent_shape() {
- Node *node = get_parent();
-
- // Estimate the radius of this physics body
- real_t radius = 0.0;
- for (int i(0); i < node->get_child_count(); i++) {
- // For each collision shape
- CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(node->get_child(i));
- if (cs) {
- // Take the distance between the Body center to the shape center
- real_t r = cs->get_transform().get_origin().length();
- if (cs->get_shape().is_valid()) {
- // and add the enclosing shape radius
- r += cs->get_shape()->get_enclosing_radius();
+ if (parent_node2d) {
+ // Estimate the radius of this physics body
+ real_t radius = 0.0;
+ for (int i(0); i < parent_node2d->get_child_count(); i++) {
+ // For each collision shape
+ CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(parent_node2d->get_child(i));
+ if (cs) {
+ // Take the distance between the Body center to the shape center
+ real_t r = cs->get_transform().get_origin().length();
+ if (cs->get_shape().is_valid()) {
+ // and add the enclosing shape radius
+ r += cs->get_shape()->get_enclosing_radius();
+ }
+ Size2 s = cs->get_global_transform().get_scale();
+ r *= MAX(s.x, s.y);
+ // Takes the biggest radius
+ radius = MAX(radius, r);
}
- Size2 s = cs->get_global_transform().get_scale();
- r *= MAX(s.x, s.y);
- // Takes the biggest radius
- radius = MAX(radius, r);
}
- }
- Node2D *node_2d = Object::cast_to<Node2D>(node);
- if (node_2d) {
- Vector2 s = node_2d->get_global_transform().get_scale();
+ Vector2 s = parent_node2d->get_global_transform().get_scale();
radius *= MAX(s.x, s.y);
- }
- if (radius == 0.0) {
- radius = 1.0; // Never a 0 radius
- }
+ if (radius == 0.0) {
+ radius = 1.0; // Never a 0 radius
+ }
- // Initialize the Agent as an object
- NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
- NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0);
- NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0);
- NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
- NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ // Initialize the Agent as an object
+ NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
+ NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0);
+ NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0);
+ NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
+ NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ }
}
diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h
index 421f8ca7cd..135ca4651e 100644
--- a/scene/2d/navigation_obstacle_2d.h
+++ b/scene/2d/navigation_obstacle_2d.h
@@ -31,15 +31,13 @@
#ifndef NAVIGATION_OBSTACLE_2D_H
#define NAVIGATION_OBSTACLE_2D_H
+#include "scene/2d/node_2d.h"
#include "scene/main/node.h"
-class Navigation2D;
-
class NavigationObstacle2D : public Node {
GDCLASS(NavigationObstacle2D, Node);
- Navigation2D *navigation = nullptr;
-
+ Node2D *parent_node2d = nullptr;
RID agent;
protected:
@@ -50,14 +48,6 @@ public:
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 {
return agent;
}
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index b02cdf12ad..794993f892 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -34,7 +34,6 @@
#include "core/core_string_names.h"
#include "core/math/geometry_2d.h"
#include "core/os/mutex.h"
-#include "navigation_2d.h"
#include "servers/navigation_server_2d.h"
#include "thirdparty/misc/polypartition.h"
@@ -366,9 +365,7 @@ void NavigationRegion2D::set_enabled(bool p_enabled) {
if (!enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
} else {
- if (navigation) {
- NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
+ NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
}
if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) {
@@ -380,6 +377,14 @@ bool NavigationRegion2D::is_enabled() const {
return enabled;
}
+void NavigationRegion2D::set_layers(uint32_t p_layers) {
+ NavigationServer2D::get_singleton()->region_set_layers(region, p_layers);
+}
+
+uint32_t NavigationRegion2D::get_layers() const {
+ return NavigationServer2D::get_singleton()->region_get_layers(region);
+}
+
/////////////////////////////
#ifdef TOOLS_ENABLED
Rect2 NavigationRegion2D::_edit_get_rect() const {
@@ -394,29 +399,15 @@ bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
void NavigationRegion2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- Node2D *c = this;
- while (c) {
- navigation = Object::cast_to<Navigation2D>(c);
- if (navigation) {
- if (enabled) {
- NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
- break;
- }
-
- c = Object::cast_to<Node2D>(c->get_parent());
+ if (enabled) {
+ NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
}
-
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform());
-
} break;
case NOTIFICATION_EXIT_TREE: {
- if (navigation) {
- NavigationServer2D::get_singleton()->region_set_map(region, RID());
- }
- navigation = nullptr;
+ NavigationServer2D::get_singleton()->region_set_map(region, RID());
} break;
case NOTIFICATION_DRAW: {
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) {
@@ -507,18 +498,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.");
}
- const Node2D *c = this;
- while (c) {
- if (Object::cast_to<Navigation2D>(c)) {
- return warning;
- }
- c = Object::cast_to<Node2D>(c->get_parent());
- }
- 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.");
+ return warning;
}
void NavigationRegion2D::_bind_methods() {
@@ -528,10 +509,14 @@ void NavigationRegion2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion2D::is_enabled);
+ ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion2D::set_layers);
+ ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion2D::get_layers);
+
ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationRegion2D::_navpoly_changed);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navpoly", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_layers", "get_layers");
}
NavigationRegion2D::NavigationRegion2D() {
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index 0b9a258a25..7b471bd555 100644
--- a/scene/2d/navigation_region_2d.h
+++ b/scene/2d/navigation_region_2d.h
@@ -91,14 +91,11 @@ public:
~NavigationPolygon() {}
};
-class Navigation2D;
-
class NavigationRegion2D : public Node2D {
GDCLASS(NavigationRegion2D, Node2D);
bool enabled = true;
RID region;
- Navigation2D *navigation = nullptr;
Ref<NavigationPolygon> navpoly;
void _navpoly_changed();
@@ -116,6 +113,9 @@ public:
void set_enabled(bool p_enabled);
bool is_enabled() const;
+ void set_layers(uint32_t p_layers);
+ uint32_t get_layers() const;
+
void set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly);
Ref<NavigationPolygon> get_navigation_polygon() const;
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index a60a32f1d2..2bb75e5967 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -88,13 +88,13 @@ bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toler
}
return Geometry2D::is_point_in_polygon(p_point - get_offset(), polygon2d);
}
+#endif
void Polygon2D::_validate_property(PropertyInfo &property) const {
if (!invert && property.name == "invert_border") {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
-#endif
void Polygon2D::_skeleton_bone_setup_changed() {
update();
diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h
index 43a66aad13..b329251277 100644
--- a/scene/2d/polygon_2d.h
+++ b/scene/2d/polygon_2d.h
@@ -72,13 +72,10 @@ class Polygon2D : public Node2D {
void _skeleton_bone_setup_changed();
-#ifdef TOOLS_ENABLED
- void _validate_property(PropertyInfo &property) const override;
-#endif
-
protected:
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
#ifdef TOOLS_ENABLED
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index e7b5cb5a51..50625a0f39 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -208,8 +208,6 @@ void RayCast2D::_update_raycast_state() {
}
void RayCast2D::_draw_debug_shape() {
- float tsize = 6.0;
- bool draw_arrow = target_position.length() >= tsize;
Color draw_col = collided ? Color(1.0, 0.01, 0) : get_tree()->get_debug_collisions_color();
if (!enabled) {
float g = draw_col.get_v();
@@ -218,26 +216,33 @@ void RayCast2D::_draw_debug_shape() {
draw_col.b = g;
}
- draw_line(Vector2(), target_position - Vector2(0, tsize * draw_arrow), draw_col, 1.4);
-
// Draw an arrow indicating where the RayCast is pointing to
- if (draw_arrow) {
- Transform2D xf;
- xf.rotate(target_position.angle());
- xf.translate(Vector2(target_position.length() - tsize, 0));
-
- Vector<Vector2> pts;
- pts.push_back(xf.xform(Vector2(tsize, 0)));
- pts.push_back(xf.xform(Vector2(0, 0.5 * tsize)));
- pts.push_back(xf.xform(Vector2(0, -0.5 * tsize)));
-
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(draw_col);
- }
+ const float max_arrow_size = 6;
+ const float line_width = 1.4;
+ bool no_line = target_position.length() < line_width;
+ float arrow_size = CLAMP(target_position.length() * 2 / 3, line_width, max_arrow_size);
+
+ if (no_line) {
+ arrow_size = target_position.length();
+ } else {
+ draw_line(Vector2(), target_position - target_position.normalized() * arrow_size, draw_col, line_width);
+ }
+
+ Transform2D xf;
+ xf.rotate(target_position.angle());
+ xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0));
- draw_primitive(pts, cols, Vector<Vector2>());
+ Vector<Vector2> pts;
+ pts.push_back(xf.xform(Vector2(arrow_size, 0)));
+ pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size)));
+ pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size)));
+
+ Vector<Color> cols;
+ for (int i = 0; i < 3; i++) {
+ cols.push_back(draw_col);
}
+
+ draw_primitive(pts, cols, Vector<Vector2>());
}
void RayCast2D::force_raycast_update() {
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index d868ebae25..81a5b0b28c 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -48,16 +48,6 @@ int TileMap::_get_quadrant_size() const {
void TileMap::_notification(int p_what) {
switch (p_what) {
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) {
_clear_quadrants();
collision_parent = Object::cast_to<CollisionObject2D>(get_parent());
@@ -77,12 +67,10 @@ void TileMap::_notification(int p_what) {
_update_quadrant_space(RID());
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
Quadrant &q = E->get();
- if (navigation) {
- 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());
- }
- q.navpoly_ids.clear();
+ 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());
}
+ q.navpoly_ids.clear();
if (collision_parent) {
collision_parent->remove_shape_owner(q.shape_owner_id);
@@ -96,8 +84,6 @@ void TileMap::_notification(int p_what) {
}
collision_parent = nullptr;
- navigation = nullptr;
-
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
@@ -135,11 +121,6 @@ void TileMap::_update_quadrant_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()) {
Quadrant &q = E->get();
Transform2D xform;
@@ -150,9 +131,9 @@ void TileMap::_update_quadrant_transform() {
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()) {
- 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();
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
Vector2 tofs = get_cell_draw_offset();
- Transform2D nav_rel;
- if (navigation) {
- nav_rel = get_relative_transform_to_parent(navigation);
- }
-
Vector2 qofs;
SceneTree *st = SceneTree::get_singleton();
@@ -352,12 +328,10 @@ void TileMap::update_dirty_quadrants() {
}
int shape_idx = 0;
- if (navigation) {
- 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());
- }
- q.navpoly_ids.clear();
+ 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());
}
+ q.navpoly_ids.clear();
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
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());
}
- if (navigation) {
+ if (bake_navigation) {
Ref<NavigationPolygon> navpoly;
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) {
@@ -596,8 +570,8 @@ void TileMap::update_dirty_quadrants() {
_fix_cell_transform(xform, c, npoly_ofs, s);
RID region = NavigationServer2D::get_singleton()->region_create();
- NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
- NavigationServer2D::get_singleton()->region_set_transform(region, nav_rel * xform);
+ NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
+ NavigationServer2D::get_singleton()->region_set_transform(region, xform);
NavigationServer2D::get_singleton()->region_set_navpoly(region, navpoly);
Quadrant::NavPoly np;
@@ -787,12 +761,10 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
dirty_quadrant_list.remove(&q.dirty_list);
}
- if (navigation) {
- 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());
- }
- q.navpoly_ids.clear();
+ 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());
}
+ q.navpoly_ids.clear();
for (Map<PosKey, Quadrant::Occluder>::Element *E = q.occluder_instances.front(); E; E = E->next()) {
RS::get_singleton()->free(E->get().id);
@@ -1360,6 +1332,17 @@ float TileMap::get_collision_bounce() const {
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 {
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("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("get_occluder_light_mask"), &TileMap::get_occluder_light_mask);
@@ -1842,6 +1828,9 @@ void TileMap::_bind_methods() {
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_GROUP("Navigation", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_navigation"), "set_bake_navigation", "is_baking_navigation");
+
ADD_PROPERTY_DEFAULT("format", FORMAT_1);
ADD_SIGNAL(MethodInfo("settings_changed"));
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 3bf4587921..26c84a0bb9 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -33,7 +33,6 @@
#include "core/templates/self_list.h"
#include "core/templates/vset.h"
-#include "scene/2d/navigation_2d.h"
#include "scene/2d/node_2d.h"
#include "scene/resources/tile_set.h"
@@ -78,7 +77,7 @@ private:
bool use_parent = false;
CollisionObject2D *collision_parent = nullptr;
bool use_kinematic = false;
- Navigation2D *navigation = nullptr;
+ bool bake_navigation = false;
union PosKey {
struct {
@@ -295,6 +294,9 @@ public:
void set_collision_bounce(float p_bounce);
float get_collision_bounce() const;
+ void set_bake_navigation(bool p_bake_navigation);
+ bool is_baking_navigation();
+
void set_mode(Mode p_mode);
Mode get_mode() const;
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index b5eab35605..7d6abe458a 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -154,13 +154,11 @@ Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
-#ifdef TOOLS_ENABLED
void Decal::_validate_property(PropertyInfo &property) const {
if (!distance_fade_enabled && (property.name == "distance_fade_begin" || property.name == "distance_fade_length")) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
-#endif
void Decal::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents);
diff --git a/scene/3d/decal.h b/scene/3d/decal.h
index 20d86ee16c..ce19e76de1 100644
--- a/scene/3d/decal.h
+++ b/scene/3d/decal.h
@@ -62,12 +62,9 @@ private:
float distance_fade_begin = 10.0;
float distance_fade_length = 1.0;
-#ifdef TOOLS_ENABLED
- void _validate_property(PropertyInfo &property) const override;
-#endif
-
protected:
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_extents(const Vector3 &p_extents);
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 87f54022b3..f109640aef 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -204,7 +204,7 @@ bool Light3D::is_editor_only() const {
}
void Light3D::_validate_property(PropertyInfo &property) const {
- if (!shadow && (property.name == "shadow_color" || property.name == "shadow_color" || property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_blur")) {
+ if (!shadow && (property.name == "shadow_color" || property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_fog_fade" || property.name == "shadow_blur")) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
diff --git a/scene/3d/navigation_3d.cpp b/scene/3d/navigation_3d.cpp
deleted file mode 100644
index eaddec7601..0000000000
--- a/scene/3d/navigation_3d.cpp
+++ /dev/null
@@ -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);
-}
diff --git a/scene/3d/navigation_3d.h b/scene/3d/navigation_3d.h
deleted file mode 100644
index b89725a3f5..0000000000
--- a/scene/3d/navigation_3d.h
+++ /dev/null
@@ -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
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 8917cc4664..21ca3d70dd 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -31,7 +31,6 @@
#include "navigation_agent_3d.h"
#include "core/config/engine.h"
-#include "scene/3d/navigation_3d.h"
#include "servers/navigation_server_3d.h"
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("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("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());
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);
} break;
case NOTIFICATION_EXIT_TREE: {
agent_parent = nullptr;
- set_navigation(nullptr);
set_physics_process_internal(false);
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -154,25 +132,6 @@ NavigationAgent3D::~NavigationAgent3D() {
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) {
target_desired_distance = p_dd;
}
@@ -303,7 +262,7 @@ void NavigationAgent3D::update_navigation() {
if (agent_parent == nullptr) {
return;
}
- if (navigation == nullptr) {
+ if (!agent_parent->is_inside_tree()) {
return;
}
if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
@@ -337,7 +296,7 @@ void NavigationAgent3D::update_navigation() {
}
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;
nav_path_index = 0;
emit_signal("path_changed");
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index bd890a051b..22db889618 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -35,13 +35,11 @@
#include "scene/main/node.h"
class Node3D;
-class Navigation3D;
class NavigationAgent3D : public Node {
GDCLASS(NavigationAgent3D, Node);
Node3D *agent_parent = nullptr;
- Navigation3D *navigation = nullptr;
RID agent;
@@ -76,14 +74,6 @@ public:
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 {
return agent;
}
diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp
index 01bf7de913..df03bca4fd 100644
--- a/scene/3d/navigation_obstacle_3d.cpp
+++ b/scene/3d/navigation_obstacle_3d.cpp
@@ -31,55 +31,38 @@
#include "navigation_obstacle_3d.h"
#include "scene/3d/collision_shape_3d.h"
-#include "scene/3d/navigation_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "servers/navigation_server_3d.h"
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) {
switch (p_what) {
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);
} break;
case NOTIFICATION_EXIT_TREE: {
- set_navigation(nullptr);
set_physics_process_internal(false);
} 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: {
- Node3D *spatial = Object::cast_to<Node3D>(get_parent());
- if (spatial) {
- NavigationServer3D::get_singleton()->agent_set_position(agent, spatial->get_global_transform().origin);
- }
-
- PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent());
- if (rigid) {
- Vector3 v = rigid->get_linear_velocity();
- NavigationServer3D::get_singleton()->agent_set_velocity(agent, v);
- NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v);
+ if (parent_node3d) {
+ NavigationServer3D::get_singleton()->agent_set_position(agent, parent_node3d->get_global_transform().origin);
+
+ PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent());
+ if (rigid) {
+ Vector3 v = rigid->get_linear_velocity();
+ NavigationServer3D::get_singleton()->agent_set_velocity(agent, v);
+ NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v);
+ }
}
-
} break;
}
}
@@ -93,29 +76,10 @@ NavigationObstacle3D::~NavigationObstacle3D() {
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 warning = Node::get_configuration_warning();
- if (!Object::cast_to<Node3D>(get_parent())) {
+ if (!parent_node3d) {
if (!warning.is_empty()) {
warning += "\n\n";
}
@@ -126,40 +90,38 @@ String NavigationObstacle3D::get_configuration_warning() const {
}
void NavigationObstacle3D::update_agent_shape() {
- Node *node = get_parent();
-
- // Estimate the radius of this physics body
- real_t radius = 0.0;
- for (int i(0); i < node->get_child_count(); i++) {
- // For each collision shape
- CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(node->get_child(i));
- if (cs) {
- // Take the distance between the Body center to the shape center
- real_t r = cs->get_transform().origin.length();
- if (cs->get_shape().is_valid()) {
- // and add the enclosing shape radius
- r += cs->get_shape()->get_enclosing_radius();
+ if (parent_node3d) {
+ // Estimate the radius of this physics body
+ real_t radius = 0.0;
+ for (int i(0); i < parent_node3d->get_child_count(); i++) {
+ // For each collision shape
+ CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(parent_node3d->get_child(i));
+ if (cs) {
+ // Take the distance between the Body center to the shape center
+ real_t r = cs->get_transform().origin.length();
+ if (cs->get_shape().is_valid()) {
+ // and add the enclosing shape radius
+ r += cs->get_shape()->get_enclosing_radius();
+ }
+ Vector3 s = cs->get_global_transform().basis.get_scale();
+ r *= MAX(s.x, MAX(s.y, s.z));
+ // Takes the biggest radius
+ radius = MAX(radius, r);
}
- Vector3 s = cs->get_global_transform().basis.get_scale();
- r *= MAX(s.x, MAX(s.y, s.z));
- // Takes the biggest radius
- radius = MAX(radius, r);
}
- }
- Node3D *spa = Object::cast_to<Node3D>(node);
- if (spa) {
- Vector3 s = spa->get_global_transform().basis.get_scale();
+
+ Vector3 s = parent_node3d->get_global_transform().basis.get_scale();
radius *= MAX(s.x, MAX(s.y, s.z));
- }
- if (radius == 0.0) {
- radius = 1.0; // Never a 0 radius
- }
+ if (radius == 0.0) {
+ radius = 1.0; // Never a 0 radius
+ }
- // Initialize the Agent as an object
- NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
- NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0);
- NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0);
- NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
- NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ // Initialize the Agent as an object
+ NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
+ NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0);
+ NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0);
+ NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
+ NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0);
+ }
}
diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h
index b8d05b8a87..b1bb53724a 100644
--- a/scene/3d/navigation_obstacle_3d.h
+++ b/scene/3d/navigation_obstacle_3d.h
@@ -31,15 +31,13 @@
#ifndef NAVIGATION_OBSTACLE_H
#define NAVIGATION_OBSTACLE_H
+#include "scene/3d/node_3d.h"
#include "scene/main/node.h"
-class Navigation3D;
-
class NavigationObstacle3D : public Node {
GDCLASS(NavigationObstacle3D, Node);
- Navigation3D *navigation = nullptr;
-
+ Node3D *parent_node3d = nullptr;
RID agent;
protected:
@@ -50,14 +48,6 @@ public:
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 {
return agent;
}
diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp
index 19bde94222..3ca704e4b8 100644
--- a/scene/3d/navigation_region_3d.cpp
+++ b/scene/3d/navigation_region_3d.cpp
@@ -32,7 +32,6 @@
#include "core/os/thread.h"
#include "mesh_instance_3d.h"
-#include "navigation_3d.h"
#include "servers/navigation_server_3d.h"
void NavigationRegion3D::set_enabled(bool p_enabled) {
@@ -48,9 +47,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) {
if (!enabled) {
NavigationServer3D::get_singleton()->region_set_map(region, RID());
} else {
- if (navigation) {
- NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
+ NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
}
if (debug_view) {
@@ -69,22 +66,21 @@ bool NavigationRegion3D::is_enabled() const {
return enabled;
}
+void NavigationRegion3D::set_layers(uint32_t p_layers) {
+ NavigationServer3D::get_singleton()->region_set_layers(region, p_layers);
+}
+
+uint32_t NavigationRegion3D::get_layers() const {
+ return NavigationServer3D::get_singleton()->region_get_layers(region);
+}
+
/////////////////////////////
void NavigationRegion3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- Node3D *c = this;
- while (c) {
- navigation = Object::cast_to<Navigation3D>(c);
- if (navigation) {
- if (enabled) {
- NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
- }
- break;
- }
-
- c = c->get_parent_spatial();
+ if (enabled) {
+ NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map());
}
if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {
@@ -105,15 +101,12 @@ void NavigationRegion3D::_notification(int p_what) {
} break;
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) {
debug_view->queue_delete();
debug_view = nullptr;
}
- navigation = nullptr;
} break;
}
}
@@ -198,19 +191,7 @@ String NavigationRegion3D::get_configuration_warning() const {
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;
- }
-
- 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.");
+ return warning;
}
void NavigationRegion3D::_bind_methods() {
@@ -220,11 +201,15 @@ void NavigationRegion3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion3D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion3D::is_enabled);
+ ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion3D::set_layers);
+ ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion3D::get_layers);
+
ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationRegion3D::bake_navigation_mesh);
ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationRegion3D::_bake_finished);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_layers", "get_layers");
ADD_SIGNAL(MethodInfo("navigation_mesh_changed"));
ADD_SIGNAL(MethodInfo("bake_finished"));
diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h
index 6ae15c9360..52fa2d6159 100644
--- a/scene/3d/navigation_region_3d.h
+++ b/scene/3d/navigation_region_3d.h
@@ -35,8 +35,6 @@
#include "scene/resources/mesh.h"
#include "scene/resources/navigation_mesh.h"
-class Navigation3D;
-
class NavigationRegion3D : public Node3D {
GDCLASS(NavigationRegion3D, Node3D);
@@ -44,7 +42,6 @@ class NavigationRegion3D : public Node3D {
RID region;
Ref<NavigationMesh> navmesh;
- Navigation3D *navigation = nullptr;
Node *debug_view = nullptr;
Thread bake_thread;
@@ -58,6 +55,9 @@ public:
void set_enabled(bool p_enabled);
bool is_enabled() const;
+ void set_layers(uint32_t p_layers);
+ uint32_t get_layers() const;
+
void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh);
Ref<NavigationMesh> get_navigation_mesh() const;
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index f881181ccd..b7a3135bd5 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -625,11 +625,9 @@ void Sprite3D::_validate_property(PropertyInfo &property) const {
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
-#ifdef TOOLS_ENABLED
if (!region && property.name == "region_rect") {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
-#endif
}
void Sprite3D::_bind_methods() {
diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp
index 0d25e2f21f..8b774444b9 100644
--- a/scene/3d/vehicle_body_3d.cpp
+++ b/scene/3d/vehicle_body_3d.cpp
@@ -407,7 +407,7 @@ real_t VehicleBody3D::_ray_cast(int p_idx, PhysicsDirectBodyState3D *s) {
PhysicsDirectSpaceState3D *ss = s->get_space_state();
- bool col = ss->intersect_ray(source, target, rr, exclude);
+ bool col = ss->intersect_ray(source, target, rr, exclude, get_collision_mask());
wheel.m_raycastInfo.m_groundObject = nullptr;
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index e8586b72e9..bddbe30f53 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -113,6 +113,24 @@ void ColorPicker::_update_controls() {
btn_hsv->set_disabled(false);
}
+ if (raw_mode_enabled) {
+ for (int i = 0; i < 3; i++) {
+ scroll[i]->add_theme_icon_override("grabber", Ref<Texture2D>());
+ scroll[i]->add_theme_icon_override("grabber_highlight", Ref<Texture2D>());
+ scroll[i]->add_theme_style_override("slider", Ref<StyleBox>());
+ scroll[i]->add_theme_style_override("grabber_area", Ref<StyleBox>());
+ scroll[i]->add_theme_style_override("grabber_area_highlight", Ref<StyleBox>());
+ }
+ } else {
+ for (int i = 0; i < 3; i++) {
+ scroll[i]->add_theme_icon_override("grabber", get_theme_icon("bar_arrow"));
+ scroll[i]->add_theme_icon_override("grabber_highlight", get_theme_icon("bar_arrow"));
+ scroll[i]->add_theme_style_override("slider", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[i]->add_theme_style_override("grabber_area", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[i]->add_theme_style_override("grabber_area_highlight", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ }
+ }
+
if (edit_alpha) {
values[3]->show();
scroll[3]->show();
@@ -243,6 +261,9 @@ void ColorPicker::_update_color(bool p_update_sliders) {
sample->update();
uv_edit->update();
w_edit->update();
+ for (int i = 0; i < 4; i++) {
+ scroll[i]->update();
+ }
updating = false;
}
@@ -456,6 +477,69 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
}
+void ColorPicker::_slider_draw(int p_which) {
+ Vector<Vector2> pos;
+ pos.resize(4);
+ Vector<Color> col;
+ col.resize(4);
+ Size2 size = scroll[p_which]->get_size();
+ Color left_color;
+ Color right_color;
+#ifdef TOOLS_ENABLED
+ const real_t margin = 4 * EDSCALE;
+#else
+ const real_t margin = 4;
+#endif
+
+ if (p_which == 3) {
+ scroll[p_which]->draw_texture_rect(get_theme_icon("preset_bg", "ColorPicker"), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+
+ left_color = color;
+ left_color.a = 0;
+ right_color = color;
+ right_color.a = 1;
+ } else {
+ if (raw_mode_enabled) {
+ return;
+ }
+ if (hsv_mode_enabled) {
+ if (p_which == 0) {
+ Ref<Texture2D> hue = get_theme_icon("color_hue", "ColorPicker");
+ scroll[p_which]->draw_set_transform(Point2(), -Math_PI / 2, Size2(1.0, 1.0));
+ scroll[p_which]->draw_texture_rect(hue, Rect2(Vector2(margin * -2, 0), Vector2(scroll[p_which]->get_size().x, margin)), false, Color(1, 1, 1), true);
+ return;
+ }
+ Color s_col;
+ Color v_col;
+ s_col.set_hsv(h, 0, v);
+ left_color = (p_which == 1) ? s_col : Color(0, 0, 0);
+ s_col.set_hsv(h, 1, v);
+ v_col.set_hsv(h, s, 1);
+ right_color = (p_which == 1) ? s_col : v_col;
+ } else {
+ left_color = Color(
+ p_which == 0 ? 0 : color.r,
+ p_which == 1 ? 0 : color.g,
+ p_which == 2 ? 0 : color.b);
+ right_color = Color(
+ p_which == 0 ? 1 : color.r,
+ p_which == 1 ? 1 : color.g,
+ p_which == 2 ? 1 : color.b);
+ }
+ }
+
+ col.set(0, left_color);
+ col.set(1, right_color);
+ col.set(2, right_color);
+ col.set(3, left_color);
+ pos.set(0, Vector2(0, margin));
+ pos.set(1, Vector2(size.x, margin));
+ pos.set(2, Vector2(size.x, margin * 2));
+ pos.set(3, Vector2(0, margin * 2));
+
+ scroll[p_which]->draw_polygon(pos, col);
+}
+
void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> bev = p_event;
@@ -799,10 +883,16 @@ ColorPicker::ColorPicker() :
scroll[i]->set_h_size_flags(SIZE_EXPAND_FILL);
scroll[i]->connect("value_changed", callable_mp(this, &ColorPicker::_value_changed));
+ scroll[i]->connect("draw", callable_mp(this, &ColorPicker::_slider_draw), make_binds(i));
vbr->add_child(hbc);
}
labels[3]->set_text("A");
+ scroll[3]->add_theme_icon_override("grabber", get_theme_icon("bar_arrow"));
+ scroll[3]->add_theme_icon_override("grabber_highlight", get_theme_icon("bar_arrow"));
+ scroll[3]->add_theme_style_override("slider", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[3]->add_theme_style_override("grabber_area", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ scroll[3]->add_theme_style_override("grabber_area_highlight", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
HBoxContainer *hhb = memnew(HBoxContainer);
vbr->add_child(hhb);
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 7915527bc0..24e1746c41 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -91,6 +91,7 @@ private:
void _text_type_toggled();
void _sample_draw();
void _hsv_draw(int p_which, Control *c);
+ void _slider_draw(int p_which);
void _uv_input(const Ref<InputEvent> &p_event);
void _w_input(const Ref<InputEvent> &p_event);
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index b98caf3562..be73fd8f51 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -260,7 +260,8 @@ void Label::_notification(int p_what) {
}
}
}
- visible_glyphs = total_glyphs * percent_visible;
+
+ visible_glyphs = MIN(total_glyphs, visible_chars);
}
Vector2 ofs;
@@ -541,6 +542,8 @@ void Label::set_visible_characters(int p_amount) {
visible_chars = p_amount;
if (get_total_character_count() > 0) {
percent_visible = (float)p_amount / (float)get_total_character_count();
+ } else {
+ percent_visible = 1.0;
}
update();
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 3e8ebd2429..830ffc092f 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1154,6 +1154,8 @@ void LineEdit::cursor_set_blink_enabled(const bool p_enabled) {
}
draw_caret = true;
+
+ notify_property_list_changed();
}
bool LineEdit::cursor_get_force_displayed() const {
@@ -2075,6 +2077,12 @@ void LineEdit::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
}
+void LineEdit::_validate_property(PropertyInfo &property) const {
+ if (!caret_blink_enabled && property.name == "caret_blink_speed") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed);
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index f1d9de255a..ef36377f2e 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -198,15 +198,15 @@ private:
void _backspace(bool p_word = false, bool p_all_to_left = false);
void _delete(bool p_word = false, bool p_all_to_right = false);
- void _gui_input(Ref<InputEvent> p_event);
- void _notification(int p_what);
-
protected:
+ void _notification(int p_what);
static void _bind_methods();
+ void _gui_input(Ref<InputEvent> p_event);
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_align(Align p_align);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 682584d73f..ed319f9fd0 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -3634,6 +3634,7 @@ void RichTextLabel::set_use_bbcode(bool p_enable) {
}
use_bbcode = p_enable;
set_bbcode(bbcode);
+ notify_property_list_changed();
}
bool RichTextLabel::is_using_bbcode() const {
@@ -3771,6 +3772,12 @@ int RichTextLabel::get_content_height() const {
return total_height;
}
+void RichTextLabel::_validate_property(PropertyInfo &property) const {
+ if (!use_bbcode && property.name == "bbcode_text") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &RichTextLabel::_gui_input);
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 2351aff0a4..e3e457d1f2 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -81,7 +81,9 @@ public:
};
protected:
+ void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
private:
struct Item;
@@ -441,9 +443,6 @@ private:
bool fit_content_height = false;
-protected:
- void _notification(int p_what);
-
public:
String get_text();
void add_text(const String &p_text);
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 2c9720e4b6..d82cc98e01 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -91,6 +91,14 @@ void SpinBox::_range_click_timeout() {
}
}
+void SpinBox::_release_mouse() {
+ if (drag.enabled) {
+ drag.enabled = false;
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ warp_mouse(drag.capture_pos);
+ }
+}
+
void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
if (!is_editable()) {
return;
@@ -136,12 +144,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
//set_default_cursor_shape(CURSOR_ARROW);
range_click_timer->stop();
-
- if (drag.enabled) {
- drag.enabled = false;
- Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
- warp_mouse(drag.capture_pos);
- }
+ _release_mouse();
drag.allowed = false;
}
@@ -199,6 +202,8 @@ void SpinBox::_notification(int p_what) {
} else if (p_what == NOTIFICATION_ENTER_TREE) {
_adjust_width_for_icon(get_theme_icon("updown"));
_value_changed(0);
+ } else if (p_what == NOTIFICATION_EXIT_TREE) {
+ _release_mouse();
} else if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
_value_changed(0);
} else if (p_what == NOTIFICATION_THEME_CHANGED) {
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index 4c3adf30e8..e116adb64c 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -43,6 +43,7 @@ class SpinBox : public Range {
Timer *range_click_timer;
void _range_click_timeout();
+ void _release_mouse();
void _text_entered(const String &p_string);
virtual void _value_changed(double) override;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 5a7901c11b..e488e7a914 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2190,9 +2190,14 @@ void TextEdit::_new_line(bool p_split_current_line, bool p_above) {
// No need to move the brace below if we are not taking the text with us.
char32_t closing_char = _get_right_pair_symbol(indent_char);
- if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column]) && !p_split_current_line) {
- brace_indent = true;
- ins += "\n" + ins.substr(1, ins.length() - 2);
+ if ((closing_char != 0) && (closing_char == text[cursor.line][cursor.column])) {
+ if (p_split_current_line) {
+ brace_indent = true;
+ ins += "\n" + ins.substr(1, ins.length() - 2);
+ } else {
+ brace_indent = false;
+ ins = "\n" + ins.substr(1, ins.length() - 2);
+ }
}
}
}
@@ -2984,8 +2989,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} else {
if (cursor.line < selection.selecting_line || (cursor.line == selection.selecting_line && cursor.column < selection.selecting_column)) {
if (selection.shiftclick_left) {
- SWAP(selection.from_column, selection.to_column);
- SWAP(selection.from_line, selection.to_line);
selection.shiftclick_left = !selection.shiftclick_left;
}
selection.from_column = cursor.column;
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index d9b29daf26..85d7edd64b 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -258,13 +258,11 @@ void CanvasLayer::_update_follow_viewport(bool p_force_exit) {
}
}
-#ifdef TOOLS_ENABLED
void CanvasLayer::_validate_property(PropertyInfo &property) const {
if (!follow_viewport && property.name == "follow_viewport_scale") {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
-#endif
void CanvasLayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer);
diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h
index b20b291367..899039340a 100644
--- a/scene/main/canvas_layer.h
+++ b/scene/main/canvas_layer.h
@@ -61,13 +61,10 @@ class CanvasLayer : public Node {
void _update_locrotscale();
void _update_follow_viewport(bool p_force_exit = false);
-#ifdef TOOLS_ENABLED
- void _validate_property(PropertyInfo &property) const override;
-#endif
-
protected:
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
void set_layer(int p_xform);
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 9d8c7981e6..4c6bcb10b2 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1021,22 +1021,8 @@ void Node::_set_name_nocheck(const StringName &p_name) {
data.name = p_name;
}
-String Node::invalid_character = ". : @ / \"";
-
-bool Node::_validate_node_name(String &p_name) {
- String name = p_name;
- Vector<String> chars = Node::invalid_character.split(" ");
- for (int i = 0; i < chars.size(); i++) {
- name = name.replace(chars[i], "");
- }
- bool is_valid = name == p_name;
- p_name = name;
- return is_valid;
-}
-
void Node::set_name(const String &p_name) {
- String name = p_name;
- _validate_node_name(name);
+ String name = p_name.validate_node_name();
ERR_FAIL_COND(name == "");
data.name = name;
@@ -2065,19 +2051,26 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
// Since nodes in the instanced hierarchy won't be duplicated explicitly, we need to make an inventory
// of all the nodes in the tree of the instanced scene in order to transfer the values of the properties
+ Vector<const Node *> instance_roots;
+ instance_roots.push_back(this);
+
for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
for (int i = 0; i < N->get()->get_child_count(); ++i) {
Node *descendant = N->get()->get_child(i);
// Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later
// but remember non-instanced nodes that are hidden below instanced ones
- if (descendant->data.owner != this) {
- if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this && descendant->data.owner != descendant->get_parent()) {
+ if (!instance_roots.has(descendant->get_owner())) {
+ if (descendant->get_parent() && descendant->get_parent() != this && descendant->data.owner != descendant->get_parent()) {
hidden_roots.push_back(descendant);
}
continue;
}
node_tree.push_back(descendant);
+
+ if (descendant->get_filename() != "" && instance_roots.has(descendant->get_owner())) {
+ instance_roots.push_back(descendant);
+ }
}
}
}
diff --git a/scene/main/node.h b/scene/main/node.h
index d47d271a10..b1e51d2aee 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -190,12 +190,6 @@ private:
_FORCE_INLINE_ bool _can_process(bool p_paused) const;
-#ifdef TOOLS_ENABLED
- friend class SceneTreeEditor;
-#endif
- static String invalid_character;
- static bool _validate_node_name(String &p_name);
-
protected:
void _block() { data.blocked++; }
void _unblock() { data.blocked--; }
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 51d4643883..fe8591e3d9 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -50,7 +50,6 @@
#include "scene/2d/line_2d.h"
#include "scene/2d/mesh_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_obstacle_2d.h"
#include "scene/2d/parallax_background.h"
@@ -206,7 +205,6 @@
#include "scene/3d/listener_3d.h"
#include "scene/3d/mesh_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_obstacle_3d.h"
#include "scene/3d/navigation_region_3d.h"
@@ -516,7 +514,6 @@ void register_scene_types() {
ClassDB::register_class<ConeTwistJoint3D>();
ClassDB::register_class<Generic6DOFJoint3D>();
- ClassDB::register_class<Navigation3D>();
ClassDB::register_class<NavigationRegion3D>();
ClassDB::register_class<NavigationAgent3D>();
ClassDB::register_class<NavigationObstacle3D>();
@@ -793,7 +790,6 @@ void register_scene_types() {
ClassDB::register_class<PathFollow2D>();
ClassDB::register_class<NavigationMesh>();
- ClassDB::register_class<Navigation2D>();
ClassDB::register_class<NavigationPolygon>();
ClassDB::register_class<NavigationRegion2D>();
ClassDB::register_class<NavigationAgent2D>();
@@ -814,6 +810,8 @@ void register_scene_types() {
ClassDB::add_compatibility_class("DynamicFont", "Font");
ClassDB::add_compatibility_class("DynamicFontData", "FontData");
ClassDB::add_compatibility_class("ToolButton", "Button");
+ ClassDB::add_compatibility_class("Navigation3D", "Node3D");
+ ClassDB::add_compatibility_class("Navigation2D", "Node2D");
// Renamed in 4.0.
// 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("MeshInstance", "MeshInstance3D");
ClassDB::add_compatibility_class("MultiMeshInstance", "MultiMeshInstance3D");
- ClassDB::add_compatibility_class("Navigation", "Navigation3D");
ClassDB::add_compatibility_class("NavigationAgent", "NavigationAgent3D");
ClassDB::add_compatibility_class("NavigationMeshInstance", "NavigationRegion3D");
ClassDB::add_compatibility_class("NavigationObstacle", "NavigationObstacle3D");
@@ -950,8 +947,10 @@ void register_scene_types() {
for (int i = 0; i < 20; i++) {
GLOBAL_DEF_BASIC(vformat("layer_names/2d_render/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/2d_physics/layer_%d", i), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/2d_navigation/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/3d_render/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/3d_physics/layer_%d", i), "");
+ GLOBAL_DEF_BASIC(vformat("layer_names/3d_navigation/layer_%d", i), "");
}
bool default_theme_hidpi = GLOBAL_DEF("gui/theme/use_hidpi", false);
diff --git a/scene/resources/camera_effects.cpp b/scene/resources/camera_effects.cpp
index 00312fc7b2..34c6bc05bc 100644
--- a/scene/resources/camera_effects.cpp
+++ b/scene/resources/camera_effects.cpp
@@ -145,7 +145,6 @@ void CameraEffects::_update_override_exposure() {
// Private methods, constructor and destructor
-#ifdef TOOLS_ENABLED
void CameraEffects::_validate_property(PropertyInfo &property) const {
if ((!dof_blur_far_enabled && (property.name == "dof_blur_far_distance" || property.name == "dof_blur_far_transition")) ||
(!dof_blur_near_enabled && (property.name == "dof_blur_near_distance" || property.name == "dof_blur_near_transition")) ||
@@ -153,7 +152,6 @@ void CameraEffects::_validate_property(PropertyInfo &property) const {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
-#endif
void CameraEffects::_bind_methods() {
// DOF blur
diff --git a/scene/resources/camera_effects.h b/scene/resources/camera_effects.h
index 51fb2b6cf7..b9338f4806 100644
--- a/scene/resources/camera_effects.h
+++ b/scene/resources/camera_effects.h
@@ -57,12 +57,9 @@ private:
float override_exposure = 1.0;
void _update_override_exposure();
-#ifdef TOOLS_ENABLED
- void _validate_property(PropertyInfo &property) const override;
-#endif
-
protected:
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
virtual RID get_rid() const override;
diff --git a/scene/resources/default_theme/bar_arrow.png b/scene/resources/default_theme/bar_arrow.png
new file mode 100644
index 0000000000..7cf146b8da
--- /dev/null
+++ b/scene/resources/default_theme/bar_arrow.png
Binary files differ
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index a94209c75f..0c661cc17d 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -884,6 +884,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("color_sample", "ColorPicker", make_icon(color_picker_sample_png));
theme->set_icon("preset_bg", "ColorPicker", make_icon(mini_checkerboard_png));
theme->set_icon("overbright_indicator", "ColorPicker", make_icon(overbright_indicator_png));
+ theme->set_icon("bar_arrow", "ColorPicker", make_icon(bar_arrow_png));
theme->set_icon("bg", "ColorPickerButton", make_icon(mini_checkerboard_png));
@@ -1017,7 +1018,7 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
Ref<StyleBox> default_style;
Ref<Texture2D> default_icon;
Ref<Font> default_font;
- int default_font_size = 16;
+ int default_font_size = 14;
if (p_font.is_valid()) {
default_font = p_font;
} else if (p_hidpi) {
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index b905c9db69..6b78ba7933 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -14,6 +14,10 @@ static const unsigned char arrow_right_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x17, 0x3c, 0xf8, 0xf, 0x82, 0xf7, 0x13, 0x70, 0x48, 0x3c, 0xf8, 0xf2, 0x50, 0x1b, 0x43, 0x2, 0xa, 0xaf, 0xbe, 0xe0, 0xc6, 0x2e, 0xf1, 0xff, 0xe1, 0x7c, 0x12, 0x24, 0x10, 0x46, 0x11, 0xb6, 0x1c, 0xe1, 0x5c, 0xa, 0x0, 0x0, 0xe0, 0x14, 0x48, 0xb1, 0x3d, 0x1b, 0x7a, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char bar_arrow_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x14, 0x8, 0x4, 0x0, 0x0, 0x0, 0x2e, 0x6b, 0x75, 0xfc, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x1, 0x73, 0x52, 0x47, 0x42, 0x0, 0xae, 0xce, 0x1c, 0xe9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc0, 0x0, 0x0, 0xe, 0xc0, 0x1, 0x6a, 0xd6, 0x89, 0x9, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0xfc, 0xcf, 0x80, 0x1f, 0x30, 0x8e, 0x20, 0x5, 0x8c, 0x38, 0x24, 0xff, 0x53, 0x5f, 0xc1, 0xb, 0xee, 0x9f, 0x53, 0x18, 0x18, 0xd8, 0x73, 0x24, 0xbe, 0x62, 0x55, 0x70, 0x5f, 0x83, 0x61, 0x15, 0xa3, 0x2e, 0x3, 0x3, 0xc3, 0xd, 0xe6, 0x30, 0xd9, 0xcb, 0x18, 0xa, 0x1e, 0xc6, 0xfd, 0x9f, 0xc6, 0xc0, 0xd, 0x35, 0xea, 0x3b, 0x63, 0x81, 0xfc, 0x2c, 0x14, 0x5, 0xf, 0x2a, 0x18, 0xda, 0xd1, 0x1c, 0x50, 0xa9, 0xd0, 0x1, 0x57, 0xf0, 0x10, 0x53, 0x9a, 0x81, 0x81, 0x81, 0xa1, 0x52, 0xbe, 0x83, 0x81, 0x81, 0xf1, 0x3f, 0x2e, 0x69, 0xa8, 0x12, 0x3a, 0x4, 0x14, 0x0, 0x7b, 0xda, 0x34, 0x1, 0xbb, 0xb5, 0x3e, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char bookmark_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x57, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0xa, 0xc0, 0x30, 0xc, 0x3, 0xa5, 0xd0, 0xff, 0x7f, 0x59, 0x1d, 0x8a, 0x42, 0x8, 0x9, 0x95, 0xc9, 0xd2, 0xa1, 0x9a, 0x8c, 0xf1, 0xdd, 0x62, 0x1b, 0x38, 0xc, 0x87, 0x5a, 0x5, 0xae, 0x79, 0xde, 0x2, 0x1, 0x80, 0x94, 0x39, 0x48, 0x76, 0x49, 0x17, 0xa4, 0xf0, 0x24, 0x61, 0x2b, 0x51, 0x8b, 0xfc, 0x82, 0xcf, 0xb, 0x48, 0x7a, 0xdf, 0x75, 0x81, 0xf, 0xe5, 0x29, 0xf7, 0x92, 0x6b, 0x3, 0x1a, 0x1e, 0xda, 0x7c, 0x3d, 0x77, 0x21, 0x7b, 0xa8, 0x74, 0x2e, 0xcb, 0xd, 0xc8, 0x75, 0x13, 0x28, 0x9, 0xed, 0xc2, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 9b80224c3f..2159f1bc97 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -460,6 +460,7 @@ Point2 StyleBoxFlat::get_shadow_offset() const {
void StyleBoxFlat::set_anti_aliased(const bool &p_anti_aliased) {
anti_aliased = p_anti_aliased;
emit_changed();
+ notify_property_list_changed();
}
bool StyleBoxFlat::is_anti_aliased() const {
@@ -781,6 +782,12 @@ float StyleBoxFlat::get_style_margin(Side p_side) const {
return border_width[p_side];
}
+void StyleBoxFlat::_validate_property(PropertyInfo &property) const {
+ if (!anti_aliased && property.name == "anti_aliasing_size") {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ }
+}
+
void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &StyleBoxFlat::set_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_color"), &StyleBoxFlat::get_bg_color);
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 8a273afbfd..dd5c873a00 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -159,6 +159,7 @@ class StyleBoxFlat : public StyleBox {
protected:
virtual float get_style_margin(Side p_side) const override;
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const override;
public:
//Color
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp
index 156c7d0576..a064ade362 100644
--- a/scene/resources/world_2d.cpp
+++ b/scene/resources/world_2d.cpp
@@ -34,6 +34,7 @@
#include "scene/2d/camera_2d.h"
#include "scene/2d/visibility_notifier_2d.h"
#include "scene/main/window.h"
+#include "servers/navigation_server_2d.h"
#include "servers/physics_server_2d.h"
#include "servers/rendering_server.h"
@@ -315,14 +316,18 @@ void World2D::_update() {
indexer->_update();
}
-RID World2D::get_canvas() {
+RID World2D::get_canvas() const {
return canvas;
}
-RID World2D::get_space() {
+RID World2D::get_space() const {
return space;
}
+RID World2D::get_navigation_map() const {
+ return navigation_map;
+}
+
void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) {
r_viewports->push_back(E->key());
@@ -332,11 +337,13 @@ void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
void World2D::_bind_methods() {
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_navigation_map"), &World2D::get_navigation_map);
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, "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");
}
@@ -346,9 +353,9 @@ PhysicsDirectSpaceState2D *World2D::get_direct_space_state() {
World2D::World2D() {
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()->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)));
@@ -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"));
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"));
+
+ // 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);
}
World2D::~World2D() {
RenderingServer::get_singleton()->free(canvas);
PhysicsServer2D::get_singleton()->free(space);
+ NavigationServer2D::get_singleton()->free(navigation_map);
memdelete(indexer);
}
diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h
index ae13367421..38abf3d7ad 100644
--- a/scene/resources/world_2d.h
+++ b/scene/resources/world_2d.h
@@ -44,6 +44,7 @@ class World2D : public Resource {
RID canvas;
RID space;
+ RID navigation_map;
SpatialIndexer2D *indexer;
@@ -63,8 +64,9 @@ protected:
void _update();
public:
- RID get_canvas();
- RID get_space();
+ RID get_canvas() const;
+ RID get_space() const;
+ RID get_navigation_map() const;
PhysicsDirectSpaceState2D *get_direct_space_state();
diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp
index 9c0317454b..0e9f7a6cf2 100644
--- a/scene/resources/world_3d.cpp
+++ b/scene/resources/world_3d.cpp
@@ -35,6 +35,7 @@
#include "scene/3d/camera_3d.h"
#include "scene/3d/visibility_notifier_3d.h"
#include "scene/scene_string_names.h"
+#include "servers/navigation_server_3d.h"
struct SpatialIndexer {
Octree<VisibilityNotifier3D> octree;
@@ -243,6 +244,10 @@ RID World3D::get_space() const {
return space;
}
+RID World3D::get_navigation_map() const {
+ return navigation_map;
+}
+
RID World3D::get_scenario() const {
return scenario;
}
@@ -310,6 +315,7 @@ void World3D::get_camera_list(List<Camera3D *> *r_cameras) {
void World3D::_bind_methods() {
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("set_environment", "env"), &World3D::set_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, "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, "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::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));
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
indexer = nullptr;
#else
@@ -348,6 +360,7 @@ World3D::World3D() {
World3D::~World3D() {
PhysicsServer3D::get_singleton()->free(space);
RenderingServer::get_singleton()->free(scenario);
+ NavigationServer3D::get_singleton()->free(navigation_map);
#ifndef _3D_DISABLED
memdelete(indexer);
diff --git a/scene/resources/world_3d.h b/scene/resources/world_3d.h
index 3d6c33997e..4e2717a2bb 100644
--- a/scene/resources/world_3d.h
+++ b/scene/resources/world_3d.h
@@ -46,6 +46,7 @@ class World3D : public Resource {
private:
RID space;
+ RID navigation_map;
RID scenario;
SpatialIndexer *indexer;
Ref<Environment> environment;
@@ -70,6 +71,7 @@ protected:
public:
RID get_space() const;
+ RID get_navigation_map() const;
RID get_scenario() const;
void set_environment(const Ref<Environment> &p_environment);