Collisions

Cloth colliding with terrain and some boxes.

Most of the time, you will want your particles to be able to collide with and react to other elements in your scene: walls, floor, crates, and whatnot. They can also collide with each other! These two types of collisions (against colliders and against other particles) can be controlled independently in Obi. Everything in this section applies to all Obi actors (cloth, ropes, fluid emitters, etc) so it's a quite important topic.

Setting up colliders

Add a ObiCollider component to any collider in your scene to make it work with Obi. You can add this component to SphereColliders, MeshColliders, BoxColliders... pretty much all standard Unity colliders, both 3D and 2D. The only collider type not currently supported by Obi are PolygonCollider2D and TilemapCollider2D.

At the beginning of each simulation step, solvers will generate collision constraints for all their particles based on what colliders are spatially close to them.

Sometimes you want certain actors, or even only some specific particles to ignore a particular collider. You can use phases for this. Each ObiCollider has a "Collision phase" property, and particles have a "Phase" channel that you can set using the blueprint editor. Only colliders and particles of different phases will collide. Colliders and particles of the same phase will ignore each other. By default, ObiColliders are in phase 0 and particles in phase 1, so they will collide right away.


ObiColliders also allow you to set their collision material and their thickness. Positive thickness values will leave a gap between the collider surface and colliding particles. Negative values will cause particles to "sink" into the collider before actually hitting its surface.

thickness: 0.75
thickness: 0
thickness: -0.05

Rigidbodies

When you add an ObiCollider component to an object, it will look for the first Rigidbody component up its hierarchy and attach an ObiRigidbody component to it. This allows for full two-way coupled interaction between Obi particles and rigidbodies. If you delete this component, Obi will recreate it automatically the next time you hit "Play".


ObiRigidbody only has one parameter: "Kinematic for particles". Enabling this shields the rigidbody from any forces applied by particles, so it will behave as if no Obi particles were present in the scene. The particles will still "feel" the rigidbody and collide with it, though.

Intercollisions

ObiActors will collide with each other if their particles have different phases, provided that they're both simulated by the same ObiSolver. Particles simulated by different solvers cannot interact with each other, which means actors in different solvers won´t be able to collide with each other.

For instance: if you wish cloth A and cloth B to collide with each other, set A's particles to phase 2, and B's particles to phase 3 (or any other phase except 2!).

Self collisions

To make an actor collide with itself, just enable the "self-collisions" checkbox in its inspector.

Surface collisions

Obi 6.0 and up allows you to use surface-based collision detection on a per-actor basis, which is more accurate than particle-based. To use it, all you need to do is enable the "surface collisions" checbox in your actor's inspector. For details, see: surface collisions.

How it works

Obi's collision pipeline is split into 3 steps: the broadphase, where objects (colliders, simplices or particles) are tested for rough spatial proximity. The narrowphase, where potentially colliding pairs generated by the broadphase are processed and contacts are generated. And finally, collision projection, where the trajectories of simplices/particles/rigidbodies involved in each contact are adjusted to prevent collision.

You can adjust various parameters of the collision pipeline in the solver settings. These will affect how the bounding boxes for particles and colliders are built, and how contacts are generated.

Broadphase: the bounding boxes of a moving particle and a static collider overlap, so they will be again tested in the narrowphase.
Narrowphase: the particle velocity will take it inside the collider if we don't do anything to prevent it, so a collision constraint (in black) is generated.
Projection: the collision constraint corrects the predicted position of the particle, and its velocity is adjusted accordingly.

Collision constraints

Once you´ve set up collisions, your solver will begin generating collision constraints (aka contacts) for particles, using the 3 steps outlined above. Obi uses a collision detection paradigm known as "speculative contacts". This means contacts will be generated before any actual collision has taken place between particles, or between colliders and particles. Thanks to this, the trajectory of particles in collision course are corrected before the collision actually takes place, and tunneling issues (the well known bullet-trough-paper problem existing in most collision engines) are almost non-existant. Contacts are detected and resolved even at high speeds. Also, TOI (time of impact) ordering is not needed if several collisions happen in the same frame.

Some contacts never cease to be "speculative", they do not progress past the broadphase and they're never actually resolved. Some others eventually progress to a real collision, and collision resolution takes place.

Several contacts can be generated for a given particle in the same frame. Then, speculative contacts must be accounted for and then resolved if they turn out to be actual collisions. However, resolving contacts sequentially (one after another) can unfortunately cause previously resolved contacts to become collisions again. See the following diagram: In step 1, two speculative contacts are generated because according to the orange particle's current velocity, it is almost certain it will collide with the grey collider in the next frame. In step 2, both speculative contacts progress to actual collisions that must be resolved. Step 3 shows how the right collision is resolved first. In step 4 we resolve the left one, but this causes penetration for the right one again. We must solve the right collision a second time (step 5) to ensure no penetration happens for either contact.



All this right, left, right, left... iterative solving causes visual jittering, as we see the particle jump between two configurations until all collisions are resolved (which can take a very high amount of iterations). For this reason, Obi lets you decide (as it does with all constraint groups) how collisions must be resolved: sequentially or in parallel. In parallel mode, all contacts are resolved independently in the same step (as if the others did not exist) and the final correction is calculated as an average of all their individual results. This increases stablity (removing jittering due to unresolved collisions) but decreases convergence speed (achieving zero-penetration takes more iterations) making collisions seem too "soft" when using low iteration counts. See the next diagram:



General rule of thumb: If multiple collisions can happen at once in your scene and jittering is an issue, set your collision constraints evaluation order to "parallel". If jittering is not a problem and/or you need faster convergence, use "sequential" evaluation order. There are separate controls for particle-particle collisions and particle-collider collisions, so you can use different methods for each of them. You can find this settings in the ObiSolver inspector, under "Particle Collision Constraint Parameters" and "Collision Constraint Parameters":



See ObiSolver for more info on sequential vs parallel solving.

Sequential and parallel contact resolution comparison, using just 3 iterations and medium friction. Jittering has been artifically increased to illustrate the differences better.

Shock propagation

Shock propagation is a technique that modifies particle masses internally during contact resolution, so that particles at the bottom of a pile have higher effective mass that the ones at the top. This results in faster convergence and stabler stacking. You can find this parameter in the ObiSolver inspector, it is applied globally per-solver. Use this when you need an extra "oomph" for your particle-particle contacts, specially when creating piles of granular material.