package electrosphere.entity.state; import com.bulletphysics.collision.dispatch.CollisionObject; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.movement.Impulse; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.game.collision.PhysicsUtils; import electrosphere.game.collision.collidable.Collidable; import electrosphere.main.Globals; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.renderer.Actor; import java.util.concurrent.CopyOnWriteArrayList; import org.joml.Quaternionf; import org.joml.Vector3f; /** * * @author amaterasu */ public class GravityTree { public static enum GravityTreeState { ACTIVE, NOT_ACTIVE, } GravityTreeState state; Entity parent; CollisionObject body; Collidable collidable; CopyOnWriteArrayList networkMessageQueue = new CopyOnWriteArrayList(); int frameCurrent; int maxFrame = 60; public GravityTree(Entity e){ state = GravityTreeState.ACTIVE; parent = e; } public void setCollisionObject(CollisionObject body, Collidable collidable){ this.body = body; this.collidable = collidable; } public GravityTreeState getState(){ return state; } public void start(){ //TODO: check if can start moving state = GravityTreeState.ACTIVE; frameCurrent = 0; } public void interrupt(){ state = GravityTreeState.NOT_ACTIVE; } public void stop(){ state = GravityTreeState.NOT_ACTIVE; } static final float gravityConstant = 0.2f; static final float linearDamping = 0.02f; public void simulate(float deltaTime){ float velocity = CreatureUtils.getVelocity(parent); float acceleration = CreatureUtils.getAcceleration(parent); float maxNaturalVelocity = CreatureUtils.getMaxNaturalVelocity(parent); Actor entityActor = EntityUtils.getActor(parent); Vector3f position = EntityUtils.getPosition(parent); Vector3f movementVector = CreatureUtils.getMovementVector(parent); Quaternionf rotation = EntityUtils.getRotation(parent); Vector3f newPosition; javax.vecmath.Matrix4f bodyTransformMatrix; //parse attached network messages // for(EntityMessage message : networkMessageQueue){ // networkMessageQueue.remove(message); //// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ()); // switch(message.getMessageSubtype()){ // case ATTACKUPDATE: // switch(message.gettreeState()){ // case 0: // state = IdleTreeState.IDLE; // break; // case 1: // state = IdleTreeState.NOT_IDLE; // break; // } // EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ()); // CreatureUtils.setMovementVector(parent, new Vector3f(message.getrotationX(),message.getrotationY(),message.getrotationZ())); // break; // } // } boolean isIdle; //state machine switch(state){ case ACTIVE: if(hadGroundCollision()){ state = GravityTreeState.NOT_ACTIVE; } else { float gravityDif = gravityConstant * (float)Math.pow(1.0f - linearDamping,deltaTime * 2); Vector3f newGravityPos = new Vector3f(position.x,position.y - gravityDif,position.z); float hitFraction = Globals.collisionEngine.sweepTest(body, position, newGravityPos); if(hitFraction >= 0){ position.set(new Vector3f(position.x,position.y - gravityDif * hitFraction,position.z)); } else { position.set(new Vector3f(position.x,position.y - gravityDif,position.z)); } // System.out.println(hitFraction); bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(position),1.0f); body.setWorldTransform(new com.bulletphysics.linearmath.Transform(bodyTransformMatrix)); } break; case NOT_ACTIVE: if(hadEntityCollision()){ start(); } //nothing here atm //eventually want to check if need to re-activate somehow break; } } public void addNetworkMessage(EntityMessage networkMessage) { networkMessageQueue.add(networkMessage); } public boolean hadGroundCollision(){ boolean rVal = false; for(Impulse impulse : collidable.getImpulses()){ if(impulse.getType().equals(Collidable.TYPE_TERRAIN)){ rVal = true; break; } else if( impulse.getType().equals(Collidable.TYPE_STRUCTURE) && new Vector3f(impulse.getDirection()).normalize().y > 0.7 ){ rVal = true; } } return rVal; } public boolean hadEntityCollision(){ boolean rVal = false; for(Impulse impulse : collidable.getImpulses()){ if(impulse.getType().equals(Collidable.TYPE_CREATURE)){ rVal = true; break; } } return rVal; } }