Get Adobe Flash player

CLOTHX.PHYSICS 3.0.1


A simple particle system physics engine for processing. (Jeff) designed this to be application / domain agnostic. All this is supposed to do is let you make particles, apply forces and calculate the positions of particles over time in real-time. Anything else you need to handle yourself And I've ported it to haXe so you can cross target. Also on my to-do list are… 


  1. optimize flash performance
  2. c++ target
  3. js target


There are four parts

  1. ParticleSystem - takes care of gravity, drag, making particles, applying forces and advancing the simulation
  2. Particles - they move around in 3D space based on forces you've applied to them
  3. Springs - they act on two particles
  4. Attractions - which also act on two particles

DOWNLOAD SOURCE FROM GITHUB



Or use haxelib to install it via terminal/bash

haxelib install clothx


LICENSE - Use this code for whatever you want, just send me a link Jeff(at)traer(dot)com

                   - I agree, link me something awesome martin.lindelof(at)gmail(dot)com



Get Adobe Flash player

DOCS


PARTICLE SYSTEM


The particle system is in charge of everything. It makes particles and forces for you and you tell it to advance the simulation using tick().


new ParticleSystem()

new ParticleSystem(?gravity : Vector3D, drag : Float = 0.001)

Construct a new particle system with some downward (positive y) or 3D gravity and some drag. You can make as many of these as you'd like per sketch as long as forces from one system don't refer to particles from another. I don't know what would happen if you connected particles from one system to another.


void setIntegrator(integrator : Int)

pass this either:  ParticleSystem.RUNGE_KUTTA or ParticleSystem.MODIFIED_EULER Runge-Kutta is the default. It takes about 4 times as many cycles as Modified Euler. In return the system gets very stable. If you plan to have have over 1000 particles interacting with each other try Modified Euler. If you will have fewer particles and want tight springs and quicker responses use Runge-Kutta. Stick with the default and if things get slow try switching to Euler. You may have to add more drag or reduce the strength of springs and attractions to keep it stable. The example Random Arboretum above has sections of code you can uncomment to experiment with this.


void setGravity(gravity : Vector3D)

set the strength of gravity, down (in the positive y direction) or in whatever 3D direction you feel like. You probably want the magnitude of this to be in the range of 0-5.


void setDrag(d : Float)

set the drag force that acts on all objects equally, and proportional to velocity.


void tick()

void tick(t : Float = 1)

advance the simulation by some time t, or by the default 1.0. You'll want to call this in draw(). You probably want to keep this the same at all times unless you want speed up or slow things down.


void clear()

this deletes all the particles and all the forces in the system (except the omnipresent gravity and drag even if ther are 0).


Particle makeParticle()

Particle makeParticle(mass : Float = 1, ?position : Vector3D)

Create a new particle in the system with some mass and at some x, y, z position. The default is a new particle with mass 1.0 at (0, 0, 0).


numberOfParticles():Int

getParticle(i : Int):Particle

removeParticle(i : Int):Void

removeParticleByReference(p : Particle):Bool

Note removing things shifts the indices and the library does not take responsibility for you deleting particles that forces refer to. e.g. if you have a spring between two particles and remove one things will definitely break. 


makeSpring(a : Particle, b : Particle, springConstant : Float, damping : Float, restLength : Float):Spring

make a spring in the system between 2 particles you have previously created. Look at spring down there for what the parameters mean.


numberOfSprings():Int

getSpring(i : Int):Spring

removeSpring(i : Int):Void

removeSpringByReference(s : Spring):Bool

Note removing things shifts the indices.


Attraction makeAttraction( Particle a, Particle b, float strength, float minimumDistance )

Make an attraction (or repulsion) force between two particles. If the strength is negative they repel each other, if the strength is positive they attract. There is also a minimum distance that limits how strong this force can get close up.


numberOfAttractions():Int

getAttraction(i : Int):Attraction

removeAttraction(i : Int):Void

removeAttractionByReference(s : Attraction):Bool

Note removing things shifts the indices.



PARTICLE


