Static Particles and Force Fields problem [solved]

Using sketchy’s fur…

I created a force field, after enabling the “animated” button under effects, I got the partcles to move as I moved the force field around.
http://snowshoe.f2o.org/staticforce/left.gifhttp://snowshoe.f2o.org/staticforce/right.gif

http://snowshoe.f2o.org/staticforce/left02.gif
http://snowshoe.f2o.org/staticforce/right02.gif

But there is a problem, when I tell the force field to move (from one location to another) from frame 01 to 20; The location of the force field of frame 01 and frame 20 act on all frames. This is the image I got for all the 20 frames.

http://snowshoe.f2o.org/staticforce/all.gif

I decided to take a less drastic approach at animating static particles, after reading that I could “IPO-ize the strength of the force field, and the distance.” I tried just that. Same story, the strength of the first and last frame is combined (in a strange way) and is used on all frames, thus no animation.

I hope this is not a bug, and just something I missed. Please Help!

I think the particle paths are pre-calculated for the whole animation andcannot easily change.

I believe there is a small piece of Python script that can be called for each frame that forces a particle re-calculate for every frame.

Not sure where, but seek in the forums and you should find.

I agree. As far as I can tell, static particles remain the same for the entire animation. I’m not really sure what you can do to avoid it.

I can render each frame, one at a time… But that takes a long time.

  • Changes in the Object module:
  • Added buildParts() method.
    This method forces computation of the particle system

Thats all I can find as far as python goes, I’ll go try it now.
[edit] - Found more: https://blenderartists.org/forum/viewtopic.php?t=39019&highlight=buildparts

[update] - The python script didn’t help… Is there a way to delete the “pre-calculated” position of particle, and recalculate (or start a new calculation) at each frame?

I wrote a script for this that worked. It was a tiny script --But i can’t find it.

I’ll keep looking …

Found it.


import Blender
object = Blender.Object.Get("Cube")
effector=Blender.Object.Get("Effector")

effector.setLocation(object.getLocation())
print effector.getLocation()
parts=Blender.Effect.get("Parts")


Blender.Object.Get("Parts").buildParts()

I used it as a world script link, with framed changed event.

Ok so its a hack… So heres how to use it…

Animate a empty That does not have any effect on the static particles. This is called “Cube” in the script… At this point rotations don’t do anything… Not much to change tho in the python.

Then add a empty that has force or wind or whatever. dont animate it… It won’t work if you do. Its called “Effector” in the script.

The static particles come from a object named “Parts” …

If you use different names then you will need to change them.

Now each frame the effector is moved to the “cube’s” postion and the particles are recalulated each frame.

If you know python then you can change the script to your needs.

If you don’t you can ask nicly… But i’m pretty bussy… so i would’nt hold your breath.

Delt0r

Delt0r, thank you so much. The script worked. :smiley:

can we see a blend example

This is a quick test with one force field, strength 2 and max distance disabled.

http://snowshoe.f2o.org/0001_0030.avi

I don’t have good access to a host. I have a tank tut as well and looking to host that somewhere… Some free hosting site either require me to sign my life away or has really small bandwidth restrictions.

Delt0r

effector.setPIStrength(object.getPIStrength())

Now you can animate the strength too. :smiley:

BTW, have you tried going the other way and animating the “parts”?
[edit] I tried, but am having problems. No matter where I move the “parts” it pretends that it’s at the 0,0,0 location and deforms to the force field as if it was there. Is there a way to define this “particle origin”?

It worn’t for the the same reasons. So you add a few lines to the script to dd kinda the same thing.

Don’t animate parts. But animate some empty, the script at each frame copys the “parts” object to the empty (and rotation as required). ie just like it does for the effector.

Then it recalculates static particles just like it does now.

Again, this can be made into a sliglty usefull script without too much difficulty. But i’m behind on work at the momnet.

Delt0r

I’ve been trying to all day. Animated or not, the particle position is based on the 0,0,0 location. The force field affects the particles as if they were at that location.

BTW Delt0r, don’t worry about my dumbness now… Your job is more important. :wink:

Well i already did try… Mainly cus i want to do it.

But yes its based on the frame 1 postion. There are one or 2 things that can be done however.

