Notifications
Clear all

[Closed] CgTalk Maxscript Challenge 022: "Particles"

CgTalk Maxscript Challenge 022: “Particles”
Thanks to David Wortley for the suggestion!

DESCRIPTION: Since particle flow has scriptable operators, it might be high time for everyone to play with it in a challenge! Try to control particles in a way the nodes can’t, or extend ideas that have already been presented, such as fracturing objects crowd control systems. I’m keeping it broad so you can flex your brains.

This is a reasonably advanced version of the challenge, but I would encourage beginners and intermediates to find some of the great scripting tutorials out there and have a go at making something of your own.

DEADLINE: 14/2/2009

RULES:
[ul]
[li]Do NOT post your code until the deadline![/li][li]Code from scratch. Try not to use pre-exisitng functions or plugins.[/li][li]Show your script references, if any (eg. Looking at another script to assist you).[/li][li]You are encouraged to ask for help where needed, but try to do it on your own. The maxscript reference is an invaluable resource.[/li][li]Post your final script inside [/li]“`
tags (located on your posting toolbar).
[li]Post all code into THIS thread.[/li][li]Post the max version you coded in, plus any maxscript extensions you used.[/li][li]Try to finish the challenge in the proscribed time. There is no definite time limit.[/li][/ul]NOTES: Remember thatBobo has a new DVD series out on this very subject!

7 Replies

I’m in. Time to dust off Rifter.

Suppose as it’s my idea I better think of something as well…

Just under a week before the “formal” deadline, has anyone been working on it?

I was particularly interested in this challenge, but as I’m still in the middle of a lot of work, I barely managed to squeeze some time to dig up an old method I used roughly 3-4 years ago…
What I was generally after back then was to use PFlow to initialize the motion of the objects, then use Reactor to continue the motion with all the physics goodness.

     I basically started by used the concept from [this thread at Orbaz.]( http://www.orbaz.com/forum/viewtopic.php?t=326) 
     - it uses a Birth Script and a Script Operator to control objects currently in the scene.
     
     Birth Script:
on ChannelsUsed pCont do
         (
             pCont.useAge = true
             pCont.useTM = true  
         )
         
         on Init pCont do 
         (
             global ChunksArray = $Chunk* as array
             global fragTime = 0
             global TM_Reset
             /*
             TM_Reset = undefined
             */
             
             if ChunksArray != undefined do
             (
                 if TM_Reset == undefined do TM_Reset = true
                 if TM_Reset do
                 (            
                     Global ChunksArray_TM = for i in ChunksArray collect i.transform
                     TM_Reset = false        
                 )
             )
         )
         
         on Proceed pCont do 
         (
             t = (pCont.getTimeEnd() as float)/ticksperframe    
             NumChunks = ChunksArray.count
             
             if t == fragTime do
             (
                 for i = 1 to NumChunks do
                 (        
                     pCont.AddParticle()
                     pCont.particleIndex = pCont.NumParticles() 
                     pCont.particleAge = 0
                     pCont.particleTM = ChunksArray_TM[i] 
                 )
             )
         )
   and the Script Operator
on ChannelsUsed pCont do pCont.useTM = true
      
      on Proceed pCont do 
      (
      	count = pCont.NumParticles()
      	ChunkCheck = (ChunksArray != undefined)	
      	if chunkcheck do
      	(
      		for i in 1 to count do
      		(		
      			pCont.particleIndex = i
      			j = pcont.particleID
      			ChunksArray[j].Transform = pCont.particleTM
      		)
      	)
      )
  The birth script will get and save the transforms of the objects to be used by the particles. Then the script operator will control the transforms of the scene geometry, moving, rotating, scaling them with pflow operators.
  
  A particular setup would be like this:
  [img] http://www.geocities.com/jepoy20/files/pflow/per_obj_sim_pflow.gif [/img]
  
  [img] http://www.geocities.com/jepoy20/files/pflow/per_obj_sim_ani_start.gif [/img]
  
  The next thing to do (if you're already OK with the motion) is to bake out the motion to keyframes...
  
  But since this method works directly with scene objects, it's not posiible to just bake them out using a PFlow Baker script. I totally forgot why I needed to control the actual objects and not just use thier .mesh property and feed it to pflow..
  
  So in order to get the keyframes for the objects, all you need to do is:
  
  (Under the Time Configuration Dialog)
  - Set the Realtime Playback to OFF
  - Set the Loop Playback to OFF
  
  - Turn on ANIMATE
  - PLAY the animation
  
  - Turn OFF Pflow
  
  After doing the above, we now have keyframes for the objects, and pflow can now be turned off (or deleted).
  
  Next thing to do now is use the current baked motion and use Reactor to continue the animation. So I wrote another script to automate the simulation of each object.
  
  The script was temporarily named "PFlow Per-Obj-Sim"
  
  [img] http://www.geocities.com/jepoy20/files/pflow/per_obj_sim_UI.gif [/img]
  
  As what the name of the script says, it will simulate each object separately..
  [b]Object Collection[/b] -> assign the collection of objects that you want to simulate. Also make sure the these objects have reactor properties
  [b]Rigid Body Collection[/b] -> pick a Reactor Rigid Body Collection, with objects like walls and ground for the Object Collection to interact with. This reactor collection does NOT need to have the animated objects inside its collection list, because the script will be the one to add them during simulation.
  [b]Key Trim Offset[/b] -> this will delete N number of keyframes starting from the second to the last keyframe of the object.
  
  If all went well with the setup, this would be the final animation.
  
  [img] http://www.geocities.com/jepoy20/files/pflow/per_obj_sim_ani_final.gif [/img]
  
  Final Notes:
  As some of you may obviously notice, there's no interaction between the objects :sad: .. that was because each object was simmed separately.. But for what I used this script for, there were just too many little chunks, that it was barely noticable..

I've attached a max file (max 9) and the per-obj-sim script.
  
  * I hope that this didn't veer far too off from the challenge topic.

** I would also like to note that I initially did this with max6 so i can’t assure if the code would still work flawlessly with new max versions.
*** also the upcoming Pflow Box2 definitely is a must for this kind of stuff.

Jeff

Just to add some ground to the Galagast’s claim about upcoming PFTools: Box#2 – inspired by the script setup, I did a simple test with Box#2 functionality, quick and dirty. Here’s the animation: WallToWall3.zip (2.3 MB)

Thanks,
Oleg B.

Funny i stumble across this thread as i just finished my first little script! YAY!

 As i am just learning maxscript and saw a fracture geometry script ages ago on script spot called [MBFracture]( http://scripts.breidt.net/index.html#fracture)Well  this gave me the initial idea :)

But first i wanted to learn the basic’s…ie “For” loops and “if” statement!..Well this is what the basics it turned into

 Basically I started on the weekend that has just finished, and made a similar little tool, no where in the realm of anything too fantastic and not really a tool for a team of people to use, but as it is my first attempt at a script (and i mean first!) so i am pretty happy with it overall result!

Also most of the reference came from watching the listener window and reading tones of maxscript help docs.

 I hope this qualifies to enter:)!
 
 Suggestion are definitely welcome!
 
 BTW the little pflow to reactor script before is very cool, also very funny as that was going to be a little trial i was going to give myself later down thge track...o-well :) but i imagine that most of my idea would of already been made, just a case of doing it anyways so i learn :D
 
 Cool hope you enjoy!
 
 --------------------------------------------------------------------
 Okay to the script!
 
 Things to know before hand....and this is because i am still learning and am grasping the concept of everything!
 
 1. Currently the object it breaks needs to be under a file unit size of 100 (need to do a bounding box check on the object and feed that back to the script, but need to learn)
 2. The object needs to be at world zero (need to move the cutting objects to the local position of the selected "to be cut" object)
 3. For some reason the script crashes after a few goes...not sure why...
 4. The object needs to be "water tight" ie haev not open edges, it crashs the script...not sure why.
 5. Uncoment the "gc()" comand at own risk as this crashes the script when run (must have in incorrect place i gather)
 6 You need to have the object you want to break selected first, before you execute the "Crack" button.(would like to make a list box for this, but need to learn more about how array's work ie actually write them)
 7. Be kind! This is my very first attempt, but over-all i am happy with what i made!

     /*
   Created by Kieran Ogden-Brunell March 2009
   This script should break a selected object into chunks
   Good for stone/rock debris
   
   --FOR LATER REVISION--
   ______________________
   - Pick button for object
   - List box for multi objects
   - Bounding box function to drive crack plane sizes (currently this is a hard coded value of 120 in scene size)
   - Dialog box for user enable cancel or continue
   - Save "tick" option, so scene is saved before calculation
   - Tick option to keep original mesh
   - Iteration feature to run the simulation over the first pass cracks
   - Minimum size threshold for breaking on first pass and iteration
   _______________________
   
   KNOW ISSUE"S
   _______________________
   -Crash's MAX randomly if used to much.
   -Crash's MAX if gc() is used...sometimes...
   -Process breaks if the crack planes are too small compared to the user object
   _______________________
   
   */
   
   
   
   rollout kobCracks "Crack Geometry"
   (
   	edittext _oName "Name" fieldWidth: 160 height:16
   	
   	spinner _pAmount "Crack Density" type:#integer range:[1,20,8]
   	spinner _pSegs "Crack Detail" type:#integer range:[10,30,20]
   	spinner _pNoiseHieght "Crack Shear" range:[0,120,55]
   	spinner _pSmoothAmount "Internal Smooth" range:[0,90,65]
   	
   
   	button _create "Create Cracks" width:150 height:50 tooltip:"Crack Object!"--this should eventually name the seperate chunks!
   
   			
   	on _create pressed do
   		(
   		
   			if _pAmount.value >= 15 then messagebox "WARNING: Could become unstable!" --warns if you have too many planes need a cancel or continue dialog
   
   		DisableSceneRedraw
   
   -- create planes from the spinners value
   
   		(
   		_firstPlane = null
   			
   			for j = 1 to _pAmount.value do
   					(
   						
   						 p= (plane())
   							p.name = uniquename "cutPlanes"
   						if (j == 1) then _firstPlane = p
   							p.length = 150
   							p.width = 150
   							p.lengthsegs = _pSegs.value
   							p.widthsegs =_pSegs.value
   							p.wirecolor = [random 0 255,random 0 255,random 0 255]
   
   --adding noise modifier to plane
   
   						addModifier p (Noisemodifier())
   							p.modifiers[#Noise].seed = random 1 1000
   							p.modifiers[#Noise].scale = random 45 85
   							p.modifiers[#Noise].fractal = on
   							p.modifiers[#Noise].strength = [(random 0.0 1),(random 0.0 1),(random _pNoiseHieght.value (_pNoiseHieght.value+5))]
   
   --adding smooth modifier to plane
   
   						addModifier p (smooth())
   							p.modifiers[#smooth].autosmooth = on
   							p.modifiers[#smooth].threshold = _pSmoothAmount.value
   
   --rotates planes in "for" a random value from 0 to 360 degrees
   
   						rotate p (eulerAngles (random 0 360) (random 0 360) (random 0 360))
   							
   --convert to edit poly
   							convertTo p (Editable_Poly)
   							
   						if (j > 1) then polyop.attach _firstPlane p
   							
   							
   							
   						
   					
   					)
   					
   					-- this is the pro cutter section currently works with one cut
   					a = _firstPlane
   					c = $
   						ProCutter.CreateCutter #(a) 1 True True False True True
   						ProCutter.AddStocks a #(c) 1 1
   						Delete a
   					
   					-- Rename objects to the name specified
   					all = $cutPlanes*
   					all.name = uniquename _oName.text
   					
   		)
   			EnableSceneRedraw()
   			gc()
   		)
   		
   	button _howToBox "Info" tooltip:"Info"
   	
   	on _howToBox pressed do
   		(
   			messagebox "Create an Object or use an existing prop. 
 Select the mesh you want to crack. 
Press Create Cracks to Run!"
   		)	
   		
   
   	button _aboutBox "About" tooltip:"About"
   		
   	on _aboutBox pressed do
   		(
   			messagebox "This script creates cracks in selected objects
Created by Kieran Ogden-Brunell 2009"
   		)
   			
   )
   createdialog kobCracks width:220 height:220
     

Enjoy!

mmmmMMMM Whoops just relised it was a particle comp…please dis-regard…sorry guys!!

but look by all means…

runs and hides

Kieran