Particles can represent objects, corners of 2D or 3D shapes or abstract things that won't even be drawn. Particles have 4 properties:

  1. Mass
  2. Position
  3. Velocity
  4. Age
  5. Fixed / Free

positon.setTo(xa : Float, ya : Float, za : Float):Void

Move the particle to some 3D location.


position.add(a : Vector3D)

Move the particle by some 3D amount


position.x : Float 

position.y : Float 

position.z : Float

This is how you get to the dimensions of particle position.


velocity.setTo(xa : Float, ya : Float, za : Float):Void

Set the velocity to some 3D quantity, maybe use this to send a particle flying off in a particular direction.


velocity.add(a : Vector3D):Void

This adds some 3D quantity to the velocity of the particle. You could maybe use this to speed up or slow down a particle.


velocity.x : Float 

velocity.y : Float 

velocity.z : Float

This is how you get at the dimensions of the particles velocity.


mass -> Float 

setMass(m : Float):Void

These set and get the mass of the particle. Heavier particles will have more inertia and will accelerate slower. Attraction/repulsion forces will also be stronger for heavier particles. If you aren't doing anything special this will probably be the same for all particles.


makeFixed():Void 

isFixed():Bool 

makeFree():Void 

isFree():Bool

Particles can either be fixed or free. If they are free they move around and are affected by forces, if they are fixed they stay where they are.


age : Float

How long the particle has been around. Every time you advance the simulation by t every particle gets a little older by t.



Get Adobe Flash player

SPRING


Springs connect 2 particles and try to keep them a certain distance apart. They have 3 properties:

  1. Rest Length - the spring wants to be at this length and acts on the particles to push or pull them exactly this far apart at all times.
  2. Strength - If they are strong they act like a stick. If they are weak they take a long time to return to their rest length.
  3. Damping - If springs have high damping they don't overshoot and they settle down quickly, with low damping springs oscillate.

getOneEnd():Particle

getTheOtherEnd():Particle

Return the particles that are on either end of this spring.


currentLength():Float

The current length of the spring.


getRestLength():Float 

setRestLength(l : Float):Void

getStrength():Float 

setStrength(ks : Float)

getDamping():Float 

setDamping(d : Float)

turnOff():Void

turnOn():Void

isOn():Bool

isOff():Bool



ATTRACTION


Attractions or repulsions (negative attraction) act on 2 particles and either constantly pull them together or constantly pull them apart by applying a force to each particle: 


G*m1*m2/d2


in other words the force is is much stronger close up than far away. 


Attractions/repulsions have 2 properties:

  1. Strength - the G up there.
  2. Minimum Distance - the force does not get stronger closer than this

getStrength():Float 

setStrength(k : Float):Void

Positive strength is attraction negative strength is repulsion.


getOneEnd():Particle

getTheOtherEnd():Particle

Return the particles being attracting or repeling each other.


getMinimumDistance():Float

setMinimumDistance(d : Float):Void

Get and set the minimum distance, which limits how strong the force can get close up.


turnOff():Void

turnOn():Void

isOn():Void

isOff():Void



CUSTOM FORCES


Each particle has a Vector3D called force. If you make your own subclass of Force you can stick it in the particle system and have it applied along with all the other forces. The relevant methods from ParticleSystem are: 


addCustomForce(f : Force):Void

getCustomForce(i : Int):Force

numberOfCustomForces():Int

removeCustomForce(i : Int):Void

removeCustomForceByReference(f : Force):Bool


Example


class MyCustomForce implements Force

{

// Particle p; or one or more particles

// you're applying this force to


public function apply():Void

{

// calculate force to apply to particle(s) 

// based on their position and velocity

// e.g. float f = p.position().x();

// add that force to the particle's force vector 

// e.g. p.force().add( f, f, f );

}

}


Then in setup() do something like


physics.addCustomForce( new MyCustomForce( p ) );


p.force() is an instance of Vector3D (just like position and velocity). It has all sorts of facilities like multiplication and dot products that you may want to use. Have a look at the source and how it's used in Spring and Attraction for inspiration.


If you have a good example of a custom force of some kind drop me a line and I'll put it up for others.