Ride The Flow! |
This
tutorial shows how to create a Camera Ride on a Particle Flow
system.
A Script Operator assigns the transformation of a particle to a scene camera
which then travels with the particles in the middle of the stream.
Final Result |
Watch the Ride Preview AVI (2.9MB, DivX 5.2)
Particle View Setup |
The Particle View contains 3 Events
All events feature Find Target Test which redirect the particles to different scene objects.
When the particles come close to the object, they change to the next Event.
All Events feature an instanced Rotation Operator which is set to orient the particles along the motion direction using Speed Space Follow and X:90, Z:-90 rotations about the axes.
All Events feature an instanced Script Operator which is described below. It moves a scene camera to one of the particles.
Natural Language - Script |
Enable the Transformation Matrix channel
In the Init handler, get the Camera from the scene by its unique name
If the Camera does not exist, create a new one, assign a unique name
In the Proceed handler, define a local variable to store the particle index.
Define a second variable to define the ID of the particle to ride on.
If the particle already exists, get its index in the current Event
Set the current particle to the index of the particle in the current Event
Copy the transformation of the current particle to the transformation of the Camera
Complete Script |
on
ChannelsUsed pCont do
(
pCont.useTM = true
)
on
Init pCont do
(
global pflow_travel_camera_170268 =
$pflow_travel_camera_170268
if pflow_travel_camera_170268 == undefuned then
pflow_travel_camera_170268
= FreeCamera name:"pflow_travel_camera_170268"
)
on
Proceed pCont do
(
index = 0
rideParticleId = 400
if pCont.hasParticleId rideParticleId
&index then
(
pCont.particleIndex = index
pflow_travel_camera_170268.transform = pCont.particleTM
)
)
on
Release pCont do
(
)
Step-By-Step Comments |
on
ChannelsUsed pCont do
(
The ChannelsUsed handler defines the channels to be used by the Script Operator - you cannot get or set particle related values from the particle container without specifying which properties you need access to. This way, Particle Flow does not have to provide the Script Operator with all possible channels (and there can be an arbitrary number of channels in Particle Flow) but only with those that are actually needed. This conserves memory!
The parameter pCont contains the Particle Container.
pCont.useTM = true
Since we want to read the Transformation Matrix of the particles in order to orient the Camera, we will need access to the TM channel.
)
on
Init pCont do
(
The Init handler is executed when the Operator is being initialized.
We will use it to get an existing scene Camera, check its validity and create a new one if no Camera existed.
global pflow_travel_camera_170268 = $pflow_travel_camera_170268
Create a global variable with a unique name and get the scene camera by its unique name.
The Camera must have a unique name to make sure the correct object is referenced by the script.
if pflow_travel_camera_170268 == undefuned then
pflow_travel_camera_170268 =
FreeCamera name:"pflow_travel_camera_170268"
In the variable is undefined, there was no Camera with this name in the scene.
In this case, we create a new Free Camera with the unique name and assign it to the variable.
)
on
Proceed pCont do
(
The Proceed handler contains the main code of the script.
It will be evaluated every time the Operator is proceeded.
The pCont parameter references the Particle Container of the Event the Operator is located in.
index = 0
We will need a user-defined local variable to store the index of the particle to ride on.
We initialize to 0.
rideParticleId = 400
This variable contains the Particle ID we want to ride on.
if pCont.hasParticleId rideParticleId &index then
(
Now we call the .hasParticleId method in the Particle Container.
We pass the Particle ID as parameter, and the index variable by reference.
The method returns true when a particle with the specified ID exists in the container.What is the difference between ParticleID and ParticleIndex?
The ParticleID is a sequential number given to every new born particle in a Particle System.
This ID identifies the particle throughout its whole life and stays the same when a particle changes from Event to Event.Every Particle Container of every Event contains a pool of particles.
These particles are always numbered from 1 to the number of particles in the pool without gaps.
When particles change between Events, the ParticleIndex will change, and the pools will be renumbered to avoid gaps.Since we want to stick to the same particle no matter which Event it is in, we want to access it by the Particle ID.
But we also want to access the corresponding ParticleIndex in every Event the script is evaluated in.
Using the .hasParticleId method, we get true or false depending on whether the particle is in the current Event or not.
If it is in the Event, we also get the actual ParticleIndex of this particle inside the variable index.
pCont.particleIndex = index
Now we can set the current particle in the current Event to access its Transformation Matrix.
pflow_travel_camera_170268.transform = pCont.particleTM
Finally, we get the Transformation Matrix of the current particle and assign it to the transformation of the Camera.
)
The
If context ends here. If the particle ID does not exist in the current Event,
the script will do nothing.
Since the particle with ID 400 can be only in one Event at a time, but the
script is instanced in 3 different Events, the Camera will be affected by just
one Script Operator a time.
)
on
Release pCont do
(
)
Copyright © 2003 by Borislav 'Bobo' Petrov. |