VolumeDocking Sample Script

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()