OK its all working well although i am getting alot of bunching of particles at the start (bottom of vertical ) of the spline. Any ideas?
Hello jobwallis,
I see your file and after an hour of research, i see too that the arrow must be turn in his space object
to be align. I think is that you did. The Arrow was there but we see it’s thin side.
The fact you must close the script window to apply the script, it’s the way it works. Save deosn’t have any effect just close the windows to start the particles calculations.
I look at your file to see
Not behind max now, but I think hitting CTRL+e also evaluates/updates the script node.
-Johan
solution to my problems…
http://www.orbaz.com/forum/viewtopic.php?p=14597#14597
i found my machine slowing alot after including about 4 PF’s. I will need about 12 in the end.
Solution at the moment is to do away with the PF altogether and just animate along path (with out of range keys) and duplicate arrows. Much simpler. KISS keep it simple stupid. :wavey:
thanks all for you help. particularly BebeteLANUITE
:bowdown: :wavey:
Hello jobwallis,
I am happy if you find a good solution for your work.
In fact, i see your file and i made a test. The bunch of particles is the particles that appears after the time
they take to travel over the spline.
For example :
You want the particles travel the spline in 100 frames. (you type it in the script)
if you play it’s ok from the global time from 0 to 100 but after the particles don’t follow the spline anymore and stay on the pivot of the emitter.
So, it’s a problem of my script. I must modify it but i don’t have time by now to analyse what’s happens. But when i have time i will do it.
So here is the same script but to use as script test. I think it’s more interesting as a test.
When the particles leave the spline you can send them to an other event.
The “frame limit” problem still there but i will fix it soon.
on ChannelsUsed pCont do
(
pCont.useTM = true
pCont.useAge = true
pCont.usePosition = true
pCont.useVector = true
pCont.useTime = true
)
on Init pCont do ()
on Proceed pCont do
(
count = pCont.NumParticles()
splPath = $Line01 -- Path to follow. Put your path name here
PartEmitter = $'PFlow Emitter 01' -- Emitter to get his position
KnotPnt = (getKnotPoint splPath 1 1) -- First Knot position of the Path
NumFrames = 100 -- Number of frame that the particle take to travel over the Path
sw_Banking = True -- True/False : If you want the particle follow the orientation of the Path.
sw_AlignToPath = True -- True/False : If you want the particles follow the path from emitter (False) or directly on the Spline Path (True).
sw_ReorientParticles = True -- True/False : If you want the Transform Matrix of the particle be oriented to the Path. Useful for shape Orientation.
splEndPrcnt = 0.99999 --The percentage of the spline the script take to send particles in the following event.
--Avoid a value of 1.0 with "sw_ReorientParticles = True" because the particle will reorient on the last spline knot.
--It will create a strange movement of the particle at this moment.
if sw_Banking != True and sw_Banking != False do sw_Banking = True -- If there is something different in sw_Banking than True or False, we put True in sw_Banking
for i in 1 to count do -- loop in the particles
(
pCont.particleID = i
PathPartPos = (pCont.particleAge as float/ticksperframe)/NumFrames -- Get a percentage beetween 0.0 and 1.0 with the pCont.particleAge to calculate the travel position on the path (192 ticks per frame)
if sw_Banking == False do -- if you don't want the Banking
(
if pCont.particleNew do pCont.particleVector = (pCont.particlePosition - KnotPnt) -- if it's a new particle. Store a vector from the particle position to the first PathKnot
if PathPartPos <= splEndPrcnt do -- Set the new particle position if PathPartPos is smaller than 1.0
(
if sw_AlignToPath == True do pCont.particlePosition = (lengthInterp splPath PathPartPos) -- with sw_AlignToPath
if sw_AlignToPath == False do pCont.particlePosition = (lengthInterp splPath PathPartPos) + (pCont.particleVector) -- without sw_AlignToPath
)--end if
)--end if
if sw_Banking == True do -- if you want the Banking
(
if pCont.particleNew do pCont.particleVector = (pCont.particlePosition - PartEmitter.pos) -- if it's a new particle. Store a vector from the particle position to the Emitter Position
if PathPartPos <= splEndPrcnt do -- if PathPartPos is smaller than 1.0
(
-- Axis reconstruction - Thanks to Bobo for the explanation in the Max Help File ("How do I align the UVW_Modifier's Gizmo to a selected face?" section)
ZNormal = (lengthTangent splPath 1 PathPartPos) -- get direction for the Position on the Path with LengthTangent function
worldUpVector = [0,0,1] --Set up of the world
rightVector = normalize (cross worldUpVector ZNormal) --set RightVector (X axe)
upVector = normalize ( cross rightVector ZNormal ) --set upVector at 90° of the system
Pos_RightVector = RightVector*pCont.particleVector.y --set length of x vector for particle position
Pos_upVector = upVector*pCont.particleVector.z --set length of y vector for particle position
if sw_AlignToPath == True do pCont.particlePosition = ((Pos_RightVector + Pos_upVector) + (lengthInterp splPath PathPartPos)) -- Calculate the Particle Position on the Path
if sw_AlignToPath == False do
(
PartPos_Vect = (lengthInterp splPath PathPartPos) - (getKnotPoint splPath 1 1) -- Vector from first pathKnot and current path coordinates.
pCont.particlePosition = ((Pos_RightVector + Pos_upVector) + PartEmitter.pos) + PartPos_Vect -- Calculate the Particle Position and offset it from the center of the emitter
)--end if
if sw_ReorientParticles == True do pCont.particleTM = (matrix3 rightVector ZNormal upVector pCont.particlePosition) -- Create a Matrix for the particle shape Orientation
)--end if
)--end if
if PathPartPos >= splEndPrcnt do
(
pCont.particleTestStatus = true
pCont.particleTestTime = pCont.particleTime
)
)--end for
)--end proceed
on Release pCont do ()
Thanks a lot for using my script
Hello folks !
This is the fixed “Script Test” for my spline follow script.
Now it works. Try it guys and report me if you have some bugs.
Jobwallis, i test the fixed script test in your scene and i work perfectly now.
I put a delete operator in as a next event from the script test.
The created particles follow the line from the beginning and be deleted when they
reach the “splEndPrcnt” value of the spline.
Test it and tell me if it works for you
on ChannelsUsed pCont do
(
pCont.useTM = true
pCont.useAge = true
pCont.usePosition = true
pCont.useVector = true
pCont.useTime = true
)
on Init pCont do ()
on Proceed pCont do
(
count = pCont.NumParticles()
splPath = $Line01 -- Path to follow. Put your path name here
PartEmitter = $'PFlow Emitter 01' -- Emitter to get his position
KnotPnt = (getKnotPoint splPath 1 1) -- First Knot position of the Path
NumFrames = 100 -- Number of frame that the particle take to travel over the Path
sw_Banking = True -- True/False : If you want the particle follow the orientation of the Path.
sw_AlignToPath = True -- True/False : If you want the particles follow the path from emitter (False) or directly on the Spline Path (True).
sw_ReorientParticles = True -- True/False : If you want the Transform Matrix of the particle be oriented to the Path. Useful for shape Orientation.
splEndPrcnt = 0.99999 --The percentage of the spline the script take to send particles in the following event.
--Avoid a value of 1.0 with "sw_ReorientParticles = True" because the particle will reorient on the last spline knot.
--It will create a strange movement of the particle at this moment.
if sw_Banking != True and sw_Banking != False do sw_Banking = True -- If there is something different in sw_Banking than True or False, we put True in sw_Banking
for i in 1 to count do -- loop in the particles
(
pCont.particleIndex = i
PathPartPos = (pCont.particleAge as float/ticksperframe)/NumFrames -- Get a percentage beetween 0.0 and 1.0 with the pCont.particleAge to calculate the travel position on the path (192 ticks per frame)
if sw_Banking == False do -- if you don't want the Banking
(
if pCont.particleNew do pCont.particleVector = (pCont.particlePosition - KnotPnt) -- if it's a new particle. Store a vector from the particle position to the first PathKnot
if PathPartPos <= splEndPrcnt then -- Set the new particle position if PathPartPos is smaller than 1.0
(
if sw_AlignToPath == True do pCont.particlePosition = (lengthInterp splPath PathPartPos) -- with sw_AlignToPath
if sw_AlignToPath == False do pCont.particlePosition = (lengthInterp splPath PathPartPos) + (pCont.particleVector) -- without sw_AlignToPath
)--end if
else
(
pCont.particleTestStatus = true
pCont.particleTestTime = pCont.particleTime
)
)--end if
if sw_Banking == True do -- if you want the Banking
(
if pCont.particleNew do pCont.particleVector = (pCont.particlePosition - PartEmitter.pos) -- if it's a new particle. Store a vector from the particle position to the Emitter Position
if PathPartPos <= splEndPrcnt then -- if PathPartPos is smaller than 1.0
(
-- Axis reconstruction - Thanks to Bobo for the explanation in the Max Help File ("How do I align the UVW_Modifier's Gizmo to a selected face?" section)
ZNormal = (lengthTangent splPath 1 PathPartPos) -- get direction for the Position on the Path with LengthTangent function
worldUpVector = [0,0,1] --Set up of the world
rightVector = normalize (cross worldUpVector ZNormal) --set RightVector (X axe)
upVector = normalize ( cross rightVector ZNormal ) --set upVector at 90° of the system
Pos_RightVector = RightVector*pCont.particleVector.y --set length of x vector for particle position
Pos_upVector = upVector*pCont.particleVector.z --set length of y vector for particle position
if sw_AlignToPath == True do pCont.particlePosition = ((Pos_RightVector + Pos_upVector) + (lengthInterp splPath PathPartPos)) -- Calculate the Particle Position on the Path
if sw_AlignToPath == False do
(
PartPos_Vect = (lengthInterp splPath PathPartPos) - (getKnotPoint splPath 1 1) -- Vector from first pathKnot and current path coordinates.
pCont.particlePosition = ((Pos_RightVector + Pos_upVector) + PartEmitter.pos) + PartPos_Vect -- Calculate the Particle Position and offset it from the center of the emitter
)--end if
if sw_ReorientParticles == True do pCont.particleTM = (matrix3 rightVector ZNormal upVector pCont.particlePosition) -- Create a Matrix for the particle shape Orientation
)--end if
else
(
pCont.particleTestStatus = true
pCont.particleTestTime = pCont.particleTime
)
)--end if
)--end for
)--end proceed
on Release pCont do ()
Hope this script will help you guys.
Hi Guys,
Here is a new release of the script. Now you can set the "worldUpVector" which determine the direction of the top.
To use as a test Script:
-- This is a script that can be used to check particles for a condition
--
-- Created: 9-15-2010
-- Last Updated:
-- Author : ISANA Bruno
-- Version: 3ds max 9
--********************************************************************
-- MODIFY THIS AT YOUR OWN RISK
on ChannelsUsed pCont do
(
pCont.useTM = true
pCont.useAge = true
pCont.usePosition = true
pCont.useVector = true
pCont.useTime = true
pCont.useMatrix = true
)
on Init pCont do ()
on Proceed pCont do
(
count = pCont.NumParticles()
splPath = $Line03 -- Path to follow. Put your path name here
PartEmitter = $'Manif -> Pist LH' -- Emitter to get his position
KnotPnt = (getKnotPoint splPath 1 1) -- First Knot position of the Path
NumFrames = 200 -- Number of frame that the particle take to travel over the Path
sw_Banking = True -- True/False : If you want the particle follow the orientation of the Path.
sw_AlignToPath = True -- True/False : If you want the particles follow the path from emitter (False) or directly on the Spline Path (True).
sw_ReorientParticles = True -- True/False : If you want the Transform Matrix of the particle be oriented to the Path. Useful for shape Orientation.
worldUpVector = [0,0,1] --Set up of the world. If your particle is upside down try [0,0,-1] as worldUpVector.
--for a looping movement just put 1 to the rotation axis of the looping and rotate your shape in his object space by 90 degrees.
splEndPrcnt = 0.99999 --The percentage of the spline the script take to send particles in the following event.
--Avoid a value of 1.0 with "sw_ReorientParticles = True" because the particle will reorient on the last spline knot.
--It will create a strange movement of the particle at this moment.
if sw_Banking != True and sw_Banking != False do sw_Banking = True -- If there is something different in sw_Banking than True or False, we put True in sw_Banking
for i in 1 to count do -- loop in the particles
(
pCont.particleIndex = i
PathPartPos = (pCont.particleAge as float/ticksperframe)/NumFrames -- Get a percentage beetween 0.0 and 1.0 with the pCont.particleAge to calculate the travel position on the path (192 ticks per frame)
if sw_Banking == False do -- if you don't want the Banking
(
if pCont.particleNew do pCont.particleVector = (pCont.particlePosition - KnotPnt) -- if it's a new particle. Store a vector from the particle position to the first PathKnot
if PathPartPos <= splEndPrcnt then -- Set the new particle position if PathPartPos is smaller than 1.0
(
if sw_AlignToPath == True do pCont.particlePosition = (lengthInterp splPath PathPartPos) -- with sw_AlignToPath
if sw_AlignToPath == False do pCont.particlePosition = (lengthInterp splPath PathPartPos) + (pCont.particleVector) -- without sw_AlignToPath
)--end if
)--end if
if sw_Banking == True do -- if you want the Banking
(
if pCont.particleNew do pCont.particleVector = (pCont.particlePosition - PartEmitter.pos) -- if it's a new particle. Store a vector from the particle position to the Emitter Position
if PathPartPos <= splEndPrcnt then -- if PathPartPos is smaller than 1.0
(
-- Axis reconstruction - Thanks to Bobo for the explanation in the Max Help File ("How do I align the UVW_Modifier's Gizmo to a selected face?" section)
ZNormal = (lengthTangent splPath 1 PathPartPos) -- get direction for the Position on the Path with LengthTangent function
--worldUpVector = [0,0,-1] --Set up of the world
rightVector = normalize (cross worldUpVector ZNormal)--set RightVector (X axis)
upVector = normalize ( cross rightVector ZNormal ) --set upVector at 90° of the system
Pos_RightVector = RightVector*pCont.particleVector.y --set length of x vector for particle position
Pos_upVector = upVector*pCont.particleVector.z --set length of y vector for particle position
if sw_AlignToPath == True do pCont.particlePosition = ((Pos_RightVector + Pos_upVector) + (lengthInterp splPath PathPartPos)) -- Calculate the Particle Position on the Path
if sw_AlignToPath == False do
(
PartPos_Vect = (lengthInterp splPath PathPartPos) - (getKnotPoint splPath 1 1) -- Vector from first pathKnot and current path coordinates.
pCont.particlePosition = ((Pos_RightVector + Pos_upVector) + PartEmitter.pos) + PartPos_Vect -- Calculate the Particle Position and offset it from the center of the emitter
)--end if
if sw_ReorientParticles == True do pCont.particleTM = (matrix3 rightVector ZNormal upVector pCont.particlePosition) -- Create a Matrix for the particle shape Orientation
)--end if
)--end if
if PathPartPos >= splEndPrcnt do
(
pCont.particleTestStatus = true
pCont.particleTestTime = pCont.particleTime
)--end if
)--end for
)--end proceed
on Release pCont do ()
Enjoy !
Nice script very useful. But how to use it ? ok i put in pflow script operator, evaluate it. There is spline in scene, and pflow, nothing happens. how does the script know what spline to use?
Hello Dodgeas,
There is two variable in the script (“splPath” and “PartEmitter”).
Just put the name of your spline in splPath like this
splPath = $name_of_spline
-- replace name_of_spline by the name of your spline. If you have space in the name, just replace them by an underscore _.
Do the same thing for the emitter name in PartEmitter.
Enjoy !