summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/templates/rid_owner.h40
-rw-r--r--doc/classes/PhysicsTestMotionResult2D.xml6
-rw-r--r--doc/classes/Viewport.xml3
-rw-r--r--drivers/vulkan/vulkan_context.cpp2
-rw-r--r--editor/editor_node.cpp3
-rw-r--r--editor/filesystem_dock.cpp30
-rw-r--r--editor/filesystem_dock.h1
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp4
-rw-r--r--editor/script_create_dialog.cpp8
-rw-r--r--modules/gdscript/gdscript_editor.cpp6
-rw-r--r--modules/navigation/SCsub (renamed from modules/gdnavigation/SCsub)0
-rw-r--r--modules/navigation/config.py (renamed from modules/gdnavigation/config.py)0
-rw-r--r--modules/navigation/godot_navigation_server.cpp (renamed from modules/gdnavigation/gd_navigation_server.cpp)215
-rw-r--r--modules/navigation/godot_navigation_server.h (renamed from modules/gdnavigation/gd_navigation_server.h)24
-rw-r--r--modules/navigation/nav_map.cpp (renamed from modules/gdnavigation/nav_map.cpp)0
-rw-r--r--modules/navigation/nav_map.h (renamed from modules/gdnavigation/nav_map.h)0
-rw-r--r--modules/navigation/nav_region.cpp (renamed from modules/gdnavigation/nav_region.cpp)0
-rw-r--r--modules/navigation/nav_region.h (renamed from modules/gdnavigation/nav_region.h)0
-rw-r--r--modules/navigation/nav_rid.h (renamed from modules/gdnavigation/nav_rid.h)0
-rw-r--r--modules/navigation/nav_utils.h (renamed from modules/gdnavigation/nav_utils.h)0
-rw-r--r--modules/navigation/navigation_mesh_editor_plugin.cpp (renamed from modules/gdnavigation/navigation_mesh_editor_plugin.cpp)0
-rw-r--r--modules/navigation/navigation_mesh_editor_plugin.h (renamed from modules/gdnavigation/navigation_mesh_editor_plugin.h)0
-rw-r--r--modules/navigation/navigation_mesh_generator.cpp (renamed from modules/gdnavigation/navigation_mesh_generator.cpp)0
-rw-r--r--modules/navigation/navigation_mesh_generator.h (renamed from modules/gdnavigation/navigation_mesh_generator.h)0
-rw-r--r--modules/navigation/register_types.cpp (renamed from modules/gdnavigation/register_types.cpp)18
-rw-r--r--modules/navigation/register_types.h (renamed from modules/gdnavigation/register_types.h)14
-rw-r--r--modules/navigation/rvo_agent.cpp (renamed from modules/gdnavigation/rvo_agent.cpp)0
-rw-r--r--modules/navigation/rvo_agent.h (renamed from modules/gdnavigation/rvo_agent.h)0
-rw-r--r--modules/websocket/editor_debugger_server_websocket.cpp6
-rw-r--r--scene/2d/physics_body_2d.cpp57
-rw-r--r--scene/2d/physics_body_2d.h2
-rw-r--r--scene/3d/physics_body_3d.cpp63
-rw-r--r--scene/3d/physics_body_3d.h2
-rw-r--r--scene/main/viewport.cpp13
-rw-r--r--scene/main/viewport.h5
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp9
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp5
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp11
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h10
-rw-r--r--servers/physics_2d/physics_server_2d_sw.cpp4
-rw-r--r--servers/physics_2d/space_2d_sw.cpp37
-rw-r--r--servers/physics_3d/area_pair_3d_sw.cpp9
-rw-r--r--servers/physics_3d/body_pair_3d_sw.cpp10
-rw-r--r--servers/physics_3d/collision_object_3d_sw.cpp42
-rw-r--r--servers/physics_3d/collision_object_3d_sw.h31
-rw-r--r--servers/physics_3d/physics_server_3d_sw.cpp4
-rw-r--r--servers/physics_3d/space_3d_sw.cpp35
-rw-r--r--servers/physics_server_2d.cpp18
-rw-r--r--servers/physics_server_2d.h6
-rw-r--r--servers/physics_server_3d.h3
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp27
-rw-r--r--servers/rendering/renderer_canvas_cull.h10
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp6
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h2
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp5
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h2
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h4
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl3
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl3
-rw-r--r--servers/rendering/renderer_scene_cull.cpp18
-rw-r--r--servers/rendering/renderer_scene_cull.h6
-rw-r--r--servers/rendering/renderer_viewport.cpp15
-rw-r--r--servers/rendering/renderer_viewport.h4
-rw-r--r--servers/rendering/rendering_server_default.h1
-rw-r--r--servers/rendering_server.h1
66 files changed, 474 insertions, 399 deletions
diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h
index 31278b71bd..e4964f744e 100644
--- a/core/templates/rid_owner.h
+++ b/core/templates/rid_owner.h
@@ -79,7 +79,7 @@ class RID_Alloc : public RID_AllocBase {
SpinLock spin_lock;
- _FORCE_INLINE_ RID _allocate_rid(const T *p_initializer) {
+ _FORCE_INLINE_ RID _allocate_rid() {
if (THREAD_SAFE) {
spin_lock.lock();
}
@@ -114,11 +114,6 @@ class RID_Alloc : public RID_AllocBase {
uint32_t free_chunk = free_index / elements_in_chunk;
uint32_t free_element = free_index % elements_in_chunk;
- if (p_initializer) {
- T *ptr = &chunks[free_chunk][free_element];
- memnew_placement(ptr, T(*p_initializer));
- }
-
uint32_t validator = (uint32_t)(_gen_id() & 0x7FFFFFFF);
uint64_t id = validator;
id <<= 32;
@@ -126,9 +121,7 @@ class RID_Alloc : public RID_AllocBase {
validator_chunks[free_chunk][free_element] = validator;
- if (!p_initializer) {
- validator_chunks[free_chunk][free_element] |= 0x80000000; //mark uninitialized bit
- }
+ validator_chunks[free_chunk][free_element] |= 0x80000000; //mark uninitialized bit
alloc_count++;
@@ -140,13 +133,20 @@ class RID_Alloc : public RID_AllocBase {
}
public:
+ RID make_rid() {
+ RID rid = _allocate_rid();
+ initialize_rid(rid);
+ return rid;
+ }
RID make_rid(const T &p_value) {
- return _allocate_rid(&p_value);
+ RID rid = _allocate_rid();
+ initialize_rid(rid, p_value);
+ return rid;
}
//allocate but don't initialize, use initialize_rid afterwards
RID allocate_rid() {
- return _allocate_rid(nullptr);
+ return _allocate_rid();
}
_FORCE_INLINE_ T *getornull(const RID &p_rid, bool p_initialize = false) {
@@ -207,6 +207,11 @@ public:
return ptr;
}
+ void initialize_rid(RID p_rid) {
+ T *mem = getornull(p_rid, true);
+ ERR_FAIL_COND(!mem);
+ memnew_placement(mem, T);
+ }
void initialize_rid(RID p_rid, const T &p_value) {
T *mem = getornull(p_rid, true);
ERR_FAIL_COND(!mem);
@@ -333,7 +338,7 @@ public:
description = p_descrption;
}
- RID_Alloc(uint32_t p_target_chunk_byte_size = 4096) {
+ RID_Alloc(uint32_t p_target_chunk_byte_size = 65536) {
elements_in_chunk = sizeof(T) > p_target_chunk_byte_size ? 1 : (p_target_chunk_byte_size / sizeof(T));
}
@@ -434,7 +439,7 @@ public:
alloc.set_description(p_descrption);
}
- RID_PtrOwner(uint32_t p_target_chunk_byte_size = 4096) :
+ RID_PtrOwner(uint32_t p_target_chunk_byte_size = 65536) :
alloc(p_target_chunk_byte_size) {}
};
@@ -443,6 +448,9 @@ class RID_Owner {
RID_Alloc<T, THREAD_SAFE> alloc;
public:
+ _FORCE_INLINE_ RID make_rid() {
+ return alloc.make_rid();
+ }
_FORCE_INLINE_ RID make_rid(const T &p_ptr) {
return alloc.make_rid(p_ptr);
}
@@ -451,6 +459,10 @@ public:
return alloc.allocate_rid();
}
+ _FORCE_INLINE_ void initialize_rid(RID p_rid) {
+ alloc.initialize_rid(p_rid);
+ }
+
_FORCE_INLINE_ void initialize_rid(RID p_rid, const T &p_ptr) {
alloc.initialize_rid(p_rid, p_ptr);
}
@@ -486,7 +498,7 @@ public:
void set_description(const char *p_descrption) {
alloc.set_description(p_descrption);
}
- RID_Owner(uint32_t p_target_chunk_byte_size = 4096) :
+ RID_Owner(uint32_t p_target_chunk_byte_size = 65536) :
alloc(p_target_chunk_byte_size) {}
};
diff --git a/doc/classes/PhysicsTestMotionResult2D.xml b/doc/classes/PhysicsTestMotionResult2D.xml
index da04ffa86a..bf3497386e 100644
--- a/doc/classes/PhysicsTestMotionResult2D.xml
+++ b/doc/classes/PhysicsTestMotionResult2D.xml
@@ -19,10 +19,16 @@
</member>
<member name="collider_velocity" type="Vector2" setter="" getter="get_collider_velocity" default="Vector2(0, 0)">
</member>
+ <member name="collision_depth" type="float" setter="" getter="get_collision_depth" default="0.0">
+ </member>
<member name="collision_normal" type="Vector2" setter="" getter="get_collision_normal" default="Vector2(0, 0)">
</member>
<member name="collision_point" type="Vector2" setter="" getter="get_collision_point" default="Vector2(0, 0)">
</member>
+ <member name="collision_safe_fraction" type="float" setter="" getter="get_collision_safe_fraction" default="0.0">
+ </member>
+ <member name="collision_unsafe_fraction" type="float" setter="" getter="get_collision_unsafe_fraction" default="0.0">
+ </member>
<member name="motion" type="Vector2" setter="" getter="get_motion" default="Vector2(0, 0)">
</member>
<member name="motion_remainder" type="Vector2" setter="" getter="get_motion_remainder" default="Vector2(0, 0)">
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 292be34a0d..bc0c3c5516 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -208,6 +208,9 @@
<member name="debug_draw" type="int" setter="set_debug_draw" getter="get_debug_draw" enum="Viewport.DebugDraw" default="0">
The overlay mode for test rendered geometry in debug purposes.
</member>
+ <member name="disable_3d" type="bool" setter="set_disable_3d" getter="is_3d_disabled" default="false">
+ Disable 3D rendering (but keep 2D rendering).
+ </member>
<member name="global_canvas_transform" type="Transform2D" setter="set_global_canvas_transform" getter="get_global_canvas_transform">
The global canvas transform of the viewport. The canvas transform is relative to this.
</member>
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 9939611a83..74bd938822 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -1752,7 +1752,7 @@ Error VulkanContext::prepare_buffers() {
print_verbose("Vulkan: Early suboptimal swapchain.");
break;
} else if (err != VK_SUCCESS) {
- ERR_BREAK(ERR_CANT_CREATE);
+ ERR_BREAK_MSG(err != VK_SUCCESS, "Vulkan: Did not create swapchain successfully.");
} else {
w->semaphore_acquired = true;
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 1bc04676b7..31f84d2508 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -6116,7 +6116,8 @@ EditorNode::EditorNode() {
scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL);
scene_root = memnew(SubViewport);
- //scene_root->set_usage(Viewport::USAGE_2D); canvas BG mode prevents usage of this as 2D
+ scene_root->set_embed_subwindows_hint(true);
+ scene_root->set_disable_3d(true);
RenderingServer::get_singleton()->viewport_set_hide_scenario(scene_root->get_viewport_rid(), true);
scene_root->set_disable_input(true);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index cb89e5c7d0..527ffc86df 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1985,20 +1985,6 @@ void FileSystemDock::_resource_created() {
editor->save_resource_as(RES(r), fpath);
}
-void FileSystemDock::_focus_current_search_box() {
- LineEdit *current_search_box = nullptr;
- if (display_mode == DISPLAY_MODE_TREE_ONLY) {
- current_search_box = tree_search_box;
- } else if (display_mode == DISPLAY_MODE_SPLIT) {
- current_search_box = file_list_search_box;
- }
-
- if (current_search_box) {
- current_search_box->grab_focus();
- current_search_box->select_all();
- }
-}
-
void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) {
if (searched_string.length() == 0) {
// Register the uncollapsed paths before they change.
@@ -2040,7 +2026,17 @@ void FileSystemDock::fix_dependencies(const String &p_for_file) {
}
void FileSystemDock::focus_on_filter() {
- file_list_search_box->grab_focus();
+ LineEdit *current_search_box = nullptr;
+ if (display_mode == DISPLAY_MODE_TREE_ONLY) {
+ current_search_box = tree_search_box;
+ } else if (display_mode == DISPLAY_MODE_SPLIT) {
+ current_search_box = file_list_search_box;
+ }
+
+ if (current_search_box) {
+ current_search_box->grab_focus();
+ current_search_box->select_all();
+ }
}
void FileSystemDock::set_file_list_display_mode(FileListDisplayMode p_mode) {
@@ -2590,7 +2586,7 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) {
} else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) {
_tree_rmb_option(FILE_RENAME);
} else if (ED_IS_SHORTCUT("editor/open_search", p_event)) {
- _focus_current_search_box();
+ focus_on_filter();
} else {
return;
}
@@ -2611,7 +2607,7 @@ void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) {
} else if (ED_IS_SHORTCUT("filesystem_dock/rename", p_event)) {
_file_list_rmb_option(FILE_RENAME);
} else if (ED_IS_SHORTCUT("editor/open_search", p_event)) {
- _focus_current_search_box();
+ focus_on_filter();
} else {
return;
}
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 12c567fb69..21a7abe622 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -253,7 +253,6 @@ private:
void _toggle_split_mode(bool p_active);
- void _focus_current_search_box();
void _search_changed(const String &p_text, const Control *p_from);
MenuButton *_create_file_menu_button();
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 033a3e4fab..38659dcac3 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -4317,11 +4317,11 @@ void CanvasItemEditor::_button_toggle_anchor_mode(bool p_status) {
void CanvasItemEditor::_update_override_camera_button(bool p_game_running) {
if (p_game_running) {
override_camera_button->set_disabled(false);
- override_camera_button->set_tooltip(TTR("Game Camera Override\nOverrides game camera with editor viewport camera."));
+ override_camera_button->set_tooltip(TTR("Project Camera Override\nOverrides the running project's camera with the editor viewport camera."));
} else {
override_camera_button->set_disabled(true);
override_camera_button->set_pressed(false);
- override_camera_button->set_tooltip(TTR("Game Camera Override\nNo game instance running."));
+ override_camera_button->set_tooltip(TTR("Project Camera Override\nNo project instance running. Run the project from the editor to use this feature."));
}
}
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 01743bccab..fdbde8dc5c 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -784,6 +784,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
status_panel = memnew(PanelContainer);
status_panel->set_h_size_flags(Control::SIZE_FILL);
+ status_panel->set_v_size_flags(Control::SIZE_EXPAND_FILL);
status_panel->add_child(vb);
/* Spacing */
@@ -795,10 +796,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
vb->add_child(gc);
vb->add_child(spacing);
vb->add_child(status_panel);
- HBoxContainer *hb = memnew(HBoxContainer);
- hb->add_child(vb);
-
- add_child(hb);
+ add_child(vb);
/* Language */
@@ -827,7 +825,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
base_type = "Object";
- hb = memnew(HBoxContainer);
+ HBoxContainer *hb = memnew(HBoxContainer);
hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
parent_name = memnew(LineEdit);
parent_name->connect("text_changed", callable_mp(this, &ScriptCreateDialog::_parent_name_changed));
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index b149828a2f..c1a7bedbc8 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -3038,9 +3038,9 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
if (!is_function) {
// Guess in autoloads as singletons.
if (ProjectSettings::get_singleton()->has_autoload(p_symbol)) {
- const ProjectSettings::AutoloadInfo &singleton = ProjectSettings::get_singleton()->get_autoload(p_symbol);
- if (singleton.is_singleton) {
- String script = singleton.path;
+ const ProjectSettings::AutoloadInfo &autoload = ProjectSettings::get_singleton()->get_autoload(p_symbol);
+ if (autoload.is_singleton) {
+ String script = autoload.path;
if (!script.ends_with(".gd")) {
// Not a script, try find the script anyway,
// may have some success.
diff --git a/modules/gdnavigation/SCsub b/modules/navigation/SCsub
index 22b5509b32..22b5509b32 100644
--- a/modules/gdnavigation/SCsub
+++ b/modules/navigation/SCsub
diff --git a/modules/gdnavigation/config.py b/modules/navigation/config.py
index d22f9454ed..d22f9454ed 100644
--- a/modules/gdnavigation/config.py
+++ b/modules/navigation/config.py
diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp
index d5e6e5e69f..df003cfe6f 100644
--- a/modules/gdnavigation/gd_navigation_server.cpp
+++ b/modules/navigation/godot_navigation_server.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* gd_navigation_server.cpp */
+/* godot_navigation_server.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "gd_navigation_server.h"
+#include "godot_navigation_server.h"
#include "core/os/mutex.h"
@@ -44,96 +44,96 @@
/// an instance of that struct with the submitted parameters.
/// Then, that struct is stored in an array; the `sync` function consume that array.
-#define COMMAND_1(F_NAME, T_0, D_0) \
- struct MERGE(F_NAME, _command) : public SetCommand { \
- T_0 d_0; \
- MERGE(F_NAME, _command) \
- (T_0 p_d_0) : \
- d_0(p_d_0) {} \
- virtual void exec(GdNavigationServer *server) { \
- server->MERGE(_cmd_, F_NAME)(d_0); \
- } \
- }; \
- void GdNavigationServer::F_NAME(T_0 D_0) const { \
- auto cmd = memnew(MERGE(F_NAME, _command)( \
- D_0)); \
- add_command(cmd); \
- } \
- void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0)
-
-#define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1) \
- struct MERGE(F_NAME, _command) : public SetCommand { \
- T_0 d_0; \
- T_1 d_1; \
- MERGE(F_NAME, _command) \
- ( \
- T_0 p_d_0, \
- T_1 p_d_1) : \
- d_0(p_d_0), \
- d_1(p_d_1) {} \
- virtual void exec(GdNavigationServer *server) { \
- server->MERGE(_cmd_, F_NAME)(d_0, d_1); \
- } \
- }; \
- void GdNavigationServer::F_NAME(T_0 D_0, T_1 D_1) const { \
- auto cmd = memnew(MERGE(F_NAME, _command)( \
- D_0, \
- D_1)); \
- add_command(cmd); \
- } \
- void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1)
-
-#define COMMAND_4(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3) \
- struct MERGE(F_NAME, _command) : public SetCommand { \
- T_0 d_0; \
- T_1 d_1; \
- T_2 d_2; \
- T_3 d_3; \
- MERGE(F_NAME, _command) \
- ( \
- T_0 p_d_0, \
- T_1 p_d_1, \
- T_2 p_d_2, \
- T_3 p_d_3) : \
- d_0(p_d_0), \
- d_1(p_d_1), \
- d_2(p_d_2), \
- d_3(p_d_3) {} \
- virtual void exec(GdNavigationServer *server) { \
- server->MERGE(_cmd_, F_NAME)(d_0, d_1, d_2, d_3); \
- } \
- }; \
- void GdNavigationServer::F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) const { \
- auto cmd = memnew(MERGE(F_NAME, _command)( \
- D_0, \
- D_1, \
- D_2, \
- D_3)); \
- add_command(cmd); \
- } \
- void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
-
-GdNavigationServer::GdNavigationServer() :
+#define COMMAND_1(F_NAME, T_0, D_0) \
+ struct MERGE(F_NAME, _command) : public SetCommand { \
+ T_0 d_0; \
+ MERGE(F_NAME, _command) \
+ (T_0 p_d_0) : \
+ d_0(p_d_0) {} \
+ virtual void exec(GodotNavigationServer *server) { \
+ server->MERGE(_cmd_, F_NAME)(d_0); \
+ } \
+ }; \
+ void GodotNavigationServer::F_NAME(T_0 D_0) const { \
+ auto cmd = memnew(MERGE(F_NAME, _command)( \
+ D_0)); \
+ add_command(cmd); \
+ } \
+ void GodotNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0)
+
+#define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1) \
+ struct MERGE(F_NAME, _command) : public SetCommand { \
+ T_0 d_0; \
+ T_1 d_1; \
+ MERGE(F_NAME, _command) \
+ ( \
+ T_0 p_d_0, \
+ T_1 p_d_1) : \
+ d_0(p_d_0), \
+ d_1(p_d_1) {} \
+ virtual void exec(GodotNavigationServer *server) { \
+ server->MERGE(_cmd_, F_NAME)(d_0, d_1); \
+ } \
+ }; \
+ void GodotNavigationServer::F_NAME(T_0 D_0, T_1 D_1) const { \
+ auto cmd = memnew(MERGE(F_NAME, _command)( \
+ D_0, \
+ D_1)); \
+ add_command(cmd); \
+ } \
+ void GodotNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1)
+
+#define COMMAND_4(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3) \
+ struct MERGE(F_NAME, _command) : public SetCommand { \
+ T_0 d_0; \
+ T_1 d_1; \
+ T_2 d_2; \
+ T_3 d_3; \
+ MERGE(F_NAME, _command) \
+ ( \
+ T_0 p_d_0, \
+ T_1 p_d_1, \
+ T_2 p_d_2, \
+ T_3 p_d_3) : \
+ d_0(p_d_0), \
+ d_1(p_d_1), \
+ d_2(p_d_2), \
+ d_3(p_d_3) {} \
+ virtual void exec(GodotNavigationServer *server) { \
+ server->MERGE(_cmd_, F_NAME)(d_0, d_1, d_2, d_3); \
+ } \
+ }; \
+ void GodotNavigationServer::F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) const { \
+ auto cmd = memnew(MERGE(F_NAME, _command)( \
+ D_0, \
+ D_1, \
+ D_2, \
+ D_3)); \
+ add_command(cmd); \
+ } \
+ void GodotNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
+
+GodotNavigationServer::GodotNavigationServer() :
NavigationServer3D() {
}
-GdNavigationServer::~GdNavigationServer() {
+GodotNavigationServer::~GodotNavigationServer() {
flush_queries();
}
-void GdNavigationServer::add_command(SetCommand *command) const {
- GdNavigationServer *mut_this = const_cast<GdNavigationServer *>(this);
+void GodotNavigationServer::add_command(SetCommand *command) const {
+ GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this);
{
MutexLock lock(commands_mutex);
mut_this->commands.push_back(command);
}
}
-RID GdNavigationServer::map_create() const {
- GdNavigationServer *mut_this = const_cast<GdNavigationServer *>(this);
+RID GodotNavigationServer::map_create() const {
+ GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this);
MutexLock lock(mut_this->operations_mutex);
- NavMap *space = memnew(NavMap);
- RID rid = map_owner.make_rid(space);
+ RID rid = map_owner.make_rid();
+ NavMap *space = map_owner.getornull(rid);
space->set_self(rid);
return rid;
}
@@ -155,7 +155,7 @@ COMMAND_2(map_set_active, RID, p_map, bool, p_active) {
}
}
-bool GdNavigationServer::map_is_active(RID p_map) const {
+bool GodotNavigationServer::map_is_active(RID p_map) const {
NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, false);
@@ -169,7 +169,7 @@ COMMAND_2(map_set_up, RID, p_map, Vector3, p_up) {
map->set_up(p_up);
}
-Vector3 GdNavigationServer::map_get_up(RID p_map) const {
+Vector3 GodotNavigationServer::map_get_up(RID p_map) const {
const NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector3());
@@ -183,7 +183,7 @@ COMMAND_2(map_set_cell_size, RID, p_map, real_t, p_cell_size) {
map->set_cell_size(p_cell_size);
}
-real_t GdNavigationServer::map_get_cell_size(RID p_map) const {
+real_t GodotNavigationServer::map_get_cell_size(RID p_map) const {
const NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, 0);
@@ -197,53 +197,53 @@ COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margi
map->set_edge_connection_margin(p_connection_margin);
}
-real_t GdNavigationServer::map_get_edge_connection_margin(RID p_map) const {
+real_t GodotNavigationServer::map_get_edge_connection_margin(RID p_map) const {
const NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, 0);
return map->get_edge_connection_margin();
}
-Vector<Vector3> GdNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const {
+Vector<Vector3> GodotNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_layers) const {
const NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector<Vector3>());
return map->get_path(p_origin, p_destination, p_optimize, p_layers);
}
-Vector3 GdNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
+Vector3 GodotNavigationServer::map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
const NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector3());
return map->get_closest_point_to_segment(p_from, p_to, p_use_collision);
}
-Vector3 GdNavigationServer::map_get_closest_point(RID p_map, const Vector3 &p_point) const {
+Vector3 GodotNavigationServer::map_get_closest_point(RID p_map, const Vector3 &p_point) const {
const NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector3());
return map->get_closest_point(p_point);
}
-Vector3 GdNavigationServer::map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const {
+Vector3 GodotNavigationServer::map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const {
const NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, Vector3());
return map->get_closest_point_normal(p_point);
}
-RID GdNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const {
+RID GodotNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const {
const NavMap *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == nullptr, RID());
return map->get_closest_point_owner(p_point);
}
-RID GdNavigationServer::region_create() const {
- GdNavigationServer *mut_this = const_cast<GdNavigationServer *>(this);
+RID GodotNavigationServer::region_create() const {
+ GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this);
MutexLock lock(mut_this->operations_mutex);
- NavRegion *reg = memnew(NavRegion);
- RID rid = region_owner.make_rid(reg);
+ RID rid = region_owner.make_rid();
+ NavRegion *reg = region_owner.getornull(rid);
reg->set_self(rid);
return rid;
}
@@ -284,7 +284,7 @@ COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers) {
region->set_layers(p_layers);
}
-uint32_t GdNavigationServer::region_get_layers(RID p_region) const {
+uint32_t GodotNavigationServer::region_get_layers(RID p_region) const {
NavRegion *region = region_owner.getornull(p_region);
ERR_FAIL_COND_V(region == nullptr, 0);
@@ -298,7 +298,7 @@ COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh) {
region->set_mesh(p_nav_mesh);
}
-void GdNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const {
+void GodotNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const {
ERR_FAIL_COND(r_mesh.is_null());
ERR_FAIL_COND(p_node == nullptr);
@@ -308,32 +308,32 @@ void GdNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p
#endif
}
-int GdNavigationServer::region_get_connections_count(RID p_region) const {
+int GodotNavigationServer::region_get_connections_count(RID p_region) const {
NavRegion *region = region_owner.getornull(p_region);
ERR_FAIL_COND_V(!region, 0);
return region->get_connections_count();
}
-Vector3 GdNavigationServer::region_get_connection_pathway_start(RID p_region, int p_connection_id) const {
+Vector3 GodotNavigationServer::region_get_connection_pathway_start(RID p_region, int p_connection_id) const {
NavRegion *region = region_owner.getornull(p_region);
ERR_FAIL_COND_V(!region, Vector3());
return region->get_connection_pathway_start(p_connection_id);
}
-Vector3 GdNavigationServer::region_get_connection_pathway_end(RID p_region, int p_connection_id) const {
+Vector3 GodotNavigationServer::region_get_connection_pathway_end(RID p_region, int p_connection_id) const {
NavRegion *region = region_owner.getornull(p_region);
ERR_FAIL_COND_V(!region, Vector3());
return region->get_connection_pathway_end(p_connection_id);
}
-RID GdNavigationServer::agent_create() const {
- GdNavigationServer *mut_this = const_cast<GdNavigationServer *>(this);
+RID GodotNavigationServer::agent_create() const {
+ GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this);
MutexLock lock(mut_this->operations_mutex);
- RvoAgent *agent = memnew(RvoAgent());
- RID rid = agent_owner.make_rid(agent);
+ RID rid = agent_owner.make_rid();
+ RvoAgent *agent = agent_owner.getornull(rid);
agent->set_self(rid);
return rid;
}
@@ -428,7 +428,7 @@ COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore) {
agent->get_agent()->ignore_y_ = p_ignore;
}
-bool GdNavigationServer::agent_is_map_changed(RID p_agent) const {
+bool GodotNavigationServer::agent_is_map_changed(RID p_agent) const {
RvoAgent *agent = agent_owner.getornull(p_agent);
ERR_FAIL_COND_V(agent == nullptr, false);
@@ -472,7 +472,6 @@ COMMAND_1(free, RID, p_object) {
active_maps.remove(map_index);
active_maps_update_id.remove(map_index);
map_owner.free(p_object);
- memdelete(map);
} else if (region_owner.owns(p_object)) {
NavRegion *region = region_owner.getornull(p_object);
@@ -484,7 +483,6 @@ COMMAND_1(free, RID, p_object) {
}
region_owner.free(p_object);
- memdelete(region);
} else if (agent_owner.owns(p_object)) {
RvoAgent *agent = agent_owner.getornull(p_object);
@@ -496,20 +494,19 @@ COMMAND_1(free, RID, p_object) {
}
agent_owner.free(p_object);
- memdelete(agent);
} else {
ERR_FAIL_COND("Invalid ID.");
}
}
-void GdNavigationServer::set_active(bool p_active) const {
- GdNavigationServer *mut_this = const_cast<GdNavigationServer *>(this);
+void GodotNavigationServer::set_active(bool p_active) const {
+ GodotNavigationServer *mut_this = const_cast<GodotNavigationServer *>(this);
MutexLock lock(mut_this->operations_mutex);
mut_this->active = p_active;
}
-void GdNavigationServer::flush_queries() {
+void GodotNavigationServer::flush_queries() {
// In c++ we can't be sure that this is performed in the main thread
// even with mutable functions.
MutexLock lock(commands_mutex);
@@ -521,7 +518,7 @@ void GdNavigationServer::flush_queries() {
commands.clear();
}
-void GdNavigationServer::process(real_t p_delta_time) {
+void GodotNavigationServer::process(real_t p_delta_time) {
flush_queries();
if (!active) {
diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/navigation/godot_navigation_server.h
index 759d15e508..65224493fd 100644
--- a/modules/gdnavigation/gd_navigation_server.h
+++ b/modules/navigation/godot_navigation_server.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* gd_navigation_server.h */
+/* godot_navigation_server.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GD_NAVIGATION_SERVER_H
-#define GD_NAVIGATION_SERVER_H
+#ifndef GODOT_NAVIGATION_SERVER_H
+#define GODOT_NAVIGATION_SERVER_H
#include "core/templates/local_vector.h"
#include "core/templates/rid.h"
@@ -61,31 +61,31 @@
virtual void F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3 = D_3_DEF) const; \
void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
-class GdNavigationServer;
+class GodotNavigationServer;
struct SetCommand {
virtual ~SetCommand() {}
- virtual void exec(GdNavigationServer *server) = 0;
+ virtual void exec(GodotNavigationServer *server) = 0;
};
-class GdNavigationServer : public NavigationServer3D {
+class GodotNavigationServer : public NavigationServer3D {
Mutex commands_mutex;
/// Mutex used to make any operation threadsafe.
Mutex operations_mutex;
std::vector<SetCommand *> commands;
- mutable RID_PtrOwner<NavMap> map_owner;
- mutable RID_PtrOwner<NavRegion> region_owner;
- mutable RID_PtrOwner<RvoAgent> agent_owner;
+ mutable RID_Owner<NavMap> map_owner;
+ mutable RID_Owner<NavRegion> region_owner;
+ mutable RID_Owner<RvoAgent> agent_owner;
bool active = true;
LocalVector<NavMap *> active_maps;
LocalVector<uint32_t> active_maps_update_id;
public:
- GdNavigationServer();
- virtual ~GdNavigationServer();
+ GodotNavigationServer();
+ virtual ~GodotNavigationServer();
void add_command(SetCommand *command) const;
@@ -146,4 +146,4 @@ public:
#undef COMMAND_2
#undef COMMAND_4_DEF
-#endif // GD_NAVIGATION_SERVER_H
+#endif // GODOT_NAVIGATION_SERVER_H
diff --git a/modules/gdnavigation/nav_map.cpp b/modules/navigation/nav_map.cpp
index 41306f0687..41306f0687 100644
--- a/modules/gdnavigation/nav_map.cpp
+++ b/modules/navigation/nav_map.cpp
diff --git a/modules/gdnavigation/nav_map.h b/modules/navigation/nav_map.h
index 8e013a72eb..8e013a72eb 100644
--- a/modules/gdnavigation/nav_map.h
+++ b/modules/navigation/nav_map.h
diff --git a/modules/gdnavigation/nav_region.cpp b/modules/navigation/nav_region.cpp
index 81b15a49f5..81b15a49f5 100644
--- a/modules/gdnavigation/nav_region.cpp
+++ b/modules/navigation/nav_region.cpp
diff --git a/modules/gdnavigation/nav_region.h b/modules/navigation/nav_region.h
index f8b067e638..f8b067e638 100644
--- a/modules/gdnavigation/nav_region.h
+++ b/modules/navigation/nav_region.h
diff --git a/modules/gdnavigation/nav_rid.h b/modules/navigation/nav_rid.h
index a0a60a3643..a0a60a3643 100644
--- a/modules/gdnavigation/nav_rid.h
+++ b/modules/navigation/nav_rid.h
diff --git a/modules/gdnavigation/nav_utils.h b/modules/navigation/nav_utils.h
index 35da391eea..35da391eea 100644
--- a/modules/gdnavigation/nav_utils.h
+++ b/modules/navigation/nav_utils.h
diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp b/modules/navigation/navigation_mesh_editor_plugin.cpp
index aa9248d2a1..aa9248d2a1 100644
--- a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
+++ b/modules/navigation/navigation_mesh_editor_plugin.cpp
diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.h b/modules/navigation/navigation_mesh_editor_plugin.h
index c39269865b..c39269865b 100644
--- a/modules/gdnavigation/navigation_mesh_editor_plugin.h
+++ b/modules/navigation/navigation_mesh_editor_plugin.h
diff --git a/modules/gdnavigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp
index 0d8330c1da..0d8330c1da 100644
--- a/modules/gdnavigation/navigation_mesh_generator.cpp
+++ b/modules/navigation/navigation_mesh_generator.cpp
diff --git a/modules/gdnavigation/navigation_mesh_generator.h b/modules/navigation/navigation_mesh_generator.h
index 847c7d097b..847c7d097b 100644
--- a/modules/gdnavigation/navigation_mesh_generator.h
+++ b/modules/navigation/navigation_mesh_generator.h
diff --git a/modules/gdnavigation/register_types.cpp b/modules/navigation/register_types.cpp
index 8443d3d242..0f3c412d4a 100644
--- a/modules/gdnavigation/register_types.cpp
+++ b/modules/navigation/register_types.cpp
@@ -31,9 +31,10 @@
#include "register_types.h"
#include "core/config/engine.h"
-#include "gd_navigation_server.h"
#include "servers/navigation_server_3d.h"
+#include "godot_navigation_server.h"
+
#ifndef _3D_DISABLED
#include "navigation_mesh_generator.h"
#endif
@@ -42,19 +43,15 @@
#include "navigation_mesh_editor_plugin.h"
#endif
-/**
- @author AndreaCatania
-*/
-
#ifndef _3D_DISABLED
NavigationMeshGenerator *_nav_mesh_generator = nullptr;
#endif
NavigationServer3D *new_server() {
- return memnew(GdNavigationServer);
+ return memnew(GodotNavigationServer);
}
-void register_gdnavigation_types() {
+void register_navigation_types() {
NavigationServer3DManager::set_default_server(new_server);
#ifndef _3D_DISABLED
@@ -65,15 +62,10 @@ void register_gdnavigation_types() {
#ifdef TOOLS_ENABLED
EditorPlugins::add_by_type<NavigationMeshEditorPlugin>();
-
- ClassDB::APIType prev_api = ClassDB::get_current_api();
- ClassDB::set_current_api(ClassDB::API_EDITOR);
-
- ClassDB::set_current_api(prev_api);
#endif
}
-void unregister_gdnavigation_types() {
+void unregister_navigation_types() {
#ifndef _3D_DISABLED
if (_nav_mesh_generator) {
memdelete(_nav_mesh_generator);
diff --git a/modules/gdnavigation/register_types.h b/modules/navigation/register_types.h
index c2bb08c649..4737c818eb 100644
--- a/modules/gdnavigation/register_types.h
+++ b/modules/navigation/register_types.h
@@ -28,14 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-/**
- @author AndreaCatania
-*/
+#ifndef NAVIGATION_REGISTER_TYPES_H
+#define NAVIGATION_REGISTER_TYPES_H
-#ifndef GDNAVIGATION_REGISTER_TYPES_H
-#define GDNAVIGATION_REGISTER_TYPES_H
+void register_navigation_types();
+void unregister_navigation_types();
-void register_gdnavigation_types();
-void unregister_gdnavigation_types();
-
-#endif // GDNAVIGATION_REGISTER_TYPES_H
+#endif // NAVIGATION_REGISTER_TYPES_H
diff --git a/modules/gdnavigation/rvo_agent.cpp b/modules/navigation/rvo_agent.cpp
index 21e43d08c1..21e43d08c1 100644
--- a/modules/gdnavigation/rvo_agent.cpp
+++ b/modules/navigation/rvo_agent.cpp
diff --git a/modules/gdnavigation/rvo_agent.h b/modules/navigation/rvo_agent.h
index 369cb1f9a3..369cb1f9a3 100644
--- a/modules/gdnavigation/rvo_agent.h
+++ b/modules/navigation/rvo_agent.h
diff --git a/modules/websocket/editor_debugger_server_websocket.cpp b/modules/websocket/editor_debugger_server_websocket.cpp
index b02d212c42..2e61cbfc08 100644
--- a/modules/websocket/editor_debugger_server_websocket.cpp
+++ b/modules/websocket/editor_debugger_server_websocket.cpp
@@ -50,9 +50,9 @@ void EditorDebuggerServerWebSocket::poll() {
Error EditorDebuggerServerWebSocket::start() {
int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
- Vector<String> protocols;
- protocols.push_back("binary"); // compatibility with EMSCRIPTEN TCP-to-WebSocket layer.
- return server->listen(remote_port, protocols);
+ Vector<String> compatible_protocols;
+ compatible_protocols.push_back("binary"); // compatibility with EMSCRIPTEN TCP-to-WebSocket layer.
+ return server->listen(remote_port, compatible_protocols);
}
void EditorDebuggerServerWebSocket::stop() {
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 6c1cdc2129..2f552af3d9 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -76,13 +76,46 @@ Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_motion, bool p_i
return Ref<KinematicCollision2D>();
}
-bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only) {
+bool PhysicsBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only, bool p_cancel_sliding) {
if (is_only_update_transform_changes_enabled()) {
ERR_PRINT("Move functions do not work together with 'sync to physics' option. Please read the documentation.");
}
Transform2D gt = get_global_transform();
bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes);
+ // Restore direction of motion to be along original motion,
+ // in order to avoid sliding due to recovery,
+ // but only if collision depth is low enough to avoid tunneling.
+ real_t motion_length = p_motion.length();
+ if (motion_length > CMP_EPSILON) {
+ real_t precision = 0.001;
+
+ if (colliding && p_cancel_sliding) {
+ // Can't just use margin as a threshold because collision depth is calculated on unsafe motion,
+ // so even in normal resting cases the depth can be a bit more than the margin.
+ precision += motion_length * (r_result.collision_unsafe_fraction - r_result.collision_safe_fraction);
+
+ if (r_result.collision_depth > (real_t)p_margin + precision) {
+ p_cancel_sliding = false;
+ }
+ }
+
+ if (p_cancel_sliding) {
+ // Check depth of recovery.
+ Vector2 motion_normal = p_motion / motion_length;
+ real_t dot = r_result.motion.dot(motion_normal);
+ Vector2 recovery = r_result.motion - motion_normal * dot;
+ real_t recovery_length = recovery.length();
+ // Fixes cases where canceling slide causes the motion to go too deep into the ground,
+ // Becauses we're only taking rest information into account and not general recovery.
+ if (recovery_length < (real_t)p_margin + precision) {
+ // Apply adjustment to motion.
+ r_result.motion = motion_normal * dot;
+ r_result.remainder = p_motion - r_result.motion;
+ }
+ }
+ }
+
if (!p_test_only) {
gt.elements[2] += r_result.motion;
set_global_transform(gt);
@@ -942,15 +975,16 @@ void CharacterBody2D::move_and_slide() {
floor_normal = Vector2();
floor_velocity = Vector2();
- int slide_count = max_slides;
- while (slide_count) {
+ // No sliding on first attempt to keep floor motion stable when possible.
+ bool sliding_enabled = false;
+ for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer2D::MotionResult result;
bool found_collision = false;
for (int i = 0; i < 2; ++i) {
bool collided;
if (i == 0) { //collide
- collided = move_and_collide(motion, infinite_inertia, result, margin);
+ collided = move_and_collide(motion, infinite_inertia, result, margin, true, false, !sliding_enabled);
if (!collided) {
motion = Vector2(); //clear because no collision happened and motion completed
}
@@ -966,7 +1000,6 @@ void CharacterBody2D::move_and_slide() {
found_collision = true;
motion_results.push_back(result);
- motion = result.remainder;
if (up_direction == Vector2()) {
//all is a wall
@@ -980,7 +1013,7 @@ void CharacterBody2D::move_and_slide() {
floor_velocity = result.collider_velocity;
if (stop_on_slope) {
- if ((body_velocity_normal + up_direction).length() < 0.01 && result.motion.length() < 1) {
+ if ((body_velocity_normal + up_direction).length() < 0.01) {
Transform2D gt = get_global_transform();
gt.elements[2] -= result.motion.slide(up_direction);
set_global_transform(gt);
@@ -995,16 +1028,20 @@ void CharacterBody2D::move_and_slide() {
}
}
- motion = motion.slide(result.collision_normal);
- linear_velocity = linear_velocity.slide(result.collision_normal);
+ if (sliding_enabled || !on_floor) {
+ motion = result.remainder.slide(result.collision_normal);
+ linear_velocity = linear_velocity.slide(result.collision_normal);
+ } else {
+ motion = result.remainder;
+ }
}
+
+ sliding_enabled = true;
}
if (!found_collision || motion == Vector2()) {
break;
}
-
- --slide_count;
}
if (!was_on_floor || snap == Vector2()) {
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index f084a247aa..b1d48a2cc9 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -50,7 +50,7 @@ protected:
Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.08);
public:
- bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
+ bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, PhysicsServer2D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false, bool p_cancel_sliding = true);
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
TypedArray<PhysicsBody2D> get_collision_exceptions();
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 8e10a37afb..7c9245cd3e 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -118,10 +118,43 @@ Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_i
return Ref<KinematicCollision3D>();
}
-bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only) {
+bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only, bool p_cancel_sliding) {
Transform3D gt = get_global_transform();
bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes);
+ // Restore direction of motion to be along original motion,
+ // in order to avoid sliding due to recovery,
+ // but only if collision depth is low enough to avoid tunneling.
+ real_t motion_length = p_motion.length();
+ if (motion_length > CMP_EPSILON) {
+ real_t precision = CMP_EPSILON;
+
+ if (colliding && p_cancel_sliding) {
+ // Can't just use margin as a threshold because collision depth is calculated on unsafe motion,
+ // so even in normal resting cases the depth can be a bit more than the margin.
+ precision += motion_length * (r_result.collision_unsafe_fraction - r_result.collision_safe_fraction);
+
+ if (r_result.collision_depth > (real_t)p_margin + precision) {
+ p_cancel_sliding = false;
+ }
+ }
+
+ if (p_cancel_sliding) {
+ // Check depth of recovery.
+ Vector3 motion_normal = p_motion / motion_length;
+ real_t dot = r_result.motion.dot(motion_normal);
+ Vector3 recovery = r_result.motion - motion_normal * dot;
+ real_t recovery_length = recovery.length();
+ // Fixes cases where canceling slide causes the motion to go too deep into the ground,
+ // Becauses we're only taking rest information into account and not general recovery.
+ if (recovery_length < (real_t)p_margin + precision) {
+ // Apply adjustment to motion.
+ r_result.motion = motion_normal * dot;
+ r_result.remainder = p_motion - r_result.motion;
+ }
+ }
+ }
+
for (int i = 0; i < 3; i++) {
if (locked_axis & (1 << i)) {
r_result.motion[i] = 0;
@@ -978,15 +1011,16 @@ void CharacterBody3D::move_and_slide() {
floor_normal = Vector3();
floor_velocity = Vector3();
- int slide_count = max_slides;
- while (slide_count) {
+ // No sliding on first attempt to keep motion stable when possible.
+ bool sliding_enabled = false;
+ for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer3D::MotionResult result;
bool found_collision = false;
for (int i = 0; i < 2; ++i) {
bool collided;
if (i == 0) { //collide
- collided = move_and_collide(motion, infinite_inertia, result, margin);
+ collided = move_and_collide(motion, infinite_inertia, result, margin, true, false, !sliding_enabled);
if (!collided) {
motion = Vector3(); //clear because no collision happened and motion completed
}
@@ -1002,7 +1036,6 @@ void CharacterBody3D::move_and_slide() {
found_collision = true;
motion_results.push_back(result);
- motion = result.remainder;
if (up_direction == Vector3()) {
//all is a wall
@@ -1016,7 +1049,7 @@ void CharacterBody3D::move_and_slide() {
floor_velocity = result.collider_velocity;
if (stop_on_slope) {
- if ((body_velocity_normal + up_direction).length() < 0.01 && result.motion.length() < 1) {
+ if ((body_velocity_normal + up_direction).length() < 0.01) {
Transform3D gt = get_global_transform();
gt.origin -= result.motion.slide(up_direction);
set_global_transform(gt);
@@ -1031,22 +1064,26 @@ void CharacterBody3D::move_and_slide() {
}
}
- motion = motion.slide(result.collision_normal);
- linear_velocity = linear_velocity.slide(result.collision_normal);
+ if (sliding_enabled || !on_floor) {
+ motion = result.remainder.slide(result.collision_normal);
+ linear_velocity = linear_velocity.slide(result.collision_normal);
- for (int j = 0; j < 3; j++) {
- if (locked_axis & (1 << j)) {
- linear_velocity[j] = 0.0;
+ for (int j = 0; j < 3; j++) {
+ if (locked_axis & (1 << j)) {
+ linear_velocity[j] = 0.0;
+ }
}
+ } else {
+ motion = result.remainder;
}
}
+
+ sliding_enabled = true;
}
if (!found_collision || motion == Vector3()) {
break;
}
-
- --slide_count;
}
if (!was_on_floor || snap == Vector3()) {
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index 7d7adf1624..bc4556494d 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -53,7 +53,7 @@ protected:
Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.001);
public:
- bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
+ bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false, bool p_cancel_sliding = true);
bool test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001);
void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index cc56d6a49e..319e589036 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -929,6 +929,15 @@ bool Viewport::is_audio_listener_2d() const {
return audio_listener_2d;
}
+void Viewport::set_disable_3d(bool p_disable) {
+ disable_3d = p_disable;
+ RenderingServer::get_singleton()->viewport_set_disable_3d(viewport, disable_3d);
+}
+
+bool Viewport::is_3d_disabled() const {
+ return disable_3d;
+}
+
void Viewport::enable_canvas_transform_override(bool p_enable) {
if (override_canvas_transform == p_enable) {
return;
@@ -3516,6 +3525,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d);
ClassDB::bind_method(D_METHOD("is_audio_listener_2d"), &Viewport::is_audio_listener_2d);
+ ClassDB::bind_method(D_METHOD("set_disable_3d", "disable"), &Viewport::set_disable_3d);
+ ClassDB::bind_method(D_METHOD("is_3d_disabled"), &Viewport::is_3d_disabled);
+
ClassDB::bind_method(D_METHOD("get_mouse_position"), &Viewport::get_mouse_position);
ClassDB::bind_method(D_METHOD("warp_mouse", "to_position"), &Viewport::warp_mouse);
@@ -3582,6 +3594,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel"), "set_snap_2d_transforms_to_pixel", "is_snap_2d_transforms_to_pixel_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_vertices_to_pixel"), "set_snap_2d_vertices_to_pixel", "is_snap_2d_vertices_to_pixel_enabled");
ADD_GROUP("Rendering", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)"), "set_msaa", "get_msaa");
ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding");
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index d905e44a82..29491a1178 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -288,6 +288,8 @@ private:
void _update_listener();
void _update_listener_2d();
+ bool disable_3d = false;
+
void _propagate_enter_world(Node *p_node);
void _propagate_exit_world(Node *p_node);
void _propagate_viewport_notification(Node *p_node, int p_what);
@@ -503,6 +505,9 @@ public:
void set_as_audio_listener_2d(bool p_enable);
bool is_audio_listener_2d() const;
+ void set_disable_3d(bool p_disable);
+ bool is_3d_disabled() const;
+
void update_canvas_items();
Rect2 get_visible_rect() const;
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index eb9fc0e800..5cc5bae09b 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -33,10 +33,7 @@
bool AreaPair2DSW::setup(real_t p_step) {
bool result = false;
-
- if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
- result = false;
- } else if (area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), nullptr, this)) {
+ if (area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), nullptr, this)) {
result = true;
}
@@ -113,9 +110,7 @@ AreaPair2DSW::~AreaPair2DSW() {
bool Area2Pair2DSW::setup(real_t p_step) {
bool result = false;
- if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
- result = false;
- } else if (area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), nullptr, this)) {
+ if (area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), nullptr, this)) {
result = true;
}
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index ff31825b83..e5eb374fa3 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -244,11 +244,6 @@ bool BodyPair2DSW::setup(real_t p_step) {
}
}
- if (A->is_shape_set_as_disabled(shape_A) || B->is_shape_set_as_disabled(shape_B)) {
- collided = false;
- return false;
- }
-
//use local A coordinates to avoid numerical issues on collision detection
offset_B = B->get_transform().get_origin() - A->get_transform().get_origin();
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index fa87dc1f3f..5d1ef83165 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -47,8 +47,6 @@ void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_tra
if (!pending_shape_update_list.in_list()) {
PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
- // _update_shapes();
- // _shapes_changed();
}
void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) {
@@ -61,8 +59,6 @@ void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) {
if (!pending_shape_update_list.in_list()) {
PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
- // _update_shapes();
- // _shapes_changed();
}
void CollisionObject2DSW::set_shape_metadata(int p_index, const Variant &p_metadata) {
@@ -79,11 +75,9 @@ void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_
if (!pending_shape_update_list.in_list()) {
PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
- // _update_shapes();
- // _shapes_changed();
}
-void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) {
+void CollisionObject2DSW::set_shape_disabled(int p_idx, bool p_disabled) {
ERR_FAIL_INDEX(p_idx, shapes.size());
CollisionObject2DSW::Shape &shape = shapes.write[p_idx];
@@ -103,12 +97,10 @@ void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) {
if (!pending_shape_update_list.in_list()) {
PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
- //_update_shapes();
} else if (!p_disabled && shape.bpid == 0) {
if (!pending_shape_update_list.in_list()) {
PhysicsServer2DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
- //_update_shapes(); // automatically adds shape with bpid == 0
}
}
@@ -177,7 +169,6 @@ void CollisionObject2DSW::_update_shapes() {
for (int i = 0; i < shapes.size(); i++) {
Shape &s = shapes.write[i];
-
if (s.disabled) {
continue;
}
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index c395e59694..67da758d14 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -118,10 +118,6 @@ public:
void set_shape_metadata(int p_index, const Variant &p_metadata);
_FORCE_INLINE_ int get_shape_count() const { return shapes.size(); }
- _FORCE_INLINE_ bool is_shape_disabled(int p_index) const {
- CRASH_BAD_INDEX(p_index, shapes.size());
- return shapes[p_index].disabled;
- }
_FORCE_INLINE_ Shape2DSW *get_shape(int p_index) const {
CRASH_BAD_INDEX(p_index, shapes.size());
return shapes[p_index].shape;
@@ -147,9 +143,9 @@ public:
_FORCE_INLINE_ const Transform2D &get_inv_transform() const { return inv_transform; }
_FORCE_INLINE_ Space2DSW *get_space() const { return space; }
- void set_shape_as_disabled(int p_idx, bool p_disabled);
- _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const {
- CRASH_BAD_INDEX(p_idx, shapes.size());
+ void set_shape_disabled(int p_idx, bool p_disabled);
+ _FORCE_INLINE_ bool is_shape_disabled(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, shapes.size(), false);
return shapes[p_idx].disabled;
}
diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp
index 1c2dca0259..155dda4394 100644
--- a/servers/physics_2d/physics_server_2d_sw.cpp
+++ b/servers/physics_2d/physics_server_2d_sw.cpp
@@ -366,7 +366,7 @@ void PhysicsServer2DSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_
ERR_FAIL_INDEX(p_shape, area->get_shape_count());
FLUSH_QUERY_CHECK(area);
- area->set_shape_as_disabled(p_shape, p_disabled);
+ area->set_shape_disabled(p_shape, p_disabled);
}
int PhysicsServer2DSW::area_get_shape_count(RID p_area) const {
@@ -663,7 +663,7 @@ void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
FLUSH_QUERY_CHECK(body);
- body->set_shape_as_disabled(p_shape_idx, p_disabled);
+ body->set_shape_disabled(p_shape_idx, p_disabled);
}
void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) {
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 1380e57b57..4b123b2d46 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -84,10 +84,6 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S
int shape_idx = space->intersection_query_subindex_results[i];
- if (col_obj->is_shape_set_as_disabled(shape_idx)) {
- continue;
- }
-
Shape2DSW *shape = col_obj->get_shape(shape_idx);
Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_point);
@@ -233,10 +229,6 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- if (col_obj->is_shape_set_as_disabled(shape_idx)) {
- continue;
- }
-
if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) {
continue;
}
@@ -280,10 +272,6 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- if (col_obj->is_shape_set_as_disabled(shape_idx)) {
- continue;
- }
-
Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
//test initial overlap, does it collide if going all the way?
if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) {
@@ -365,10 +353,6 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D &
int shape_idx = space->intersection_query_subindex_results[i];
- if (col_obj->is_shape_set_as_disabled(shape_idx)) {
- continue;
- }
-
cbk.valid_dir = Vector2();
cbk.valid_depth = 0;
@@ -460,10 +444,6 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh
int shape_idx = space->intersection_query_subindex_results[i];
- if (col_obj->is_shape_set_as_disabled(shape_idx)) {
- continue;
- }
-
rcd.valid_dir = Vector2();
rcd.object = col_obj;
rcd.shape = shape_idx;
@@ -516,8 +496,6 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
keep = false;
} else if (static_cast<Body2DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) {
keep = false;
- } else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i])) {
- keep = false;
}
if (!keep) {
@@ -540,7 +518,7 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
bool shapes_found = false;
for (int i = 0; i < p_body->get_shape_count(); i++) {
- if (p_body->is_shape_set_as_disabled(i)) {
+ if (p_body->is_shape_disabled(i)) {
continue;
}
@@ -592,7 +570,7 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_disabled(j)) {
+ if (p_body->is_shape_disabled(j)) {
continue;
}
@@ -732,7 +710,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
bool shapes_found = false;
for (int i = 0; i < p_body->get_shape_count(); i++) {
- if (p_body->is_shape_set_as_disabled(i)) {
+ if (p_body->is_shape_disabled(i)) {
continue;
}
@@ -795,7 +773,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_disabled(j)) {
+ if (p_body->is_shape_disabled(j)) {
continue;
}
@@ -918,7 +896,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int amount = _cull_aabb_for_body(p_body, motion_aabb);
for (int body_shape_idx = 0; body_shape_idx < p_body->get_shape_count(); body_shape_idx++) {
- if (p_body->is_shape_set_as_disabled(body_shape_idx)) {
+ if (p_body->is_shape_disabled(body_shape_idx)) {
continue;
}
@@ -1060,7 +1038,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count();
for (int j = from_shape; j < to_shape; j++) {
- if (p_body->is_shape_set_as_disabled(j)) {
+ if (p_body->is_shape_disabled(j)) {
continue;
}
@@ -1142,6 +1120,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
r_result->collision_local_shape = rcd.best_local_shape;
r_result->collision_normal = rcd.best_normal;
r_result->collision_point = rcd.best_contact;
+ r_result->collision_depth = rcd.best_len;
+ r_result->collision_safe_fraction = safe;
+ r_result->collision_unsafe_fraction = unsafe;
r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
const Body2DSW *body = static_cast<const Body2DSW *>(rcd.best_object);
diff --git a/servers/physics_3d/area_pair_3d_sw.cpp b/servers/physics_3d/area_pair_3d_sw.cpp
index 2073df7dee..9f93a61909 100644
--- a/servers/physics_3d/area_pair_3d_sw.cpp
+++ b/servers/physics_3d/area_pair_3d_sw.cpp
@@ -33,10 +33,7 @@
bool AreaPair3DSW::setup(real_t p_step) {
bool result = false;
-
- if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
- result = false;
- } else if (area->test_collision_mask(body) && CollisionSolver3DSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), nullptr, this)) {
+ if (area->test_collision_mask(body) && CollisionSolver3DSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), nullptr, this)) {
result = true;
}
@@ -113,9 +110,7 @@ AreaPair3DSW::~AreaPair3DSW() {
bool Area2Pair3DSW::setup(real_t p_step) {
bool result = false;
- if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
- result = false;
- } else if (area_a->test_collision_mask(area_b) && CollisionSolver3DSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), nullptr, this)) {
+ if (area_a->test_collision_mask(area_b) && CollisionSolver3DSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), nullptr, this)) {
result = true;
}
diff --git a/servers/physics_3d/body_pair_3d_sw.cpp b/servers/physics_3d/body_pair_3d_sw.cpp
index aed4815c5e..6fc0fa8690 100644
--- a/servers/physics_3d/body_pair_3d_sw.cpp
+++ b/servers/physics_3d/body_pair_3d_sw.cpp
@@ -230,11 +230,6 @@ bool BodyPair3DSW::setup(real_t p_step) {
}
}
- if (A->is_shape_set_as_disabled(shape_A) || B->is_shape_set_as_disabled(shape_B)) {
- collided = false;
- return false;
- }
-
offset_B = B->get_transform().get_origin() - A->get_transform().get_origin();
validate_contacts();
@@ -607,11 +602,6 @@ bool BodySoftBodyPair3DSW::setup(real_t p_step) {
return false;
}
- if (body->is_shape_set_as_disabled(body_shape)) {
- collided = false;
- return false;
- }
-
const Transform3D &xform_Au = body->get_transform();
Transform3D xform_A = xform_Au * body->get_shape_transform(body_shape);
diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/collision_object_3d_sw.cpp
index 51e2432071..24c7d7b85c 100644
--- a/servers/physics_3d/collision_object_3d_sw.cpp
+++ b/servers/physics_3d/collision_object_3d_sw.cpp
@@ -45,8 +45,6 @@ void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform3D &p_tra
if (!pending_shape_update_list.in_list()) {
PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
- //_update_shapes();
- //_shapes_changed();
}
void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) {
@@ -58,8 +56,6 @@ void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) {
if (!pending_shape_update_list.in_list()) {
PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
- //_update_shapes();
- //_shapes_changed();
}
void CollisionObject3DSW::set_shape_transform(int p_index, const Transform3D &p_transform) {
@@ -70,14 +66,32 @@ void CollisionObject3DSW::set_shape_transform(int p_index, const Transform3D &p_
if (!pending_shape_update_list.in_list()) {
PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
- //_update_shapes();
- //_shapes_changed();
}
-void CollisionObject3DSW::set_shape_as_disabled(int p_idx, bool p_enable) {
- shapes.write[p_idx].disabled = p_enable;
- if (!pending_shape_update_list.in_list()) {
- PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
+void CollisionObject3DSW::set_shape_disabled(int p_idx, bool p_disabled) {
+ ERR_FAIL_INDEX(p_idx, shapes.size());
+
+ CollisionObject3DSW::Shape &shape = shapes.write[p_idx];
+ if (shape.disabled == p_disabled) {
+ return;
+ }
+
+ shape.disabled = p_disabled;
+
+ if (!space) {
+ return;
+ }
+
+ if (p_disabled && shape.bpid != 0) {
+ space->get_broadphase()->remove(shape.bpid);
+ shape.bpid = 0;
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ } else if (!p_disabled && shape.bpid == 0) {
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
+ }
}
}
@@ -108,8 +122,6 @@ void CollisionObject3DSW::remove_shape(int p_index) {
if (!pending_shape_update_list.in_list()) {
PhysicsServer3DSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
}
- //_update_shapes();
- //_shapes_changed();
}
void CollisionObject3DSW::_set_static(bool p_static) {
@@ -146,6 +158,9 @@ void CollisionObject3DSW::_update_shapes() {
for (int i = 0; i < shapes.size(); i++) {
Shape &s = shapes.write[i];
+ if (s.disabled) {
+ continue;
+ }
//not quite correct, should compute the next matrix..
AABB shape_aabb = s.shape->get_aabb();
@@ -173,6 +188,9 @@ void CollisionObject3DSW::_update_shapes_with_motion(const Vector3 &p_motion) {
for (int i = 0; i < shapes.size(); i++) {
Shape &s = shapes.write[i];
+ if (s.disabled) {
+ continue;
+ }
//not quite correct, should compute the next matrix..
AABB shape_aabb = s.shape->get_aabb();
diff --git a/servers/physics_3d/collision_object_3d_sw.h b/servers/physics_3d/collision_object_3d_sw.h
index 5505fec3da..b2b2fa0f50 100644
--- a/servers/physics_3d/collision_object_3d_sw.h
+++ b/servers/physics_3d/collision_object_3d_sw.h
@@ -120,15 +120,26 @@ public:
void set_shape(int p_index, Shape3DSW *p_shape);
void set_shape_transform(int p_index, const Transform3D &p_transform);
_FORCE_INLINE_ int get_shape_count() const { return shapes.size(); }
- _FORCE_INLINE_ bool is_shape_disabled(int p_index) const {
+ _FORCE_INLINE_ Shape3DSW *get_shape(int p_index) const {
CRASH_BAD_INDEX(p_index, shapes.size());
- return shapes[p_index].disabled;
+ return shapes[p_index].shape;
+ }
+ _FORCE_INLINE_ const Transform3D &get_shape_transform(int p_index) const {
+ CRASH_BAD_INDEX(p_index, shapes.size());
+ return shapes[p_index].xform;
+ }
+ _FORCE_INLINE_ const Transform3D &get_shape_inv_transform(int p_index) const {
+ CRASH_BAD_INDEX(p_index, shapes.size());
+ return shapes[p_index].xform_inv;
+ }
+ _FORCE_INLINE_ const AABB &get_shape_aabb(int p_index) const {
+ CRASH_BAD_INDEX(p_index, shapes.size());
+ return shapes[p_index].aabb_cache;
+ }
+ _FORCE_INLINE_ real_t get_shape_area(int p_index) const {
+ CRASH_BAD_INDEX(p_index, shapes.size());
+ return shapes[p_index].area_cache;
}
- _FORCE_INLINE_ Shape3DSW *get_shape(int p_index) const { return shapes[p_index].shape; }
- _FORCE_INLINE_ const Transform3D &get_shape_transform(int p_index) const { return shapes[p_index].xform; }
- _FORCE_INLINE_ const Transform3D &get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; }
- _FORCE_INLINE_ const AABB &get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; }
- _FORCE_INLINE_ real_t get_shape_area(int p_index) const { return shapes[p_index].area_cache; }
_FORCE_INLINE_ const Transform3D &get_transform() const { return transform; }
_FORCE_INLINE_ const Transform3D &get_inv_transform() const { return inv_transform; }
@@ -137,9 +148,9 @@ public:
_FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable = p_enable; }
_FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; }
- void set_shape_as_disabled(int p_idx, bool p_enable);
- _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const {
- CRASH_BAD_INDEX(p_idx, shapes.size());
+ void set_shape_disabled(int p_idx, bool p_disabled);
+ _FORCE_INLINE_ bool is_shape_disabled(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, shapes.size(), false);
return shapes[p_idx].disabled;
}
diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp
index 7a95a8abc8..f26129a404 100644
--- a/servers/physics_3d/physics_server_3d_sw.cpp
+++ b/servers/physics_3d/physics_server_3d_sw.cpp
@@ -335,7 +335,7 @@ void PhysicsServer3DSW::area_set_shape_disabled(RID p_area, int p_shape_idx, boo
ERR_FAIL_COND(!area);
ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count());
FLUSH_QUERY_CHECK(area);
- area->set_shape_as_disabled(p_shape_idx, p_disabled);
+ area->set_shape_disabled(p_shape_idx, p_disabled);
}
void PhysicsServer3DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id) {
@@ -537,7 +537,7 @@ void PhysicsServer3DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
FLUSH_QUERY_CHECK(body);
- body->set_shape_as_disabled(p_shape_idx, p_disabled);
+ body->set_shape_disabled(p_shape_idx, p_disabled);
}
Transform3D PhysicsServer3DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const {
diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp
index c1e09c9a22..eff480396d 100644
--- a/servers/physics_3d/space_3d_sw.cpp
+++ b/servers/physics_3d/space_3d_sw.cpp
@@ -214,10 +214,6 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- if (col_obj->is_shape_set_as_disabled(shape_idx)) {
- continue;
- }
-
if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) {
continue;
}
@@ -273,10 +269,6 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- if (col_obj->is_shape_set_as_disabled(shape_idx)) {
- continue;
- }
-
Vector3 point_A, point_B;
Vector3 sep_axis = p_motion.normalized();
@@ -385,10 +377,6 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform3D &
int shape_idx = space->intersection_query_subindex_results[i];
- if (col_obj->is_shape_set_as_disabled(shape_idx)) {
- continue;
- }
-
if (CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_margin)) {
collided = true;
}
@@ -460,10 +448,6 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform3D &p_sh
int shape_idx = space->intersection_query_subindex_results[i];
- if (col_obj->is_shape_set_as_disabled(shape_idx)) {
- continue;
- }
-
rcd.object = col_obj;
rcd.shape = shape_idx;
bool sc = CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin);
@@ -508,7 +492,7 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob
bool shapes_found = false;
for (int i = 0; i < obj->get_shape_count(); i++) {
- if (obj->is_shape_set_as_disabled(i)) {
+ if (obj->is_shape_disabled(i)) {
continue;
}
@@ -555,8 +539,6 @@ int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) {
keep = false;
} else if (static_cast<Body3DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) {
keep = false;
- } else if (static_cast<Body3DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i])) {
- keep = false;
}
if (!keep) {
@@ -579,7 +561,7 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform3D &p_t
bool shapes_found = false;
for (int i = 0; i < p_body->get_shape_count(); i++) {
- if (p_body->is_shape_set_as_disabled(i)) {
+ if (p_body->is_shape_disabled(i)) {
continue;
}
@@ -626,7 +608,7 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform3D &p_t
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_disabled(j)) {
+ if (p_body->is_shape_disabled(j)) {
continue;
}
@@ -740,7 +722,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
bool shapes_found = false;
for (int i = 0; i < p_body->get_shape_count(); i++) {
- if (p_body->is_shape_set_as_disabled(i)) {
+ if (p_body->is_shape_disabled(i)) {
continue;
}
@@ -793,7 +775,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_disabled(j)) {
+ if (p_body->is_shape_disabled(j)) {
continue;
}
@@ -871,7 +853,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
int amount = _cull_aabb_for_body(p_body, motion_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_disabled(j)) {
+ if (p_body->is_shape_disabled(j)) {
continue;
}
@@ -989,7 +971,7 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count();
for (int j = from_shape; j < to_shape; j++) {
- if (p_body->is_shape_set_as_disabled(j)) {
+ if (p_body->is_shape_disabled(j)) {
continue;
}
@@ -1032,6 +1014,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform3D &p_from, co
r_result->collision_local_shape = rcd.best_local_shape;
r_result->collision_normal = rcd.best_normal;
r_result->collision_point = rcd.best_contact;
+ r_result->collision_depth = rcd.best_len;
+ r_result->collision_safe_fraction = safe;
+ r_result->collision_unsafe_fraction = unsafe;
//r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
const Body3DSW *body = static_cast<const Body3DSW *>(rcd.best_object);
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index faab4f43b8..12200989fd 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -487,6 +487,18 @@ int PhysicsTestMotionResult2D::get_collider_shape() const {
return result.collider_shape;
}
+real_t PhysicsTestMotionResult2D::get_collision_depth() const {
+ return result.collision_depth;
+}
+
+real_t PhysicsTestMotionResult2D::get_collision_safe_fraction() const {
+ return result.collision_safe_fraction;
+}
+
+real_t PhysicsTestMotionResult2D::get_collision_unsafe_fraction() const {
+ return result.collision_unsafe_fraction;
+}
+
void PhysicsTestMotionResult2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_motion"), &PhysicsTestMotionResult2D::get_motion);
ClassDB::bind_method(D_METHOD("get_motion_remainder"), &PhysicsTestMotionResult2D::get_motion_remainder);
@@ -497,6 +509,9 @@ void PhysicsTestMotionResult2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_collider_rid"), &PhysicsTestMotionResult2D::get_collider_rid);
ClassDB::bind_method(D_METHOD("get_collider"), &PhysicsTestMotionResult2D::get_collider);
ClassDB::bind_method(D_METHOD("get_collider_shape"), &PhysicsTestMotionResult2D::get_collider_shape);
+ ClassDB::bind_method(D_METHOD("get_collision_depth"), &PhysicsTestMotionResult2D::get_collision_depth);
+ ClassDB::bind_method(D_METHOD("get_collision_safe_fraction"), &PhysicsTestMotionResult2D::get_collision_safe_fraction);
+ ClassDB::bind_method(D_METHOD("get_collision_unsafe_fraction"), &PhysicsTestMotionResult2D::get_collision_unsafe_fraction);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "", "get_motion");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion_remainder"), "", "get_motion_remainder");
@@ -507,6 +522,9 @@ void PhysicsTestMotionResult2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::RID, "collider_rid"), "", "get_collider_rid");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape"), "", "get_collider_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_depth"), "", "get_collision_depth");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_safe_fraction"), "", "get_collision_safe_fraction");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_unsafe_fraction"), "", "get_collision_unsafe_fraction");
}
///////////////////////////////////////
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index df39d6ae50..90f50810f9 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -493,6 +493,9 @@ public:
Vector2 collision_point;
Vector2 collision_normal;
Vector2 collider_velocity;
+ real_t collision_depth = 0.0;
+ real_t collision_safe_fraction = 0.0;
+ real_t collision_unsafe_fraction = 0.0;
int collision_local_shape = 0;
ObjectID collider_id;
RID collider;
@@ -619,6 +622,9 @@ public:
RID get_collider_rid() const;
Object *get_collider() const;
int get_collider_shape() const;
+ real_t get_collision_depth() const;
+ real_t get_collision_safe_fraction() const;
+ real_t get_collision_unsafe_fraction() const;
};
typedef PhysicsServer2D *(*CreatePhysicsServer2DCallback)();
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index d9b805de87..fcdd207843 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -497,6 +497,9 @@ public:
Vector3 collision_point;
Vector3 collision_normal;
Vector3 collider_velocity;
+ real_t collision_depth = 0.0;
+ real_t collision_safe_fraction = 0.0;
+ real_t collision_unsafe_fraction = 0.0;
int collision_local_shape = 0;
ObjectID collider_id;
RID collider;
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index 016a172f25..ec0a8347f8 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -97,7 +97,7 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2
}
}
-void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_PtrOwner<RendererCanvasCull::Item, true> &canvas_item_owner) {
+void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner, RID_Owner<RendererCanvasCull::Item, true> &canvas_item_owner) {
do {
ysort_owner->ysort_children_count = -1;
ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : nullptr;
@@ -392,8 +392,7 @@ RID RendererCanvasCull::canvas_allocate() {
return canvas_owner.allocate_rid();
}
void RendererCanvasCull::canvas_initialize(RID p_rid) {
- Canvas *canvas = memnew(Canvas);
- canvas_owner.initialize_rid(p_rid, canvas);
+ canvas_owner.initialize_rid(p_rid);
}
void RendererCanvasCull::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) {
@@ -429,8 +428,7 @@ RID RendererCanvasCull::canvas_item_allocate() {
return canvas_item_owner.allocate_rid();
}
void RendererCanvasCull::canvas_item_initialize(RID p_rid) {
- Item *canvas_item = memnew(Item);
- canvas_item_owner.initialize_rid(p_rid, canvas_item);
+ canvas_item_owner.initialize_rid(p_rid);
}
void RendererCanvasCull::canvas_item_set_parent(RID p_item, RID p_parent) {
@@ -1171,9 +1169,9 @@ RID RendererCanvasCull::canvas_light_allocate() {
return canvas_light_owner.allocate_rid();
}
void RendererCanvasCull::canvas_light_initialize(RID p_rid) {
- RendererCanvasRender::Light *clight = memnew(RendererCanvasRender::Light);
+ canvas_light_owner.initialize_rid(p_rid);
+ RendererCanvasRender::Light *clight = canvas_light_owner.getornull(p_rid);
clight->light_internal = RSG::canvas_render->light_create();
- return canvas_light_owner.initialize_rid(p_rid, clight);
}
void RendererCanvasCull::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) {
@@ -1367,9 +1365,7 @@ RID RendererCanvasCull::canvas_light_occluder_allocate() {
return canvas_light_occluder_owner.allocate_rid();
}
void RendererCanvasCull::canvas_light_occluder_initialize(RID p_rid) {
- RendererCanvasRender::LightOccluderInstance *occluder = memnew(RendererCanvasRender::LightOccluderInstance);
-
- return canvas_light_occluder_owner.initialize_rid(p_rid, occluder);
+ return canvas_light_occluder_owner.initialize_rid(p_rid);
}
void RendererCanvasCull::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) {
@@ -1451,9 +1447,9 @@ RID RendererCanvasCull::canvas_occluder_polygon_allocate() {
return canvas_light_occluder_polygon_owner.allocate_rid();
}
void RendererCanvasCull::canvas_occluder_polygon_initialize(RID p_rid) {
- LightOccluderPolygon *occluder_poly = memnew(LightOccluderPolygon);
+ canvas_light_occluder_polygon_owner.initialize_rid(p_rid);
+ LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_rid);
occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create();
- return canvas_light_occluder_polygon_owner.initialize_rid(p_rid, occluder_poly);
}
void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) {
@@ -1596,8 +1592,6 @@ bool RendererCanvasCull::free(RID p_rid) {
canvas_owner.free(p_rid);
- memdelete(canvas);
-
} else if (canvas_item_owner.owns(p_rid)) {
Item *canvas_item = canvas_item_owner.getornull(p_rid);
ERR_FAIL_COND_V(!canvas_item, true);
@@ -1632,8 +1626,6 @@ bool RendererCanvasCull::free(RID p_rid) {
canvas_item_owner.free(p_rid);
- memdelete(canvas_item);
-
} else if (canvas_light_owner.owns(p_rid)) {
RendererCanvasRender::Light *canvas_light = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND_V(!canvas_light, true);
@@ -1648,7 +1640,6 @@ bool RendererCanvasCull::free(RID p_rid) {
RSG::canvas_render->free(canvas_light->light_internal);
canvas_light_owner.free(p_rid);
- memdelete(canvas_light);
} else if (canvas_light_occluder_owner.owns(p_rid)) {
RendererCanvasRender::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_rid);
@@ -1667,7 +1658,6 @@ bool RendererCanvasCull::free(RID p_rid) {
}
canvas_light_occluder_owner.free(p_rid);
- memdelete(occluder);
} else if (canvas_light_occluder_polygon_owner.owns(p_rid)) {
LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_rid);
@@ -1680,7 +1670,6 @@ bool RendererCanvasCull::free(RID p_rid) {
}
canvas_light_occluder_polygon_owner.free(p_rid);
- memdelete(occluder_poly);
} else {
return false;
}
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index a51b419613..79b5450d14 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -116,9 +116,9 @@ public:
}
};
- RID_PtrOwner<LightOccluderPolygon, true> canvas_light_occluder_polygon_owner;
+ RID_Owner<LightOccluderPolygon, true> canvas_light_occluder_polygon_owner;
- RID_PtrOwner<RendererCanvasRender::LightOccluderInstance, true> canvas_light_occluder_owner;
+ RID_Owner<RendererCanvasRender::LightOccluderInstance, true> canvas_light_occluder_owner;
struct Canvas : public RendererViewport::CanvasBase {
Set<RID> viewports;
@@ -163,9 +163,9 @@ public:
}
};
- mutable RID_PtrOwner<Canvas, true> canvas_owner;
- RID_PtrOwner<Item, true> canvas_item_owner;
- RID_PtrOwner<RendererCanvasRender::Light, true> canvas_light_owner;
+ mutable RID_Owner<Canvas, true> canvas_owner;
+ RID_Owner<Item, true> canvas_item_owner;
+ RID_Owner<RendererCanvasRender::Light, true> canvas_light_owner;
bool disable_scale;
bool sdf_used = false;
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index 1653453c5c..b66b9b597c 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -903,6 +903,9 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
uint32_t flags = inst->base_flags; //fill flags if appropriate
+ if (inst->non_uniform_scale) {
+ flags |= INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE;
+ }
bool uses_lightmap = false;
bool uses_gi = false;
@@ -2594,6 +2597,8 @@ void RenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geome
//Fill push constant
+ ginstance->base_flags = 0;
+
bool store_transform = true;
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
@@ -2737,6 +2742,7 @@ void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p
float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z));
float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z));
+
ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9;
ginstance->lod_model_scale = max_scale;
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
index 579c8de05e..8fbe3935e8 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -184,6 +184,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
};
enum {
+ INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 5,
INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7,
INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
@@ -196,7 +197,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_SHIFT = 16,
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_MASK = 0xFF,
- INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 24,
};
struct SceneState {
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index ae09d215ff..fdcf4394a7 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -963,6 +963,10 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
uint32_t flags = inst->base_flags; //fill flags if appropriate
+ if (inst->non_uniform_scale) {
+ flags |= INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE;
+ }
+
bool uses_lightmap = false;
// bool uses_gi = false;
@@ -1995,6 +1999,7 @@ void RenderForwardMobile::_geometry_instance_update(GeometryInstance *p_geometry
//Fill push constant
bool store_transform = true;
+ ginstance->base_flags = 0;
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
index 99cbd45b10..35e62be281 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -390,6 +390,7 @@ protected:
// check which ones of these apply, probably all except GI and SDFGI
enum {
+ INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 5,
INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7,
INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
@@ -402,7 +403,6 @@ protected:
INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_SHIFT = 16,
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_MASK = 0xFF,
- INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 24,
};
struct GeometryInstanceLightmapSH {
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index b95647b8b7..a5a4b0e2d1 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -1234,7 +1234,7 @@ RID RendererStorageRD::canvas_texture_allocate() {
return canvas_texture_owner.allocate_rid();
}
void RendererStorageRD::canvas_texture_initialize(RID p_rid) {
- canvas_texture_owner.initialize_rid(p_rid, memnew(CanvasTexture));
+ canvas_texture_owner.initialize_rid(p_rid);
}
void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
@@ -2934,7 +2934,8 @@ RID RendererStorageRD::mesh_instance_create(RID p_base) {
Mesh *mesh = mesh_owner.getornull(p_base);
ERR_FAIL_COND_V(!mesh, RID());
- MeshInstance *mi = memnew(MeshInstance);
+ RID rid = mesh_instance_owner.make_rid();
+ MeshInstance *mi = mesh_instance_owner.getornull(rid);
mi->mesh = mesh;
@@ -2946,7 +2947,7 @@ RID RendererStorageRD::mesh_instance_create(RID p_base) {
mi->dirty = true;
- return mesh_instance_owner.make_rid(mi);
+ return rid;
}
void RendererStorageRD::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) {
MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance);
@@ -8657,8 +8658,6 @@ bool RendererStorageRD::free(RID p_rid) {
texture_owner.free(p_rid);
} else if (canvas_texture_owner.owns(p_rid)) {
- CanvasTexture *ct = canvas_texture_owner.getornull(p_rid);
- memdelete(ct);
canvas_texture_owner.free(p_rid);
} else if (shader_owner.owns(p_rid)) {
Shader *shader = shader_owner.getornull(p_rid);
@@ -8704,7 +8703,6 @@ bool RendererStorageRD::free(RID p_rid) {
mi->I = nullptr;
mesh_instance_owner.free(p_rid);
- memdelete(mi);
} else if (multimesh_owner.owns(p_rid)) {
_update_dirty_multimeshes();
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index ab470cb3a6..5de5593204 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -221,7 +221,7 @@ private:
~CanvasTexture();
};
- RID_PtrOwner<CanvasTexture, true> canvas_texture_owner;
+ RID_Owner<CanvasTexture, true> canvas_texture_owner;
/* TEXTURE API */
struct Texture {
@@ -513,7 +513,7 @@ private:
void _mesh_instance_clear(MeshInstance *mi);
void _mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint32_t p_surface);
- mutable RID_PtrOwner<MeshInstance> mesh_instance_owner;
+ mutable RID_Owner<MeshInstance> mesh_instance_owner;
SelfList<MeshInstance>::List dirty_mesh_instance_weights;
SelfList<MeshInstance>::List dirty_mesh_instance_arrays;
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
index e64e52623e..6599a42bab 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
@@ -52,6 +52,7 @@ layout(set = 0, binding = 1) uniform sampler material_samplers[12];
layout(set = 0, binding = 2) uniform sampler shadow_sampler;
+#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 5)
#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6)
#define INSTANCE_FLAGS_USE_SDFGI (1 << 7)
#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8)
@@ -66,8 +67,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler;
//3 bits of stride
#define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF
-#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 24)
-
layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights {
LightData data[];
}
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl
index 7fcd84695d..d4ebcbeec4 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl
@@ -51,6 +51,7 @@ layout(set = 0, binding = 1) uniform sampler material_samplers[12];
layout(set = 0, binding = 2) uniform sampler shadow_sampler;
+#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 5)
#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6)
#define INSTANCE_FLAGS_USE_SDFGI (1 << 7)
#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8)
@@ -65,8 +66,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler;
//3 bits of stride
#define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF
-#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 24)
-
layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights {
LightData data[];
}
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index e0d0ce76be..5aaecb83c4 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -43,7 +43,7 @@ RID RendererSceneCull::camera_allocate() {
return camera_owner.allocate_rid();
}
void RendererSceneCull::camera_initialize(RID p_rid) {
- camera_owner.initialize_rid(p_rid, memnew(Camera));
+ camera_owner.initialize_rid(p_rid);
}
void RendererSceneCull::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) {
@@ -310,7 +310,9 @@ RID RendererSceneCull::scenario_allocate() {
return scenario_owner.allocate_rid();
}
void RendererSceneCull::scenario_initialize(RID p_rid) {
- Scenario *scenario = memnew(Scenario);
+ scenario_owner.initialize_rid(p_rid);
+
+ Scenario *scenario = scenario_owner.getornull(p_rid);
scenario->self = p_rid;
scenario->reflection_probe_shadow_atlas = scene_render->shadow_atlas_create();
@@ -326,8 +328,6 @@ void RendererSceneCull::scenario_initialize(RID p_rid) {
scenario->instance_visibility.set_page_pool(&instance_visibility_data_page_pool);
RendererSceneOcclusionCull::get_singleton()->add_scenario(p_rid);
-
- scenario_owner.initialize_rid(p_rid, scenario);
}
void RendererSceneCull::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) {
@@ -422,10 +422,9 @@ RID RendererSceneCull::instance_allocate() {
return instance_owner.allocate_rid();
}
void RendererSceneCull::instance_initialize(RID p_rid) {
- Instance *instance = memnew(Instance);
+ instance_owner.initialize_rid(p_rid);
+ Instance *instance = instance_owner.getornull(p_rid);
instance->self = p_rid;
-
- instance_owner.initialize_rid(p_rid, instance);
}
void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) {
@@ -3818,10 +3817,7 @@ bool RendererSceneCull::free(RID p_rid) {
}
if (camera_owner.owns(p_rid)) {
- Camera *camera = camera_owner.getornull(p_rid);
-
camera_owner.free(p_rid);
- memdelete(camera);
} else if (scenario_owner.owns(p_rid)) {
Scenario *scenario = scenario_owner.getornull(p_rid);
@@ -3837,7 +3833,6 @@ bool RendererSceneCull::free(RID p_rid) {
scene_render->free(scenario->reflection_atlas);
scenario_owner.free(p_rid);
RendererSceneOcclusionCull::get_singleton()->remove_scenario(p_rid);
- memdelete(scenario);
} else if (RendererSceneOcclusionCull::get_singleton()->is_occluder(p_rid)) {
RendererSceneOcclusionCull::get_singleton()->free_occluder(p_rid);
@@ -3861,7 +3856,6 @@ bool RendererSceneCull::free(RID p_rid) {
update_dirty_instances(); //in case something changed this
instance_owner.free(p_rid);
- memdelete(instance);
} else {
return false;
}
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index 652d322731..e303f3c739 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -97,7 +97,7 @@ public:
}
};
- mutable RID_PtrOwner<Camera, true> camera_owner;
+ mutable RID_Owner<Camera, true> camera_owner;
virtual RID camera_allocate();
virtual void camera_initialize(RID p_rid);
@@ -345,7 +345,7 @@ public:
int indexer_update_iterations = 0;
- mutable RID_PtrOwner<Scenario, true> scenario_owner;
+ mutable RID_Owner<Scenario, true> scenario_owner;
static void _instance_pair(Instance *p_A, Instance *p_B);
static void _instance_unpair(Instance *p_A, Instance *p_B);
@@ -895,7 +895,7 @@ public:
uint32_t thread_cull_threshold = 200;
- RID_PtrOwner<Instance, true> instance_owner;
+ RID_Owner<Instance, true> instance_owner;
uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecessary on clustered
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 34bdb15c62..2cf4c035a9 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -122,7 +122,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport, uint32_t p_view_coun
}
}
- bool can_draw_3d = RSG::scene->is_camera(p_viewport->camera);
+ bool can_draw_3d = RSG::scene->is_camera(p_viewport->camera) && !p_viewport->disable_3d;
if (p_viewport->clear_mode != RS::VIEWPORT_CLEAR_NEVER) {
if (p_viewport->transparent_bg) {
@@ -630,15 +630,14 @@ RID RendererViewport::viewport_allocate() {
}
void RendererViewport::viewport_initialize(RID p_rid) {
- Viewport *viewport = memnew(Viewport);
+ viewport_owner.initialize_rid(p_rid);
+ Viewport *viewport = viewport_owner.getornull(p_rid);
viewport->self = p_rid;
viewport->hide_scenario = false;
viewport->hide_canvas = false;
viewport->render_target = RSG::storage->render_target_create();
viewport->shadow_atlas = RSG::scene->shadow_atlas_create();
viewport->viewport_render_direct_to_screen = false;
-
- viewport_owner.initialize_rid(p_rid, viewport);
}
void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
@@ -813,6 +812,13 @@ void RendererViewport::viewport_set_disable_environment(RID p_viewport, bool p_d
viewport->disable_environment = p_disable;
}
+void RendererViewport::viewport_set_disable_3d(RID p_viewport, bool p_disable) {
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->disable_3d = p_disable;
+}
+
void RendererViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -1085,7 +1091,6 @@ bool RendererViewport::free(RID p_rid) {
}
viewport_owner.free(p_rid);
- memdelete(viewport);
return true;
}
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index ffda9ad8f0..ca40829648 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -71,6 +71,7 @@ public:
bool hide_scenario;
bool hide_canvas;
bool disable_environment;
+ bool disable_3d = false;
bool measure_render_time;
bool snap_2d_transforms_to_pixel;
@@ -172,7 +173,7 @@ public:
uint64_t draw_viewports_pass = 0;
- mutable RID_PtrOwner<Viewport, true> viewport_owner;
+ mutable RID_Owner<Viewport, true> viewport_owner;
struct ViewportSort {
_FORCE_INLINE_ bool operator()(const Viewport *p_left, const Viewport *p_right) const {
@@ -220,6 +221,7 @@ public:
void viewport_set_hide_scenario(RID p_viewport, bool p_hide);
void viewport_set_hide_canvas(RID p_viewport, bool p_hide);
void viewport_set_disable_environment(RID p_viewport, bool p_disable);
+ void viewport_set_disable_3d(RID p_viewport, bool p_disable);
void viewport_attach_camera(RID p_viewport, RID p_camera);
void viewport_set_scenario(RID p_viewport, RID p_scenario);
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 16e9f1fc77..b9afeafbab 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -585,6 +585,7 @@ public:
FUNC2(viewport_set_hide_scenario, RID, bool)
FUNC2(viewport_set_hide_canvas, RID, bool)
FUNC2(viewport_set_disable_environment, RID, bool)
+ FUNC2(viewport_set_disable_3d, RID, bool)
FUNC2(viewport_attach_camera, RID, RID)
FUNC2(viewport_set_scenario, RID, RID)
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 594e2d885c..0a568eeb13 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -799,6 +799,7 @@ public:
virtual void viewport_set_hide_scenario(RID p_viewport, bool p_hide) = 0;
virtual void viewport_set_hide_canvas(RID p_viewport, bool p_hide) = 0;
virtual void viewport_set_disable_environment(RID p_viewport, bool p_disable) = 0;
+ virtual void viewport_set_disable_3d(RID p_viewport, bool p_disable) = 0;
virtual void viewport_attach_camera(RID p_viewport, RID p_camera) = 0;
virtual void viewport_set_scenario(RID p_viewport, RID p_scenario) = 0;