Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Solver.OnParticleCollision not work + mix 3 color
#1
Hi, im working on a project that currently using obi fluid 5.3

1. As i follow tutorial with collision callback, i noticed that solver.OnParticleCollision not work as i expect.
- ObiSolver.ObiCollisionEventArgs alway return with count = 0.
- I already change emitter A and B with difference phase (1 & 2) still not work

2.Im checking your mixing color scene, i saw that it use field "x" in diffusion data, it running from 0 - 1 and revert.

- Is this value update auto by obi ?
- I want to mix 3 or more color, how can i use this data to receive infomation i need ?

Thanks !
Reply
#2
1.- solver.OnParticleCollision returns collisions between particles. If you're emitting fluids, you will always get zero contacts as fluid particles do not collide with each other. Fluids use density constraints to try and keep constant local density. If they collided, you'd get granular (sand) simulation instead. From the manual:

Quote:Density constraints

Each density constraint tries to keep the amount of mass in the neighborhood around a particle constant. This will push out particles getting too close (as that would increase the mass) and pull in particles going away (which results in surface tension effects). Used to simulate fluids. High iteration counts will make the fluid more incompressible, so it will behave less like jelly.

2.- Diffusion works by averaging diffusion data between neighboring particles. There's 4 diffusion channels: x,y,z and w. You can use each one to average one "property" of the fluid, which one is up to you. Could be color, viscosity, vorticity, or any other.

For instance, the "Raclette" sample scene maps "x" to viscosity, and "y" to surface tension.

To mix two colors, you can use a single diffusion channel and lerp (linearly interpolate) between the two colors based on the value of the channel. To mix many colors (3,4,5...), the easiest way is to use the x,y,z diffusion channels to store color r,g,b, and use them directly. This way you can have as many colors as you want.
Reply
#3
"use the x,y,z diffusion channels to store color r,g,b"

As i understand, i need to loop through all particles, get it rgb value, then set it back to userdata ?

then other particle will receive this userdata, calculate new color ?

I don't really understand this userdata, it store current particle's value ? or store value of particle next to it ?
Reply
#4
All per-particle data arrays (position, velocity, color, userData, etc) store a value for each particle. So userData[i] is the data for particle i, not any of its neighbors.

During the simulation, each particle averages its userData with the neighboring particles via density constraints, that's how diffusion is implemented.

So all you need to do is set the desired color of each fluid type in the diffusion data (userData) or the blueprint, then at runtime iterate over all particles and set color[i] = userData[i] at the end of every frame. That's all there is to it. Let me know if you need help writing the code for this.
Reply
#5
Triste 
I'm not sure if i got it right, but it not working so well  Huh

First of all, i using 2 emitters, 2 blueprints

Then i put color data into userdata when particle emit
Code:
private void _actor_OnEmitParticle(ObiEmitter emitter, int particleIndex)
    {
        if (emitter.solver != null)
        {
            int k = emitter.solverIndices[particleIndex];

            Vector4 userData = emitter.solver.userData[k];

            userData[0] = emitter.solver.colors[k].r;
            userData[1] = emitter.solver.colors[k].g;
            userData[2] = emitter.solver.colors[k].b;

            emitter.solver.userData[k] = userData;
        }
    }

After that, i set color in LateUpdate
Code:
private void LateUpdate()
    {
        for (int i = 0; i < _actor.solverIndices.Length; ++i)
        {

            int k = _actor.solverIndices[i];

            Vector4 userData = _actor.solver.userData[k];

            _actor.solver.colors[k] = new Color(userData[0], userData[1], userData[2]);
        }
    }

Nvm, i figure it out now.

My code is working fine, but color field in "Obi Particle Renderer" component mess it up, after set it back to "White", it look good now !

Btw, thanks for your help, great asset but lack of documents  Gran sonrisa

I think you should update document with these info, that'll be great !  Corazón
Reply