VolumeDocking Sample Script

 

   

Particle Flow - Quick Navigation

Description:

The following sample is based on Laszlo Sebo's VolumeDocking01.max scene and illustrates the following MAXScript operations with Particle Flow :

Can Be Used With:

The script is self-contained and recreates all objects and Particle Flow Events and Actions on the fly:

Effect:

The script creates two geometry primitives and two PF_Sources with corresponding Actions and Events.

The geometry objects are used as volumes to be filled with particles. The initial positions of the particles are dumped to the particleVector channel. Using a Find_Target action, the particles find their way from the one volume to the other and switch places after swirling around.

EXAMPLE

-----------------
-- SCENE SETUP --
-----------------
 
-- Set scene animation range to 150 frames
animationRange = interval 0f 150f
-- Create Cylinder primitive
cyl=cylinder radius:44 height:44 heightsegs:5 sides:18 pos:[-60, -55, 0]
-- Create a Torus primitive
tor=torus radius1:55 radius2:20 smooth:2 pos:[135, 120, 0]
-- Create a Vortex Space Warp
vor=vortex timeOff:33 axialStrength:22 rotationStrength:33 iconSise:40 rotation:(quat -1 0 0 0) pos:[20,35,-5]
 
-- PF_Flow setup
pf=PF_Source Show_Logo:off Show_Emitter:off Quantity_Viewport:100 isSelected:true
 
-------------------------------------
-- Action List - Appending Example --
-------------------------------------
 
-- Disable automatic Event Encapsulation & begin editing:
ParticleFlow.BeginEdit()
a1 = RenderParticles()--define Action 1
pf.AppendAction a1--append the Action to PF_Source
ParticleFlow.EndEdit()--End editing, enable Auto-Encapsulation
 
x=y=1--Initialize two variables
--Get the location of the PF_Source in Particle View:
pf.GetPViewLocation &x &y
 
------------------------
-- Define First Event --
------------------------
ParticleFlow.BeginEdit()--start editing
-- Create a Birth Action for Event 1
ev1_a1 = Birth Emit_Start:0 Emit_Stop:0 Amount:300
 
-- Create a Position Object Action for Event 1
ev1_a2 = Position_Object Location:4 Emitter_Objects:#(tor) name:"PositionObjectFirst"
-- Comment the Position Object
pf.SetComments ev1_a2 "The operator defines the destination point inside the target volume"
 
-- Create a Script Operator
ev1_a3 = Script_Operator()
-- Set the script operator’s script code as string.
-- The code enables Position and Vector channels,
-- the writes the particle position in the Vector channel
-- for all new particles.
ev1_a3.proceed_script = "on ChannelsUsed pCont do
(
 pCont.usePosition = true
 pCont.useVector = true
)
on Init pCont do
(\n
)
on Proceed pCont do
(
 count = pCont.NumParticles()
 for i in 1 to count do
 (
 pCont.particleIndex = i
 if (pCont.particleNew) then
 ( pCont.particleVector = pCont.particlePosition)
 )
)
on Release pCont do
(\n
)"
 
-- Comment the action:
pf.SetComments ev1_a3 "The script is used to dump particle position to script vector channel"
 
-- Clone the Position_Object action from Event 1
-- The result of the cloning will be stored in the
-- by-reference variable dc.
maxOps.cloneNodes ev1_a2 newNodes:&dc
-- Get the clone (first element of array)
ev1_a4 = dc[1]
-- Set the name of the action
ev1_a4.name ="PositionObjectSecond"
-- Set the Cylinder as the Emitter
ev1_a4.Emitter_Objects = #(cyl)
 
-- Comment the action:
pf.SetComments ev1_a4 "The operator defines the initial position of a particle inside a start volume. The destination position is overwritten but the real value is kept in Script Vector channel"
 
-- Create some more actions needed to control the particle system
ev1_a5 = Speed Direction:3
ev1_a6 = Rotation()
ev1_a7 = ShapeStandard Shape:1
ev1_a8 = DisplayParticles Type:6 Color:(color 255 0 0)
 
-- Create a new empty event, then append all already created
-- actions to it:
ev1 = Event()
ev1.AppendAction ev1_a1
ev1.AppendAction ev1_a2
ev1.AppendAction ev1_a3
ev1.AppendAction ev1_a4
ev1.AppendAction ev1_a5
ev1.AppendAction ev1_a6
ev1.AppendAction ev1_a7
ev1.AppendAction ev1_a8
-- Disable editing, enable Auto-Event-Encapsulation
ParticleFlow.EndEdit()
 
-- Append the event as the Initial Action List to the PF_Source.
-- This will connect the Event to the PF_Source.
pf.appendInitialActionList ev1
-- Position the Event inside the Particle View
ev1.SetPViewLocation x (y+100)
 
-------------------------------------
-- Action List - Inserting Example --
-------------------------------------
 
--Begin Editing again
ParticleFlow.BeginEdit()
 
ev1_a9 = Spin SpinRate:200 Variation:55--Create a Spin action
ev1_a10 = Force Influence:111--Create a Force
--Set the Vortex as Space Warp in the Force
ev1_a10.Force_Space_Warps = #(vor)
 
--Create and setup a Find_Target action:
ev1_a11 = Find_Target()
ev1_a11.name ="FindTarget"
ev1_a11.Cruise_Speed_Variation = 1000
ev1_a11.Acceleration_Limit=3000
ev1_a11.Aim_Point_Type = 2
ev1_a11.Icon_Size = 0
 
-- Comment the action:
pf.SetComments ev1_a11 "The destination point is defined by script vector. The script vector value was defined by the Script Operator 01 from the Position Object 01"
 
-- Insert the new actions into the existing Event
ev1.InsertAction ev1_a9 8
ev1.InsertAction ev1_a10 9
ev1.InsertAction ev1_a11 10
ParticleFlow.EndEdit()
 
-- Create a Second Event and its actions:
ParticleFlow.BeginEdit()
ev2_a1 = Speed Speed:0
ev2 = Event()
ev2_a2 = DisplayParticles Type:6 Color:(color 0 255 0)
ev2.AppendAction ev2_a1
ev2.AppendAction ev2_a2
ParticleFlow.EndEdit()
 
--Connect the second Event to the Find_Target
ev1_a11.setNextActionList ev2 ev1_a11
--Reposition the even
ev2.SetPViewLocation x (y+400)
 
 
-- Make copy of PF_Source and exchange Emitter objects
-- for Position_Object operators:
 
-- Clone the PF_Source and the two Emitters,
-- store the clones in a by-reference variable
maxOps.CloneNodes #(pf, ev1, ev2) newNodes:&dc
 
-- Get the PF_Source and Emitter clones
pfc = dc[1]
ev1c = dc[2]
ev2c = dc[3]
 
-- Get the current position of the Particle View...
x=y=1
pfc.GetPViewLocation &x &y
-- Reposition the two Events
ev1c.SetPViewLocation x (y+100)
ev2c.SetPViewLocation x (y+400)
 
-- Copy the emitter objects from the original Position_Objects
if $PositionObjectFirst01 != undefined then (
 $PositionObjectFirst01.Emitter_Objects = ev1_a4.Emitter_Objects
)
if $PositionObjectSecond01 != undefined then (
 $PositionObjectSecond01.Emitter_Objects = ev1_a2.Emitter_Objects
)
 
-- Bind the Find_Target Test output to the clone of the Second Event
if $FindTarget01 != undefined then (
 $FindTarget01.setNextActionList ev2c $FindTarget01
) 
 
-- Switch to Modify Tab
max modify mode
-- Open Particle View to see what happened...
ParticleFlow.OpenParticleView()

See Also