-
-
Notifications
You must be signed in to change notification settings - Fork 22.8k
SoftBody3D: process set_mesh() changes directly #108061
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This updates `MeshInstance3D::set_mesh()` to be a virtual method, so that `SoftBody3D` can override it. The `SoftBody3D` code always wants to replace the input mesh with a new unique mesh that is created with the `Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE` flag enabled, allowing it to dynamically modify the mesh and without affecting other users of the original resource. (However, it does not create a dynamic mesh in the editor, because it does want the original input mesh saved in the scene.) Previously, `SoftBody3D` did not override `set_mesh()`, and instead simply periodically checked to see if the `mesh` property had been modified and was different from the old value it remembered. It did this check at various points in time. Precisely when it would check the mesh depends on the object settings, whether the code is running in the editor or not, and these checks have moved around over time. In past releases it normally checked in a `frame_pre_draw` callback, but the recent physics interpolation logic changed it to check in `NOTIFICATION_INTERNAL_PHYSICS_PROCESS` instead. This behavior made it rather confusing to reason about when a `SoftBody3D` object would resync the physics state with the MeshInstance3D mesh, and when it would be out-of-date. Often in the editor it would not notice changes to the `mesh`, resulting in confusing behavior and bugs. This commit updates `SoftBody3D` to process `set_mesh()` calls directly, so it can never be in a state where it can no longer be out-of-sync with the parent MeshInstance3D state. This also fixes the code to check that the mesh is actually supported before allowing it to be set, and to correctly update editor warnings after the mesh is changed. Fixes godotengine#108036 and godotengine#108059.
191e789
to
05738d8
Compare
// The soft body physics simulation does not run in the editor, | ||
// so we do not create a dynamically modifiable mesh in this case. | ||
MeshInstance3D::set_mesh(p_mesh); | ||
update_configuration_warnings(); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one behavior change that I think is worth calling out here, in case anyone thinks it I should keep the old behavior:
After this commit, the code no longer calls PhysicsServer3D::get_singleton()->soft_body_set_mesh()
in the editor. The old code would call soft_body_set_mesh()
in the editor when processing NOTIFICATION_ENTER_WORLD
(although it would not update the physics server if the mesh changed in the future). The old code would pass in the original non-dynamic mesh as-is when running in the editor.
If desired I could update this code to still call soft_body_set_mesh()
when running in the editor here. As best as I can tell though, I don't believe this matters.
This updates
MeshInstance3D::set_mesh()
to be a virtual method, so thatSoftBody3D
can override it.The
SoftBody3D
code always wants to replace the input mesh with a new unique mesh that is created with theMesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE
flag enabled, allowing it to dynamically modify the mesh and without affecting other users of the original resource. (However, it does not create a dynamic mesh in the editor, because it does want the original input mesh saved in the scene.)Previously,
SoftBody3D
did not overrideset_mesh()
, and instead simply periodically checked to see if themesh
property had been modified and was different from the old value it remembered. It did this check at various points in time. Precisely when it would check the mesh depends on the object settings, whether the code is running in the editor or not, and these checks have moved around over time. In past releases it normally checked in aframe_pre_draw
callback, but the recent physics interpolation logic changed it to check inNOTIFICATION_INTERNAL_PHYSICS_PROCESS
instead.This behavior made it rather confusing to reason about when a
SoftBody3D
object would resync the physics state with the MeshInstance3D mesh, and when it would be out-of-date. Often in the editor it would not notice changes to themesh
, resulting in confusing behavior and bugs.This commit updates
SoftBody3D
to processset_mesh()
calls directly, so it can never be in a state where it can no longer be out-of-sync with the parent MeshInstance3D state.This also fixes the code to check that the mesh is actually supported before allowing it to be set, and to correctly update editor warnings after the mesh is changed.