import Geometry.*; import java.awt.*; /** * Summary description for ParticleSystem. */ public class ParticleSystem { class Particle { Vector3 position; Vector3 velocity; double age=-1; double lifespan; double size; double[] startColor = new double[4]; double[] endColor = new double[4]; double[] color = new double[4]; } boolean explosion=false; boolean rings=false; public ParticleSystem(int maxParticles) { particles = new Particle[maxParticles]; for(int i=0; i _end ) { start = _end; end = _start; } else { start = _start; end = _end; } return Math.random() * (end - start) + start; } Vector3 cp; private void resetParticle(Particle particle) { particle.position = this.position.copy(); double angle = random(minAngle, maxAngle); double rotation = random(minRotate, maxRotate); double speed = random(minSpeed,maxSpeed); //Vector3 cp = up.cross(direction).NORMALIZE(); if(explosion) { if(particle.velocity == null) particle.velocity = new Vector3(); particle.velocity.SET(random(-1,1), random(-1,1), random(-1,1)); particle.velocity.NORMALIZE(); particle.velocity.MUL(speed); } else if(rings) { if(particle.velocity == null) particle.velocity = new Vector3(); if(random(-1,1) > 0) { particle.velocity.SET(random(-1,1), random(-1,1), 0); } else { particle.velocity.SET(random(-1,1), 0, random(-1,1)); } particle.velocity.NORMALIZE(); particle.velocity.MUL(speed); } else { Matrix4x4 rotateMatrix = (new Matrix4x4()).rotate(cp, rotation).rotate(direction, angle); //Matrix4x4 rotateMatrix = // (new Matrix4x4()).rotate(direction, rotation).rotate(cp, angle); //particle.velocity = rotateMatrix.mul(direction).mul(speed); particle.velocity = rotateMatrix.mul(direction); particle.velocity.MUL(speed); } particle.age = 0; particle.size = random(minSize, maxSize); particle.lifespan = random(minLife, maxLife); for(int k=0; k<4; k++) { particle.startColor[k] = random(minStartColor[k], maxStartColor[k]); particle.endColor[k] = random(minEndColor[k], maxEndColor[k]); } /* particle.startColor[1] = random(minStartColor[1], maxStartColor[1]); particle.startColor[2] = random(minStartColor[2], maxStartColor[2]); particle.startColor[3] = random(minStartColor[3], maxStartColor[3]); particle.endColor[1] = random(minEndColor[1], maxEndColor[1]); particle.endColor[2] = random(minEndColor[2], maxEndColor[2]); */ } double lerp(double x, double y, double a) { return a*x + (1-a)*y; } private void updateParticle(Particle particle, double timeDelta) { if( particle.age == -1 ) return; particle.age += timeDelta; if( particle.age >= particle.lifespan ) { particle.age = -1; return; } /*particle.position = */ particle.position.ADD(particle.velocity.mul(timeDelta) ); /*particle.velocity = */ particle.velocity.ADD(gravity.mul(timeDelta) ); double interp = particle.age / particle.lifespan; for(int i=0; i<4; i++) particle.color[i] = lerp( particle.endColor[i], particle.startColor[i],interp ); } private void renderParticle(ThreeDimensionalApplet app, Particle particle) { app.pointSize((int)Math.round(particle.size)); //app.color(new Color(255, 0, 0)); app.color4d(particle.color[0], particle.color[1], particle.color[2], particle.color[3]); app.vertex(particle.position); } public void update(double timeDelta) { double particlesNeeded = timeDelta * flowRate + flowResidue; for(int i=0; i= 1 ) { resetParticle(particles[i]); particlesNeeded = particlesNeeded - 1.0; } } flowResidue = particlesNeeded; } public void render(ThreeDimensionalApplet app) { app.enable(app.RENDER_BLENDING); app.blendFunc(app.RENDER_SRC_ALPHA, app.RENDER_ONE_MINUS_SRC_ALPHA); //app.blendFunc(app.RENDER_SRC_ALPHA, app.RENDER_ONE); app.disable(app.RENDER_LIGHTING); app.enable(app.RENDER_TEXTURE); app.pointSize(4); app.begin(app.RENDER_POINTS); for(int i=0; i