Description:
The following sample is based on Laszlo Sebo's VolumeDocking01.max scene and illustrates the following MAXScript operations with Particle Flow :
Common Action creation,
Appending Actions to an Event,
Inserting Actions to an Event,
Cloning Actions and Events
Wiring
Repositioning events in Particle View
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()