public ParticleManager(int noParticles, Camera cam) { camera = cam;
public ParticleManager(int noParticles) {
    public ParticleManager(int noParticles, Camera cam) {        camera = cam;        this.noParticles = noParticles;        //      init non-null, non-zero field members        rotMatrix = new Matrix3f();        originCenter = new Vector3f();        upVector = new Vector3f(0.0f, 1.0f, 0.0f);        gravityForce = new Vector3f(0.0f, 0.0f, 0.0f);        emissionDirection = new Vector3f(0.0f, 1.0f, 0.0f);        startColor = new ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f);        endColor = new ColorRGBA(1.0f, 1.0f, 0.0f, 0.0f);        particleSpeed = new Vector3f();                // init working vectors.. used to prevent additional object creation.        upXemit = new Vector3f();        absUpVector = new Vector3f();        abUpMinUp = new Vector3f();                setMinTime(0);        setMaxTime(Float.MAX_VALUE);        setRepeatType(Controller.RT_WRAP);        setSpeed(1.0f);                initialVelocity = 1.0f;        minimumLifeTime = 2500f;        maximumAngle = 0.7853982f;        startSize = 20f;        endSize = 4f;        randomMod = 1.0f;        releaseRate = noParticles;        releaseVariance = 0;        particleSpinSpeed = 0;        controlFlow = false;        precision = .01f; // 10ms                geometryCoordinates = new Vector3f[noParticles << 2];        int[] indices = new int[noParticles * 6];        for (int j = 0; j < noParticles; j++) {            indices[0 + j * 6] = j * 4 + 2;            indices[1 + j * 6] = j * 4 + 1;            indices[2 + j * 6] = j * 4 + 0;            indices[3 + j * 6] = j * 4 + 3;            indices[4 + j * 6] = j * 4 + 2;            indices[5 + j * 6] = j * 4 + 0;        }                appearanceColors = new ColorRGBA[noParticles << 2];        particles = new Particle[noParticles];                // overriding the worldRotation allows the programmer to attach the particles        // to things which have changing rotation without ruining the particle bill-        // boarding.        particlesGeometry = new TriMesh("particles") {            private static final long serialVersionUID = 1L;            public void updateGeometricState(float time, boolean initiator) {                super.updateGeometricState(time, initiator);                if (geoToUse == GS_MESH) {                    psMesh.getWorldRotation().mult(emissionDirection, worldEmit);                } else                    getWorldRotation().mult(emissionDirection, worldEmit);                getWorldRotation().set(0,0,0,1);            }        };        particlesGeometry.setVertices(new Vector3f[noParticles << 2]);        particlesGeometry.setTextures(new Vector2f[noParticles << 2], 0);        particlesGeometry.setIndices(indices);        particlesGeometry.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);        particlesGeometry.setLightCombineMode(LightState.OFF);        particlesGeometry.setTextureCombineMode(TextureState.REPLACE);                invScale = new Vector3f();                Vector3f speed = new Vector3f();        Vector3f location = new Vector3f();        updateRotationMatrix();        for (int k = 0; k < noParticles; k++) {            float life = getRandomLifeSpan();            getRandomSpeed(speed);            particles[k] = new Particle(this, speed, location, life);            for (int a = 3; a >= 0; a--) {                particlesGeometry.setTextureCoord(0, (k << 2) + a, sharedTextureData[a]);                geometryCoordinates[ (k << 2) + a] = particles[k].verts[a];                appearanceColors[ (k << 2) + a] = particles[k].currColor;            }                    }        particlesGeometry.updateTextureBuffer();                warmUp(60);    }