Merge pull request #100463 from PiCode9560/softbody-apply-force-and-impulse

Add ability to apply forces and impulses to `SoftBody3D`
This commit is contained in:
Thaddeus Crews 2025-05-26 11:24:45 -05:00
commit de2cd663fd
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
19 changed files with 303 additions and 0 deletions

View file

@ -391,6 +391,57 @@ bool JoltSoftBody3D::is_sleeping() const {
}
}
void JoltSoftBody3D::apply_vertex_impulse(int p_index, const Vector3 &p_impulse) {
ERR_FAIL_COND_MSG(!in_space(), vformat("Failed to apply impulse to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
ERR_FAIL_NULL(shared);
ERR_FAIL_INDEX(p_index, (int)shared->mesh_to_physics.size());
const size_t physics_index = (size_t)shared->mesh_to_physics[p_index];
ERR_FAIL_COND_MSG(pinned_vertices.has(physics_index), vformat("Failed to apply impulse to point at index %d for '%s'. Point was found to be pinned.", static_cast<int>(physics_index), to_string()));
JPH::SoftBodyMotionProperties &motion_properties = static_cast<JPH::SoftBodyMotionProperties &>(*jolt_body->GetMotionPropertiesUnchecked());
JPH::Array<JPH::SoftBodyVertex> &physics_vertices = motion_properties.GetVertices();
JPH::SoftBodyVertex &physics_vertex = physics_vertices[physics_index];
physics_vertex.mVelocity += to_jolt(p_impulse) * physics_vertex.mInvMass;
wake_up();
}
void JoltSoftBody3D::apply_vertex_force(int p_index, const Vector3 &p_force) {
ERR_FAIL_COND_MSG(!in_space(), vformat("Failed to apply force to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
apply_vertex_impulse(p_index, p_force * space->get_last_step());
}
void JoltSoftBody3D::apply_central_impulse(const Vector3 &p_impulse) {
ERR_FAIL_COND_MSG(!in_space(), vformat("Failed to apply central impulse to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
ERR_FAIL_NULL(shared);
JPH::SoftBodyMotionProperties &motion_properties = static_cast<JPH::SoftBodyMotionProperties &>(*jolt_body->GetMotionPropertiesUnchecked());
JPH::Array<JPH::SoftBodyVertex> &physics_vertices = motion_properties.GetVertices();
const JPH::Vec3 impulse = to_jolt(p_impulse) / physics_vertices.size();
for (JPH::SoftBodyVertex &physics_vertex : physics_vertices) {
if (physics_vertex.mInvMass > 0.0f) {
physics_vertex.mVelocity += impulse * physics_vertex.mInvMass;
}
}
wake_up();
}
void JoltSoftBody3D::apply_central_force(const Vector3 &p_force) {
ERR_FAIL_COND_MSG(!in_space(), vformat("Failed to apply central force to '%s'. Doing so without a physics space is not supported when using Jolt Physics. If this relates to a node, try adding the node to a scene tree first.", to_string()));
ERR_FAIL_NULL(shared);
JPH::BodyInterface &body_iface = space->get_body_iface();
body_iface.AddForce(jolt_body->GetID(), to_jolt(p_force), JPH::EActivation::Activate);
}
void JoltSoftBody3D::set_is_sleeping(bool p_enabled) {
if (!in_space()) {
return;