Transfrom the Effector to the correct 1 postion. Let the script work out where that is… And bobs you uncle --That would work… Softbodys mite be a better choice however.

delt0r

It has nothing to do with frame one… Here: http://snowshoe.f2o.org/test04.blend

Leave the empty (the force field) where it is, and move the mesh (the static Particles) around. Then “RecalcAll.” Notice that the position of the static particles, as individuals didn’t change.

I believe there is a solution, but before I start writing this huge script (I thought out in my head.) I just want to confirm that this isn’t just a little button I forgot to enable in blender.

I don’t think so --Theres a Animate button under the static button in the particles options. But i can only get that to recalc animated textures, ie when theres texture effects in the particles.

I Played with this heaps earlyer this year, and i think script is the only way to go, Assuming that softbodys is just not a option.

Delt0r

Much simpler then I thought…

import Blender
force = Blender.Object.Get("Empty")
parts = Blender.Object.Get("Mesh")

# Temp Location for Force
x = (parts.LocX - force.LocX) * (-1)
y = (parts.LocY - force.LocY) * (-1)
z = (parts.LocZ - force.LocZ) * (-1)

# Real Location
oldx = force.LocX
oldy = force.LocY
oldz = force.LocZ

# Switch to the Temp Location
force.setLocation(x,y,z)

# Recalculate Parts
parts.buildParts()

# Switch Back to the Real Location
force.setLocation(oldx,oldy,oldz)

Now you can just simply animate the location of mesh. :smiley:

Now to work on the rotation aspects of it. Does anyone know how to rotate (or orbit) an object around a certian point, with certian radius, angle and direction (XYZ) using python? I mean is there a function for this?

I guess there is no easy already built in function…

The Math:
d = squareroot((x-x)^2 + (y-y)^2)
http://www.jjgifford.com/expressions/geometry/img/circle_coordinates.gif

you can use the matrix functions. I have seen them somewhere.

So use Object.setMatrix/getMatrix

multiply by the appriprate rotation matrix or its inverse.,…

Well, it’s a little too late for that, I got it to work with the math above. Once I fix it all up I’ll post.

[edit] This problem is slowly killing me…

Got the distance…

dis = sqrt((xE * xE) + (yE * yE) + (zE * zE))

Got it working for the xyz rotations individually.

########## Z Axis ###################
angleZ = parts.RotZ
x2 = dis*cos(angleZ)
y2 = dis*sin(angleZ)
empty.setLocation(x2,y2,0)

########## Y Axis ###################
angleY = parts.RotY
x2 = dis*cos(angleY)
z2 = dis*sin(angleY)*(-1)
empty.setLocation(x2,0,z2)

########## X Axis ###################
angleX = parts.RotX
y2 = dis*cos(angleX)
z2 = dis*sin(angleX)

empty.setLocation(0,y2,z2)

Now the pain of putting it all together, or starting all over with a different approach… die die kill ahhhh!.. lol %|

Ahhh!! Spent all that time for nothing. Anyways I found another to do it.

When you parent an object to another, and rotate the child, the parent orbits the child. So I’m just going to copy the location of the parent. So simple! :smiley:

import Blender

cube = Blender.Object.Get("Cube")
force = Blender.Object.Get("Force")

cubeEMU = Blender.Object.Get("EMU")
empty = Blender.Object.Get("Empty")

# Rotate cubeEMU, based on cube Rotation
cubeEMU.RotX = (cube.RotX * (-1))
cubeEMU.RotY = (cube.RotY * (-1))
cubeEMU.RotZ = (cube.RotZ * (-1))

# Find real location of empty
def reallocation(mat): 
	mtx = [list(mat[0][:4]),list(mat[1][:4]),
		list(mat[2][:4]), list(mat[3][:4])] 
	a = mtx[3][0] 
	b = mtx[3][1]
	c = mtx[3][2]
	return [a, b, c]
mat = empty.getMatrix()

# Set force Location
force.setLocation(reallocation(mat))

# Rebuild cube or particles
cube.buildParts()

Here is a little diagram…
http://snowshoe.f2o.org/rot.gif
All you do now is animate the rotation of cube.

Now must put everything together… :smiley: