diff --git a/scene/3d/physics/ray_cast_3d.cpp b/scene/3d/physics/ray_cast_3d.cpp index dc50ecccc0e..0cb722a77eb 100644 --- a/scene/3d/physics/ray_cast_3d.cpp +++ b/scene/3d/physics/ray_cast_3d.cpp @@ -41,7 +41,7 @@ void RayCast3D::set_target_position(const Vector3 &p_point) { if (is_inside_tree()) { _update_debug_shape_vertices(); } - } else if (debug_shape) { + } else if (debug_instance.is_valid()) { _update_debug_shape(); } } @@ -186,11 +186,17 @@ void RayCast3D::_notification(int p_what) { set_physics_process_internal(false); } - if (debug_shape) { + if (debug_instance.is_valid()) { _clear_debug_shape(); } } break; + case NOTIFICATION_VISIBILITY_CHANGED: { + if (is_inside_tree() && debug_instance.is_valid()) { + RenderingServer::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree()); + } + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (!enabled) { break; @@ -200,6 +206,9 @@ void RayCast3D::_notification(int p_what) { _update_raycast_state(); if (prev_collision_state != collided && get_tree()->is_debugging_collisions_hint()) { _update_debug_shape_material(true); + if (is_inside_tree() && debug_instance.is_valid()) { + RenderingServer::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); + } } } break; } @@ -416,7 +425,7 @@ void RayCast3D::set_debug_shape_thickness(const int p_debug_shape_thickness) { if (is_inside_tree()) { _update_debug_shape_vertices(); } - } else if (debug_shape) { + } else if (debug_instance.is_valid()) { _update_debug_shape(); } } @@ -448,13 +457,13 @@ const Color &RayCast3D::get_debug_shape_custom_color() const { void RayCast3D::_create_debug_shape() { _update_debug_shape_material(); - Ref mesh = memnew(ArrayMesh); + if (!debug_instance.is_valid()) { + debug_instance = RenderingServer::get_singleton()->instance_create(); + } - MeshInstance3D *mi = memnew(MeshInstance3D); - mi->set_mesh(mesh); - - add_child(mi); - debug_shape = mi; + if (debug_mesh.is_null()) { + debug_mesh = Ref(memnew(ArrayMesh)); + } } void RayCast3D::_update_debug_shape_material(bool p_check_collision) { @@ -494,19 +503,17 @@ void RayCast3D::_update_debug_shape() { return; } - if (!debug_shape) { + if (!debug_instance.is_valid()) { _create_debug_shape(); } - MeshInstance3D *mi = static_cast(debug_shape); - Ref mesh = mi->get_mesh(); - if (!mesh.is_valid()) { + if (!debug_instance.is_valid() || debug_mesh.is_null()) { return; } _update_debug_shape_vertices(); - mesh->clear_surfaces(); + debug_mesh->clear_surfaces(); Array a; a.resize(Mesh::ARRAY_MAX); @@ -516,32 +523,36 @@ void RayCast3D::_update_debug_shape() { if (!debug_line_vertices.is_empty()) { a[Mesh::ARRAY_VERTEX] = debug_line_vertices; - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); - mesh->surface_set_material(surface_count, debug_material); + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); + debug_mesh->surface_set_material(surface_count, debug_material); ++surface_count; } if (!debug_shape_vertices.is_empty()) { a[Mesh::ARRAY_VERTEX] = debug_shape_vertices; - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLE_STRIP, a, Array(), Dictionary(), flags); - mesh->surface_set_material(surface_count, debug_material); + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLE_STRIP, a, Array(), Dictionary(), flags); + debug_mesh->surface_set_material(surface_count, debug_material); ++surface_count; } + + RenderingServer::get_singleton()->instance_set_base(debug_instance, debug_mesh->get_rid()); + if (is_inside_tree()) { + RenderingServer::get_singleton()->instance_set_scenario(debug_instance, get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree()); + RenderingServer::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); + } } void RayCast3D::_clear_debug_shape() { - if (!debug_shape) { - return; + ERR_FAIL_NULL(RenderingServer::get_singleton()); + if (debug_instance.is_valid()) { + RenderingServer::get_singleton()->free(debug_instance); + debug_instance = RID(); } - - MeshInstance3D *mi = static_cast(debug_shape); - if (mi->is_inside_tree()) { - mi->queue_free(); - } else { - memdelete(mi); + if (debug_mesh.is_valid()) { + RenderingServer::get_singleton()->free(debug_mesh->get_rid()); + debug_mesh = Ref(); } - - debug_shape = nullptr; } RayCast3D::RayCast3D() { diff --git a/scene/3d/physics/ray_cast_3d.h b/scene/3d/physics/ray_cast_3d.h index 7b7f6981143..40f22236022 100644 --- a/scene/3d/physics/ray_cast_3d.h +++ b/scene/3d/physics/ray_cast_3d.h @@ -53,7 +53,6 @@ class RayCast3D : public Node3D { uint32_t collision_mask = 1; bool exclude_parent_body = true; - Node *debug_shape = nullptr; Ref debug_material; Color debug_shape_custom_color = Color(0.0, 0.0, 0.0); int debug_shape_thickness = 2; @@ -72,6 +71,9 @@ class RayCast3D : public Node3D { bool hit_from_inside = false; bool hit_back_faces = true; + RID debug_instance; + Ref debug_mesh; + protected: void _notification(int p_what); void _update_raycast_state(); diff --git a/scene/3d/physics/shape_cast_3d.cpp b/scene/3d/physics/shape_cast_3d.cpp index 5e6302cb81b..ada238c7f27 100644 --- a/scene/3d/physics/shape_cast_3d.cpp +++ b/scene/3d/physics/shape_cast_3d.cpp @@ -64,11 +64,17 @@ void ShapeCast3D::_notification(int p_what) { set_physics_process_internal(false); } - if (debug_shape) { + if (debug_instance.is_valid()) { _clear_debug_shape(); } } break; + case NOTIFICATION_VISIBILITY_CHANGED: { + if (is_inside_tree() && debug_instance.is_valid()) { + RenderingServer::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree()); + } + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (!enabled) { break; @@ -86,6 +92,9 @@ void ShapeCast3D::_notification(int p_what) { if (prev_collision_state == collided && !collided) { _update_debug_shape(); } + if (is_inside_tree() && debug_instance.is_valid()) { + RenderingServer::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); + } } } break; } @@ -217,7 +226,7 @@ void ShapeCast3D::set_target_position(const Vector3 &p_point) { if (is_inside_tree()) { _update_debug_shape_vertices(); } - } else if (debug_shape) { + } else if (debug_instance.is_valid()) { _update_debug_shape(); } } @@ -532,13 +541,13 @@ const Color &ShapeCast3D::get_debug_shape_custom_color() const { void ShapeCast3D::_create_debug_shape() { _update_debug_shape_material(); - Ref mesh = memnew(ArrayMesh); + if (!debug_instance.is_valid()) { + debug_instance = RenderingServer::get_singleton()->instance_create(); + } - MeshInstance3D *mi = memnew(MeshInstance3D); - mi->set_mesh(mesh); - - add_child(mi); - debug_shape = mi; + if (debug_mesh.is_null()) { + debug_mesh = Ref(memnew(ArrayMesh)); + } } void ShapeCast3D::_update_debug_shape_material(bool p_check_collision) { @@ -578,7 +587,7 @@ void ShapeCast3D::_update_debug_shape() { return; } - if (!debug_shape) { + if (!debug_instance.is_valid()) { _create_debug_shape(); } @@ -588,13 +597,11 @@ void ShapeCast3D::_update_debug_shape() { return; } - MeshInstance3D *mi = static_cast(debug_shape); - Ref mesh = mi->get_mesh(); - if (!mesh.is_valid()) { + if (!debug_instance.is_valid() || debug_mesh.is_null()) { return; } - mesh->clear_surfaces(); + debug_mesh->clear_surfaces(); Array a; a.resize(Mesh::ARRAY_MAX); @@ -604,30 +611,34 @@ void ShapeCast3D::_update_debug_shape() { if (!debug_shape_vertices.is_empty()) { a[Mesh::ARRAY_VERTEX] = debug_shape_vertices; - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); - mesh->surface_set_material(surface_count, debug_material); + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); + debug_mesh->surface_set_material(surface_count, debug_material); ++surface_count; } if (!debug_line_vertices.is_empty()) { a[Mesh::ARRAY_VERTEX] = debug_line_vertices; - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); - mesh->surface_set_material(surface_count, debug_material); + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); + debug_mesh->surface_set_material(surface_count, debug_material); ++surface_count; } + + RenderingServer::get_singleton()->instance_set_base(debug_instance, debug_mesh->get_rid()); + if (is_inside_tree()) { + RenderingServer::get_singleton()->instance_set_scenario(debug_instance, get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree()); + RenderingServer::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); + } } void ShapeCast3D::_clear_debug_shape() { - if (!debug_shape) { - return; + ERR_FAIL_NULL(RenderingServer::get_singleton()); + if (debug_instance.is_valid()) { + RenderingServer::get_singleton()->free(debug_instance); + debug_instance = RID(); } - - MeshInstance3D *mi = static_cast(debug_shape); - if (mi->is_inside_tree()) { - mi->queue_free(); - } else { - memdelete(mi); + if (debug_mesh.is_valid()) { + RenderingServer::get_singleton()->free(debug_mesh->get_rid()); + debug_mesh = Ref(); } - - debug_shape = nullptr; } diff --git a/scene/3d/physics/shape_cast_3d.h b/scene/3d/physics/shape_cast_3d.h index 9052db90469..19b73e3f722 100644 --- a/scene/3d/physics/shape_cast_3d.h +++ b/scene/3d/physics/shape_cast_3d.h @@ -55,7 +55,6 @@ class ShapeCast3D : public Node3D { bool collide_with_areas = false; bool collide_with_bodies = true; - Node *debug_shape = nullptr; Ref debug_material; Color debug_shape_custom_color = Color(0.0, 0.0, 0.0); Vector debug_shape_vertices; @@ -76,6 +75,9 @@ class ShapeCast3D : public Node3D { Array _get_collision_result() const; + RID debug_instance; + Ref debug_mesh; + protected: void _notification(int p_what); void _update_shapecast_state();