Add functions to apply impulse and force to SoftBody on GodotPhysics and JoltPhysics
This commit is contained in:
@ -288,6 +288,34 @@ void JoltPhysicsServer3D::area_set_space(RID p_area, RID p_space) {
|
||||
area->set_space(space);
|
||||
}
|
||||
|
||||
void JoltPhysicsServer3D::soft_body_apply_point_impulse(RID p_body, int p_point_index, const Vector3 &p_impulse) {
|
||||
JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body);
|
||||
ERR_FAIL_NULL(body);
|
||||
|
||||
body->apply_vertex_impulse(p_point_index, p_impulse);
|
||||
}
|
||||
|
||||
void JoltPhysicsServer3D::soft_body_apply_point_force(RID p_body, int p_point_index, const Vector3 &p_force) {
|
||||
JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body);
|
||||
ERR_FAIL_NULL(body);
|
||||
|
||||
body->apply_vertex_force(p_point_index, p_force);
|
||||
}
|
||||
|
||||
void JoltPhysicsServer3D::soft_body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {
|
||||
JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body);
|
||||
ERR_FAIL_NULL(body);
|
||||
|
||||
body->apply_central_impulse(p_impulse);
|
||||
}
|
||||
|
||||
void JoltPhysicsServer3D::soft_body_apply_central_force(RID p_body, const Vector3 &p_force) {
|
||||
JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body);
|
||||
ERR_FAIL_NULL(body);
|
||||
|
||||
body->apply_central_force(p_force);
|
||||
}
|
||||
|
||||
RID JoltPhysicsServer3D::area_get_space(RID p_area) const {
|
||||
const JoltArea3D *area = area_owner.get_or_null(p_area);
|
||||
ERR_FAIL_NULL_V(area, RID());
|
||||
|
||||
@ -322,6 +322,11 @@ public:
|
||||
|
||||
virtual void soft_body_set_transform(RID p_body, const Transform3D &p_transform) override;
|
||||
|
||||
virtual void soft_body_apply_point_impulse(RID p_body, int p_point_index, const Vector3 &p_impulse) override;
|
||||
virtual void soft_body_apply_point_force(RID p_body, int p_point_index, const Vector3 &p_force) override;
|
||||
virtual void soft_body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) override;
|
||||
virtual void soft_body_apply_central_force(RID p_body, const Vector3 &p_force) override;
|
||||
|
||||
virtual void soft_body_set_simulation_precision(RID p_body, int p_precision) override;
|
||||
virtual int soft_body_get_simulation_precision(RID p_body) const override;
|
||||
|
||||
|
||||
@ -396,6 +396,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;
|
||||
|
||||
@ -166,4 +166,9 @@ public:
|
||||
void unpin_all_vertices();
|
||||
|
||||
bool is_vertex_pinned(int p_index) const;
|
||||
|
||||
void apply_vertex_impulse(int p_index, const Vector3 &p_impulse);
|
||||
void apply_vertex_force(int p_index, const Vector3 &p_force);
|
||||
void apply_central_impulse(const Vector3 &p_impulse);
|
||||
void apply_central_force(const Vector3 &p_force);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user