Obi Official Forum
Buoyancy diffusion not working - Printable Version

+- Obi Official Forum (https://obi.virtualmethodstudio.com/forum)
+-- Forum: Obi Users Category (https://obi.virtualmethodstudio.com/forum/forum-1.html)
+--- Forum: Obi Fluid (https://obi.virtualmethodstudio.com/forum/forum-3.html)
+--- Thread: Buoyancy diffusion not working (/thread-2683.html)



Buoyancy diffusion not working - Booyaka - 05-01-2021

I'm trying to change buoyancy for each particle to make them move upward.

I used user data and map Buoyancy to one of the slots, but when I change the value nothing happens to particles.

Here is part of my code:

Code:
void Start()
{
    solver.OnCollision += Solver_OnCollision;
    emitter.OnEmitParticle += Emitter_OnEmitParticle;
}


void Emitter_OnEmitParticle(ObiEmitter em, int particleIndex)
{
    int k = emitter.solverIndices[particleIndex];
    Vector4 userData = emitter.solver.userData[k];
    userData[0] = solver.buoyancies[k];
    emitter.solver.userData[k] = userData;
}


private void Solver_OnCollision(ObiSolver s, ObiSolver.ObiCollisionEventArgs e)
{
    var world = ObiColliderWorld.GetInstance();
    foreach (Oni.Contact contact in e.contacts)
    {

        if (contact.distance < 0.01f)
        {
            var col = world.colliderHandles[contact.other].owner;
            var userData = solver.userData[contact.particle];
                 
            if (evaporators[0].collider == col)
            {
                userData[0] = 0;
            }

            solver.userData[contact.particle] = userData;
        }
    }
}

Could you please help me?


RE: Buoyancy diffusion not working - josemendez - 05-01-2021

(05-01-2021, 11:40 AM)Booyaka Wrote: I'm trying to change buoyancy for each particle to make them move upward.

I used user data and map Buoyancy to one of the slots, but when I change the value nothing happens to particles.

Here is part of my code:

Code:
void Start()
{
    solver.OnCollision += Solver_OnCollision;
    emitter.OnEmitParticle += Emitter_OnEmitParticle;
}


void Emitter_OnEmitParticle(ObiEmitter em, int particleIndex)
{
    int k = emitter.solverIndices[particleIndex];
    Vector4 userData = emitter.solver.userData[k];
    userData[0] = solver.buoyancies[k];
    emitter.solver.userData[k] = userData;
}


private void Solver_OnCollision(ObiSolver s, ObiSolver.ObiCollisionEventArgs e)
{
    var world = ObiColliderWorld.GetInstance();
    foreach (Oni.Contact contact in e.contacts)
    {

        if (contact.distance < 0.01f)
        {
            var col = world.colliderHandles[contact.other].owner;
            var userData = solver.userData[contact.particle];
                 
            if (evaporators[0].collider == col)
            {
                userData[0] = 0;
            }

            solver.userData[contact.particle] = userData;
        }
    }
}

Could you please help me?

You don’t seem to write back any data to the buoyancies array, you’re just writing values to the userData array.

Check the Raclette sample scene for reference. You need to write the userData values back to the array you wish to use, in this case, the buoyancies array.


RE: Buoyancy diffusion not working - Booyaka - 05-01-2021

(05-01-2021, 07:47 PM)josemendez Wrote: You don’t seem to write back any data to the buoyancies array, you’re just writing values to the userData array.

Check the Raclette sample scene for reference. You need to write the userData values back to the array you wish to use, in this case, the buoyancies array.

I can't find the problem. Everything is just like "Melt" & "ViscositySurfTensionToUserData" scripts in Raclette sample.
Could you please mention it more precisely?

The weird thing is that the code will work for color but not any other parameters like viscosity, buoyancy, etc.


RE: Buoyancy diffusion not working - josemendez - 06-01-2021

This is what's happening in your script:

When you emit a new particle, you store its buoyancy value in userData.
When a particle hits a collider, you set its userData to 0.
(when particles are simulated by Obi, the contents of userData are diffused)
But you never do solver.buoyancies[k] = something. So ofc, buoyancy values are never actually set to the diffused values in userData.

In the Raclette sample scene, you'll see there's a "ColorFromViscosity" component added to the emitter. In its LateUpdate() method, color is driven by viscosity, then viscosity and surface tension are set to whatever values are in userData[k][0] and userData[k][1]. That's what maps the userData values to viscosity and surface tension and that's precisely what you're missing.

To make it clear, these are the steps required:

  1. buoyancy ---> userData (every time a particle is emitted)
  2. userData undergoes diffusion (during simulation, done automatically)
  3. userData ----> buoyancy (after simulation) // you're missing this one.

Anytime after the simulation has taken place (that is, after FixedUpdate()), you need to copy back from userData to buoyancies. LateUpdate() is a good place.


RE: Buoyancy diffusion not working - Booyaka - 06-01-2021

(06-01-2021, 08:18 AM)josemendez Wrote: This is what's happening in your script:

When you emit a new particle, you store its buoyancy value in userData.
When a particle hits a collider, you set its userData to 0.
(when particles are simulated by Obi, the contents of userData are diffused)
But you never do solver.buoyancies[k] = something. So ofc, buoyancy values are never actually set to the diffused values in userData.

In the Raclette sample scene, you'll see there's a "ColorFromViscosity" component added to the emitter. In its LateUpdate() method, color is driven by viscosity, then viscosity and surface tension are set to whatever values are in userData[k][0] and userData[k][1]. That's what maps the userData values to viscosity and surface tension and that's precisely what you're missing.

To make it clear, these are the steps required:

  1. buoyancy ---> userData (every time a particle is emitted)
  2. userData undergoes diffusion (during simulation, done automatically)
  3. userData ----> buoyancy (after simulation) // you're missing this one.

Anytime after the simulation has taken place (that is, after FixedUpdate()), you need to copy back from userData to buoyancies. LateUpdate() is a good place.

I added this code to my script and it works correctly


Code:
void LateUpdate()
{
    for (int i = 0; i < emitter.solverIndices.Length; ++i)
    {
        int k = emitter.solverIndices[i];
        emitter.solver.buoyancies[k] = emitter.solver.userData[k][0];
    }
}

Thank you so much!