159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/* 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * To change this template, choose Tools | Templates 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * and open the template in the editor. 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage jme3test.bullet; 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.AssetManager; 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.PhysicsSpace; 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.PhysicsTickListener; 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.collision.PhysicsCollisionEvent; 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.collision.PhysicsCollisionListener; 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.collision.PhysicsCollisionObject; 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.collision.shapes.CollisionShape; 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.collision.shapes.SphereCollisionShape; 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.control.RigidBodyControl; 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.objects.PhysicsGhostObject; 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.bullet.objects.PhysicsRigidBody; 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.ParticleEmitter; 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.ParticleMesh.Type; 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.shapes.EmitterSphereShape; 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeExporter; 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeImporter; 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.material.Material; 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.ColorRGBA; 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f; 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException; 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Iterator; 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/** 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author normenhansen 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class BombControl extends RigidBodyControl implements PhysicsCollisionListener, PhysicsTickListener { 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float explosionRadius = 10; 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private PhysicsGhostObject ghostObject; 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private Vector3f vector = new Vector3f(); 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private Vector3f vector2 = new Vector3f(); 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float forceFactor = 1; 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private ParticleEmitter effect; 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float fxTime = 0.5f; 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float maxTime = 4f; 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float curTime = -1.0f; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float timer; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BombControl(CollisionShape shape, float mass) { 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(shape, mass); 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta createGhostObject(); 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public BombControl(AssetManager manager, CollisionShape shape, float mass) { 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(shape, mass); 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta createGhostObject(); 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta prepareEffect(manager); 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setPhysicsSpace(PhysicsSpace space) { 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.setPhysicsSpace(space); 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (space != null) { 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta space.addCollisionListener(this); 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private void prepareEffect(AssetManager assetManager) { 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int COUNT_FACTOR = 1; 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float COUNT_FACTOR_F = 1f; 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR); 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setSelectRandomImage(true); 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (float) (1f / COUNT_FACTOR_F))); 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f)); 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setStartSize(1.3f); 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setEndSize(2f); 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setParticlesPerSec(0); 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setGravity(0, -5f, 0); 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setLowLife(.4f); 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setHighLife(.5f); 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setInitialVelocity(new Vector3f(0, 7, 0)); 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setVelocityVariation(1f); 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setImagesX(2); 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setImagesY(2); 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setMaterial(mat); 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected void createGhostObject() { 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ghostObject = new PhysicsGhostObject(new SphereCollisionShape(explosionRadius)); 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void collision(PhysicsCollisionEvent event) { 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (space == null) { 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return; 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (event.getObjectA() == this || event.getObjectB() == this) { 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta space.add(ghostObject); 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ghostObject.setPhysicsLocation(getPhysicsLocation(vector)); 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta space.addTickListener(this); 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (effect != null && spatial.getParent() != null) { 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta curTime = 0; 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.setLocalTranslation(spatial.getLocalTranslation()); 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta spatial.getParent().attachChild(effect); 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.emitAllParticles(); 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta space.remove(this); 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta spatial.removeFromParent(); 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void prePhysicsTick(PhysicsSpace space, float f) { 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta space.removeCollisionListener(this); 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void physicsTick(PhysicsSpace space, float f) { 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //get all overlapping objects and apply impulse to them 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (Iterator<PhysicsCollisionObject> it = ghostObject.getOverlappingObjects().iterator(); it.hasNext();) { 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta PhysicsCollisionObject physicsCollisionObject = it.next(); 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (physicsCollisionObject instanceof PhysicsRigidBody) { 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta PhysicsRigidBody rBody = (PhysicsRigidBody) physicsCollisionObject; 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rBody.getPhysicsLocation(vector2); 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vector2.subtractLocal(vector); 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float force = explosionRadius - vector2.length(); 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta force *= forceFactor; 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta force = force > 0 ? force : 0; 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vector2.normalizeLocal(); 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta vector2.multLocal(force); 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ((PhysicsRigidBody) physicsCollisionObject).applyImpulse(vector2, Vector3f.ZERO); 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta space.removeTickListener(this); 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta space.remove(ghostObject); 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void update(float tpf) { 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.update(tpf); 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if(enabled){ 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta timer+=tpf; 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if(timer>maxTime){ 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if(spatial.getParent()!=null){ 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta space.removeCollisionListener(this); 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta space.remove(this); 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta spatial.removeFromParent(); 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (enabled && curTime >= 0) { 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta curTime += tpf; 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (curTime > fxTime) { 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta curTime = -1; 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta effect.removeFromParent(); 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the explosionRadius 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getExplosionRadius() { 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return explosionRadius; 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param explosionRadius the explosionRadius to set 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setExplosionRadius(float explosionRadius) { 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.explosionRadius = explosionRadius; 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta createGhostObject(); 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public float getForceFactor() { 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return forceFactor; 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void setForceFactor(float forceFactor) { 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.forceFactor = forceFactor; 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void read(JmeImporter im) throws IOException { 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new UnsupportedOperationException("Reading not supported."); 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void write(JmeExporter ex) throws IOException { 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new UnsupportedOperationException("Saving not supported."); 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 190