diff options
Diffstat (limited to 'engine/src/test/jme3test/bullet/BombControl.java')
-rw-r--r-- | engine/src/test/jme3test/bullet/BombControl.java | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/engine/src/test/jme3test/bullet/BombControl.java b/engine/src/test/jme3test/bullet/BombControl.java new file mode 100644 index 0000000..29d49c4 --- /dev/null +++ b/engine/src/test/jme3test/bullet/BombControl.java @@ -0,0 +1,189 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package jme3test.bullet; + +import com.jme3.asset.AssetManager; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.PhysicsTickListener; +import com.jme3.bullet.collision.PhysicsCollisionEvent; +import com.jme3.bullet.collision.PhysicsCollisionListener; +import com.jme3.bullet.collision.PhysicsCollisionObject; +import com.jme3.bullet.collision.shapes.CollisionShape; +import com.jme3.bullet.collision.shapes.SphereCollisionShape; +import com.jme3.bullet.control.RigidBodyControl; +import com.jme3.bullet.objects.PhysicsGhostObject; +import com.jme3.bullet.objects.PhysicsRigidBody; +import com.jme3.effect.ParticleEmitter; +import com.jme3.effect.ParticleMesh.Type; +import com.jme3.effect.shapes.EmitterSphereShape; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import java.io.IOException; +import java.util.Iterator; + +/** + * + * @author normenhansen + */ +public class BombControl extends RigidBodyControl implements PhysicsCollisionListener, PhysicsTickListener { + + private float explosionRadius = 10; + private PhysicsGhostObject ghostObject; + private Vector3f vector = new Vector3f(); + private Vector3f vector2 = new Vector3f(); + private float forceFactor = 1; + private ParticleEmitter effect; + private float fxTime = 0.5f; + private float maxTime = 4f; + private float curTime = -1.0f; + private float timer; + + public BombControl(CollisionShape shape, float mass) { + super(shape, mass); + createGhostObject(); + } + + public BombControl(AssetManager manager, CollisionShape shape, float mass) { + super(shape, mass); + createGhostObject(); + prepareEffect(manager); + } + + public void setPhysicsSpace(PhysicsSpace space) { + super.setPhysicsSpace(space); + if (space != null) { + space.addCollisionListener(this); + } + } + + private void prepareEffect(AssetManager assetManager) { + int COUNT_FACTOR = 1; + float COUNT_FACTOR_F = 1f; + effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR); + effect.setSelectRandomImage(true); + effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (float) (1f / COUNT_FACTOR_F))); + effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f)); + effect.setStartSize(1.3f); + effect.setEndSize(2f); + effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); + effect.setParticlesPerSec(0); + effect.setGravity(0, -5f, 0); + effect.setLowLife(.4f); + effect.setHighLife(.5f); + effect.setInitialVelocity(new Vector3f(0, 7, 0)); + effect.setVelocityVariation(1f); + effect.setImagesX(2); + effect.setImagesY(2); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); + mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); + effect.setMaterial(mat); + } + + protected void createGhostObject() { + ghostObject = new PhysicsGhostObject(new SphereCollisionShape(explosionRadius)); + } + + public void collision(PhysicsCollisionEvent event) { + if (space == null) { + return; + } + if (event.getObjectA() == this || event.getObjectB() == this) { + space.add(ghostObject); + ghostObject.setPhysicsLocation(getPhysicsLocation(vector)); + space.addTickListener(this); + if (effect != null && spatial.getParent() != null) { + curTime = 0; + effect.setLocalTranslation(spatial.getLocalTranslation()); + spatial.getParent().attachChild(effect); + effect.emitAllParticles(); + } + space.remove(this); + spatial.removeFromParent(); + } + } + + public void prePhysicsTick(PhysicsSpace space, float f) { + space.removeCollisionListener(this); + } + + public void physicsTick(PhysicsSpace space, float f) { + //get all overlapping objects and apply impulse to them + for (Iterator<PhysicsCollisionObject> it = ghostObject.getOverlappingObjects().iterator(); it.hasNext();) { + PhysicsCollisionObject physicsCollisionObject = it.next(); + if (physicsCollisionObject instanceof PhysicsRigidBody) { + PhysicsRigidBody rBody = (PhysicsRigidBody) physicsCollisionObject; + rBody.getPhysicsLocation(vector2); + vector2.subtractLocal(vector); + float force = explosionRadius - vector2.length(); + force *= forceFactor; + force = force > 0 ? force : 0; + vector2.normalizeLocal(); + vector2.multLocal(force); + ((PhysicsRigidBody) physicsCollisionObject).applyImpulse(vector2, Vector3f.ZERO); + } + } + space.removeTickListener(this); + space.remove(ghostObject); + } + + @Override + public void update(float tpf) { + super.update(tpf); + if(enabled){ + timer+=tpf; + if(timer>maxTime){ + if(spatial.getParent()!=null){ + space.removeCollisionListener(this); + space.remove(this); + spatial.removeFromParent(); + } + } + } + if (enabled && curTime >= 0) { + curTime += tpf; + if (curTime > fxTime) { + curTime = -1; + effect.removeFromParent(); + } + } + } + + /** + * @return the explosionRadius + */ + public float getExplosionRadius() { + return explosionRadius; + } + + /** + * @param explosionRadius the explosionRadius to set + */ + public void setExplosionRadius(float explosionRadius) { + this.explosionRadius = explosionRadius; + createGhostObject(); + } + + public float getForceFactor() { + return forceFactor; + } + + public void setForceFactor(float forceFactor) { + this.forceFactor = forceFactor; + } + + + @Override + public void read(JmeImporter im) throws IOException { + throw new UnsupportedOperationException("Reading not supported."); + } + + @Override + public void write(JmeExporter ex) throws IOException { + throw new UnsupportedOperationException("Saving not supported."); + } +} |