166 lines
5.7 KiB
Java
166 lines
5.7 KiB
Java
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<EntityMessage> 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;
|
|
}
|
|
|
|
}
|