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.
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 is PolygonCollider2D.
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.
Rope particles colliding with a cube, from left to right: thickness = 0.1, thickness = 0, thickness = -0.05
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 component allows Obi particles to interact with 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.
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!).
To make an actor collide with itself, just enable the "self-collisions" checkbox in its inspector.
Once you´ve set up collisions, your solver will begin generating collision constraints for particles. Obi uses a collision detection paradigm known as "speculative contacts". This means contact constraints can be generated before any actual collision has taken place between particles, or between colliders and particles. Thanks to this, collisions are accounted for before they actually happen, 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" 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.
Once a collision constraint ceases to be an speculative contact and becomes an actual contact (both objects are really in touch with each other), the collision must be resolved in some way. How is it resolved depends on what ObiCollisionMaterials you particles and colliders are using. All Obi actors (cloth, ropes, etc) have a "Material" property that lets you specify which ObiCollisionMaterial will be used by all of that actor's particles. You can also assign collision materials to ObiColliders.
ObiCollisionMaterials are assets, just like Unity's PhysicMaterials. You can right click in your project folders, and select Create->Obi->ObiCollisionMaterial. Here's the material inspector:
In the image above, the red arrow represents the particle's velocity upon collision. This velocity is split in two components: one along the contact normal, and one along the contact tangent. The blue arrow represents the force applied to the particle to cancel its normal velocity, which is always fully applied. The purple arrow is the friction force, which removes a percentage of the tangential velocity component (in the image, 100% of it). The green arrow is the stickiness force.
Heavy ball falling on a very sticky piece of cloth.
Regular contacts (both particle-particle and particle-collider) treat particles as simple positions in space, so they won't cause particles to rotate. This simplification allows for very cheap collision response, as only linear velocities are considered. However, you can choose to perform full contact resolution taking angular velocities and particle orientations into account by enabling rolling contacts in the contact material.
If you enable rolling contacts for a collision material, a new parameter "rolling friction" will appear. Rolling friction acts by appling a torque that opposes the angular velocity of the particles involved in a contact. In real life, perfectly spherical particles would never stop rolling on an inclined plane. However, particles with an irregular surface (such as rocks or pebbles) would stop rolling after a while, due to the unevenness of their surface. This is what rolling friction strives to simulate.
Shock propagation is a technique that alters 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.