1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 package jme3test.effect;
34 
35 import com.jme3.app.SimpleApplication;
36 import com.jme3.effect.ParticleEmitter;
37 import com.jme3.effect.ParticleMesh.Type;
38 import com.jme3.effect.shapes.EmitterSphereShape;
39 import com.jme3.material.Material;
40 import com.jme3.math.ColorRGBA;
41 import com.jme3.math.FastMath;
42 import com.jme3.math.Quaternion;
43 import com.jme3.math.Vector3f;
44 import com.jme3.scene.Node;
45 
46 public class TestExplosionEffect extends SimpleApplication {
47 
48     private float time = 0;
49     private int state = 0;
50     private Node explosionEffect = new Node("explosionFX");
51     private ParticleEmitter flame, flash, spark, roundspark, smoketrail, debris,
52                             shockwave;
53 
54 
55     private static final int COUNT_FACTOR = 1;
56     private static final float COUNT_FACTOR_F = 1f;
57 
58     private static final boolean POINT_SPRITE = true;
59     private static final Type EMITTER_TYPE = POINT_SPRITE ? Type.Point : Type.Triangle;
60 
main(String[] args)61     public static void main(String[] args){
62         TestExplosionEffect app = new TestExplosionEffect();
63         app.start();
64     }
65 
createFlame()66     private void createFlame(){
67         flame = new ParticleEmitter("Flame", EMITTER_TYPE, 32 * COUNT_FACTOR);
68         flame.setSelectRandomImage(true);
69         flame.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (float) (1f / COUNT_FACTOR_F)));
70         flame.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f));
71         flame.setStartSize(1.3f);
72         flame.setEndSize(2f);
73         flame.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
74         flame.setParticlesPerSec(0);
75         flame.setGravity(0, -5, 0);
76         flame.setLowLife(.4f);
77         flame.setHighLife(.5f);
78         flame.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 7, 0));
79         flame.getParticleInfluencer().setVelocityVariation(1f);
80         flame.setImagesX(2);
81         flame.setImagesY(2);
82         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
83         mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
84         mat.setBoolean("PointSprite", POINT_SPRITE);
85         flame.setMaterial(mat);
86         explosionEffect.attachChild(flame);
87     }
88 
createFlash()89     private void createFlash(){
90         flash = new ParticleEmitter("Flash", EMITTER_TYPE, 24 * COUNT_FACTOR);
91         flash.setSelectRandomImage(true);
92         flash.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1f / COUNT_FACTOR_F)));
93         flash.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
94         flash.setStartSize(.1f);
95         flash.setEndSize(3.0f);
96         flash.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f));
97         flash.setParticlesPerSec(0);
98         flash.setGravity(0, 0, 0);
99         flash.setLowLife(.2f);
100         flash.setHighLife(.2f);
101         flash.setInitialVelocity(new Vector3f(0, 5f, 0));
102         flash.setVelocityVariation(1);
103         flash.setImagesX(2);
104         flash.setImagesY(2);
105         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
106         mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flash.png"));
107         mat.setBoolean("PointSprite", POINT_SPRITE);
108         flash.setMaterial(mat);
109         explosionEffect.attachChild(flash);
110     }
111 
createRoundSpark()112     private void createRoundSpark(){
113         roundspark = new ParticleEmitter("RoundSpark", EMITTER_TYPE, 20 * COUNT_FACTOR);
114         roundspark.setStartColor(new ColorRGBA(1f, 0.29f, 0.34f, (float) (1.0 / COUNT_FACTOR_F)));
115         roundspark.setEndColor(new ColorRGBA(0, 0, 0, (float) (0.5f / COUNT_FACTOR_F)));
116         roundspark.setStartSize(1.2f);
117         roundspark.setEndSize(1.8f);
118         roundspark.setShape(new EmitterSphereShape(Vector3f.ZERO, 2f));
119         roundspark.setParticlesPerSec(0);
120         roundspark.setGravity(0, -.5f, 0);
121         roundspark.setLowLife(1.8f);
122         roundspark.setHighLife(2f);
123         roundspark.setInitialVelocity(new Vector3f(0, 3, 0));
124         roundspark.setVelocityVariation(.5f);
125         roundspark.setImagesX(1);
126         roundspark.setImagesY(1);
127         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
128         mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/roundspark.png"));
129         mat.setBoolean("PointSprite", POINT_SPRITE);
130         roundspark.setMaterial(mat);
131         explosionEffect.attachChild(roundspark);
132     }
133 
createSpark()134     private void createSpark(){
135         spark = new ParticleEmitter("Spark", Type.Triangle, 30 * COUNT_FACTOR);
136         spark.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1.0f / COUNT_FACTOR_F)));
137         spark.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
138         spark.setStartSize(.5f);
139         spark.setEndSize(.5f);
140         spark.setFacingVelocity(true);
141         spark.setParticlesPerSec(0);
142         spark.setGravity(0, 5, 0);
143         spark.setLowLife(1.1f);
144         spark.setHighLife(1.5f);
145         spark.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 20, 0));
146         spark.getParticleInfluencer().setVelocityVariation(1);
147         spark.setImagesX(1);
148         spark.setImagesY(1);
149         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
150         mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/spark.png"));
151         spark.setMaterial(mat);
152         explosionEffect.attachChild(spark);
153     }
154 
createSmokeTrail()155     private void createSmokeTrail(){
156         smoketrail = new ParticleEmitter("SmokeTrail", Type.Triangle, 22 * COUNT_FACTOR);
157         smoketrail.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1.0f / COUNT_FACTOR_F)));
158         smoketrail.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f));
159         smoketrail.setStartSize(.2f);
160         smoketrail.setEndSize(1f);
161 
162 //        smoketrail.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
163         smoketrail.setFacingVelocity(true);
164         smoketrail.setParticlesPerSec(0);
165         smoketrail.setGravity(0, 1, 0);
166         smoketrail.setLowLife(.4f);
167         smoketrail.setHighLife(.5f);
168         smoketrail.setInitialVelocity(new Vector3f(0, 12, 0));
169         smoketrail.setVelocityVariation(1);
170         smoketrail.setImagesX(1);
171         smoketrail.setImagesY(3);
172         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
173         mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/smoketrail.png"));
174         smoketrail.setMaterial(mat);
175         explosionEffect.attachChild(smoketrail);
176     }
177 
createDebris()178     private void createDebris(){
179         debris = new ParticleEmitter("Debris", Type.Triangle, 15 * COUNT_FACTOR);
180         debris.setSelectRandomImage(true);
181         debris.setRandomAngle(true);
182         debris.setRotateSpeed(FastMath.TWO_PI * 4);
183         debris.setStartColor(new ColorRGBA(1f, 0.59f, 0.28f, (float) (1.0f / COUNT_FACTOR_F)));
184         debris.setEndColor(new ColorRGBA(.5f, 0.5f, 0.5f, 0f));
185         debris.setStartSize(.2f);
186         debris.setEndSize(.2f);
187 
188 //        debris.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f));
189         debris.setParticlesPerSec(0);
190         debris.setGravity(0, 12f, 0);
191         debris.setLowLife(1.4f);
192         debris.setHighLife(1.5f);
193         debris.setInitialVelocity(new Vector3f(0, 15, 0));
194         debris.setVelocityVariation(.60f);
195         debris.setImagesX(3);
196         debris.setImagesY(3);
197         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
198         mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/Debris.png"));
199         debris.setMaterial(mat);
200         explosionEffect.attachChild(debris);
201     }
202 
createShockwave()203     private void createShockwave(){
204         shockwave = new ParticleEmitter("Shockwave", Type.Triangle, 1 * COUNT_FACTOR);
205 //        shockwave.setRandomAngle(true);
206         shockwave.setFaceNormal(Vector3f.UNIT_Y);
207         shockwave.setStartColor(new ColorRGBA(.48f, 0.17f, 0.01f, (float) (.8f / COUNT_FACTOR_F)));
208         shockwave.setEndColor(new ColorRGBA(.48f, 0.17f, 0.01f, 0f));
209 
210         shockwave.setStartSize(0f);
211         shockwave.setEndSize(7f);
212 
213         shockwave.setParticlesPerSec(0);
214         shockwave.setGravity(0, 0, 0);
215         shockwave.setLowLife(0.5f);
216         shockwave.setHighLife(0.5f);
217         shockwave.setInitialVelocity(new Vector3f(0, 0, 0));
218         shockwave.setVelocityVariation(0f);
219         shockwave.setImagesX(1);
220         shockwave.setImagesY(1);
221         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
222         mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/shockwave.png"));
223         shockwave.setMaterial(mat);
224         explosionEffect.attachChild(shockwave);
225     }
226 
227     @Override
simpleInitApp()228     public void simpleInitApp() {
229         createFlame();
230         createFlash();
231         createSpark();
232         createRoundSpark();
233         createSmokeTrail();
234         createDebris();
235         createShockwave();
236         explosionEffect.setLocalScale(0.5f);
237         renderManager.preloadScene(explosionEffect);
238 
239         cam.setLocation(new Vector3f(0, 3.5135868f, 10));
240         cam.setRotation(new Quaternion(1.5714673E-4f, 0.98696727f, -0.16091813f, 9.6381607E-4f));
241 
242         rootNode.attachChild(explosionEffect);
243     }
244 
245     @Override
simpleUpdate(float tpf)246     public void simpleUpdate(float tpf){
247         time += tpf / speed;
248         if (time > 1f && state == 0){
249             flash.emitAllParticles();
250             spark.emitAllParticles();
251             smoketrail.emitAllParticles();
252             debris.emitAllParticles();
253             shockwave.emitAllParticles();
254             state++;
255         }
256         if (time > 1f + .05f / speed && state == 1){
257             flame.emitAllParticles();
258             roundspark.emitAllParticles();
259             state++;
260         }
261 
262         // rewind the effect
263         if (time > 5 / speed && state == 2){
264             state = 0;
265             time = 0;
266 
267             flash.killAllParticles();
268             spark.killAllParticles();
269             smoketrail.killAllParticles();
270             debris.killAllParticles();
271             flame.killAllParticles();
272             roundspark.killAllParticles();
273             shockwave.killAllParticles();
274         }
275     }
276 
277 }
278