Cloth Simulation
Cloth simulation with triangle culling
using RK4 numerical integration
===============================
Usage:
- Drag and move the handles
- Click on the cloth to organically modify the cloth form
- Space: toggle on/off the performance status
- Right: only wireframe
- Up: bitmap fill
- Right: bitmap + wireframe
/**
* Copyright esimov ( http://wonderfl.net/user/esimov )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/vATQ
*/
package
{
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.system.SecurityDomain;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.net.URLRequest;
import flash.display.DisplayObject;
import flash.display.LoaderInfo;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.GradientType;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.IOErrorEvent;
import flash.geom.Matrix;
import flash.geom.Vector3D;
import flash.ui.Keyboard;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.display.TriangleCulling;
import com.bit101.components.PushButton;
import net.hires.debug.Stats;
import mx.utils.Base64Decoder;
[SWF(width=480,height=480,backgroundColor=0xeaeaea,frameRate=60)]
/**
* @author simoe
*/
public class ClothSimulation extends Sprite
{
private var ps:ParticleSystem;
private var particles:Vector.<Vector.<Particle>>;
private var springs:Vector.<Spring>;
private var dragPoint:Particle;
private var mouseDown:Boolean = false;
private var handle1Down:Boolean = false;
private var handle2Down:Boolean = false;
private var wireframeOn:Boolean = false;
private var textureOn:Boolean = true;
private var allOn:Boolean = false;
private var numRows:Number = 22;
private var numCols:Number = 22;
private var offset:Number = 15;
private var handle1:DisplayObject;
private var handle2:DisplayObject;
private var pin1:Sprite;
private var pin2:Sprite;
private var canvas:Sprite;
private var stats:Stats;
private const STAGE_WIDTH:Number = stage.stageWidth;
private const STAGE_HEIGHT:Number = stage.stageHeight;
private var btnSelectPic:PushButton;
private var bmd:BitmapData;
private var vseg:int;
private var hseg:int;
private var vPos:Vector.<Number>;
private var vIndex:Vector.<int>;
private var uvtData:Vector.<Number>;
private var fr:FileReference;
public function ClothSimulation():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = "medium";
var i:int, j:int;
var clothWidth:Number = (numRows - 1) * offset;
var clothHeight:Number = (numCols - 1) * offset;
var posX:Number = (STAGE_WIDTH - clothWidth) / 2;
var posY:Number = (STAGE_HEIGHT - clothHeight) / 2;
particles = new Vector.<Vector.<Particle>>();
springs = new Vector.<Spring>();
ps = new ParticleSystem(new Vector3D(0, 0.08, 0), 0.01);
//switch colums and rows if rows>cols
if (numRows > numCols)
{
var temp:Number = numRows;
numRows = numCols;
numCols = temp;
}
//create a two dimensional vector array
for (i = 0; i < numRows; i++)
{
var vector_rows:Vector.<Particle> = new Vector.<Particle>();
for (j = 0; j < numCols; j++)
{
vector_rows.push(ps.makeParticle(0.9, new Vector3D(posX + j * offset, posY + i * offset, 0)));
}
particles.push(vector_rows);
}
//create Spring attractors between particles horozontally
for (i = 0; i < numRows; i++)
{
for (j = 0; j < numCols - 1; j++)
{
ps.makeSpring(particles[i][j], particles[i][j + 1], 0.9, 0.2, offset >> 1);
}
}
//create Spring attractors between particles vertically
for (i = 0; i < numRows - 1; i++)
{
for (j = 0; j < numCols; j++)
{
ps.makeSpring(particles[i][j], particles[i + 1][j], 0.9, 0.2, offset >> 1);
}
}
bmd = null;
//set Indices and UVT data
vseg = numRows;
hseg = numCols;
var vseg_1:int = vseg - 1;
var hseg_1:int = hseg - 1;
var v:int;
var h:int;
vPos = new Vector.<Number>(2 * vseg * hseg);
uvtData = new Vector.<Number>(2 * vseg * hseg);
vIndex = new Vector.<int>(6 * vseg_1 * hseg_1);
for (v = 0; v < vseg; v++)
{
for (h = 0; h < hseg; h++)
{
//x
uvtData[2 * (v * hseg + h)] = Number(h) / hseg_1;
uvtData[2 * (v * hseg + h) + 1] = Number(v) / vseg_1;
}
}
for (v = 0; v < vseg_1; v++)
{
for (h = 0; h < hseg_1; h++)
{
vIndex[6 * (v * hseg_1 + h)] = v * hseg + h;
vIndex[6 * (v * hseg_1 + h) + 1] = v * hseg + h + 1;
vIndex[6 * (v * hseg_1 + h) + 2] = (v + 1) * hseg + h;
vIndex[6 * (v * hseg_1 + h) + 3] = (v + 1) * hseg + h;
vIndex[6 * (v * hseg_1 + h) + 4] = v * hseg + h + 1;
vIndex[6 * (v * hseg_1 + h) + 5] = (v + 1) * hseg + h + 1;
}
}
createBackground();
canvas = new Sprite();
pin1 = new Sprite();
pin2 = new Sprite();
pin1.x = particles[0][0].position.x - 35;
pin1.y = particles[0][0].position.y - 25;
pin2.x = particles[0][numRows - 1].position.x - 30;
pin2.y = particles[0][numCols - 1].position.y - 25;
addChild(canvas);
canvas.addChild(pin1);
canvas.addChild(pin2);
addChild(stats = new Stats());
Security.loadPolicyFile("http://esimov.zxq.net/crossdomain.xml");
var context:LoaderContext = new LoaderContext();
context.checkPolicyFile = true;
context.applicationDomain = ApplicationDomain.currentDomain;
context.securityDomain = SecurityDomain.currentDomain;
var loader1:Loader = new Loader();
loader1.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadImage1);
loader1.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, IOErrorListener);
loader1.load(new URLRequest("http://esimov.zxq.net/pin_handle.png"));
var loader2:Loader = new Loader();
loader2.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadImage2);
loader2.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, IOErrorListener);
loader2.load(new URLRequest("http://esimov.zxq.net/pin_handle.png") );
particles[0][0].makeFix();
particles[0][numCols - 1].makeFix();
stage.addEventListener(MouseEvent.MOUSE_DOWN, onClothPress);
stage.addEventListener(MouseEvent.MOUSE_UP, onClothRelease);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
addEventListener(Event.ENTER_FRAME, renderCloth);
btnSelectPic = new PushButton(this, 5, 440, "Load Texture", buttonSelectImage);
var decoder:Base64Decoder = new Base64Decoder;
decoder.decode("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");
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadBMDComplete);
loader.loadBytes(decoder.toByteArray());
}
private function buttonSelectImage(event:MouseEvent):void
{
fr = new FileReference();
fr.addEventListener(Event.SELECT, startLoadImage);
fr.addEventListener(Event.COMPLETE, completeLoadImage);
var filter:FileFilter = new FileFilter("Images (*.jpg, *.png)", "*.jpg;*.jpeg;*.png", null);
fr.browse([filter]);
}
private function startLoadImage(event:Event):void
{
fr.load();
}
private function completeLoadImage(event:Event):void
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadBMDComplete);
loader.loadBytes(fr.data);
}
private function loadBMDComplete(event:Event):void
{
if (bmd != null)
{
bmd.dispose();
bmd = null;
}
bmd = event.target.content.bitmapData.clone();
}
private function createBackground():void
{
var background:Sprite = new Sprite();
var matrix:Matrix = new Matrix();
matrix.createGradientBox(STAGE_WIDTH, STAGE_HEIGHT);
background.graphics.beginGradientFill(GradientType.RADIAL, [0xEFEFEF, 0xEFEFEF, 0xEAEAEA], [1, 1, 1], [0x00, 0x7F, 0xFF], matrix);
background.graphics.drawRect(0, 0, STAGE_WIDTH, STAGE_HEIGHT);
background.graphics.endFill();
addChild(background);
}
private function onLoadImage1(event:Event):void
{
var info:LoaderInfo = event.target as LoaderInfo;
handle1= info.content;
pin1.addChild(handle1);
pin1.addEventListener(MouseEvent.MOUSE_DOWN, onHandleDown);
pin1.addEventListener(MouseEvent.MOUSE_UP, onHandleDown);
}
private function onLoadImage2(event:Event):void
{
var info:LoaderInfo = event.target as LoaderInfo;
handle2 = info.content;
pin2.addChild(handle2);
pin2.addEventListener(MouseEvent.MOUSE_DOWN, onHandleDown);
pin2.addEventListener(MouseEvent.MOUSE_UP, onHandleDown);
}
private function clearLoader(event:LoaderInfo):void
{
event.removeEventListener(Event.COMPLETE, onLoadImage1);
event.removeEventListener(IOErrorEvent.IO_ERROR, IOErrorListener);
}
private function IOErrorListener(event:IOErrorEvent):void
{
try {
throw new Error("Loading failed");
} catch (e:Error)
{
trace(e.toString());
}
clearLoader(event.target as LoaderInfo);
}
private function onHandleDown(event:MouseEvent):void
{
event.stopPropagation();
switch (event.type)
{
case "mouseDown":
if (event.target == pin1)
{
handle1Down = true;
handle2Down = false;
}
else if (event.target == pin2)
{
handle1Down = false;
handle2Down = true;
}
break;
case "mouseUp":
handle1Down = false;
handle2Down = false;
break;
}
}
//Togle stats visibility
private function keyDownListener(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.SPACE)
{
stats.visible = !stats.visible;
}
switch(event.keyCode)
{
case Keyboard.LEFT:
wireframeOn = true;
textureOn = false;
allOn = false;
break;
case Keyboard.UP:
wireframeOn = false;
textureOn = true;
allOn = false;
break;
case Keyboard.RIGHT:
wireframeOn = false;
textureOn = false;
allOn = true;
break;
}
}
private function onClothPress(event:MouseEvent):void
{
mouseDown = true;
dragPoint = searchDraggingPoint();
dragPoint.isDragging = true;
}
private function onClothRelease(event:MouseEvent):void
{
mouseDown = false;
dragPoint.isDragging = false;
dragPoint = undefined;
}
private function searchDraggingPoint():Particle
{
var target:Particle;
var lastMinimumDist:Number = Infinity;
for (var i:int = 0; i < numRows; i++)
{
for (var j:int = 0; j < numCols; j++)
{
var particle:Particle = particles[i][j];
var mousePos:Vector3D = new Vector3D(mouseX, mouseY, 0);
var dist:Number = particle.position.subtract(mousePos).lengthSquared;
if (dist < lastMinimumDist)
{
lastMinimumDist = dist;
target = particle;
}
}
}
return target;
}
private function renderCloth(event:Event):void
{
particles[0][0].position.x = pin1.x + 35;
particles[0][0].position.y = pin1.y + 25;
particles[0][numCols - 1].position.x = pin2.x + 30;
particles[0][numCols - 1].position.y = pin2.y + 25;
if (handle1Down)
{
pin1.x = mouseX - 35;
pin1.y = mouseY - 25;
}
if (handle2Down)
{
pin2.x = mouseX - 35;
pin2.y = mouseY - 25;
}
if (mouseDown)
{
dragPoint.position.x = mouseX;
dragPoint.position.y = mouseY;
dragPoint.velocity.scaleBy(dragPoint.mass);
}
ps.applyIntegrator(1);
ps.clearForces();
if (wireframeOn){
showWireFrame();
} else if (textureOn){
showTexture();
}
if (allOn)
{
showTexture();
showWireFrame();
}
}
private function showWireFrame():void
{
if (!allOn)
canvas.graphics.clear();
canvas.graphics.lineStyle(1, 0xAEAEAE, 1, false, null, "none");
for (var i:int = 0; i < numRows; i++)
{
for (var j:int = 0; j < numCols - 1; j++)
{
canvas.graphics.moveTo(particles[i][j].position.x, particles[i][j].position.y);
canvas.graphics.lineTo(particles[i][j + 1].position.x, particles[i][j + 1].position.y);
}
}
for (i = 0; i < numRows - 1; i++)
{
for (j = 0; j < numCols; j++)
{
canvas.graphics.moveTo(particles[i][j].position.x, particles[i][j].position.y);
canvas.graphics.lineTo(particles[i + 1][j].position.x, particles[i + 1][j].position.y);
}
}
}
private function showTexture():void
{
var i:int;
var j:int;
if (bmd != null)
{
for (i = 0; i < numRows; i++)
{
for (j = 0; j < numCols; j++)
{
vPos[2 * (i * hseg + j)] = particles[i][j].position.x; //x
vPos[2 * (i * hseg + j) + 1] = particles[i][j].position.y; //y
}
}
canvas.graphics.clear();
canvas.graphics.beginBitmapFill(bmd, null, false, true);
canvas.graphics.drawTriangles(vPos, vIndex, uvtData, TriangleCulling.NONE);
canvas.graphics.endFill();
}
}
}
}
import flash.geom.Vector3D;
internal class Particle
{
public var position : Vector3D;
public var velocity : Vector3D;
public var force : Vector3D;
public var mass : Number;
public var fixed : Boolean;
public var isDragging : Boolean;
public static const BOUNCE : String = "bounce";
public static const WRAP : String = "wrap";
public function Particle(mass : Number, position : Vector3D) : void
{
this.position = (position) ? position : new Vector3D();
this.velocity = new Vector3D;
this.force = new Vector3D;
this.mass = mass;
isDragging = false;
fixed = false;
}
public final function distanceBetween(p : Particle) : Number
{
return Vector3D.distance(this.position, p.position);
}
public final function makeFree() : void
{
fixed = false;
}
public final function makeFix() : void
{
fixed = true;
this.velocity.x = 0;
this.velocity.y = 0;
this.velocity.z = 0;
}
public final function isFree() : Boolean
{
return !fixed;
}
public final function isFixed() : Boolean
{
return fixed;
}
public function setMass(value : Number) : void
{
this.mass = value;
}
public function reset() : void
{
this.position.x = 0;
this.position.y = 0;
this.position.z = 0;
this.velocity.y = 0;
this.velocity.y = 0;
this.velocity.z = 0;
this.force.x = 0;
this.force.y = 0;
this.force.z = 0;
this.mass = 1;
}
public function boundCheck(type : String, left : Number, right : Number, top : Number, bottom : Number) : void
{
switch (type)
{
case Particle.BOUNCE:
if (this.position.x < left)
{
position.x = left + (left - position.x);
velocity.x *= -1;
}
if (this.position.x > right)
{
position.x = right - (position.x - right);
velocity.x *= -1;
}
if (this.position.y < top)
{
position.y = top + (top - position.y);
velocity.y *= -1;
}
if (this.position.y > bottom)
{
position.y = bottom - (position.y - bottom);
velocity.y *= -1;
}
break;
case Particle.WRAP:
break;
}
}
}
internal interface Integrator
{
function apply(t : Number) : void;
}
internal class Spring
{
private var p1 : Particle;
private var p2 : Particle;
private var springConst : Number;
private var on : Boolean;
private var damping : Number;
private var restLength : Number;
public function Spring(p1 : Particle, p2 : Particle, springConst : Number, damping : Number, restLength : Number) : void
{
this.p1 = p1;
this.p2 = p2;
this.damping = damping;
this.restLength = restLength;
this.springConst = springConst;
this.on = true;
}
public final function turnOn() : void
{
on = true;
}
public final function turnOff() : void
{
on = false;
}
public final function isOn() : Boolean
{
return on;
}
public final function isOff() : Boolean
{
return !on;
}
public final function getDistance(p1 : Particle, p2 : Particle) : Number
{
return Vector3D.distance(p1.position, p2.position);
}
public final function setDamping(value : Number) : void
{
this.damping = value;
}
public final function getDamping() : Number
{
return damping;
}
public final function setRestLength(value : Number) : void
{
this.restLength = value;
}
public final function getRestLength() : Number
{
return this.restLength;
}
public function update() : void
{
if (on && (p1.isFree() || p2.isFree() ))
{
var distX : Number = p2.position.x - p1.position.x;
var distY : Number = p2.position.y - p1.position.y;
var distZ : Number = p2.position.z - p1.position.z;
var distSq : Number = Math.sqrt(distX * distX + distY * distY + distZ * distZ);
if (distSq == 0)
{
distX = 0;
distY = 0;
distZ = 0;
}
distX /= distSq;
distY /= distSq;
distZ /= distSq;
var springForce : Number = -(distSq - restLength) * springConst;
var velX : Number = p2.velocity.x - p1.velocity.x;
var velY : Number = p2.velocity.y - p1.velocity.y;
var velZ : Number = p2.velocity.z - p1.velocity.z;
var dampingForce : Number = -damping * (distX * velX + distY * velY + distZ * velZ);
var aggregateForce : Number = springForce + dampingForce;
distX *= aggregateForce;
distY *= aggregateForce;
distZ *= aggregateForce;
if (p1.isFree())
{
p1.force = p1.force.add(new Vector3D(-distX, -distY, -distZ));
}
if (p2.isFree())
{
p2.force = p2.force.add(new Vector3D(distX, distY, distZ));
}
}
}
}
internal class Attraction
{
private var p1 : Particle;
private var p2 : Particle;
private var minDistance : Number;
private var minDistanceSq : Number;
private var strength : Number;
private var on : Boolean;
public function Attraction(p1 : Particle, p2 : Particle, strength : Number, minDistance : Number) : void
{
this.p1 = p1;
this.p2 = p2;
this.minDistance = minDistance;
this.minDistanceSq = minDistance * minDistance;
this.strength = strength;
on = true;
}
public final function turnOn() : void
{
on = true;
}
public final function turnOff() : void
{
on = false;
}
public final function isOn() : Boolean
{
return on;
}
public final function isOff() : Boolean
{
return !on;
}
public final function setStrength(value : Number) : void
{
this.strength = value;
}
public final function getStrength() : Number
{
return this.strength;
}
public final function setDistance(value : Number) : void
{
this.minDistance = value;
this.minDistanceSq = value * value;
}
public final function getDistance() : Number
{
return minDistance;
}
public function update() : void
{
if (on && (p1.isFree() || p2.isFree() ))
{
var distX : Number = p2.position.x - p1.position.x;
var distY : Number = p2.position.y - p1.position.y;
var distZ : Number = p2.position.z - p1.position.z;
var distanceSq : Number = distX * distX + distY * distY + distZ * distZ;
var lenght : Number = Math.sqrt(distanceSq);
if (distanceSq < minDistanceSq)
{
distanceSq = minDistanceSq;
}
var force : Number = strength * (p1.mass * p2.mass) / distanceSq;
distX /= lenght;
distY /= lenght;
distZ /= lenght;
distX *= force;
distY *= force;
distZ *= force;
if (p1.isFree())
{
p1.force = p1.force.add(new Vector3D(distX, distY, distZ));
}
if (p2.isFree())
{
p2.force = p2.force.add(new Vector3D(-distX, -distY, -distZ));
}
}
}
}
internal class RKIntegrator implements Integrator
{
private var originalPosV : Vector.<Vector3D>;
private var originalVelV : Vector.<Vector3D>;
private var k1VelV : Vector.<Vector3D>;
private var k1ForceV : Vector.<Vector3D>;
private var k2VelV : Vector.<Vector3D>;
private var k2ForceV : Vector.<Vector3D>;
private var k3VelV : Vector.<Vector3D>;
private var k3ForceV : Vector.<Vector3D>;
private var k4VelV : Vector.<Vector3D>;
private var k4ForceV : Vector.<Vector3D>;
private var p : Particle;
private var particleSystem : ParticleSystem;
public function RKIntegrator(particleSystem : ParticleSystem) : void
{
this.particleSystem = particleSystem;
originalPosV = new Vector.<Vector3D>();
originalVelV = new Vector.<Vector3D>();
k1VelV = new Vector.<Vector3D>();
k1ForceV = new Vector.<Vector3D>();
k2VelV = new Vector.<Vector3D>();
k2ForceV = new Vector.<Vector3D>();
k3VelV = new Vector.<Vector3D>();
k3ForceV = new Vector.<Vector3D>();
k4VelV = new Vector.<Vector3D>();
k4ForceV = new Vector.<Vector3D>();
}
/* INTERFACE esimov.physics.Integrator */
private function createParticles() : void
{
while(particleSystem.particles.length > originalPosV.length)
{
originalPosV.push(new Vector3D());
originalVelV.push(new Vector3D());
k1VelV.push(new Vector3D());
k1ForceV.push(new Vector3D());
k2VelV.push(new Vector3D());
k2ForceV.push(new Vector3D());
k3VelV.push(new Vector3D());
k3ForceV.push(new Vector3D());
k4VelV.push(new Vector3D());
k4ForceV.push(new Vector3D());
}
}
public function apply(t : Number) : void
{
createParticles();
var numPart : Number = particleSystem.particles.length;
var particles : Vector.<Particle> = particleSystem.particles;
var i : int;
var originalPos : Vector3D;
var originalVel : Vector3D;
var k1Vel : Vector3D;
var k1Force : Vector3D;
var k2Vel : Vector3D;
var k2Force : Vector3D;
var k3Vel : Vector3D;
var k3Force : Vector3D;
var k4Vel : Vector3D;
var k4Force : Vector3D;
/**
* Get initial position and velocity,
* apply forces and velocity, the result is K1
*/
for (i = 0;i < numPart;i++)
{
if (!Particle(particles[i]).fixed)
{
originalPosV[i] = Particle(particles[i]).position.clone();
originalVelV[i] = Particle(particles[i]).velocity.clone();
}
Particle(particles[i]).force.x = 0;
Particle(particles[i]).force.y = 0;
Particle(particles[i]).force.z = 0;
}
particleSystem.applyForces();
for (i = 0;i < numPart;i++)
{
if (!Particle(particles[i]).fixed)
{
k1ForceV[i] = Particle(particles[i]).force.clone();
k1VelV[i] = Particle(particles[i]).velocity.clone();
}
Particle(particles[i]).force.x = 0;
Particle(particles[i]).force.y = 0;
Particle(particles[i]).force.z = 0;
}
/**
* Get initial position, K1 velocity
* apply forces and velocity, the result is K2
*/
for (i = 0;i < numPart;i++)
{
p = particles[i];
if (!p.fixed)
{
originalPos = originalPosV[i];
k1Vel = k1VelV[i];
k1Vel.scaleBy(0.5 * t);
p.position = originalPos.add(k1Vel);
originalVel = originalVelV[i];
k1Force = k1ForceV[i];
k1Force.scaleBy(0.5 * t / p.mass);
p.velocity = originalVel.add(k1Force);
}
}
particleSystem.applyForces();
for (i = 0;i < numPart;i++)
{
p = particles[i];
if (!p.fixed)
{
k2ForceV[i] = p.force.clone();
k2VelV[i] = p.velocity.clone();
}
p.force.x = 0;
p.force.y = 0;
p.force.z = 0;
}
/**
* Get initial position, K2 velocity
* apply forces and velocity, the result is K3
*/
for (i = 0;i < numPart;i++)
{
p = particles[i];
if (!p.fixed)
{
originalPos = originalPosV[i];
k2Vel = k2VelV[i];
k2Vel.scaleBy(0.5 * t);
p.position = originalPos.add(k2Vel);
originalVel = originalVelV[i];
k2Force = k2ForceV[i];
k2Force.scaleBy(0.5 * t / p.mass);
p.velocity = originalVel.add(k2Force);
}
}
particleSystem.applyForces();
for (i = 0;i < numPart;i++)
{
p = particles[i];
if (!p.fixed)
{
k3ForceV[i] = p.force.clone();
k3VelV[i] = p.velocity.clone();
}
p.force.x = 0;
p.force.y = 0;
p.force.z = 0;
}
/**
* Get initial position, K3 velocity
* apply forces and velocity, the result is K4
*/
for (i = 0;i < numPart;i++)
{
p = particles[i];
if (!p.fixed)
{
originalPos = originalPosV[i];
k3Vel = k3VelV[i];
k3Vel.scaleBy(0.5 * t);
p.position = originalPos.add(k2Vel);
originalVel = originalVelV[i];
k3Force = k3ForceV[i];
k3Force.scaleBy(0.5 * t / p.mass);
p.velocity = originalVel.add(k3Force);
}
}
particleSystem.applyForces();
for (i = 0;i < numPart;i++)
{
p = particles[i];
if (!p.fixed)
{
k4ForceV[i] = p.force.clone();
k4VelV[i] = p.velocity.clone();
}
p.force.x = 0;
p.force.y = 0;
p.force.z = 0;
}
/**
* Update initial position and velocity based on intermediate values
*/
for (i = 0;i < numPart;i++)
{
p = particles[i];
if (!p.fixed)
{
//position
originalPos = originalPosV[i];
k1Vel = k1VelV[i];
k2Vel = k2VelV[i];
k3Vel = k3VelV[i];
k4Vel = k4VelV[i];
var k2VelInt : Vector3D = k2Vel.clone();
k2VelInt.scaleBy(2);
var k3VelInt : Vector3D = k3Vel.clone();
k3VelInt.scaleBy(2);
var intVel : Vector3D = k1Vel.add(k2VelInt).add(k3VelInt).add(k4Vel);
intVel.scaleBy(t / 6);
p.position = originalPos.add(intVel);
// velocity
originalVel = originalVelV[i];
k1Force = k1ForceV[i];
k2Force = k2ForceV[i];
k3Force = k3ForceV[i];
k4Force = k4ForceV[i];
var k2ForceInt : Vector3D = k2Force.clone();
k2ForceInt.scaleBy(2);
var k3ForceInt : Vector3D = k3Force.clone();
k3ForceInt.scaleBy(2);
var intForce : Vector3D = k1Force.add(k2ForceInt).add(k3ForceInt).add(k4Force);
intForce.scaleBy(t / 6 * p.mass);
p.velocity = originalVel.add(intForce);
}
}
}
}
internal class ParticleSystem
{
internal var particles : Vector.<Particle>;
internal var springs : Vector.<Spring>;
internal var attractors : Vector.<Attraction>;
private var integrator : Integrator;
private var gravity : Vector3D;
private var drag : Number;
private var restLength : Number = 200;
public static const RK : String = "RUNGE_KUTTA";
public static const EULER : String = "MODIFIED_EULER";
public static const VERLET : String = "VERLET";
public function ParticleSystem(gravity : Vector3D = null, drag : Number = 0.001) : void
{
particles = new Vector.<Particle>();
springs = new Vector.<Spring>();
attractors = new Vector.<Attraction>();
this.integrator = new RKIntegrator(this);
this.gravity = (gravity) ? gravity : new Vector3D();
this.drag = drag;
}
public final function getIntegrator() : Integrator
{
return this.integrator;
}
public final function applyIntegrator(t : Number = 1) : void
{
integrator.apply(t);
}
public final function setGravity(value : Number) : void
{
this.gravity.scaleBy(value);
}
public final function getGravity() : Vector3D
{
return this.gravity;
}
public final function setDrag(value : Number) : void
{
this.drag = value;
}
public final function getDrag() : Number
{
return drag;
}
public final function makeParticle(mass : Number = 1, position : Vector3D = null) : Particle
{
var particle : Particle = new Particle(mass, position);
particle.isDragging = false;
particles.push(particle);
return particle;
}
public final function makeSpring(p1 : Particle, p2 : Particle, damping : Number, restLenght : Number, springConst : Number) : Spring
{
var spring : Spring = new Spring(p1, p2, damping, restLenght, springConst);
springs.push(spring);
return spring;
}
public final function makeAttractors(p1 : Particle, p2 : Particle, strength : Number, minDist : Number) : Attraction
{
var attraction : Attraction = new Attraction(p1, p2, strength, minDist);
attractors.push(attraction);
return attraction;
}
public function getParticlesLength() : Number
{
return particles.length;
}
public function getSpringsLength() : Number
{
return springs.length;
}
public function getAttractorsLength() : Number
{
return attractors.length;
}
public final function applyForces() : void
{
var i : int;
if (gravity.x != 0 || gravity.y != 0 || gravity.z != 0)
{
for (i = 0;i < getParticlesLength();i++)
{
var particle : Particle = Particle(particles[i]);
if (!particle.isDragging)
{
particle.force = particle.force.add(gravity);
}
else
{
particle.force = new Vector3D();
}
}
}
for (i = 0;i < getParticlesLength();i++)
{
particle = Particle(particles[i]);
if (!particle.isDragging)
{
var vel : Vector3D = particle.velocity.clone();
vel.scaleBy(-drag);
particle.force = particle.force.add(vel);
}
else
{
particle.velocity = new Vector3D();
}
}
for (i = 0;i < getSpringsLength();i++)
{
var spring : Spring = Spring(springs[i]);
spring.update();
}
for (i = 0;i < getAttractorsLength();i++)
{
var attractor : Attraction = Attraction(attractors[i]);
attractor.update();
}
}
public final function clear() : void
{
var i : int;
for (i = 0;i <= getParticlesLength();i++)
particles[i] = null;
for (i = 0;i <= getAttractorsLength();i++)
attractors[i] = null;
for (i = 0;i <= getSpringsLength();i++)
springs[i] = null;
particles = new Vector.<Particle>();
attractors = new Vector.<Attraction>();
springs = new Vector.<Spring>();
}
public final function clearForces() : void
{
for (var i : int = i;i < getParticlesLength();i++)
{
Particle(particles[i]).force.x = 0;
Particle(particles[i]).force.y = 0;
Particle(particles[i]).force.z = 0;
}
}
public final function getParticle(index : Number) : Particle
{
return particles[index];
}
public final function getAttractor(index : Number) : Attraction
{
return attractors[index];
}
public final function getSpring(index : Number) : Spring
{
return springs[index];
}
public final function removeParticle(n : int) : void
{
particles[n] = null;
particles.splice(n, 1);
}
public final function removeSprings(n : int) : void
{
springs[n] = null;
springs.splice(n, 1);
}
public final function removeAttractors(n : int) : void
{
attractors[n] = null;
attractors.splice(n, 1);
}
public final function removeParticleByIndex(p : Particle) : Boolean
{
var i : int;
var n : Number = -1;
for (i = 0;i <= getParticlesLength();i++)
{
if (particles[i] == p)
{
n = i;
break;
}
}
if (n != -1)
{
particles[n] = null;
particles.splice(n, 1);
return true;
}
else return false;
}
public final function removeSpringByIndex(s : Spring) : Boolean
{
var i : int;
var n : Number = -1;
for (i = 0;i <= getParticlesLength();i++)
{
if (springs[i] == s)
{
n = i;
break;
}
}
if (n != -1)
{
springs[n] = null;
springs.splice(n, 1);
return true;
}
else return false;
}
public final function removeAttractorByIndex(a : Attraction) : Boolean
{
var i : int;
var n : Number = -1;
for (i = 0;i <= getParticlesLength();i++)
{
if (attractors[i] == a)
{
n = i;
break;
}
}
if (n != -1)
{
attractors[n] = null;
attractors.splice(n, 1);
return true;
}
else return false;
}
public function constraintSolve() : void
{
for (var i : int = 0;i < getParticlesLength() - 1;i++)
{
var p1 : Particle = particles[i];
var p2 : Particle = particles[i + 1];
var dx : Number = p2.position.x - p1.position.x;
var dy : Number = p2.position.y - p1.position.y;
var delta : Number = Math.sqrt(dx * dx + dy * dy);
var diff : Number = restLength - delta;
var offsetX : Number = (diff * dx / delta) * 0.5;
var offsetY : Number = (diff * dy / delta) * 0.5;
p1.position.x -= offsetX;
p1.position.y -= offsetY;
p2.position.x += offsetX;
p2.position.y += offsetY;
}
}
}