Skip to content

Commit 7be272e

Browse files
committed
SoftBody3D's position influences its physics in Jolt
The position of a soft body was always kept at identity. This introduced computational errors when moving the soft body away from the origin. Translation is now stored in the soft body's position rather than in its vertices. Fixes godotengine#112348
1 parent cb3af5a commit 7be272e

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

modules/jolt_physics/objects/jolt_soft_body_3d.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ void JoltSoftBody3D::_space_changing() {
7777
// Note that we should not use `in_space()` as the condition here, since we could have cleared the mesh at this point.
7878
if (jolt_body != nullptr) {
7979
jolt_settings = new JPH::SoftBodyCreationSettings(jolt_body->GetSoftBodyCreationSettings());
80+
jolt_settings->mPosition = JPH::RVec3::sZero(); // We'll be getting the vertices in world space when we re-insert the body so we need to reset the position here.
8081
jolt_settings->mSettings = nullptr;
8182
jolt_settings->mVertexRadius = JoltProjectSettings::soft_body_point_radius;
8283
}
@@ -341,7 +342,7 @@ JoltSoftBody3D::JoltSoftBody3D() :
341342
JoltObject3D(OBJECT_TYPE_SOFT_BODY) {
342343
jolt_settings->mRestitution = 0.0f;
343344
jolt_settings->mFriction = 1.0f;
344-
jolt_settings->mUpdatePosition = false;
345+
jolt_settings->mUpdatePosition = true;
345346
jolt_settings->mMakeRotationIdentity = false;
346347
}
347348

@@ -606,11 +607,16 @@ void JoltSoftBody3D::set_transform(const Transform3D &p_transform) {
606607
// We also discard any scaling, since we have no way of scaling the actual edge lengths.
607608
const JPH::Mat44 relative_transform = to_jolt(p_transform.orthonormalized());
608609

610+
// The translation delta goes to the body's position to avoid vertices getting too far away from it.
611+
JPH::BodyInterface &body_iface = space->get_body_iface();
612+
body_iface.SetPosition(jolt_body->GetID(), jolt_body->GetPosition() + relative_transform.GetTranslation(), JPH::EActivation::DontActivate);
613+
614+
// The rotation difference goes to the vertices. We also reset the velocity of these vertices.
609615
JPH::SoftBodyMotionProperties &motion_properties = static_cast<JPH::SoftBodyMotionProperties &>(*jolt_body->GetMotionPropertiesUnchecked());
610616
JPH::Array<JPH::SoftBodyVertex> &physics_vertices = motion_properties.GetVertices();
611617

612618
for (JPH::SoftBodyVertex &vertex : physics_vertices) {
613-
vertex.mPosition = vertex.mPreviousPosition = relative_transform * vertex.mPosition;
619+
vertex.mPosition = vertex.mPreviousPosition = relative_transform.Multiply3x3(vertex.mPosition);
614620
vertex.mVelocity = JPH::Vec3::sZero();
615621
}
616622
wake_up();
@@ -672,11 +678,12 @@ void JoltSoftBody3D::update_rendering_server(PhysicsServer3DRenderingServerHandl
672678
}
673679

674680
const int mesh_vertex_count = shared->mesh_to_physics.size();
681+
const JPH::RVec3 body_position = jolt_body->GetCenterOfMassPosition();
675682

676683
for (int i = 0; i < mesh_vertex_count; ++i) {
677684
const int physics_index = shared->mesh_to_physics[i];
678685
if (physics_index >= 0) {
679-
const Vector3 vertex = to_godot(physics_vertices[(size_t)physics_index].mPosition);
686+
const Vector3 vertex = to_godot(body_position + physics_vertices[(size_t)physics_index].mPosition);
680687
const Vector3 normal = normals[(uint32_t)physics_index];
681688

682689
p_rendering_server_handler->set_vertex(i, vertex);

0 commit comments

Comments
 (0)