• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * To change this template, choose Tools | Templates
3  * and open the template in the editor.
4  */
5 package jme3test.bullet;
6 
7 import com.jme3.asset.AssetManager;
8 import com.jme3.bullet.PhysicsSpace;
9 import com.jme3.bullet.PhysicsTickListener;
10 import com.jme3.bullet.collision.PhysicsCollisionEvent;
11 import com.jme3.bullet.collision.PhysicsCollisionListener;
12 import com.jme3.bullet.collision.PhysicsCollisionObject;
13 import com.jme3.bullet.collision.shapes.CollisionShape;
14 import com.jme3.bullet.collision.shapes.SphereCollisionShape;
15 import com.jme3.bullet.control.RigidBodyControl;
16 import com.jme3.bullet.objects.PhysicsGhostObject;
17 import com.jme3.bullet.objects.PhysicsRigidBody;
18 import com.jme3.effect.ParticleEmitter;
19 import com.jme3.effect.ParticleMesh.Type;
20 import com.jme3.effect.shapes.EmitterSphereShape;
21 import com.jme3.export.JmeExporter;
22 import com.jme3.export.JmeImporter;
23 import com.jme3.material.Material;
24 import com.jme3.math.ColorRGBA;
25 import com.jme3.math.Vector3f;
26 import java.io.IOException;
27 import java.util.Iterator;
28 
29 /**
30  *
31  * @author normenhansen
32  */
33 public class BombControl extends RigidBodyControl implements PhysicsCollisionListener, PhysicsTickListener {
34 
35     private float explosionRadius = 10;
36     private PhysicsGhostObject ghostObject;
37     private Vector3f vector = new Vector3f();
38     private Vector3f vector2 = new Vector3f();
39     private float forceFactor = 1;
40     private ParticleEmitter effect;
41     private float fxTime = 0.5f;
42     private float maxTime = 4f;
43     private float curTime = -1.0f;
44     private float timer;
45 
BombControl(CollisionShape shape, float mass)46     public BombControl(CollisionShape shape, float mass) {
47         super(shape, mass);
48         createGhostObject();
49     }
50 
BombControl(AssetManager manager, CollisionShape shape, float mass)51     public BombControl(AssetManager manager, CollisionShape shape, float mass) {
52         super(shape, mass);
53         createGhostObject();
54         prepareEffect(manager);
55     }
56 
setPhysicsSpace(PhysicsSpace space)57     public void setPhysicsSpace(PhysicsSpace space) {
58         super.setPhysicsSpace(space);
59         if (space != null) {
60             space.addCollisionListener(this);
61         }
62     }
63 
prepareEffect(AssetManager assetManager)64     private void prepareEffect(AssetManager assetManager) {
65         int COUNT_FACTOR = 1;
66         float COUNT_FACTOR_F = 1f;
67         effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR);
68         effect.setSelectRandomImage(true);
69         effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (float) (1f / COUNT_FACTOR_F)));
70         effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f));
71         effect.setStartSize(1.3f);
72         effect.setEndSize(2f);
73         effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
74         effect.setParticlesPerSec(0);
75         effect.setGravity(0, -5f, 0);
76         effect.setLowLife(.4f);
77         effect.setHighLife(.5f);
78         effect.setInitialVelocity(new Vector3f(0, 7, 0));
79         effect.setVelocityVariation(1f);
80         effect.setImagesX(2);
81         effect.setImagesY(2);
82         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
83         mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
84         effect.setMaterial(mat);
85     }
86 
createGhostObject()87     protected void createGhostObject() {
88         ghostObject = new PhysicsGhostObject(new SphereCollisionShape(explosionRadius));
89     }
90 
collision(PhysicsCollisionEvent event)91     public void collision(PhysicsCollisionEvent event) {
92         if (space == null) {
93             return;
94         }
95         if (event.getObjectA() == this || event.getObjectB() == this) {
96             space.add(ghostObject);
97             ghostObject.setPhysicsLocation(getPhysicsLocation(vector));
98             space.addTickListener(this);
99             if (effect != null && spatial.getParent() != null) {
100                 curTime = 0;
101                 effect.setLocalTranslation(spatial.getLocalTranslation());
102                 spatial.getParent().attachChild(effect);
103                 effect.emitAllParticles();
104             }
105             space.remove(this);
106             spatial.removeFromParent();
107         }
108     }
109 
prePhysicsTick(PhysicsSpace space, float f)110     public void prePhysicsTick(PhysicsSpace space, float f) {
111         space.removeCollisionListener(this);
112     }
113 
physicsTick(PhysicsSpace space, float f)114     public void physicsTick(PhysicsSpace space, float f) {
115         //get all overlapping objects and apply impulse to them
116         for (Iterator<PhysicsCollisionObject> it = ghostObject.getOverlappingObjects().iterator(); it.hasNext();) {
117             PhysicsCollisionObject physicsCollisionObject = it.next();
118             if (physicsCollisionObject instanceof PhysicsRigidBody) {
119                 PhysicsRigidBody rBody = (PhysicsRigidBody) physicsCollisionObject;
120                 rBody.getPhysicsLocation(vector2);
121                 vector2.subtractLocal(vector);
122                 float force = explosionRadius - vector2.length();
123                 force *= forceFactor;
124                 force = force > 0 ? force : 0;
125                 vector2.normalizeLocal();
126                 vector2.multLocal(force);
127                 ((PhysicsRigidBody) physicsCollisionObject).applyImpulse(vector2, Vector3f.ZERO);
128             }
129         }
130         space.removeTickListener(this);
131         space.remove(ghostObject);
132     }
133 
134     @Override
update(float tpf)135     public void update(float tpf) {
136         super.update(tpf);
137         if(enabled){
138             timer+=tpf;
139             if(timer>maxTime){
140                 if(spatial.getParent()!=null){
141                     space.removeCollisionListener(this);
142                     space.remove(this);
143                     spatial.removeFromParent();
144                 }
145             }
146         }
147         if (enabled && curTime >= 0) {
148             curTime += tpf;
149             if (curTime > fxTime) {
150                 curTime = -1;
151                 effect.removeFromParent();
152             }
153         }
154     }
155 
156     /**
157      * @return the explosionRadius
158      */
getExplosionRadius()159     public float getExplosionRadius() {
160         return explosionRadius;
161     }
162 
163     /**
164      * @param explosionRadius the explosionRadius to set
165      */
setExplosionRadius(float explosionRadius)166     public void setExplosionRadius(float explosionRadius) {
167         this.explosionRadius = explosionRadius;
168         createGhostObject();
169     }
170 
getForceFactor()171     public float getForceFactor() {
172         return forceFactor;
173     }
174 
setForceFactor(float forceFactor)175     public void setForceFactor(float forceFactor) {
176         this.forceFactor = forceFactor;
177     }
178 
179 
180     @Override
read(JmeImporter im)181     public void read(JmeImporter im) throws IOException {
182         throw new UnsupportedOperationException("Reading not supported.");
183     }
184 
185     @Override
write(JmeExporter ex)186     public void write(JmeExporter ex) throws IOException {
187         throw new UnsupportedOperationException("Saving not supported.");
188     }
189 }
190