Page MenuHome

Cloth: improved collisions
ClosedPublic

Authored by Luca Rood (LucaRood) on Sep 20 2018, 3:52 PM.
Tokens
"Love" token, awarded by SteffenD."Love" token, awarded by Loner."Love" token, awarded by erickblender."Love" token, awarded by mano-wii.

Details

Summary

This patch includes several performance, stability, and reliability improvements to cloth collisions.

Changes included in this patch (could be broken into smaller commits if deemed necessary):

  • Fix several collision bugs.
    • Collisions caused cloth to be simulated twice per step, hurting performance, and accelerating cloth motion by a factor of two.
    • Collider objects were ignoring substeps, and instead being evaluated with the state at the end of the frame.
    • Several other smaller fixes.
  • Fix some mathematical mistakes.
  • Algorithmic improvements for both performance and stability/reliability.
    • Use static BVH overlap, to reduce false positives, as moving collisions are not computed anyway.
    • Apply all object collisions simultaneously, instead of sequentially, thus not favouring colliders later in the array over earlier ones.
  • Implement new self-collision model based on face contacts instead of vertex proximity.
  • Multithread collision detection.
  • Implement new collision point computation function, which is faster and better tailored to our collision system than the Bullet one (also removes Bullet dependency for cloth)
  • Implement single sided collisions, to prevent cloth from getting "stuck" inside the collider.
  • Implement normal overrides, forcing collision impulses to act in the direction of the collider normal (gives better results for some simulations)
  • Move friction to the collider settings, allowing a cloth to have different frictions with different colliders.
  • Remove repulses, as they were just a hack to deal with unreliable collisions.
  • Implement impulse clamping to prevent explosions from extreme collisions.

Diff Detail

Repository
rB Blender

Event Timeline

This sounds great, will review more closely later.

The two test files from T47195 seem to fail for me though, the cloth ends up falling through the collider.


The following test files seem to have correct collision, although the second once seems to take a long time to settle down. Maybe that's just different working settings.
https://developer.blender.org/diffusion/BL/browse/trunk/lib/tests/physics/clothtest.blend
https://developer.blender.org/diffusion/BL/browse/trunk/lib/tests/physics/continue_physics.blend

Thanks for looking at it, @Brecht Van Lommel (brecht).

As for those files, bug cloth.blend works for me. There is just an issue in 2.8, with caches not being cleared when loading files (technically they shouldn't even be saved in the first place), and it seems that that file contains an existing cache where the cloth goes through the collider. Simply switching to edit mode and back on the cloth mesh, should clear the cache, and then everything should work fine (this also applies to when you change cloth properties, as the cache is not being cleared).

The cloth.blend file is a bit more tricky, as it puts a lot of stress on a few collisions, so there is no way around it other than increasing the substeps (or collision quality, but that is still pushing it). The default of 5 is laughably low anyway, and perhaps I should change it to at least 10 or 20. Enabling single sided collisions on the collider can also help, though it will still be unstable with only 5 substeps. On that particular file I got reliable collisions at 10 substeps, but only got stable ones at 20, with the result being slightly better when single sided collisions are enabled.

And lastly, the continue_physics.blend file you mentioned shouldn't really settle, as far as I can see. It has a wind field, which should introduce oscillations. Even with the wind noise at zero, the fact that the net wind force depends on the normal of the cloth almost invariably induces oscillations (as in the real world).

If you found any further issues, please let me know, and I'll look into them. Regarding the cache clearing issue, I haven't had time to look into that yet. I also found that impulse clamping might not be working in this patch, so I'll have an update on that shortly.

Indeed I had a typo in impulse clamping, that caused it to be ignored. I fixed that now.

@Brecht Van Lommel (brecht), I forgot to mention, regarding continue_physics.blend not settling, there is another factor at play. The old collision system caused the cloth to be solved twice whenever collisions were found, and it applied both those solves to the cloth, causing it to move twice as fast, so that explains why you might see it settling sooner with the old system. Also, this should explain why more steps are needed to get reliable collisions in the cloth.blend file, as the old solver was effectively using twice as many steps (though the order in which collisions are applied is also a factor here, and I might actually revise the way I'm doing that).

Luca Rood (LucaRood) planned changes to this revision.Sep 22 2018, 12:07 AM

I found a couple of reliability issues, which I am looking into, and will get sorted ASAP. I'll update this patch as soon as I resolve these problems.

Luca Rood (LucaRood) edited the summary of this revision. (Show Details)

Sorted all the issues I had found.

@Brecht Van Lommel (brecht), you were right about cloth.blend, that file shouldn't fail. It turns out that compute_collision_point (my replacement for Bullet's plNearestPoints) had a little bug, that caused many relevant collisions to be thrown away. I was calling isect_line_line_v3, to find the closest points on two lines, but it turns out that the lines were often being considered coplanar, due to the function's pre-set epsilon. I replaced that with a direct call to isect_line_line_epsilon_v3, passing an epsilon of zero. This resolved the reliability issue.

Further, there was some instability being caused by my impulse clustering algorithm, and after some experimentation with different clustering algorithms, and no success in improving the results, I decided to scrap the idea altogether, and simply keep the existing axis based naive impulse pruning, which seems to give more stable results.

Lastly, I decided to move the collision detection and response evaluation to run after the implicit solver has solved for velocities. So now instead of computing positions->collisions->velocities->positions, we compute velocities->positions->collisions->positions (note that in both cases the second position computation is based on the old positions, so the two position computations don't accumulate). This order of evaluation has obvious reliability advantages, but surprisingly also seems to be more stable.

In short, all the changes since the last patch are:

  • Fixed compute_collision_point
  • Removed impulse clustering
  • Changed collision evaluation order
  • Added versioning to set default friction on colliders
  • Fixed a crash with self-collisions

Enabling Self Collision in the above cloth.blend seems to be extremely slow and the mesh "explodes".

I looked through the code and at a high level it all seems fine to me.

Brecht Van Lommel (brecht) requested changes to this revision.Sep 25 2018, 12:32 PM
This revision now requires changes to proceed.Sep 25 2018, 12:32 PM

Oh, right. That's because the self collision distance is even out of range for the new system. The new system uses actual distance for the self collision, while it was a factor for the old system, so the old default of 0.75 causes a huge amount of BVH overlap results, and makes everything collide. I'll just add versioning to bring that down to the new default.

Technically the self collision can still be unstable, if the distance is greater than the size of the polygons, so ideally the distance should be clamped by the size of the surrounding polygons, but that is a bit tricky as variable distance could not be accounted for at the BVH level, and it would be inefficient to clamp it afterwards when checking actual collisions.

For now, I'm hoping that just bringing the distance down in the versioning will suffice.

I have implemented the self collision distance versioning.

I also experimented with clamping the collision distance based on the size of the surrounding edges, but this had poor and unpredictable results, requiring a very small factor of the distance to be used, in order to be somewhat effective. And in the end, the clamping just ended up masking an issue that was still there. Because of this, I dropped the clamping, and the only change I made in this revision, was adding the versioning.

Ok, one last update... Hopefully...

Turns out there was a bug causing self collisions to be ignored when object collisions were enabled, but no collision object existed. This update fixes that.

Looks good to me now.

Can you add some better cloth tests to our test files? That we can use to verify collision and the other new features are working correctly.
https://developer.blender.org/diffusion/BL/browse/trunk/lib/tests/physics/

This revision is now accepted and ready to land.Sep 26 2018, 1:53 PM
This revision was automatically updated to reflect the committed changes.

@Brecht Van Lommel (brecht), thanks for all the helpful reviews! And sure, I'll compile some tests together, as soon as I can.