Integrate passive flex contact implicitly
Contact of a flex with `passive` collisions enabled was applied as an explicit spring of fixed stiffness 1e4, which the timestep bounds: any stiffness worth having oscillates faster than the step can resolve, so the force was too soft to keep sheets apart and interpenetration was routine. Carry its curvature in the effective metric M + K instead, alongside the flex's own stretch and bending stiffness. The contact block k*J^T*J is appended to the per-vertex candidate list already assembled for the flex stencils, so it costs additional entries in an existing matrix rather than a new one, and the accompanying shift -h*K*v is what damps the stiff modes. At a 2 ms timestep this holds roughly 50x the stiffness an explicit force of the same step could. With the timestep no longer setting the bound, the stiffness is chosen as a natural frequency scaled by the participating vertex mass rather than left at a fixed 1e4, so one value suits models of any scale. Passive handling is scoped to contacts whose every dof is a flex vertex carried by the metric: flex against flex, flex against itself, and flex against static geometry, which contributes no dofs of its own. For those the Hessian is assembled in full. Contact with a body that can move would have that body's dofs dropped from it, and is left on the constraint solver. The feature now requires an integrator whose constraint solve runs in that metric, and is rejected with an error otherwise. Add model/flex/drape.xml as the example model, replacing sphere_passive, whose contacts no longer demonstrated the feature.
This commit is contained in:
+18
-3
@@ -4550,9 +4550,24 @@ extensions specific to flexes.
|
||||
.. _flex-contact-passive:
|
||||
|
||||
:at:`passive`: :at-val:`[true, false], "false"`
|
||||
When enabled, the contact is not added to the contact solver but it is instead used to compute passive
|
||||
(spring-damper) contact forces. All contacts, regardless of the specified condim, are frictionless (condim 1). This
|
||||
is an experimental feature.
|
||||
When enabled, contact of this flex with another flex, with itself, or with static geometry is not added to the
|
||||
contact solver and is instead applied as a passive normal force. Contact with a body that can move is left on the
|
||||
constraint solver.
|
||||
|
||||
Friction is not modelled on this path: every passive contact is frictionless (condim 1) regardless of the
|
||||
specified condim, and the force is purely normal. A flex therefore slides freely over static geometry, so a cloth
|
||||
will not stay draped over a fixed shape and will not come to rest on a slope. Where friction matters more than
|
||||
non-penetration, leave this option off.
|
||||
|
||||
The force is a penalty on penetration depth whose stiffness is chosen as a natural frequency scaled by the
|
||||
participating vertex mass, so a single value is appropriate across model scales; it is not user-specified. That
|
||||
stiffness is integrated implicitly, its curvature being carried by the effective metric, and is therefore far
|
||||
stiffer than an explicit force at the same timestep could be. It follows that the feature requires an integrator
|
||||
whose constraint solve runs in that metric: :at:`implicit` or :at:`implicitfast` with the CG solver, pyramidal
|
||||
friction cones and sleep disabled. A model requesting passive flex collisions otherwise is rejected with an error.
|
||||
|
||||
Being a penalty force, it does not guarantee non-penetration: a thin flex moving fast enough to cross another
|
||||
within one step will pass through it. This is an experimental feature.
|
||||
|
||||
|
||||
.. _deformable-skin:
|
||||
|
||||
Reference in New Issue
Block a user