ObiSolver

The ObiSolver component is arguably the most important component in Obi. It is responsible for simulating particle physics and enforcing constraints. Three important things to remember about ObiSolver:

  • This component can be added to any GameObject in your scene (unless it has "simulate in local space" activated, see below), and there can be more than one ObiSolver working simultaneously in the same scene.
  • Every ObiActor needs to be included in an ObiSolver to get its simulation updated. Every ObiActor has a Solver property, to which you should assign the solver you want them to be included in.
  • Each ObiSolver is completely independent from other solvers. Therefore, actors being updated by different ObiSolvers won't interact / collide with each other. Only ObiActors in the same ObiSolver will react to each other.

Solver parameters

Max Particles

ObiSolver allocates memory for a particle pool, from which ObiActors will borrow particles when needed. This is the size of the pool, and thus the maximum amount of particles simulated by this solver. So for instance, if you have 5000 particles in the pool, and your actors consume 1000 particles each, you can have a maximum of 5 actors simulated by this solver.

Substeps

How many times will Obi be updated each physics step. The solver will subdivide each Unity physics step into multiple smaller substeps, increasing the accuracy of the solution. Increasing this value will result in more accurate simulations, but will adversely affect performance. A value of 1 should generally be used, resorting to 2,3,4 or higher if more accuracy is desired.

If you're using FixedUpdate simulation order, increasing the amount of substeps is equivalent to reducing Unity's fixed timestep (see Time Manager). For instance, a fixed timestep of 0.02 and 2 substeps = fixed timestep of 0.01 and 1 substep. However, reducing the timestep will affect both Unity's own physics engine as well as Obi. Using substepping lets you control the accuracy of Obi's simulation and Unity's own physics separately.

Simulate when invisible

Should this solver keep the simulation going when invisible to all cameras? Keep this enabled if your simulation needs to be updated at all times, disable it to improve performance when multiple solvers exist in the scene but they are not visible at all times.

Simulate in local space

If deactivated, the solver will perform the simulation in world space. This is the default behavior. If you enable this option, the solver will perform its simulation in local space, and each actor will be able to decide how much of the solver's world-space velocity should be applied to its particles. See world/local space for more info.

Simulation order

The solver can perform the simulation at different times during Unity's normal update cycle:

Fixed Update
This is the default. Updates particles during Unity's physics update, which is ideal for accurate simulation and two-way coupling with rigidbodies.
After Fixed Update
Updates particles after all GameObjects have ended their animation and physics update. Should be used when you want particles to react to rigidbodies or skeletal animations in the same frame.
Late Update
Updates particles in LateUpdate(). This is ideal when you have other scripts that manipulate scene transforms (such as IK or procedural animation scripts) and you need Obi to be aware of these changes before performing the particle simulations.

Mode

The solver can simulate in 2D or 3D mode. In 2D mode, simulation only happens in the XY plane.

Interpolation

Interpolation mode used to render particles. None is faster to calculate, but Interpolate will give more visually pleasing results.

Gravity

Direction and magnitude of gravity applied to particles in this solver.

Damping

Velocity damping applied to particle velocities. Increase it to reduce particle velocities over time.

Max Anisotropy

Particles in Obi can be ellipsoidal in shape, instead of perfectly spherical. This is used to better adapt their shape to the surface of the object they represent, achieving more accurate collision detection and smoother rendering. Max anistropy lets you determine the maximum ratio between the ellipsoid's radii: a value of 1 will force all particles to be spherical (deactivates anisotropy), values larger than 1 will allow particles to become more ellipsoidal the higher max anisotropy is.

fluid w/max anisotropy = 1
fluid w/max anisotropy = 3

Sleep threshold

Any particle with a kinetic energy below this value will be freezed in place. This is useful when you don´t want minuscule variations in velocity or force to perturb an actor, making it look like its jittering or moving very slowly. Set it to zero if you want your particles' positions to be affected by any force that acts upon them, however small it may be.

Constraints

Enable/disable constraints using the checkbox next to their name.

You can globally enable/disable each constraint type for all actors being managed by the solver. Disabling constraints this way (as opposed to disabling constraint components for individual actors) will allow the solver to completely skip any related calculations. This allows you to customize what's being done under the hood and get rid of unnecessary overhead.

Constraint parameters

ObiSolver exposes 4 parameters for each constraint type:

  • Enabled (checkbox right next to the name)
  • Iterations
  • Evaluation order
  • SOR Factor

Enabled

Are these constraints updated at all? By default all constraint types are enabled, altough this is rarely what you want for production-ready simulations. You should disable any constraints that are not critical for the final look of your simulation.

Iterations

How many times per substep should these constraints be evaluated? A high iteration count will keep the simulation closer to the ground-truth solution. Keep it low if these constraints aren`t very important for your particular purpose and you want to get better performance. The default is 3.

Evaluation order

This tells the solver in which order to evaluate the constraints of this kind. There are two modes:

  • In Sequential mode, all constraints are evaluated in the order they were created (which is determined by each specific ObiActor) and each constraint “sees” the adjustments made by all previous constraints. This ensures quick convergence, so your constraints will need few iterations to look good. However it is not very stable when several constraints are fighting for control, so there are some use-cases where this mode is not a good choice. For those of you a bit on the technical side, this is a Gauss-Seidel type of solver.

  • In Parallel mode, all constraints are evaluated but their adjustments are not immediately applied to the particles. Instead, they are stored, averaged, and then the final result is then used to adjust particle positions. This yields a very stable simulation even with lots of constraints applied at once, however more iterations are needed for “hard” constraints. Use this mode if you want to trade performance -with high iteration counts- or quality -with low iteration counts- for stability. Again, for technical users: this is Jacobi-like solving.

SOR Factor

SOR stands for Successive Over-Relaxation. When trying to satisfy constraints, one way to improve convergence is to “over-relax” the constraints. That is, if moving a particle 2 units to the left would satisfy the constraint for now, why not moving it 3 units? This is exactly what this factor is used for. 1 is the default value, which does not perform over-relaxation at all. 2 is the maximum, which allows you to perform twice as much relaxation on constraints. High values can be used to help speed up convergence in any of the two modes (sequential or parallel), but keep in mind that simulation stability can degrade.