Obi Official Forum
Random instantiating at old particle positions - 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: Random instantiating at old particle positions (/thread-3011.html)



Random instantiating at old particle positions - corel - 06-07-2021

Hi,

I've been trying to simulate an evaporation/destruction event when fluids touch certain surfaces, where the obi fluid particle position is used to instantiate a particle effect that matches the fluid colour. In general this is just a collider check, wait until particle has sat on surface longer than a given time, then take position and colour, instantiate smoke and kill particle. This works at first but it quickly results in the smoke effect spawning randomly in previously used locations, immediately on particle contact, which I feel may be the result of the particle ID numbers being reused. When I separate all of the actual emitter.life = 0 events into a separate foreach loop at the end of the collision event by making a list of the affected particles after the smoke effects should have been completed I still see the same behaviour. I have attached the trimmed down code as an example. 

Any help would be most appreciated!

Code:
    void Solver_OnCollision (object sender, Obi.ObiSolver.ObiCollisionEventArgs e)
    {
        var world = ObiColliderWorld.GetInstance();


        foreach (Oni.Contact contact in e.contacts)
        {        

            if (contact.distance < 0.001)
            {
                ObiColliderBase collider = world.colliderHandles[contact.bodyB].owner;
                
                if (collider != null)
                {
                    

                    if(collider.tag == "Evaporate"){

                Vector4 userDataUpdate = solver.userData[contact.bodyA];

                userDataUpdate[0] = userDataUpdate[0] +  Time.fixedDeltaTime;

                solver.userData[contact.bodyA] = userDataUpdate;


                if (userDataUpdate[0] > evapTimer){

                ObiSolver.ParticleInActor pa = solver.particleToActor[solver.simplices[contact.bodyA]];

                ObiEmitter emitter1 = pa.actor as ObiEmitter;

                Transform emitterTransform = emitter1.transform;

                Vector3 particlePosition = solver.positions[contact.bodyA];


        GameObject smoke = Instantiate(evaporationSmoke, particlePosition, Quaternion.identity);

        Material smokeMat = smoke.GetComponent<ParticleSystemRenderer>().material;

            smokeMat.SetVector("SmokeColor", solver.colors[contact.bodyA]);

        emitter1.life[pa.indexInActor] =  0f;

    }



RE: Random instantiating at old particle positions - josemendez - 07-07-2021

Hi there!

Your code is mixing up particle and simplex indices. All data arrays in the solver must be acessed using particle indices. For instance, you're accessing the particleToActor array using a particle index:

Code:
solver.particleToActor[solver.simplices[contact.bodyA]];

Which is correct. But you're accessing the positions array using a simplex index:

Code:
Vector3 particlePosition = solver.positions[contact.bodyA];

Which will return essentially random data. contact.bodyA is always a simplex index. You can retrieve the particle index like this:

Code:
int particleIndex = solver.simplices[contact.bodyA];

Then use this index to access positions, velocities, userData, particleToActor, or any other array in the solver. For instance:
Code:
int particleIndex = solver.simplices[contact.bodyA];
Vector3 particlePosition = solver.positions[particleIndex];

See:
http://obi.virtualmethodstudio.com/manual/6.2/scriptingcollisions.html


RE: Random instantiating at old particle positions - corel - 08-07-2021

(07-07-2021, 08:19 AM)josemendez Wrote: Hi there!

Your code is mixing up particle and simplex indices. All data arrays in the solver must be acessed using particle indices. For instance, you're accessing the particleToActor array using a particle index:

Code:
solver.particleToActor[solver.simplices[contact.bodyA]];

Which is correct. But you're accessing the positions array using a simplex index:

Code:
Vector3 particlePosition = solver.positions[contact.bodyA];

Which will return essentially random data. contact.bodyA is always a simplex index. You can retrieve the particle index like this:

Code:
int particleIndex = solver.simplices[contact.bodyA];

Then use this index to access positions, velocities, userData, particleToActor, or any other array in the solver. For instance:
Code:
int particleIndex = solver.simplices[contact.bodyA];
Vector3 particlePosition = solver.positions[particleIndex];

See:
http://obi.virtualmethodstudio.com/manual/6.2/scriptingcollisions.html

Thanks so much!