SoftBody3D: Add a property for scaling rest lengths of edge constraints

This commit is contained in:
Elzewyr 2025-05-12 19:33:39 +03:00
parent 0d8f33a74a
commit 9f67bf96fa
19 changed files with 126 additions and 0 deletions

View file

@ -1104,6 +1104,20 @@ real_t GodotPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) const {
return soft_body->get_linear_stiffness();
}
void GodotPhysicsServer3D::soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) {
GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);
ERR_FAIL_NULL(soft_body);
soft_body->set_shrinking_factor(p_shrinking_factor);
}
real_t GodotPhysicsServer3D::soft_body_get_shrinking_factor(RID p_body) const {
GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);
ERR_FAIL_NULL_V(soft_body, 0.f);
return soft_body->get_shrinking_factor();
}
void GodotPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) {
GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body);
ERR_FAIL_NULL(soft_body);

View file

@ -289,6 +289,9 @@ public:
virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override;
virtual real_t soft_body_get_linear_stiffness(RID p_body) const override;
virtual void soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) override;
virtual real_t soft_body_get_shrinking_factor(RID p_body) const override;
virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) override;
virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override;

View file

@ -272,8 +272,10 @@ void GodotSoftBody3D::update_area() {
}
void GodotSoftBody3D::reset_link_rest_lengths() {
float multiplier = 1.0 - shrinking_factor;
for (Link &link : links) {
link.rl = (link.n[0]->x - link.n[1]->x).length();
link.rl *= multiplier;
link.c1 = link.rl * link.rl;
}
}
@ -837,6 +839,7 @@ void GodotSoftBody3D::append_link(uint32_t p_node1, uint32_t p_node2) {
link.n[0] = node1;
link.n[1] = node2;
link.rl = (node1->x - node2->x).length();
link.rl *= 1.0 - shrinking_factor;
links.push_back(link);
}
@ -894,6 +897,10 @@ void GodotSoftBody3D::set_linear_stiffness(real_t p_val) {
linear_stiffness = p_val;
}
void GodotSoftBody3D::set_shrinking_factor(real_t p_val) {
shrinking_factor = p_val;
}
void GodotSoftBody3D::set_pressure_coefficient(real_t p_val) {
pressure_coefficient = p_val;
}

View file

@ -95,6 +95,7 @@ class GodotSoftBody3D : public GodotCollisionObject3D {
int iteration_count = 5;
real_t linear_stiffness = 0.5; // [0,1]
real_t shrinking_factor = 0.0; // [-1,1]
real_t pressure_coefficient = 0.0; // [-inf,+inf]
real_t damping_coefficient = 0.01; // [0,1]
real_t drag_coefficient = 0.0; // [0,1]
@ -191,6 +192,9 @@ public:
void set_linear_stiffness(real_t p_val);
_FORCE_INLINE_ real_t get_linear_stiffness() const { return linear_stiffness; }
void set_shrinking_factor(real_t p_val);
_FORCE_INLINE_ real_t get_shrinking_factor() const { return shrinking_factor; }
void set_pressure_coefficient(real_t p_val);
_FORCE_INLINE_ real_t get_pressure_coefficient() const { return pressure_coefficient; }

View file

@ -1126,6 +1126,20 @@ real_t JoltPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) const {
return (real_t)body->get_stiffness_coefficient();
}
void JoltPhysicsServer3D::soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) {
JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body);
ERR_FAIL_NULL(body);
return body->set_shrinking_factor((float)p_shrinking_factor);
}
real_t JoltPhysicsServer3D::soft_body_get_shrinking_factor(RID p_body) const {
JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body);
ERR_FAIL_NULL_V(body, 0.0);
return (real_t)body->get_shrinking_factor();
}
void JoltPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_coefficient) {
JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body);
ERR_FAIL_NULL(body);

View file

@ -331,6 +331,9 @@ public:
virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_coefficient) override;
virtual real_t soft_body_get_linear_stiffness(RID p_body) const override;
virtual void soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) override;
virtual real_t soft_body_get_shrinking_factor(RID p_body) const override;
virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_coefficient) override;
virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override;

View file

@ -202,6 +202,10 @@ bool JoltSoftBody3D::_ref_shared_data() {
vertex_attrib.mCompliance = vertex_attrib.mShearCompliance = inverse_stiffness;
settings.CreateConstraints(&vertex_attrib, 1, JPH::SoftBodySharedSettings::EBendType::None);
float multiplier = 1.0f - shrinking_factor;
for (JPH::SoftBodySharedSettings::Edge &e : settings.mEdgeConstraints) {
e.mRestLength *= multiplier;
}
settings.Optimize();
} else {
iter_shared_data->value.ref_count++;
@ -454,6 +458,14 @@ void JoltSoftBody3D::set_stiffness_coefficient(float p_coefficient) {
stiffness_coefficient = CLAMP(p_coefficient, 0.0f, 1.0f);
}
float JoltSoftBody3D::get_shrinking_factor() const {
return shrinking_factor;
}
void JoltSoftBody3D::set_shrinking_factor(float p_shrinking_factor) {
shrinking_factor = p_shrinking_factor;
}
void JoltSoftBody3D::set_pressure(float p_pressure) {
if (unlikely(pressure == p_pressure)) {
return;

View file

@ -64,6 +64,7 @@ class JoltSoftBody3D final : public JoltObject3D {
float pressure = 0.0f;
float linear_damping = 0.01f;
float stiffness_coefficient = 0.5f;
float shrinking_factor = 0.0f;
int simulation_precision = 5;
@ -138,6 +139,9 @@ public:
float get_stiffness_coefficient() const;
void set_stiffness_coefficient(float p_coefficient);
float get_shrinking_factor() const;
void set_shrinking_factor(float p_shrinking_factor);
float get_pressure() const { return pressure; }
void set_pressure(float p_pressure);