191 lines
7.2 KiB
Java
191 lines
7.2 KiB
Java
package electrosphere.entity.state;
|
|
|
|
import electrosphere.collision.dispatch.CollisionObject;
|
|
import electrosphere.entity.Entity;
|
|
import electrosphere.entity.EntityUtils;
|
|
import electrosphere.entity.state.collidable.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.Vector3d;
|
|
import org.joml.Vector3f;
|
|
|
|
/**
|
|
*
|
|
* @author amaterasu
|
|
*/
|
|
public class GravityTree {
|
|
|
|
public static enum GravityTreeState {
|
|
ACTIVE,
|
|
NOT_ACTIVE,
|
|
}
|
|
|
|
GravityTreeState state;
|
|
|
|
Entity parent;
|
|
|
|
float gravityVelocity = 0;
|
|
float gravityAccel = 0.01f;
|
|
|
|
CollisionObject body;
|
|
Collidable collidable;
|
|
|
|
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList();
|
|
|
|
public GravityTree(Entity e, Collidable collidable, CollisionObject body){
|
|
state = GravityTreeState.ACTIVE;
|
|
parent = e;
|
|
this.body = body;
|
|
this.collidable = collidable;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
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.1f;
|
|
|
|
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);
|
|
Vector3d 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;
|
|
// }
|
|
// }
|
|
|
|
//state machine
|
|
switch(state){
|
|
case ACTIVE:
|
|
if(hadGroundCollision()){
|
|
state = GravityTreeState.NOT_ACTIVE;
|
|
if(!hadStructureCollision()){
|
|
position.set(new Vector3d(position.x,Globals.commonWorldData.getElevationAtPoint(position) + 0.0001f,position.z));
|
|
}
|
|
gravityVelocity = 0;
|
|
} else {
|
|
if(gravityVelocity < gravityConstant){
|
|
gravityVelocity = gravityVelocity + gravityAccel;
|
|
}
|
|
if(gravityVelocity > gravityConstant){
|
|
gravityVelocity = gravityConstant;
|
|
}
|
|
float gravityDif = gravityVelocity * (float)Math.pow(1.0f - linearDamping,deltaTime * 2);
|
|
Vector3d newGravityPos = new Vector3d(position.x,position.y - gravityDif,position.z);
|
|
float hitFraction = Globals.collisionEngine.sweepTest(body, new Vector3f((float)position.x,(float)position.y,(float)position.z), new Vector3f((float)newGravityPos.x,(float)newGravityPos.y,(float)newGravityPos.z));
|
|
// if(hitFraction >= 0){
|
|
// collidable.addImpulse(new Impulse(new Vector3d(0,-1,0),gravityDif * hitFraction,"gravity"));
|
|
// position.set(new Vector3d(position.x,position.y - gravityDif * hitFraction,position.z));
|
|
// } else {
|
|
// position.set(new Vector3d(position.x,position.y - gravityDif,position.z));
|
|
// }
|
|
if(hitFraction < 0){
|
|
hitFraction = 1;
|
|
}
|
|
collidable.addImpulse(new Impulse(new Vector3d(0,-1,0),gravityDif * hitFraction,"gravity"));
|
|
// System.out.println(hitFraction);
|
|
// bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)position.x,(float)position.y,(float)position.z)),1.0f);
|
|
// body.setWorldTransform(new electrosphere.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 hadStructureCollision(){
|
|
boolean rVal = false;
|
|
for(Impulse impulse : collidable.getImpulses()){
|
|
if(impulse.getType().equals(Collidable.TYPE_STRUCTURE)){
|
|
rVal = true;
|
|
break;
|
|
}
|
|
}
|
|
return rVal;
|
|
}
|
|
|
|
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 Vector3d(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;
|
|
}
|
|
|
|
}
|