/****************************************************************************** * Copyright (c) 2008 Marco Della Vedova, Matteo Foppiano * and Pimods contributors * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.pixelinstrument.net/license/cpl-v10.html ******************************************************************************/ package net.sf.robocode.bv3d.scenegraph; import java.util.Random; import net.sf.robocode.bv3d.math.Vertex3f; import net.sf.robocode.bv3d.scenegraph.ModelView; /** * @author Marco Della Vedova - pixelinstrument.net * @author Matteo Foppiano - pixelinstrument.net * */ public class ParticleSystem extends TransformationNode implements Ageing { private static Random random = new Random(); private static final float ELAPSED_TIME = 1.0f / 25; // TODO variabilizzare/mettere in funzione dell'aggiornamento della scena? private int numParticles; private float position_var, velocity, velocity_var, direction_var, groundHeight; private int lifetime, lifetime_var; private Vertex3f direction; private Vertex3f gravity; private Particle particle[]; public ParticleSystem(int numParticles, float position_var, float velocity, float velocity_var, int lifetime, int lifetime_var, float direction_var, Vertex3f direction, float groundHeight, Vertex3f gravity, ModelView mvParticle) { this.numParticles = numParticles; this.velocity = velocity; this.velocity_var = velocity_var; this.lifetime = lifetime; this.lifetime_var = lifetime_var; this.direction_var = direction_var; this.direction = direction; this.gravity = gravity; this.groundHeight = groundHeight; this.particle = new Particle[numParticles]; for (int i = 0; i < numParticles; i++) { Vertex3f pos = new Vertex3f((float) random.nextGaussian() / 2 * position_var, (float) random.nextGaussian() / 2 * position_var, (float) random.nextGaussian() / 2 * position_var); // Particles underground are forbidden! if (groundHeight + pos.getY() < 0) { pos.setY(-pos.getY()); } Vertex3f vel = (Vertex3f) direction.clone(); // vel.normalize(); vel.x += (float) random.nextGaussian() / 2 * direction_var; vel.y += (float) random.nextGaussian() / 2 * direction_var; vel.z += (float) random.nextGaussian() / 2 * direction_var; vel.normalize(); vel.mul(velocity + (float) random.nextGaussian() / 2 * velocity_var); int ttl = lifetime + random.nextInt(lifetime_var) - lifetime / 2; Particle p = new Particle(vel, ttl, mvParticle); p.setRotate(random.nextFloat() * 180, 1, 1, 1); p.setPosition(pos); p.setScale(2f, 2f, 2f); this.particle[i] = p; this.addDrawable(p); } } public boolean heartBeat() { boolean alive = false; for (int i = 0; i < this.particle.length; i++) { Vertex3f pos = particle[i].getPosition(); Vertex3f vel = particle[i].getVelocity(); int ttl = particle[i].getTTL(); pos.add(vel); Vertex3f speedUp = ((Vertex3f) this.gravity.clone()); speedUp.mul(ELAPSED_TIME); vel.add(speedUp); if (pos.y + this.groundHeight < 0) { vel.y = -vel.y; vel.mul(0.5f); } particle[i].setPosition(pos); particle[i].setVelocity(vel); particle[i].setTTL(--ttl); if (!alive && ttl > 0) { alive = true; } } return(alive); } }