...
Particle shifting can also be done with the new "Container" emitter and "Filter" daemon. With this built-in and ready-to-use combination you can achieve the same effect, but sometimes it is better to implement the transition from one emitter to another with a script:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
# Type this part to Simulation Events > Scene > ScenePre
# Initialize the container emitter before starting the simulation
source_emitter = scene.get_PB_Emitter("Source")
source_resolution = source_emitter.getParameter("Resolution")
container_emitter = scene.get_PB_Emitter("Container")
container_emitter.setParameter("Interpolation", "Local")
container_emitter.setParameter("Resolution",source_resolution)
container_emitter.setParameter("Speed", 0.0)
# Write this part to Simulation Events > Steps > StepsPre
velocity_threshold = 3.0
source_emitter = scene.get_PB_Emitter("Source")
container_emitter = scene.get_PB_Emitter("Container")
source_particle = source_emitter.getFirstParticle()
while (source_particle):
source_particle_vel = source_particle.getVelocity()
source_particle_magnitude = source_particle_vel.module()
source_particle_id = source_particle.getId()
if (source_particle_magnitude >= velocity_threshold):
source_particle_pos = source_particle.getPosition()
container_emitter.addParticle(source_particle_pos,source_particle_vel)
source_emitter.removeParticle(source_particle_id)
source_particle = source_particle.getNextParticle() |
...
Now, what is going on here? The basic structure and syntax should already be familiar, though there are few new functions. The very first part initializes the container emitter. You may remember that it is crucial that both emitters share equal resolution and the container’s speed must be 0.0. Equalizing the resolution is a pretty easy task, but it is recommended to change interpolation to local, as you perform a change of resolution. The script just reads out the resolution value from the source emitter and uses the result for the container. Resetting speed to 0.0 is even simpler, because you just have to set the parameter to the desired value. Here it would also be possible to insert an “if”-condition:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
container_emitter_speed = container_emitter.getParameter("Speed") if (container_emitter_speed != 0.0): container_emitter.setParameter("Speed", 0.0) |
...
This means that if the container emitter’s speed is not 0.0 then you need to reset it. This query is not really necessary here, but similar constructions might be useful for other tasks where you have to reset speed or other parameters, or limit them to a certain value. The second part of the script is executed during a time step. First you have to find a certain threshold value. This threshold triggers the particle’s transition to the container emitter. The next step is a basic loop through all of the source emitter’s particles. As long as there are particles, the script constantly checks whether the velocity_threshold
value is exceeded or not. For this purpose the script does not check against each individual value of the velocity vector, because this would not lead to reasonable results.
Here, the magnitude of the velocity vector is used. The magnitude is not a vector, but a single floating number, which is much easier to handle and can be extracted with:
Code Block | ||||
---|---|---|---|---|
| ||||
source_particle_velocity = source_particle.getVelocity() source_velocity_magnitude = source_particle_velocity.module() |
...