Recycle particles

i'm using lots of particles for magical effects (the biggest one, mininuke, uses 2500) and i'm afraid i'll run into garbage collector problems in big fights. is there a way to recycle particles or particle meshes? if i simply reuse them, the effects are quite buggy (particles disappear before they should, appearing not every time they should…)

i have thought about that as well, currently in our game we use just one explosion effect. Our effect of course can only appear once to a given time which is not very nice.



One possible solution might be:

Define how many effects of the same type need to be active at the same time, say 5.

Now create an Array of 5 of those particle meshes.



When en effect needs to be triggered, get the next from the array, set location and fire.

When 5 of those effects are already active and a 6. effect needs to be triggered, then the oldest effect would be reused. (but chances are good that this effect is already fading.

i thought about pooling per effect, but i didn't know how to completely reset a particle mesh.

and i still don't. do you?

i don't, but why would you need to reset it?

explosions should always emit all particles at once. i randomized their lifetime a bit, so if i simply reuse the meshes, they are "out of sync". some particles are emitted too late, some vanish too soon.

FurBallz used recycled particles for explosions and such.  It's older code, but could give you ideas.  (http://www.renanse.com/furballz/webstart/furballzsrc.zip)

thats what i meant.

here the part from FurBallz:


   
    public static ParticleMesh getExplosion() {
        for (int x = 0, tSize = explosions.size(); x < tSize; x++) {
            ParticleMesh e = (ParticleMesh)explosions.get(x);
            if (!e.isActive()) {
                return e;
            }
        }
        return createExplosion();
    }
   
    private static ParticleMesh createExplosion() {
        ParticleMesh explosion = ParticleFactory.buildParticles("big", 80);
        explosion.setGravityForce(new Vector3f(0.0f, 0.0f, 0.0f));
        explosion.setEmissionDirection(new Vector3f(0.0f, 1.0f, 0.0f));
        explosion.setMaximumAngle(FastMath.PI);
        explosion.setSpeed(0.4f);
        explosion.setMinimumLifeTime(600.0f);
        explosion.setStartSize(2.0f);
        explosion.setEndSize(5.0f);
        explosion.setStartColor(new ColorRGBA(1.0f, 0.312f, 0.121f, 1.0f));
        explosion.setEndColor(new ColorRGBA(1.0f, 0.24313726f, 0.03137255f, 0.0f));
        explosion.setRandomMod(0.0f);
        explosion.setControlFlow(false);
        explosion.setInitialVelocity(0.02f);
        explosion.setParticleSpinSpeed(0.0f);
        explosion.setRepeatType(Controller.RT_CLAMP);

        explosion.warmUp(1000);

        explosion.setRenderState(ts);
        explosion.setRenderState(as);
        explosion.setRenderState(zstate);
        explosion.updateRenderState();
       
        explosions.add(explosion);
       
        return explosion;
    }

In the case of furballz though, the user asking for the particles would then reset the particles back to "ALIVE" status.

i don't see any reset there

You're looking in the factory, not the user.  See PlayerShip.killShip() for example:



        FurBallzGame.shipNode.detachChild(shipModel);
        ParticleMesh mesh = ExplosionFactory.getExplosion();
        mesh.getOriginOffset().set(shipModel.getLocalTranslation());
        mesh.setLocalScale(0.65f);
        mesh.forceRespawn(); // <----
        FurBallzGame.shipNode.attachChild(mesh);
        mesh.setCullMode(Spatial.CULL_NEVER);