24-11-2021, 06:43 AM
(This post was last modified: 24-11-2021, 06:44 AM by Chua Polar.)
(18-11-2021, 09:44 AM)josemendez Wrote: User data is intended to be used to store values that can vary wildly per-particle and change as a result of particle interaction, such as temperature, viscosity, color, etc.Nice and clean explanation!!Thanks for it.
Using it to store a "type" does not make sense, as many particles will share the exact same type (many "wine" particles, "lava", "water", etc) and there can be no intermediate values. Unity already contains a functionality for this: tags.
You can tag each emitter with the type of fluid it's emitting, then at runtime retrieve the type of a particle like this:
Code:var type = solver.particleInActor[particleIndex].actor.tag;
This way the "type" is stored once for all particles of the same type, instead of storing it for every single one.
FYI, the reason why there's only 4 user data channels is because 4 is the length of the SIMD registers used to perform vector operations. This means operating with pairs of user data with 4 components is very efficient. In addition to this we know the data for particle n is at n*4 in the data arrays, making memory access efficient too. Using a variable size for the amount of user data channels would make both accessing the data and operating with it considerably less efficient.
Note that if you really want extra per-particle storage, nothing prevents you from declaring an array of the same size as the emitter's capacity and store your own data there. It can be as simple as floating point values, or as complex as per-particle structs/classes.
The original purpose of these questions of mine is that I want to realize some chemical reaction in obi, yet there are still a few obstacles for now:
0. If I use a custom array to store info of particles, how should I synchronize it with the particle index? Like when a particle goes to sleep or a new particle is emitted, will the previous indices be messed up? Is there a method to tell me the order changing?
1. As you say I can use an emitter to store particles hence implying the particle type, however, it seems trouble to instantiate a single new particle from an emitter using the function Emit(). I learned that the Emit can only specify the distance from the emitting surface, is that so? And if I want to emit one particle at a specifically 3d position, what should I do? To move the emitter and use the distance? Or Emit one particle, grab its ref and modify its position? Or grab a particle ref from the emit idle pool, wake it up, init it and modify its position? And should I use lifetime=0 to sleep particles, is there any other ways?
2. I notice the diffusion data can be spread among neighbor particles, so do you use spatial query to realize that, the query you provided? I would like to query every little volume in a cup to check whether there are particles in the same volume that will trigger some reaction and update them. Can I realize it performancely just like the diffusion spreading?