Notifications
Clear all

[Closed] Getting something to "vibrate"

Hi, I dont use maxscript much, and was wondering how I could quickly make an object randomly “vibrate”

Its for a Pflow system, so it will go in a Script Operator

9 Replies

this is pretty much waht i need to get a particle to do

for obj in $ do
(
randX = random -5.0 5.0
randY = random -5.0 5.0
randZ = random -5.0 5.0
move obj [randX,randY,randZ]
)

The naive approach would be to just add a random value to the particle position, but this would mean that the particles would drift over time away from their original positions.

Copy the following into a Script Operator right after the position operator:

on ChannelsUsed pCont do
 (
 	 pCont.usePosition = true
 )
 
 on Init pCont do ( )
 
 on Proceed pCont do 
 (
 	count = pCont.NumParticles()
 	for i in 1 to count do
 	(
 		pCont.particleIndex = i
 		pCont.particlePosition = pCont.particlePosition + (random [-1.0,-1.0,-1.0] [1.0,1.0,1.0]) * 2.0
 	)
 )
 
 on Release pCont do ( )

The good news about this approach is that you can apply velocities and forces and the particles will still jitter while moving around. You can replace the * 2.0 with any other multiplier to get a stronger or weaker effect.

If your particles are static (not going anywhere) and you want them to jitter about their original position, you could store the original position when a particle is born (age 0) in the custom Scripted Vector Channel and then jitter about that position so the particles would never drift away over long period of time:

on ChannelsUsed pCont do
 (
 	 pCont.usePosition = true
 	 pCont.useVector = true
 	 pCont.useAge = true
 )
 
 on Init pCont do ( )
 
 on Proceed pCont do 
 (
 	count = pCont.NumParticles()
 	for i in 1 to count do
 	(
 		pCont.particleIndex = i
 		if pCont.particleAge == 0 do pCont.particleVector = pCont.particlePosition
 		pCont.particlePosition = pCont.particleVector + (random [-1.0,-1.0,-1.0] [1.0,1.0,1.0]) * 2.0
 	)
 )
 
 on Release pCont do ( )
 

Thank you very much for the reply Bobo, it almost does exactly what I need, there is one small problem, the particles seem to be jumping every 4-5 frames or so. I think this could be 1 of 2 things, the random # is hitting numbers so small that you cant see the change for 3 frames (.01 etc) then hits 1 and makes a visible jump, or I am missing some sort of script Integration Step parameter.

Thanks for the help.

(EDIT) After some experamentation, it seems my first idea is correct, I made a new system/scene, and made the jitter stronger than needed, they jitter every frame, then every once in a while jump way farther, any ideas?

(SOLVED) It turns out it was network rendering, when the next block of frames came along, it didnt match up, so I got it.

So now the question, how do I get around this? bake the script to actual animation data or something. Ill do some reading/watching, but any help would be awesome.

I believe you mean that the particle’s position changes too rapidly frame to frame?

The reason is because the script is being called at every integration step, and at every step a new random value is calculated and added to an initial position. This leads to every position only being related to the initial position, and not its previous. The pure random deviation that Bobo suggested is usually enough to describe violent vibrations. If you want to have a smooth and random-like particle motion (like flies buzzing) you’ll need a little more code and fancy integrators:

on ChannelsUsed pCont do
 (
 	 pCont.usePosition = true
 	  pCont.useSpeed = true
 	  pCont.useAge = true
 	 pCont.useAcceleration = true
 	 pCont.useVector = true
 )
 
 on Init pCont do 
 (
  
 )
 
 on Proceed pCont do 
 (
 	local count = pCont.NumParticles()
 	local drag = .9
 
 	for i = 1 to count do
 	(
 		pCont.particleIndex = i
 		if pCont.particleAge == 0 do pCont.particleVector = pCont.particlePosition
 		
 		local towardsInitial = (pCont.particleVector - pCont.particlePosition) * .00001
 		local randValue = random [-.0001,-.0001,-.0001] [.0001,.0001,.0001]
 		pCont.particleAcceleration = (pCont.particleAcceleration + randValue + towardsInitial) / 3.
 		pCont.particleSpeed *= drag
 	)
 )
 
 on Release pCont do 
 (
  
 )
 

The above code will give you something close to insects flying – you can tweak the values to get a more controlled vibration.

Its important to realize that acceleration integrates velocity and velocity integrates position. They each describe the rate of change of the next. If you have a constant acceleration of 1, then velocity is increasing every integration step and position is increasing dramatically every integration (gravity can be described as a force with a constant acceleration).

To cut to the chase: to have a smooth, yet random positional change, you need to manipulate the accelerations to get there. What I’ve done above is just calculate the vector that will lead the particle back to its original position, and average it with its previous position, and a random deviation vector. This creates an acceleration that is tied to the previous integration, a random vector, and the vector leading towards its initial position (take this vector out and the particles will drift away lazily). To make everything nice and smooth, I also introduce a bit of drag into the system at the particle’s speed channel (aka velocity function).

If you really want to get into particles check out some integral calculus and look into Newton’s laws of motion.

thank you very much d3coy for the input, Bobos script is perfect, but i will definately keep your post for refference when that comes up.

The current problem is, I am network rendering, but the machines do not render the scripted particles the same, so at each block of frames, they jump. I am messing with Box 3 Cache Disk, but i cant find a way for backburner to tell the other machines to use my pflow cache file.

Any ideas?

Create a network share and make sure each computer has access to it

Your C:\Renderoutput is shared on the network and each computer sees \server\Renderoutput you can either use \server\Renderoutput\ to save your files or what I prefer is mapping that to a drive letter say R:\ so R:\ = \server\Renderoutput but you can just go to your R:\ and save files… each computer would then see all of your files on your R drive.

Ahh I see, I misunderstood your question I often get carried away and make large unnecessary posts; nothing new, haha. I hope someone else can help you. My apologies to Bobo for thinking he didn’t answer your question.

Ok, Solitude that worked, mapping all boxes to network drive, working from there, and using Cache Drive, (500 more dollars of plugin whee). Thank you so much all of you for helping me out on this. D3coy I edited my question 3 times as I did some research, so confusion was inevitable