Theres a easier way to do it with the particle effect, you just have to use the Fog Machine as sample
you can see it in my video at 0:43:
this is how particle system looks:
package particleengine;
import nlvm.lang.*;
import nlvm.math3d.*;
public class ParticleEmitter extends PhysicalObject
{
private ParticleList _ParticlePool;
private ParticleList _ParticleList;
private ParticleManager _Manager;
private float _sumTimeSteps;
public Vector3f EmitterDirection;
public Vector3f ParticleGravity = new Vector3f();
public float ParticleAirResistance = 0;
public float ParticlesPerSecond = 1;
public float ParticleInitialVelocity;
public float ParticleTimeToLive = 2;
public float ParticleMass = 1;
public float ParticleRotationSpeed = 0;
public bool ParticleRotationRandomStartAngle = false;
public bool ParticleRotationRandomDirection = false;
public float ParticleStartScale = 1;
public float ParticleEndScale = 1;
public float ParticlePositionJitterX = 0;
public float ParticlePositionJitterY = 0;
public float ParticlePositionJitterZ = 0;
// Alpha Controls
public float FadeInDuration = 0;
public float FadeOutDuration = 0;
public float Opacity = 1;
public bool Enabled = false;
// Create a new particle emitter.
public ParticleEmitter(ParticleManager manager, ParticleList pool)
{
_Manager = manager;
_ParticlePool = pool;
_ParticleList = new ParticleList();
EmitterDirection = new Vector3f();
}
public void SetEmitterDirection(float x, float y, float z)
{
EmitterDirection.x = x;
EmitterDirection.y = y;
EmitterDirection.z = z;
}
// Take a free particle from the pool and fire it out the emitter.
public void GenerateParticle()
{
if (_ParticlePool.IsEmpty())
{
return;
}
// get the first particle from the pool and attach it to the emitter's list
Particle particle = _ParticlePool.First();
_ParticleList.InsertFront(particle);
// make sure emitter direction vector is normalized, or else initial velocity will be wrong
float L = (float)Math.sqrt(EmitterDirection.x*EmitterDirection.x + EmitterDirection.y*EmitterDirection.y + EmitterDirection.z*EmitterDirection.z);
EmitterDirection.x /= L;
EmitterDirection.y /= L;
EmitterDirection.z /= L;
// set particle parameters
particle.EffectTime = 0;
particle.Gravity = ParticleGravity;
particle.AirResistance = ParticleAirResistance;
particle.TimeToLive = ParticleTimeToLive;
particle.Mass = ParticleMass;
particle.Velocity.x = EmitterDirection.x * ParticleInitialVelocity;
particle.Velocity.y = EmitterDirection.y * ParticleInitialVelocity;
particle.Velocity.z = EmitterDirection.z * ParticleInitialVelocity;
particle.Position.x = Position.x;
particle.Position.y = Position.y;
particle.Position.z = Position.z;
particle.FadeInDuration = FadeInDuration;
particle.FadeOutDuration = FadeOutDuration;
particle.Opacity = Opacity;
particle.StartScale = ParticleStartScale;
particle.EndScale = ParticleEndScale;
particle.PositionJitterX = (float)Math.random() * ParticlePositionJitterX;
particle.PositionJitterY = (float)Math.random() * ParticlePositionJitterY;
particle.PositionJitterZ = (float)Math.random() * ParticlePositionJitterZ;
if (ParticleRotationRandomStartAngle)
{
particle.RandomStartAngle = (float)(2 * Math.PI * Math.random());
}
else
{
particle.RandomStartAngle = 0;
}
if (ParticleRotationRandomDirection)
{
particle.RotationSpeed = Math.random() > 0.5 ? ParticleRotationSpeed : -ParticleRotationSpeed;
}
else
{
particle.RotationSpeed = ParticleRotationSpeed;
}
particle.SetVisible(true);
}
public void Update(float timeStep)
{
super.Update(timeStep);
if (Enabled)
{
if (ParticlesPerSecond > 0)
{
_sumTimeSteps += timeStep;
float timeBetweenParticles = (ParticlesPerSecond > 1000) ? 0.001f : (1.0f / ParticlesPerSecond);
while (_sumTimeSteps > timeBetweenParticles)
{
GenerateParticle();
_sumTimeSteps -= timeBetweenParticles;
}
}
}
// update all particles owned by the emitter
Particle particle = _ParticleList.First();
while(particle != null)
{
Particle nextParticle = particle.Next;
particle.Update(timeStep);
particle = nextParticle;
}
}
}
Here are the mains option you can edit to change the effect:
public Vector3f EmitterDirection;
public Vector3f ParticleGravity = new Vector3f();
public float ParticleAirResistance = 0;
public float ParticlesPerSecond = 1;
public float ParticleInitialVelocity;
public float ParticleTimeToLive = 2;
public float ParticleMass = 1;
public float ParticleRotationSpeed = 0;
public bool ParticleRotationRandomStartAngle = false;
public bool ParticleRotationRandomDirection = false;
public float ParticleStartScale = 1;
public float ParticleEndScale = 1;
public float ParticlePositionJitterX = 0;
public float ParticlePositionJitterY = 0;
public float ParticlePositionJitterZ = 0;