You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
7.9 KiB
217 lines
7.9 KiB
/*
|
|
* Copyright (c) 2009-2012 jMonkeyEngine
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* 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.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.getParticleInfluencer()
|
|
.setInitialVelocity(new Vector3f(0, 7, 0));
|
|
effect.getParticleInfluencer().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.");
|
|
}
|
|
}
|
|
|