diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml index f422dbb1310..130cda73611 100644 --- a/doc/classes/PhysicsServer3D.xml +++ b/doc/classes/PhysicsServer3D.xml @@ -1157,6 +1157,13 @@ Returns the pressure coefficient of the given soft body. + + + + + Returns the shrinking factor of the given soft body. + + @@ -1294,6 +1301,14 @@ Sets whether the given soft body will be pickable when using object picking. + + + + + + Sets the shrinking factor of the given soft body. + + diff --git a/doc/classes/PhysicsServer3DExtension.xml b/doc/classes/PhysicsServer3DExtension.xml index e6d3c576d5c..fdc110d0be9 100644 --- a/doc/classes/PhysicsServer3DExtension.xml +++ b/doc/classes/PhysicsServer3DExtension.xml @@ -1079,6 +1079,12 @@ + + + + + + @@ -1196,6 +1202,13 @@ + + + + + + + diff --git a/doc/classes/SoftBody3D.xml b/doc/classes/SoftBody3D.xml index 241e3bb6b77..f6bfcdcb125 100644 --- a/doc/classes/SoftBody3D.xml +++ b/doc/classes/SoftBody3D.xml @@ -156,6 +156,10 @@ If [code]true[/code], the [SoftBody3D] will respond to [RayCast3D]s. + + Scales the rest lengths of [SoftBody3D]'s edge constraints. Positive values shrink the mesh, while negative values expand it. For example, a value of [code]0.1[/code] shortens the edges of the mesh by 10%, while [code]-0.1[/code] expands the edges by 10%. + [b]Note:[/b] [member shrinking_factor] is best used on surface meshes with pinned points. + Increasing this value will improve the resulting simulation, but can affect performance. Use with care. diff --git a/modules/godot_physics_3d/godot_physics_server_3d.cpp b/modules/godot_physics_3d/godot_physics_server_3d.cpp index 1fa92c81b29..d5f12857d9e 100644 --- a/modules/godot_physics_3d/godot_physics_server_3d.cpp +++ b/modules/godot_physics_3d/godot_physics_server_3d.cpp @@ -1132,6 +1132,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); diff --git a/modules/godot_physics_3d/godot_physics_server_3d.h b/modules/godot_physics_3d/godot_physics_server_3d.h index 407a97d0ae7..23c5d1b49ce 100644 --- a/modules/godot_physics_3d/godot_physics_server_3d.h +++ b/modules/godot_physics_3d/godot_physics_server_3d.h @@ -294,6 +294,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; diff --git a/modules/godot_physics_3d/godot_soft_body_3d.cpp b/modules/godot_physics_3d/godot_soft_body_3d.cpp index 3b9270b723b..9c82781c80c 100644 --- a/modules/godot_physics_3d/godot_soft_body_3d.cpp +++ b/modules/godot_physics_3d/godot_soft_body_3d.cpp @@ -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; } } @@ -861,6 +863,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); } @@ -918,6 +921,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; } diff --git a/modules/godot_physics_3d/godot_soft_body_3d.h b/modules/godot_physics_3d/godot_soft_body_3d.h index 8e6f49a60de..7b5d345a84c 100644 --- a/modules/godot_physics_3d/godot_soft_body_3d.h +++ b/modules/godot_physics_3d/godot_soft_body_3d.h @@ -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] @@ -194,6 +195,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; } diff --git a/modules/jolt_physics/jolt_physics_server_3d.cpp b/modules/jolt_physics/jolt_physics_server_3d.cpp index 6178ab5cf66..f197dec505e 100644 --- a/modules/jolt_physics/jolt_physics_server_3d.cpp +++ b/modules/jolt_physics/jolt_physics_server_3d.cpp @@ -1154,6 +1154,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); diff --git a/modules/jolt_physics/jolt_physics_server_3d.h b/modules/jolt_physics/jolt_physics_server_3d.h index 3f183fedf61..127210c7a2e 100644 --- a/modules/jolt_physics/jolt_physics_server_3d.h +++ b/modules/jolt_physics/jolt_physics_server_3d.h @@ -336,6 +336,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; diff --git a/modules/jolt_physics/objects/jolt_soft_body_3d.cpp b/modules/jolt_physics/objects/jolt_soft_body_3d.cpp index ae54f71b63c..089e66c2d26 100644 --- a/modules/jolt_physics/objects/jolt_soft_body_3d.cpp +++ b/modules/jolt_physics/objects/jolt_soft_body_3d.cpp @@ -197,6 +197,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++; @@ -500,6 +504,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; diff --git a/modules/jolt_physics/objects/jolt_soft_body_3d.h b/modules/jolt_physics/objects/jolt_soft_body_3d.h index 68b19fe7cb8..e1e49074474 100644 --- a/modules/jolt_physics/objects/jolt_soft_body_3d.h +++ b/modules/jolt_physics/objects/jolt_soft_body_3d.h @@ -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); diff --git a/scene/3d/physics/soft_body_3d.cpp b/scene/3d/physics/soft_body_3d.cpp index fc63836cb50..c3ee1c84531 100644 --- a/scene/3d/physics/soft_body_3d.cpp +++ b/scene/3d/physics/soft_body_3d.cpp @@ -352,6 +352,9 @@ void SoftBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness); ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness); + ClassDB::bind_method(D_METHOD("set_shrinking_factor", "shrinking_factor"), &SoftBody3D::set_shrinking_factor); + ClassDB::bind_method(D_METHOD("get_shrinking_factor"), &SoftBody3D::get_shrinking_factor); + ClassDB::bind_method(D_METHOD("set_pressure_coefficient", "pressure_coefficient"), &SoftBody3D::set_pressure_coefficient); ClassDB::bind_method(D_METHOD("get_pressure_coefficient"), &SoftBody3D::get_pressure_coefficient); @@ -382,6 +385,7 @@ void SoftBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shrinking_factor", PROPERTY_HINT_RANGE, "-1,1,0.01,or_less,or_greater"), "set_shrinking_factor", "get_shrinking_factor"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient"); @@ -648,6 +652,14 @@ real_t SoftBody3D::get_linear_stiffness() { return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid); } +void SoftBody3D::set_shrinking_factor(real_t p_shrinking_factor) { + PhysicsServer3D::get_singleton()->soft_body_set_shrinking_factor(physics_rid, p_shrinking_factor); +} + +real_t SoftBody3D::get_shrinking_factor() { + return PhysicsServer3D::get_singleton()->soft_body_get_shrinking_factor(physics_rid); +} + real_t SoftBody3D::get_pressure_coefficient() { return PhysicsServer3D::get_singleton()->soft_body_get_pressure_coefficient(physics_rid); } diff --git a/scene/3d/physics/soft_body_3d.h b/scene/3d/physics/soft_body_3d.h index 722b866eaa8..1eb10a6804c 100644 --- a/scene/3d/physics/soft_body_3d.h +++ b/scene/3d/physics/soft_body_3d.h @@ -164,6 +164,9 @@ public: void set_linear_stiffness(real_t p_linear_stiffness); real_t get_linear_stiffness(); + void set_shrinking_factor(real_t p_shrinking_factor); + real_t get_shrinking_factor(); + void set_pressure_coefficient(real_t p_pressure_coefficient); real_t get_pressure_coefficient(); diff --git a/servers/extensions/physics_server_3d_extension.cpp b/servers/extensions/physics_server_3d_extension.cpp index e1479967411..ca0423bb5eb 100644 --- a/servers/extensions/physics_server_3d_extension.cpp +++ b/servers/extensions/physics_server_3d_extension.cpp @@ -338,6 +338,9 @@ void PhysicsServer3DExtension::_bind_methods() { GDVIRTUAL_BIND(_soft_body_set_linear_stiffness, "body", "linear_stiffness"); GDVIRTUAL_BIND(_soft_body_get_linear_stiffness, "body"); + GDVIRTUAL_BIND(_soft_body_set_shrinking_factor, "body", "shrinking_factor"); + GDVIRTUAL_BIND(_soft_body_get_shrinking_factor, "body"); + GDVIRTUAL_BIND(_soft_body_set_pressure_coefficient, "body", "pressure_coefficient"); GDVIRTUAL_BIND(_soft_body_get_pressure_coefficient, "body"); diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h index 424e5c983a3..acc811fbca2 100644 --- a/servers/extensions/physics_server_3d_extension.h +++ b/servers/extensions/physics_server_3d_extension.h @@ -445,6 +445,9 @@ public: EXBIND2(soft_body_set_linear_stiffness, RID, real_t) EXBIND1RC(real_t, soft_body_get_linear_stiffness, RID) + EXBIND2(soft_body_set_shrinking_factor, RID, real_t) + EXBIND1RC(real_t, soft_body_get_shrinking_factor, RID) + EXBIND2(soft_body_set_pressure_coefficient, RID, real_t) EXBIND1RC(real_t, soft_body_get_pressure_coefficient, RID) diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 53aa516d572..7c907d66c32 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -876,6 +876,9 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("soft_body_set_linear_stiffness", "body", "stiffness"), &PhysicsServer3D::soft_body_set_linear_stiffness); ClassDB::bind_method(D_METHOD("soft_body_get_linear_stiffness", "body"), &PhysicsServer3D::soft_body_get_linear_stiffness); + ClassDB::bind_method(D_METHOD("soft_body_set_shrinking_factor", "body", "shrinking_factor"), &PhysicsServer3D::soft_body_set_shrinking_factor); + ClassDB::bind_method(D_METHOD("soft_body_get_shrinking_factor", "body"), &PhysicsServer3D::soft_body_get_shrinking_factor); + ClassDB::bind_method(D_METHOD("soft_body_set_pressure_coefficient", "body", "pressure_coefficient"), &PhysicsServer3D::soft_body_set_pressure_coefficient); ClassDB::bind_method(D_METHOD("soft_body_get_pressure_coefficient", "body"), &PhysicsServer3D::soft_body_get_pressure_coefficient); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index da0d0a36045..8c857f18432 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -607,6 +607,9 @@ public: virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) = 0; virtual real_t soft_body_get_linear_stiffness(RID p_body) const = 0; + virtual void soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) = 0; + virtual real_t soft_body_get_shrinking_factor(RID p_body) const = 0; + virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) = 0; virtual real_t soft_body_get_pressure_coefficient(RID p_body) const = 0; diff --git a/servers/physics_server_3d_dummy.h b/servers/physics_server_3d_dummy.h index c719ee638ac..55368c5d39a 100644 --- a/servers/physics_server_3d_dummy.h +++ b/servers/physics_server_3d_dummy.h @@ -341,6 +341,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 { return 0; } + 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 { return 0; } + 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 { return 0; } diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h index d9f0df971a0..bd5272ff2b9 100644 --- a/servers/physics_server_3d_wrap_mt.h +++ b/servers/physics_server_3d_wrap_mt.h @@ -309,6 +309,9 @@ public: FUNC2(soft_body_set_linear_stiffness, RID, real_t); FUNC1RC(real_t, soft_body_get_linear_stiffness, RID); + FUNC2(soft_body_set_shrinking_factor, RID, real_t); + FUNC1RC(real_t, soft_body_get_shrinking_factor, RID); + FUNC2(soft_body_set_pressure_coefficient, RID, real_t); FUNC1RC(real_t, soft_body_get_pressure_coefficient, RID);