Posts: 18
Threads: 1
Joined: Nov 2020
Reputation:
0
Hi, im developing a game, and i would like to implement an interaction between to fluids (fluid A and fluid B, the particles destroy each other when in contact). I saw a thread that said fluid particles cant detect collision directly, they have to detect it by vorticity or temperature... How do you set it up so that each particle has differnt temperature? And how would a script that destroys them "onCollision" look like?
Thank you.
Posts: 6,326
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
19-11-2020, 12:50 PM
(This post was last modified: 19-11-2020, 12:54 PM by josemendez.)
(19-11-2020, 12:40 PM)JoseCarlos S Wrote: Hi, im developing a game, and i would like to implement an interaction between to fluids (fluid A and fluid B, the particles destroy each other when in contact). I saw a thread that said fluid particles cant detect collision directly, they have to detect it by vorticity or temperature... How do you set it up so that each particle has differnt temperature? And how would a script that destroys them "onCollision" look like?
Thank you.
Hi there,
I think you're mixing up concepts here.
Fluid particles interact with each other using a kernel or support function. A kernel is basically an area around each particle, where density (amount of particles per volume unit) is measured. If there are too many particles within the kernel, which means local density is too high, a repulsion force ( pressure) is applied to all particles around the center particle in order to decrease density. If there are too few particles, an attractive force is applied to increase local density. That's how fluid maintains constant density, which is what makes fluid behave like fluid.
Because of this, particles do not collide with each other, because they're not solid. They interact via constraining density within each kernel.
Vorticity and temperature have nothing to do with this. Vorticity measures how "swirly" the fluid is at a point, and temperature measures well, temperature. They play no part in particle interaction whatsoever.
Since you can't access particle kernels directly, you will need a way to know if a particle has neighbors that belong to a different type of fluid. You can use the diffusion data channels for this. Each fluid blueprint has 4 channels of diffusion data that you can give any meaning to. These values will be averaged between particles inside a kernel, so if you give fluid A a diffusion value of (1,0,0,0) and fluid B a value of (0,0,0,0), at runtime you know that any particle with a value other than these (for instance, 0.5,0,0,0) it must be destroyed because it has been within the kernel of particle of the opposite type.
You can check the FluidMixing or Raclette sample scenes for some examples on how you can use the diffusion channels. In FluidMixing, the diffusion channels are used to drive a color gradient. In Raclette, they're used to drive fluid viscosity and color.
I hope this makes sense, fluid simulation is quite complex and can have a steep learning curve at the start.
Posts: 18
Threads: 1
Joined: Nov 2020
Reputation:
0
(19-11-2020, 12:50 PM)josemendez Wrote: Hi there,
I think you're mixing up concepts here.
Fluid particles interact with each other using a kernel or support function. A kernel is basically an area around each particle, where density (amount of particles per volume unit) is measured. If there are too many particles within the kernel, which means local density is too high, a repulsion force (pressure) is applied to all particles around the center particle in order to decrease density. If there are too few particles, an attractive force is applied to increase local density. That's how fluid maintains constant density, which is what makes fluid behave like fluid.
Because of this, particles do not collide with each other, because they're not solid. They interact via constraining density within each kernel.
Vorticity and temperature have nothing to do with this. Vorticity measures how "swirly" the fluid is at a point, and temperature measures well, temperature. They play no part in particle interaction whatsoever.
Since you can't access particle kernels directly, you will need a way to know if a particle has neighbors that belong to a different type of fluid. You can use the diffusion data channels for this. Each fluid blueprint has 4 channels of diffusion data that you can give any meaning to. These values will be averaged between particles inside a kernel, so if you give fluid A a diffusion value of (1,0,0,0) and fluid B a value of (0,0,0,0), at runtime you know that any particle with a value other than these (for instance, 0.5,0,0,0) it must be destroyed because it has been within the kernel of particle of the opposite type.
You can check the FluidMixing or Raclette sample scenes for some examples on how you can use the diffusion channels. In FluidMixing, the diffusion channels are used to drive a color gradient. In Raclette, they're used to drive fluid viscosity and color.
I hope this makes sense, fluid simulation is quite complex and can have a steep learning curve at the start.
Hi, first of all, do you speak spanish aswell? XD
The diffusion data channels are edited in the inspector or by code? I´ve tried using the sample scene codes to make a particle destroying script (instead of destroying it sets particles lifespan to 0) but had no success. The fluidmixing interaction is what i look for (with particles disapearing instead of changing color) but im not able to get a working script... What part of the fluid mixing script do i have to change in order to get the interaction i need?
Thanks for the quick reply!
Posts: 6,326
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
19-11-2020, 02:18 PM
(This post was last modified: 19-11-2020, 02:18 PM by josemendez.)
(19-11-2020, 01:57 PM)JoseCarlos S Wrote: Hi, first of all, do you speak spanish aswell? XD
Yep . You can write to support(at)virtualmethodstudio.com and we can speak spanish over there if you wish.
(19-11-2020, 01:57 PM)JoseCarlos S Wrote: The diffusion data channels are edited in the inspector or by code?
As any particle property, they can be set either way. Easiest method is to just select your blueprint asset and set the diffusion data values in the inspector.
(19-11-2020, 01:57 PM)JoseCarlos S Wrote: I´ve tried using the sample scene codes to make a particle destroying script (instead of destroying it sets particles lifespan to 0) but had no success. The fluidmixing interaction is what i look for (with particles disapearing instead of changing color) but im not able to get a working script... What part of the fluid mixing script do i have to change in order to get the interaction i need?
Well, you need to change pretty much the entire fluid mixing script xD, as it's just an example. You should call emitter.KillParticle() passing the emitter particle index whenever you find a particle with non-starting diffusion data. Will write a sample script for you as soon as I can.
Posts: 18
Threads: 1
Joined: Nov 2020
Reputation:
0
(19-11-2020, 02:18 PM)josemendez Wrote: Yep . You can write to support(at)virtualmethodstudio.com and we can speak spanish over there if you wish.
As any particle property, they can be set either way. Easiest method is to just select your blueprint asset and set the diffusion data values in the inspector.
Well, you need to change pretty much the entire fluid mixing script xD, as it's just an example. You should call emitter.KillParticle() passing the emitter particle index whenever you find a particle with non-starting diffusion data. Will write a sample script for you as soon as I can. Hi, i didn´t find the spanish volg on the website you linked (It says i dont have permision on the blog)...could you pass me the complete link? How is the sample script going?
Thanks!
Posts: 6,326
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
(19-11-2020, 06:42 PM)JoseCarlos S Wrote: Hi, i didn´t find the spanish volg on the website you linked (It says i dont have permision on the blog)...could you pass me the complete link? How is the sample script going?
Thanks!
Hi,
I didn't link to any website and I don't keep any vlog . I did share an email address: support(at)virtualmethodstudio.com. We can talk in spanish over there.
It's simply for not mixing up multiple languages in the forums, where most people would expect to read english only.
Here's the script. Just add it to the ObiSolver component in the FluidMixing sample scene, and you should see blue and yellow particles disappear as soon as they touch each other. I've commented the script to make it clear what each line does.
Code: using UnityEngine;
using Obi;
[RequireComponent(typeof(ObiSolver))]
public class KillFluidOnContact : MonoBehaviour
{
ObiSolver solver;
void Awake()
{
solver = GetComponent<ObiSolver>();
}
void LateUpdate()
{
if (!isActiveAndEnabled)
return;
// iterate over all particles in the solver, looking for particles
// that have had their diffusion data altered by contact with other particles.
for (int i = 0; i < solver.particleToActor.Length; ++i)
{
// if this particle is part of an actor,
if (solver.particleToActor[i] != null)
{
// if the "user" (aka diffusion) data is not either (1,0,0,0) or (0,0,0,0)
if (solver.userData[i].x < 0.9f && solver.userData[i].x > 0.1f)
{
// take a reference to the emitter that the particle belongs to, and kill it.
var emitter = solver.particleToActor[i].actor as ObiEmitter;
emitter.KillParticle(solver.particleToActor[i].indexInActor);
}
}
}
}
}
Posts: 18
Threads: 1
Joined: Nov 2020
Reputation:
0
20-11-2020, 01:00 PM
(This post was last modified: 20-11-2020, 01:11 PM by JoseCarlos S.)
[attachment=812 Wrote:
josemendez pid='8245' dateline='1605863505']
Hi,
I didn't link to any website and I don't keep any vlog . I did share an email address: support(at)virtualmethodstudio.com. We can talk in spanish over there.
It's simply for not mixing up multiple languages in the forums, where most people would expect to read english only.
Here's the script. Just add it to the ObiSolver component in the FluidMixing sample scene, and you should see blue and yellow particles disappear as soon as they touch each other. I've commented the script to make it clear what each line does.
Code: using UnityEngine;
using Obi;
[RequireComponent(typeof(ObiSolver))]
public class KillFluidOnContact : MonoBehaviour
{
ObiSolver solver;
void Awake()
{
solver = GetComponent<ObiSolver>();
}
void LateUpdate()
{
if (!isActiveAndEnabled)
return;
// iterate over all particles in the solver, looking for particles
// that have had their diffusion data altered by contact with other particles.
for (int i = 0; i < solver.particleToActor.Length; ++i)
{
// if this particle is part of an actor,
if (solver.particleToActor[i] != null)
{
// if the "user" (aka diffusion) data is not either (1,0,0,0) or (0,0,0,0)
if (solver.userData[i].x < 0.9f && solver.userData[i].x > 0.1f)
{
// take a reference to the emitter that the particle belongs to, and kill it.
var emitter = solver.particleToActor[i].actor as ObiEmitter;
emitter.KillParticle(solver.particleToActor[i].indexInActor);
}
}
}
}
}
Nice! And if i wanted to kill both particles? Okay, didnt realize it was an email adress, thought there was a spanish forum, ill mail you my next questions (wich i promise ill have a few.... ). But lets finish this thread here, so people can find it and maybe help them.
On the sample it works perfectly, but on my own ObiSolver i get this fatal Error:
Thanks!
Posts: 6,326
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
20-11-2020, 01:22 PM
(This post was last modified: 20-11-2020, 01:25 PM by josemendez.)
(20-11-2020, 01:00 PM)JoseCarlos S Wrote: Nice! And if i wanted to kill both particles?
This script already kills both particles when they come into contact.
(20-11-2020, 01:00 PM)JoseCarlos S Wrote: On the sample it works perfectly, but on my own ObiSolver i get this fatal Error:
This is a compilation error. The error says you're trying to pass an object of type "ObiEmitter" into the emitter's KillParticle() method, which can only take a particle index (an integer) as argument, hence the code does not make sense to the compiler. This is not what the original script does, did you modify it?
Posts: 18
Threads: 1
Joined: Nov 2020
Reputation:
0
(20-11-2020, 01:22 PM)josemendez Wrote: This script already kills both particles when they come into contact.
This is a compilation error. The error says you're trying to pass an object of type "ObiEmitter" into the emitter's KillParticle() method, which can only take a particle index (an integer) as argument, hence the code does not make sense to the compiler. This is not what the original script does, did you modify it?
In the sample scene, only the blue particles got killed (or at least only yellow particles remaind..ill check, maybe not all particles came in contact). I didnt change the script, tried it first on the sample scene, worked, then on my scene (with my solvers) didnt work. Is it posible its my solvers/emitters problem?
Thanks!
Posts: 6,326
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
20-11-2020, 01:53 PM
(This post was last modified: 20-11-2020, 02:04 PM by josemendez.)
(20-11-2020, 01:47 PM)JoseCarlos S Wrote: In the sample scene, only the blue particles got killed (or at least only yellow particles remaind..ill check, maybe not all particles came in contact).
In my case, both blue and yellow particles are killed when in contact with each other. Don't see how it could be otherwise, as diffusion is symmetric: diffusion data is averaged for every particle pair, so if two particles with different diffusion data come in close proximity, they'd both modify their diffusion data, and get removed from the emitter.
(20-11-2020, 01:47 PM)JoseCarlos S Wrote: I didnt change the script, tried it first on the sample scene, worked, then on my scene (with my solvers) didnt work. Is it posible its my solvers/emitters problem?
This is a compilation error, so it will happen regardless of what scene(s) in the project it is used in. The error says:
Quote:ObiEmitter does not contain a definition for "KillParticle" and no accessible extension method "KillParticle" accepting a first argument of type "ObiEmitter" could be found.
So, the compiler can't find a KillParticle() method that accepts a ObiEmitter as argument. The original script is passing an integer (solver.particleToActor[i].indexInActor), thus the only possible way to trigger this error would be to write:
Code: emitter.KillParticle(emitter);
which ofc does not make any sense. Are you positive that the script isn't modified in any way? Another possibility is that you're using an older version of Obi that does not contain the KillParticle() method.
Obi is aimed at advanced users so it assumes you're familiar with at least basic scripting/programming. If you're not, you have a really steep learning curve ahead :/.
|