Hi all, i'm trying to do a particle system where basically i have a matrix of drops that is gonna fall down. Kind o the simulation of a 3d water courtain.
As in the Shiffman examples, i'm using a OOP approach, where each particle is an object in an arraylist and when they go too fare are deleted to free memory.
The only difference is that the particle system is executed in a parallel thread and the main one just get a copy of the particles to represent them, when is needed.
What i don't understand, is why the sketch slow down so much when the drops approach the distance where they are deleted. After all, the check happen to every loop anyway. Is there some technique to make this more efficient?
import peasy.*;
PeasyCam cam;
ParticleSystem ps;
void setup() {
size(600, 600, P3D);
cam = new PeasyCam(this, 15, 30, 15, 100);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);
ps = new ParticleSystem();
}
void draw() {
background(255);
noFill();
strokeWeight(1);
pushMatrix();
translate(15, -5, 15);
box(30, 10, 30);
popMatrix();
pushMatrix();
translate(15, 50, 15);
box(30, 30, 30);
popMatrix();
pushMatrix();
strokeWeight(0.1);
ArrayList<Particle> particles = ps.particles();
for (int i = 0; i< particles.size(); i++ ) {
point(
particles.get(i).position.x,
particles.get(i).position.y,
particles.get(i).position.z
);
}
popMatrix();
}
public class ParticleSystem implements Runnable {
boolean loop = true;
ArrayList<Particle> particles;
long lastUpdate;
int updateInterval = 10;
float maxTravelDistance = 35 ;
float pRF = 0.005; // particlesRandomFactor
public ParticleSystem() {
particles = new ArrayList<Particle>();
for (int x = 0; x < 15; x++) {
for (int z = 0; z < 15; z++) {
for (int i = 0; i < 1000; i++)
{
particles.add(new Particle(new PVector(x*2, 0, z*2), new PVector(random(-pRF, pRF), random(-pRF, pRF), random(-pRF, pRF))));
}
}
}
new Thread(this).start();
println(particles.size());
}
@Override
public void run() {
while (loop) {
if (millis()-lastUpdate > updateInterval && millis() > 3000) {
if (particles.size() >0) {
for (int i = particles.size()-1; i>0; i--) {
if (particles.get(i).position.y > maxTravelDistance) particles.remove(i);
else particles.get(i).update();
}
}
lastUpdate = millis();
}
}
}
///////////particles
public synchronized ArrayList<Particle> particles() {
return particles;
}
public synchronized PVector[] getPositions() {
//ArrayList<Particle>particlesToExport = particles().toArray(new Particle[particles.size()]);
ArrayList<Particle>particlesToExport = particles;
PVector[] output = new PVector[particlesToExport.size()];
for (int i = 0; i < output.length; i++)
{
output[i] = particlesToExport.get(i).position();
}
return output;
}
}
public class Particle {
float mass;
boolean isDead = false;
float airDrag = 0.95;
PVector position;
PVector oldPosition;
PVector speed;
PVector acceleration;
public Particle(PVector p, PVector s) {
mass = random(0.9, 1.1);
position = p;
speed = s;
acceleration = new PVector(0, 0.02*mass, 0);
}
void update() {
//oldPosition = position;
if (abs(speed.x) >=0.05 || abs(speed.z) >= 0.05) speed.mult(airDrag);
if (!(speed.y > 10)) speed.add(acceleration);
position.add(speed);
}
///////////position
public synchronized void position(PVector input) {
position = input;
}
public synchronized PVector position() {
return position;
}
}