Too few particles

I'm having trouble getting a particle system to work correctly.  My goal is to have a stream of particles moving out from the current mouse location in all directions.  It kind of works, but no matter what I do, there seem to be a lot fewer of them than I expect.



I've simplified it to a fairly small demo program, which is given below.  To make the problem easy to observe, I've set it so that particles are only generated (150/second supposedly) while the mouse button is held down.  There are two different problems that are easy to observe:


  1. Click the mouse quickly, so just a few particles are generated.  Most of them disappear almost instantly.  I've set both the minimum and maximum lifetimes to 2000 ms, yet it's clear that most of them last only a fraction of a second.


  2. Hold down the mouse for a few seconds so lots of particles get generated, then release it.  There are usually a few particles that get "stuck": they float outward for a few seconds, then just stop there and never disappear.



    This is with the latest nightly build.  Thanks in advance for any advice.



    Peter


import com.jme.app.SimpleGame;
import com.jme.input.AbsoluteMouse;
import com.jme.input.InputHandler;
import com.jme.input.MouseInput;
import com.jme.math.FastMath;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.state.AlphaState;
import com.jme.system.DisplaySystem;
import com.jmex.effects.particles.ParticleController;
import com.jmex.effects.particles.ParticleMesh;

public class Game2 extends SimpleGame
{
  private AbsoluteMouse mouse;
  private ParticleMesh particles;
 
  public Game2()
  {
  }
 
  public static void main(String[] args)
  {
    Game2 app = new Game2();
    app.setDialogBehaviour(SimpleGame.FIRSTRUN_OR_NOCONFIGFILE_SHOW_PROPS_DIALOG);
    app.start();
  }

  protected void simpleInitGame()
  {
    input.setEnabled(false);
    input = new InputHandler();
   
    mouse = new AbsoluteMouse("mouse", display.getWidth(), display.getHeight());
    mouse.registerWithInputHandler(input);
    mouse.setDefaultColor(new ColorRGBA(1, 1, 1, .3f));
    AlphaState alpha = DisplaySystem.getDisplaySystem().getRenderer().createAlphaState();
    alpha.setBlendEnabled(true);
    alpha.setSrcFunction(AlphaState.SB_SRC_ALPHA);
    alpha.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
    mouse.setRenderState(alpha);
   
    particles = new ParticleMesh("particles", 300);
    ParticleController particleController = new ParticleController(particles);
    particles.addController(particleController);
    particles.setInitialVelocity(.02f);
    particles.setEmissionDirection(new Vector3f(0, 0, -1));
    particles.setMaximumAngle(FastMath.HALF_PI);
    particles.setControlFlow(true);
    particles.setMinimumLifeTime(2000);
    particles.setMaximumLifeTime(2000);
    particles.setEndSize(2f);
    particles.setStartSize(2f);
    particles.setRandomMod(0f);
    particles.setRenderQueueMode(Renderer.QUEUE_ORTHO);
    rootNode.attachChild(particleController.getParticles());
    rootNode.attachChild(mouse);
  }

  protected void simpleUpdate()
  {
    Vector3f mousePos = mouse.getHotSpotPosition();
    particles.setOriginOffset(mousePos);
    MouseInput input = MouseInput.get();
    particles.setReleaseRate(input.isButtonDown(0) ? 150 : 0);
  }
}

Hm, i've not touched the particles in a while but my advice would be:

Try to achive the effect You wish with jmetest.effects.RenParticleEditor and cut'n paste the code from the code tab.



hth

Martin

Part of the problem is that many of the particles are coming straight at the camera.  Add this line to help spread them out:



particles.setMinimumAngle(FastMath.HALF_PI);



The sticking problem looks like an issue with your alpha state.  Dead particles are simply set to alpha = 0.



Here's your code again but with those things corrected as well as making better use of some of the particle code.


import com.jme.app.SimpleGame;
import com.jme.input.AbsoluteMouse;
import com.jme.input.InputHandler;
import com.jme.input.MouseInput;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.state.AlphaState;
import com.jme.system.DisplaySystem;
import com.jmex.effects.particles.ParticleFactory;
import com.jmex.effects.particles.ParticleMesh;

public class Game2 extends SimpleGame {
    private AbsoluteMouse mouse;
    private ParticleMesh particles;

    public Game2() {
    }

    public static void main(String[] args) {
        Game2 app = new Game2();
        app
                .setDialogBehaviour(SimpleGame.FIRSTRUN_OR_NOCONFIGFILE_SHOW_PROPS_DIALOG);
        app.start();
    }

    protected void simpleInitGame() {
        input.setEnabled(false);
        input = new InputHandler();

        mouse = new AbsoluteMouse("mouse", display.getWidth(), display
                .getHeight());
        mouse.registerWithInputHandler(input);
        mouse.setDefaultColor(new ColorRGBA(1, 1, 1, .3f));
        AlphaState alpha = DisplaySystem.getDisplaySystem().getRenderer()
                .createAlphaState();
        alpha.setBlendEnabled(true);
        alpha.setSrcFunction(AlphaState.SB_SRC_ALPHA);
        alpha.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
        mouse.setRenderState(alpha);

        particles = ParticleFactory.buildParticles("particles", 300);
        particles.setInitialVelocity(.02f);
        particles.setEmissionDirection(new Vector3f(0, 0, -1));
        particles.setMinimumAngle(FastMath.HALF_PI);
        particles.setMaximumAngle(FastMath.HALF_PI);
        particles.setControlFlow(true);
        particles.setMinimumLifeTime(2000);
        particles.setMaximumLifeTime(2000);
        particles.setEndSize(2f);
        particles.setStartSize(2f);
        particles.setRandomMod(0f);
        particles.setRenderQueueMode(Renderer.QUEUE_ORTHO);
       
        AlphaState alpha2 = DisplaySystem.getDisplaySystem().getRenderer()
                .createAlphaState();
        alpha2.setBlendEnabled(true);
        alpha2.setSrcFunction(AlphaState.SB_SRC_ALPHA);
        alpha2.setDstFunction(AlphaState.DB_ONE);
        particles.setRenderState(alpha2);
       
        rootNode.attachChild(particles);
        rootNode.attachChild(mouse);
    }

    protected void simpleUpdate() {
        Vector3f mousePos = mouse.getHotSpotPosition();
        particles.setOriginOffset(mousePos);
        MouseInput input = MouseInput.get();
        particles.setReleaseRate(input.isButtonDown(0) ? 150 : 0);
    }
}

Thanks a lot!  The call to setMinimumAngle() makes a huge difference.  It now looks the way I wanted it to. :slight_smile:



Peter