Particle Emitter :
- fixed setNumParticle method to correctly update the mesh buffers - added a getMaxNumParticle that returns the max number of particles of the emitter - changed testMovingParticles and testPointSprite to change the numParticle when hitting the space bar git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7939 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
		
							parent
							
								
									6c4a84fa92
								
							
						
					
					
						commit
						8f59984d00
					
				| @ -75,7 +75,6 @@ public class ParticleEmitter extends Geometry { | ||||
| 
 | ||||
|     private static final EmitterShape DEFAULT_SHAPE = new EmitterPointShape(Vector3f.ZERO); | ||||
|     private static final ParticleInfluencer DEFAULT_INFLUENCER = new DefaultParticleInfluencer(); | ||||
|      | ||||
|     private ParticleEmitterControl control; | ||||
|     private EmitterShape shape = DEFAULT_SHAPE; | ||||
|     private ParticleMesh particleMesh; | ||||
| @ -110,19 +109,19 @@ public class ParticleEmitter extends Geometry { | ||||
|     public static class ParticleEmitterControl implements Control { | ||||
| 
 | ||||
|         ParticleEmitter parentEmitter; | ||||
|          | ||||
|         public ParticleEmitterControl(){ | ||||
| 
 | ||||
|         public ParticleEmitterControl() { | ||||
|         } | ||||
|          | ||||
|         public ParticleEmitterControl(ParticleEmitter parentEmitter){ | ||||
| 
 | ||||
|         public ParticleEmitterControl(ParticleEmitter parentEmitter) { | ||||
|             this.parentEmitter = parentEmitter; | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         public Control cloneForSpatial(Spatial spatial) { | ||||
|             return this; // WARNING: Sets wrong control on spatial. Will be | ||||
|                          // fixed automatically by ParticleEmitter.clone() method. | ||||
|             // fixed automatically by ParticleEmitter.clone() method. | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         public void setSpatial(Spatial spatial) { | ||||
|         } | ||||
| 
 | ||||
| @ -153,21 +152,21 @@ public class ParticleEmitter extends Geometry { | ||||
|     public ParticleEmitter clone() { | ||||
|         ParticleEmitter clone = (ParticleEmitter) super.clone(); | ||||
|         clone.shape = shape.deepClone(); | ||||
|          | ||||
| 
 | ||||
|         // Reinitialize particle list | ||||
|         clone.setNumParticles(particles.length); | ||||
|          | ||||
| 
 | ||||
|         clone.faceNormal = faceNormal.clone(); | ||||
|         clone.startColor = startColor.clone(); | ||||
|         clone.endColor = endColor.clone(); | ||||
|         clone.particleInfluencer = particleInfluencer.clone(); | ||||
|          | ||||
| 
 | ||||
|         // remove wrong control | ||||
|         clone.controls.remove(control); | ||||
|          | ||||
| 
 | ||||
|         // put correct control | ||||
|         clone.controls.add(new ParticleEmitterControl(clone)); | ||||
|          | ||||
| 
 | ||||
|         // Reinitialize particle mesh | ||||
|         switch (meshType) { | ||||
|             case Point: | ||||
| @ -183,7 +182,7 @@ public class ParticleEmitter extends Geometry { | ||||
|         } | ||||
|         clone.particleMesh.initParticleData(clone, clone.particles.length); | ||||
|         clone.particleMesh.setImagesXY(clone.imagesX, clone.imagesY); | ||||
|          | ||||
| 
 | ||||
|         return clone; | ||||
|     } | ||||
| 
 | ||||
| @ -201,8 +200,8 @@ public class ParticleEmitter extends Geometry { | ||||
| 
 | ||||
|         meshType = type; | ||||
| 
 | ||||
|         this.setNumParticles(numParticles); | ||||
|          | ||||
| 
 | ||||
| 
 | ||||
|         // Must create clone of shape/influencer so that a reference to a static is  | ||||
|         // not maintained | ||||
|         shape = shape.deepClone(); | ||||
| @ -223,7 +222,8 @@ public class ParticleEmitter extends Geometry { | ||||
|             default: | ||||
|                 throw new IllegalStateException("Unrecognized particle type: " + meshType); | ||||
|         } | ||||
|         particleMesh.initParticleData(this, particles.length); | ||||
|         this.setNumParticles(numParticles); | ||||
| //        particleMesh.initParticleData(this, particles.length); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -330,10 +330,17 @@ public class ParticleEmitter extends Geometry { | ||||
|         for (int i = 0; i < numParticles; i++) { | ||||
|             particles[i] = new Particle(); | ||||
|         } | ||||
|         //We have to reinit the mesh's buffers with the new size | ||||
|         particleMesh.initParticleData(this, particles.length);         | ||||
|         particleMesh.setImagesXY(this.imagesX, this.imagesY); | ||||
|         firstUnUsed = 0; | ||||
|         lastUsed = -1; | ||||
|     } | ||||
| 
 | ||||
|     public int getMaxNumParticles() { | ||||
|         return particles.length; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns a list of all particles (shouldn't be used in most cases). | ||||
|      *  | ||||
| @ -1117,12 +1124,12 @@ public class ParticleEmitter extends Geometry { | ||||
|         super.read(im); | ||||
|         InputCapsule ic = im.getCapsule(this); | ||||
|         shape = (EmitterShape) ic.readSavable("shape", DEFAULT_SHAPE); | ||||
|          | ||||
|         if (shape == DEFAULT_SHAPE){ | ||||
| 
 | ||||
|         if (shape == DEFAULT_SHAPE) { | ||||
|             // Prevent reference to static | ||||
|             shape = shape.deepClone(); | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         meshType = ic.readEnum("meshType", ParticleMesh.Type.class, ParticleMesh.Type.Triangle); | ||||
|         int numParticles = ic.readInt("numParticles", 0); | ||||
|         this.setNumParticles(numParticles); | ||||
| @ -1161,17 +1168,17 @@ public class ParticleEmitter extends Geometry { | ||||
|         particleMesh.setImagesXY(imagesX, imagesY); | ||||
| 
 | ||||
|         particleInfluencer = (ParticleInfluencer) ic.readSavable("influencer", DEFAULT_INFLUENCER); | ||||
|         if (particleInfluencer == DEFAULT_INFLUENCER){ | ||||
|         if (particleInfluencer == DEFAULT_INFLUENCER) { | ||||
|             particleInfluencer = particleInfluencer.clone(); | ||||
|         } | ||||
|    | ||||
|         if (im.getFormatVersion() == 0){ | ||||
| 
 | ||||
|         if (im.getFormatVersion() == 0) { | ||||
|             // compatibility before the control inside particle emitter | ||||
|             // was changed: | ||||
|             // find it in the controls and take it out, then add the proper one in | ||||
|             for (int i = 0; i < controls.size(); i++){ | ||||
|             for (int i = 0; i < controls.size(); i++) { | ||||
|                 Object obj = controls.get(i); | ||||
|                 if (obj instanceof ParticleEmitter){ | ||||
|                 if (obj instanceof ParticleEmitter) { | ||||
|                     controls.remove(i); | ||||
|                     // now add the proper one in | ||||
|                     controls.add(new ParticleEmitterControl(this)); | ||||
| @ -1180,11 +1187,11 @@ public class ParticleEmitter extends Geometry { | ||||
|             } | ||||
| 
 | ||||
|             // compatability before gravity was not a vector but a float | ||||
|             if (gravity == null){ | ||||
|             if (gravity == null) { | ||||
|                 gravity = new Vector3f(); | ||||
|                 gravity.y = ic.readFloat("gravity", 0); | ||||
|             } | ||||
|         }else{ | ||||
|         } else { | ||||
|             // since the parentEmitter is not loaded, it must be  | ||||
|             // loaded separately | ||||
|             control = getControl(ParticleEmitterControl.class); | ||||
|  | ||||
| @ -64,26 +64,51 @@ public class ParticlePointMesh extends ParticleMesh { | ||||
|         FloatBuffer pb = BufferUtils.createVector3Buffer(numParticles); | ||||
|         VertexBuffer pvb = new VertexBuffer(VertexBuffer.Type.Position); | ||||
|         pvb.setupData(Usage.Stream, 3, Format.Float, pb); | ||||
|         setBuffer(pvb); | ||||
|           | ||||
|         //if the buffer is already set only update the data | ||||
|         VertexBuffer buf = getBuffer(VertexBuffer.Type.Position); | ||||
|         if (buf != null) { | ||||
|             buf.updateData(pb); | ||||
|         } else { | ||||
|             setBuffer(pvb); | ||||
|         } | ||||
| 
 | ||||
|         // set colors | ||||
|         ByteBuffer cb = BufferUtils.createByteBuffer(numParticles * 4); | ||||
|         VertexBuffer cvb = new VertexBuffer(VertexBuffer.Type.Color); | ||||
|         cvb.setupData(Usage.Stream, 4, Format.UnsignedByte, cb); | ||||
|         cvb.setNormalized(true); | ||||
|         setBuffer(cvb); | ||||
|          | ||||
|         buf = getBuffer(VertexBuffer.Type.Color); | ||||
|         if (buf != null) { | ||||
|             buf.updateData(cb); | ||||
|         } else { | ||||
|             setBuffer(cvb); | ||||
|         } | ||||
| 
 | ||||
|         // set sizes | ||||
|         FloatBuffer sb = BufferUtils.createFloatBuffer(numParticles); | ||||
|         VertexBuffer svb = new VertexBuffer(VertexBuffer.Type.Size); | ||||
|         svb.setupData(Usage.Stream, 1, Format.Float, sb); | ||||
|         setBuffer(svb); | ||||
|                  | ||||
|         buf = getBuffer(VertexBuffer.Type.Size); | ||||
|         if (buf != null) { | ||||
|             buf.updateData(sb); | ||||
|         } else { | ||||
|             setBuffer(svb); | ||||
|         } | ||||
| 
 | ||||
|         // set UV-scale | ||||
|         FloatBuffer tb = BufferUtils.createFloatBuffer(numParticles*4); | ||||
|         VertexBuffer tvb = new VertexBuffer(VertexBuffer.Type.TexCoord); | ||||
|         tvb.setupData(Usage.Stream, 4, Format.Float, tb); | ||||
|         setBuffer(tvb); | ||||
|          | ||||
|         buf = getBuffer(VertexBuffer.Type.TexCoord); | ||||
|         if (buf != null) { | ||||
|             buf.updateData(tb); | ||||
|         } else { | ||||
|             setBuffer(tvb); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | ||||
| @ -66,14 +66,27 @@ public class ParticleTriMesh extends ParticleMesh { | ||||
|         FloatBuffer pb = BufferUtils.createVector3Buffer(numParticles * 4); | ||||
|         VertexBuffer pvb = new VertexBuffer(VertexBuffer.Type.Position); | ||||
|         pvb.setupData(Usage.Stream, 3, Format.Float, pb); | ||||
|         setBuffer(pvb); | ||||
| 
 | ||||
|          | ||||
|         //if the buffer is already set only update the data | ||||
|         VertexBuffer buf = getBuffer(VertexBuffer.Type.Position); | ||||
|         if (buf != null) { | ||||
|             buf.updateData(pb); | ||||
|         } else { | ||||
|             setBuffer(pvb); | ||||
|         } | ||||
|          | ||||
|         // set colors | ||||
|         ByteBuffer cb = BufferUtils.createByteBuffer(numParticles * 4 * 4); | ||||
|         VertexBuffer cvb = new VertexBuffer(VertexBuffer.Type.Color); | ||||
|         cvb.setupData(Usage.Stream, 4, Format.UnsignedByte, cb); | ||||
|         cvb.setNormalized(true); | ||||
|         setBuffer(cvb); | ||||
|          | ||||
|         buf = getBuffer(VertexBuffer.Type.Color); | ||||
|         if (buf != null) { | ||||
|             buf.updateData(cb); | ||||
|         } else { | ||||
|             setBuffer(cvb); | ||||
|         } | ||||
| 
 | ||||
|         // set texcoords | ||||
|         VertexBuffer tvb = new VertexBuffer(VertexBuffer.Type.TexCoord); | ||||
| @ -89,7 +102,12 @@ public class ParticleTriMesh extends ParticleMesh { | ||||
|         tb.flip(); | ||||
|         tvb.setupData(Usage.Static, 2, Format.Float, tb); | ||||
|          | ||||
|         setBuffer(tvb); | ||||
|         buf = getBuffer(VertexBuffer.Type.TexCoord); | ||||
|         if (buf != null) { | ||||
|             buf.updateData(tb); | ||||
|         } else { | ||||
|             setBuffer(tvb); | ||||
|         } | ||||
| 
 | ||||
|         // set indices | ||||
|         ShortBuffer ib = BufferUtils.createShortBuffer(numParticles * 6); | ||||
| @ -110,9 +128,16 @@ public class ParticleTriMesh extends ParticleMesh { | ||||
|          | ||||
|         VertexBuffer ivb = new VertexBuffer(VertexBuffer.Type.Index); | ||||
|         ivb.setupData(Usage.Static, 3, Format.UnsignedShort, ib); | ||||
|         setBuffer(ivb); | ||||
|          | ||||
|         buf = getBuffer(VertexBuffer.Type.Index); | ||||
|         if (buf != null) { | ||||
|             buf.updateData(ib); | ||||
|         } else { | ||||
|             setBuffer(ivb); | ||||
|         } | ||||
|          | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     @Override | ||||
|     public void setImagesXY(int imagesX, int imagesY) { | ||||
|         this.imagesX = imagesX; | ||||
|  | ||||
| @ -29,13 +29,16 @@ | ||||
|  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| package jme3test.effect; | ||||
| 
 | ||||
| import com.jme3.app.SimpleApplication; | ||||
| import com.jme3.effect.ParticleEmitter; | ||||
| import com.jme3.effect.ParticleMesh.Type; | ||||
| import com.jme3.effect.shapes.EmitterSphereShape; | ||||
| import com.jme3.input.KeyInput; | ||||
| import com.jme3.input.controls.ActionListener; | ||||
| import com.jme3.input.controls.InputListener; | ||||
| import com.jme3.input.controls.KeyTrigger; | ||||
| import com.jme3.material.Material; | ||||
| import com.jme3.math.FastMath; | ||||
| import com.jme3.math.Vector3f; | ||||
| @ -45,19 +48,19 @@ import com.jme3.math.Vector3f; | ||||
|  * | ||||
|  * @author Kirill Vainer | ||||
|  */ | ||||
| public class TestMovingParticle  extends SimpleApplication { | ||||
| 
 | ||||
| public class TestMovingParticle extends SimpleApplication { | ||||
|      | ||||
|     private ParticleEmitter emit; | ||||
|     private float angle = 0; | ||||
| 
 | ||||
|     public static void main(String[] args){ | ||||
|      | ||||
|     public static void main(String[] args) { | ||||
|         TestMovingParticle app = new TestMovingParticle(); | ||||
|         app.start(); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     @Override | ||||
|     public void simpleInitApp() { | ||||
|         emit = new ParticleEmitter("Emitter", Type.Triangle, 200); | ||||
|         emit = new ParticleEmitter("Emitter", Type.Triangle, 300); | ||||
|         emit.setGravity(0, 0, 0); | ||||
|         emit.setVelocityVariation(1); | ||||
|         emit.setLowLife(1); | ||||
| @ -67,17 +70,27 @@ public class TestMovingParticle  extends SimpleApplication { | ||||
|         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); | ||||
|         mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); | ||||
|         emit.setMaterial(mat); | ||||
| 
 | ||||
|          | ||||
|         rootNode.attachChild(emit); | ||||
|          | ||||
|         inputManager.addListener(new ActionListener() { | ||||
|              | ||||
|             public void onAction(String name, boolean isPressed, float tpf) { | ||||
|                 if ("setNum".equals(name) && isPressed) { | ||||
|                     emit.setNumParticles(1000); | ||||
|                 } | ||||
|             } | ||||
|         }, "setNum"); | ||||
|          | ||||
|         inputManager.addMapping("setNum", new KeyTrigger(KeyInput.KEY_SPACE)); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     @Override | ||||
|     public void simpleUpdate(float tpf){ | ||||
|     public void simpleUpdate(float tpf) { | ||||
|         angle += tpf; | ||||
|         angle %= FastMath.TWO_PI; | ||||
|         float x = FastMath.cos(angle) * 2; | ||||
|         float y = FastMath.sin(angle) * 2; | ||||
|         emit.setLocalTranslation(x, 0, y); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -36,6 +36,9 @@ import com.jme3.app.SimpleApplication; | ||||
| import com.jme3.effect.ParticleEmitter; | ||||
| import com.jme3.effect.ParticleMesh.Type; | ||||
| import com.jme3.effect.shapes.EmitterBoxShape; | ||||
| import com.jme3.input.KeyInput; | ||||
| import com.jme3.input.controls.ActionListener; | ||||
| import com.jme3.input.controls.KeyTrigger; | ||||
| import com.jme3.material.Material; | ||||
| import com.jme3.math.ColorRGBA; | ||||
| import com.jme3.math.Vector3f; | ||||
| @ -49,13 +52,13 @@ public class TestPointSprite extends SimpleApplication { | ||||
| 
 | ||||
|     @Override | ||||
|     public void simpleInitApp() { | ||||
|         ParticleEmitter emit = new ParticleEmitter("Emitter", Type.Point, 10000); | ||||
|         final ParticleEmitter emit = new ParticleEmitter("Emitter", Type.Point, 10000); | ||||
|         emit.setShape(new EmitterBoxShape(new Vector3f(-1.8f, -1.8f, -1.8f), | ||||
|                                           new Vector3f(1.8f, 1.8f, 1.8f))); | ||||
|         emit.setGravity(0, 0, 0); | ||||
|         emit.setLowLife(60); | ||||
|         emit.setHighLife(60); | ||||
|         emit.setInitialVelocity(new Vector3f(0, 0, 0)); | ||||
|         emit.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 0, 0)); | ||||
|         emit.setImagesX(15); | ||||
|         emit.setStartSize(0.05f); | ||||
|         emit.setEndSize(0.05f); | ||||
| @ -70,6 +73,17 @@ public class TestPointSprite extends SimpleApplication { | ||||
|         emit.setMaterial(mat); | ||||
| 
 | ||||
|         rootNode.attachChild(emit); | ||||
|         inputManager.addListener(new ActionListener() { | ||||
|              | ||||
|             public void onAction(String name, boolean isPressed, float tpf) { | ||||
|                 if ("setNum".equals(name) && isPressed) { | ||||
|                     emit.setNumParticles(5000); | ||||
|                     emit.emitAllParticles(); | ||||
|                 } | ||||
|             } | ||||
|         }, "setNum"); | ||||
|          | ||||
|         inputManager.addMapping("setNum", new KeyTrigger(KeyInput.KEY_SPACE)); | ||||
|          | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user