diff options
Diffstat (limited to 'scene/3d/soft_dynamic_body_3d.cpp')
-rw-r--r-- | scene/3d/soft_dynamic_body_3d.cpp | 95 |
1 files changed, 47 insertions, 48 deletions
diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index a886c61263..903eedb58b 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -250,7 +250,7 @@ void SoftDynamicBody3D::_notification(int p_what) { RID space = get_world_3d()->get_space(); PhysicsServer3D::get_singleton()->soft_body_set_space(physics_rid, space); - prepare_physics_server(); + _prepare_physics_server(); } break; case NOTIFICATION_READY: { @@ -284,13 +284,13 @@ void SoftDynamicBody3D::_notification(int p_what) { case NOTIFICATION_DISABLED: { if (is_inside_tree() && (disable_mode == DISABLE_MODE_REMOVE)) { - prepare_physics_server(); + _prepare_physics_server(); } } break; case NOTIFICATION_ENABLED: { if (is_inside_tree() && (disable_mode == DISABLE_MODE_REMOVE)) { - prepare_physics_server(); + _prepare_physics_server(); } } break; @@ -378,7 +378,7 @@ void SoftDynamicBody3D::_bind_methods() { TypedArray<String> SoftDynamicBody3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); - if (get_mesh().is_null()) { + if (mesh.is_null()) { warnings.push_back(TTR("This body will be ignored until you set a mesh.")); } @@ -407,12 +407,19 @@ void SoftDynamicBody3D::_update_physics_server() { } void SoftDynamicBody3D::_draw_soft_mesh() { - if (get_mesh().is_null()) { + if (mesh.is_null()) { return; } - if (!rendering_server_handler.is_ready()) { - rendering_server_handler.prepare(get_mesh()->get_rid(), 0); + RID mesh_rid = mesh->get_rid(); + if (owned_mesh != mesh_rid) { + _become_mesh_owner(); + mesh_rid = mesh->get_rid(); + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, mesh_rid); + } + + if (!rendering_server_handler.is_ready(mesh_rid)) { + rendering_server_handler.prepare(mesh_rid, 0); /// Necessary in order to render the mesh correctly (Soft body nodes are in global space) simulation_started = true; @@ -429,63 +436,61 @@ void SoftDynamicBody3D::_draw_soft_mesh() { rendering_server_handler.commit_changes(); } -void SoftDynamicBody3D::prepare_physics_server() { +void SoftDynamicBody3D::_prepare_physics_server() { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - if (get_mesh().is_valid()) { - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()); + if (mesh.is_valid()) { + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, mesh->get_rid()); } else { - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, nullptr); + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, RID()); } return; } #endif - if (get_mesh().is_valid() && (is_enabled() || (disable_mode != DISABLE_MODE_REMOVE))) { - become_mesh_owner(); - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()); + if (mesh.is_valid() && (is_enabled() || (disable_mode != DISABLE_MODE_REMOVE))) { + RID mesh_rid = mesh->get_rid(); + if (owned_mesh != mesh_rid) { + _become_mesh_owner(); + mesh_rid = mesh->get_rid(); + } + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, mesh_rid); RS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh)); } else { - PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, nullptr); + PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, RID()); if (RS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh))) { RS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh)); } } } -void SoftDynamicBody3D::become_mesh_owner() { - if (mesh.is_null()) { - return; - } +void SoftDynamicBody3D::_become_mesh_owner() { + Vector<Ref<Material>> copy_materials; + copy_materials.append_array(surface_override_materials); - if (!mesh_owner) { - mesh_owner = true; + ERR_FAIL_COND(!mesh->get_surface_count()); - Vector<Ref<Material>> copy_materials; - copy_materials.append_array(surface_override_materials); + // Get current mesh array and create new mesh array with necessary flag for SoftDynamicBody + Array surface_arrays = mesh->surface_get_arrays(0); + Array surface_blend_arrays = mesh->surface_get_blend_shape_arrays(0); + Dictionary surface_lods = mesh->surface_get_lods(0); + uint32_t surface_format = mesh->surface_get_format(0); - ERR_FAIL_COND(!mesh->get_surface_count()); + surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; - // Get current mesh array and create new mesh array with necessary flag for SoftDynamicBody - Array surface_arrays = mesh->surface_get_arrays(0); - Array surface_blend_arrays = mesh->surface_get_blend_shape_arrays(0); - Dictionary surface_lods = mesh->surface_get_lods(0); - uint32_t surface_format = mesh->surface_get_format(0); + Ref<ArrayMesh> soft_mesh; + soft_mesh.instantiate(); + soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_lods, surface_format); + soft_mesh->surface_set_material(0, mesh->surface_get_material(0)); - surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; + set_mesh(soft_mesh); - Ref<ArrayMesh> soft_mesh; - soft_mesh.instantiate(); - soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_lods, surface_format); - soft_mesh->surface_set_material(0, mesh->surface_get_material(0)); - - set_mesh(soft_mesh); - - for (int i = copy_materials.size() - 1; 0 <= i; --i) { - set_surface_override_material(i, copy_materials[i]); - } + for (int i = copy_materials.size() - 1; 0 <= i; --i) { + set_surface_override_material(i, copy_materials[i]); } + + owned_mesh = soft_mesh->get_rid(); } void SoftDynamicBody3D::set_collision_mask(uint32_t p_mask) { @@ -547,16 +552,10 @@ void SoftDynamicBody3D::set_disable_mode(DisableMode p_mode) { return; } - bool inside_tree = is_inside_tree(); - - if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) { - prepare_physics_server(); - } - disable_mode = p_mode; - if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) { - prepare_physics_server(); + if (mesh.is_valid() && is_inside_tree() && !is_enabled()) { + _prepare_physics_server(); } } |