diff --git a/assets/Data/creatures.json b/assets/Data/creatures.json
index bb8841ae..bb77deb1 100644
--- a/assets/Data/creatures.json
+++ b/assets/Data/creatures.json
@@ -88,9 +88,18 @@
{
"type" : "GROUND",
"acceleration" : 0.001,
- "maxVelocity" : 0.015
+ "maxVelocity" : 0.025
}
],
+ "physicsObject" : {
+ "type" : "CYLINDER",
+ "dimension1" : 0.2,
+ "dimension2" : 0.45,
+ "dimension3" : 0.2,
+ "offsetX" : 0,
+ "offsetY" : -0.45,
+ "offsetZ" : 0
+ },
"attackMoves" : [
{
"type" : "MELEE_WEAPON_SWING_ONE_HAND",
@@ -199,6 +208,15 @@
"maxVelocity" : 0.025
}
],
+ "physicsObject" : {
+ "type" : "CYLINDER",
+ "dimension1" : 0.2,
+ "dimension2" : 0.2,
+ "dimension3" : 0.2,
+ "offsetX" : 0,
+ "offsetY" : -0.2,
+ "offsetZ" : 0
+ },
"attackMoves" : [
{
"type" : "MELEE_WEAPON_SWING_ONE_HAND",
diff --git a/assets/Data/structures.json b/assets/Data/structures.json
new file mode 100644
index 00000000..2d0badb7
--- /dev/null
+++ b/assets/Data/structures.json
@@ -0,0 +1,140 @@
+{
+ "structures" : [
+ {
+ "name" : "building1",
+ "modelPath" : "Models/building1.fbx",
+ "collision" : [
+ {
+ "type" : "CUBE",
+ "positionX" : 0,
+ "positionY" : -1,
+ "positionZ" : 0.3,
+ "scaleX" : 7.5,
+ "scaleY" : 1.5,
+ "scaleZ" : 0.3,
+ "rotationW" : 1,
+ "rotationX" : 0,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ },
+ {
+ "type" : "CUBE",
+ "positionX" : 7.2,
+ "positionY" : -1,
+ "positionZ" : 3,
+ "scaleX" : 0.3,
+ "scaleY" : 1.5,
+ "scaleZ" : 3,
+ "rotationW" : 1,
+ "rotationX" : 0,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ },
+ {
+ "type" : "CUBE",
+ "positionX" : 7.2,
+ "positionY" : 0.4,
+ "positionZ" : 3,
+ "scaleX" : 0.3,
+ "scaleY" : 2,
+ "scaleZ" : 2,
+ "rotationW" : 0.9238796,
+ "rotationX" : 0.3826834,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ },
+ {
+ "type" : "CUBE",
+ "positionX" : -7.2,
+ "positionY" : -1,
+ "positionZ" : 3,
+ "scaleX" : 0.3,
+ "scaleY" : 1.5,
+ "scaleZ" : 3,
+ "rotationW" : 1,
+ "rotationX" : 0,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ },
+ {
+ "type" : "CUBE",
+ "positionX" : -7.2,
+ "positionY" : 0.4,
+ "positionZ" : 3,
+ "scaleX" : 0.3,
+ "scaleY" : 2,
+ "scaleZ" : 2,
+ "rotationW" : 0.9238796,
+ "rotationX" : 0.3826834,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ },
+ {
+ "type" : "CUBE",
+ "positionX" : -1.5,
+ "positionY" : -1,
+ "positionZ" : 5.7,
+ "scaleX" : 5.5,
+ "scaleY" : 1.5,
+ "scaleZ" : 0.3,
+ "rotationW" : 1,
+ "rotationX" : 0,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ },
+ {
+ "type" : "CUBE",
+ "positionX" : 6.75,
+ "positionY" : -1,
+ "positionZ" : 5.7,
+ "scaleX" : 0.75,
+ "scaleY" : 1.5,
+ "scaleZ" : 0.3,
+ "rotationW" : 1,
+ "rotationX" : 0,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ },
+ {
+ "type" : "CUBE",
+ "positionX" : 0,
+ "positionY" : -2.6,
+ "positionZ" : 3,
+ "scaleX" : 7.5,
+ "scaleY" : 0.2,
+ "scaleZ" : 3,
+ "rotationW" : 1,
+ "rotationX" : 0,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ },
+ {
+ "type" : "CUBE",
+ "positionX" : 0,
+ "positionY" : 1.3,
+ "positionZ" : 4.4,
+ "scaleX" : 7.5,
+ "scaleY" : 0.2,
+ "scaleZ" : 1.8,
+ "rotationW" : 0.9570922,
+ "rotationX" : 0.2897836,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ },
+ {
+ "type" : "CUBE",
+ "positionX" : 0,
+ "positionY" : 1.3,
+ "positionZ" : 1.6,
+ "scaleX" : 7.5,
+ "scaleY" : 0.2,
+ "scaleZ" : 1.8,
+ "rotationW" : 0.9570922,
+ "rotationX" : -0.2897836,
+ "rotationY" : 0,
+ "rotationZ" : 0
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/assets/Models/unitcube.fbx b/assets/Models/unitcube.fbx
new file mode 100644
index 00000000..5c597300
Binary files /dev/null and b/assets/Models/unitcube.fbx differ
diff --git a/assets/Models/unitcylinder.fbx b/assets/Models/unitcylinder.fbx
new file mode 100644
index 00000000..b94ba405
Binary files /dev/null and b/assets/Models/unitcylinder.fbx differ
diff --git a/assets/Models/unitplane.fbx b/assets/Models/unitplane.fbx
new file mode 100644
index 00000000..b4633218
Binary files /dev/null and b/assets/Models/unitplane.fbx differ
diff --git a/assets/Textures/default_texture_map.json b/assets/Textures/default_texture_map.json
index fcebd4b2..ccebf1dc 100644
--- a/assets/Textures/default_texture_map.json
+++ b/assets/Textures/default_texture_map.json
@@ -77,6 +77,24 @@
"/Textures/building_diffuse.png",
"/Textures/building_diffuse.png"
]
+ },
+ "Models/unitcylinder.fbx" : {
+ "Cylinder" : [
+ "/Textures/transparent_blue.png",
+ "/Textures/transparent_blue.png"
+ ]
+ },
+ "Models/unitplane.fbx" : {
+ "Plane" : [
+ "/Textures/transparent_blue.png",
+ "/Textures/transparent_blue.png"
+ ]
+ },
+ "Models/unitcube.fbx" : {
+ "Cube" : [
+ "/Textures/transparent_blue.png",
+ "/Textures/transparent_blue.png"
+ ]
}
}
}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 01711d08..5c42214f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,13 +87,26 @@
2.8.6
-
+
cz.advel.jbullet
jbullet
20101010-1
+
+
org.apache.commons
diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java
index 6147af69..f272ff7a 100644
--- a/src/main/java/electrosphere/controls/ControlHandler.java
+++ b/src/main/java/electrosphere/controls/ControlHandler.java
@@ -5,8 +5,8 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.AttackTree;
-import electrosphere.entity.state.MovementTree;
-import electrosphere.entity.state.MovementTree.MovementTreeState;
+import electrosphere.entity.state.movement.MovementTree;
+import electrosphere.entity.state.movement.MovementTree.MovementTreeState;
import electrosphere.main.Globals;
import electrosphere.menu.MenuTransition;
import electrosphere.net.parser.net.message.EntityMessage;
diff --git a/src/main/java/electrosphere/engine/LoadingThread.java b/src/main/java/electrosphere/engine/LoadingThread.java
index 4a5ae3d2..63021e81 100644
--- a/src/main/java/electrosphere/engine/LoadingThread.java
+++ b/src/main/java/electrosphere/engine/LoadingThread.java
@@ -1,5 +1,6 @@
package electrosphere.engine;
+import com.bulletphysics.collision.dispatch.CollisionObject;
import electrosphere.controls.ControlHandler;
import electrosphere.entity.CameraEntityUtils;
import electrosphere.entity.Entity;
@@ -17,6 +18,10 @@ import electrosphere.game.server.terrain.manager.ServerTerrainManager;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.particle.ParticleUtils;
+import electrosphere.entity.types.collision.CollisionObjUtils;
+import electrosphere.entity.types.structure.StructureUtils;
+import electrosphere.game.collision.PhysicsUtils;
+import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.server.ai.creature.MindlessAttacker;
import electrosphere.game.state.MicroSimulation;
import electrosphere.logger.LoggerInterface;
@@ -35,6 +40,7 @@ import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.joml.Quaternionf;
import org.joml.Vector3f;
/**
@@ -307,7 +313,6 @@ public class LoadingThread extends Thread {
static void initServerArenaTerrainManager(){
Globals.serverTerrainManager = ServerTerrainManager.constructArenaTerrainManager();
- Globals.spawnPoint = new Vector3f(1,0,1);
}
static void initClientTerrainManager(){
@@ -322,7 +327,7 @@ public class LoadingThread extends Thread {
static void initServerArenaWorldData(){
Globals.serverWorldData = ServerWorldData.createArenaWorld();
- Globals.spawnPoint = new Vector3f(0,0,0);
+ Globals.spawnPoint = new Vector3f(1,3,1);
}
static void initServerGameWorldData(){
@@ -335,7 +340,6 @@ public class LoadingThread extends Thread {
} else {
Globals.commonWorldData = new CommonWorldData(Globals.clientWorldData, Globals.clientTerrainManager);
}
- Globals.collisionEngine = new CollisionEngine();
}
@@ -480,24 +484,24 @@ public class LoadingThread extends Thread {
// }
//trees \:D/
-// for(int i = 0; i < 10; i++){
-// Random rand = new Random();
-// String treePath = "Models/tree1.fbx";
-// Entity tree = EntityUtils.spawnDrawableEntity(treePath);
-// EntityUtils.getPosition(tree).set(rand.nextFloat() * 150 + 10, 0, rand.nextFloat() * 150 + 10);
-//// EntityUtils.getEntityRotation(tree).rotateAxis((float)-Math.PI/2.0f, new Vector3f(1,0,0));
-// }
+ for(int i = 0; i < 10; i++){
+ Random rand = new Random();
+ String treePath = "Models/tree1.fbx";
+ Entity tree = EntityUtils.spawnDrawableEntity(treePath);
+ EntityUtils.getPosition(tree).set(rand.nextFloat() * 150 + 10, 0, rand.nextFloat() * 150 + 10);
+// EntityUtils.getEntityRotation(tree).rotateAxis((float)-Math.PI/2.0f, new Vector3f(1,0,0));
+ }
- String buildingPath = "Models/building1.fbx";
- Entity building = EntityUtils.spawnDrawableEntity(buildingPath);
- EntityUtils.getPosition(building).set(5,1.2f,5);
- EntityUtils.getScale(building).set(0.5f);
- EntityUtils.getRotation(building).rotateLocalY((float)(Math.PI));
+// String buildingPath = "Models/building1.fbx";
+// Entity building = EntityUtils.spawnDrawableEntity(buildingPath);
+// EntityUtils.getPosition(building).set(5,1.2f,5);
+// EntityUtils.getScale(building).set(0.5f);
+// EntityUtils.getRotation(building).rotateLocalY((float)(Math.PI));
// ActorUtils.applyBlenderTransformer(building);
- //spawn evil goblin
+// //spawn evil goblin
// Entity goblin = CreatureUtils.spawnBasicCreature("Goblin");
-// EntityUtils.getPosition(goblin).set(30, 0, 30);
+// CreatureUtils.positionCharacter(goblin, new Vector3f(30, 3, 30));
// EntityUtils.getScale(goblin).set(0.005f);
// //give evil goblin sword
// Entity goblinSword = ItemUtils.spawnBasicItem("Katana");
@@ -506,12 +510,21 @@ public class LoadingThread extends Thread {
// MindlessAttacker.attachToCreature(goblin);
//
//
-// Entity testHomie = CreatureUtils.spawnBasicCreature("Human");
-// EntityUtils.getScale(testHomie).set(0.005f);
-// EntityUtils.getPosition(testHomie).set(2,0,2);
+ Entity testHomie = CreatureUtils.spawnBasicCreature("Human");
+ EntityUtils.getScale(testHomie).set(0.005f);
+ CreatureUtils.positionCharacter(testHomie, new Vector3f(10,1,10));
+
+ Entity sword = ItemUtils.spawnBasicItem("Katana");
+ AttachUtils.attachEntityToEntityAtBone(testHomie, sword, "Bone.020");
+
+
+// CollisionObjUtils.spawnCollisionPlane(new Vector3f(1,1,1), new Vector3f(11,0.5f,5), new Quaternionf().rotateLocalX(0.75f));
//
-// Entity sword = ItemUtils.spawnBasicItem("Katana");
-// AttachUtils.attachEntityToEntityAtBone(testHomie, sword, "Bone.020");
+// CollisionObjUtils.spawnCollisionCube(new Vector3f(1,1,1), new Vector3f(10,1,10), new Quaternionf());
+
+ CreatureUtils.positionCharacter(Globals.playerCharacter, new Vector3f(5,2,10));
+
+ StructureUtils.spawnBasicStructure("building1", new Vector3f(5,2.4f,15), new Quaternionf().rotateLocalY((float)Math.PI));
}
diff --git a/src/main/java/electrosphere/entity/CameraEntityUtils.java b/src/main/java/electrosphere/entity/CameraEntityUtils.java
index 0080a7a9..43dfc041 100644
--- a/src/main/java/electrosphere/entity/CameraEntityUtils.java
+++ b/src/main/java/electrosphere/entity/CameraEntityUtils.java
@@ -71,7 +71,7 @@ public class CameraEntityUtils {
cameraEye, //eye
cameraCenter, //center
cameraUp // up
- ).scale(1.0f, 1.5f, 1.0f);
+ ).scale(1.0f, 1.0f, 1.0f);
return rVal;
}
diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java
index cd6696ed..acad78c0 100644
--- a/src/main/java/electrosphere/entity/EntityDataStrings.java
+++ b/src/main/java/electrosphere/entity/EntityDataStrings.java
@@ -69,6 +69,13 @@ public class EntityDataStrings {
public static final String DATA_STRING_UI_ELEMENT = "uiEntity";
public static final String DATA_STRING_UI_ELEMENT_FONT = "uiFont";
+ /*
+ Physics Entity
+ */
+ public static final String PHYSICS_RIGID_BODY = "physicsRigidBody";
+ public static final String PHYSICS_RIGID_BODY_OFFSET = "physicsRigidBodyOffset";
+ public static final String PHYSICS_MODEL_TEMPLATE = "physicsModelTemplate";
+
/*
Collision Entity
*/
@@ -76,6 +83,14 @@ public class EntityDataStrings {
public static final String DATA_STRING_COLLISION_ENTITY = "collisionEntity";
public static final String DATA_STRING_COLLISION_ENTITY_TYPE_SPHERE = "collisionSphere";
+
+ public static final String COLLISION_ENTITY_COLLISION_OBJECT = "collisionEntityBulletObject";
+ public static final String COLLISION_ENTITY_COLLIDABLE = "collisionEntityCollidable";
+
+ public static final String COLLISION_ENTITY_TYPE_PLANE = "collisionTypePlane";
+ public static final String COLLISION_ENTITY_TYPE_CUBE = "collisionTypeCube";
+
+
public static final String COLLISION_ENTITY_DATA_TYPE_HIT = "collisionDataTypeHit";
public static final String COLLISION_ENTITY_DATA_TYPE_HURT = "collisionDataTypeHurt";
diff --git a/src/main/java/electrosphere/entity/EntityUtils.java b/src/main/java/electrosphere/entity/EntityUtils.java
index e191bf53..bf535902 100644
--- a/src/main/java/electrosphere/entity/EntityUtils.java
+++ b/src/main/java/electrosphere/entity/EntityUtils.java
@@ -5,7 +5,7 @@
*/
package electrosphere.entity;
-import electrosphere.entity.state.MovementTree;
+import electrosphere.entity.state.movement.MovementTree;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.renderer.Model;
diff --git a/src/main/java/electrosphere/entity/state/GravityTree.java b/src/main/java/electrosphere/entity/state/GravityTree.java
new file mode 100644
index 00000000..d6e722df
--- /dev/null
+++ b/src/main/java/electrosphere/entity/state/GravityTree.java
@@ -0,0 +1,122 @@
+package electrosphere.entity.state;
+
+import electrosphere.entity.Entity;
+import electrosphere.entity.EntityUtils;
+import electrosphere.entity.types.creature.CreatureUtils;
+import electrosphere.net.parser.net.message.EntityMessage;
+import electrosphere.renderer.Actor;
+import java.util.concurrent.CopyOnWriteArrayList;
+import org.joml.Vector3f;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class GravityTree {
+
+ public static enum IdleTreeState {
+ ACTIVE,
+ NOT_ACTIVE,
+ }
+
+ IdleTreeState state;
+
+ Entity parent;
+
+ CopyOnWriteArrayList networkMessageQueue = new CopyOnWriteArrayList();
+
+ int frameCurrent;
+
+ int maxFrame = 60;
+
+ public GravityTree(Entity e){
+ state = IdleTreeState.NOT_ACTIVE;
+ parent = e;
+ }
+
+ public IdleTreeState getState(){
+ return state;
+ }
+
+ public void start(){
+ //TODO: check if can start moving
+ state = IdleTreeState.ACTIVE;
+ frameCurrent = 0;
+ }
+
+ public void interrupt(){
+ state = IdleTreeState.NOT_ACTIVE;
+ }
+
+ public void stop(){
+ state = IdleTreeState.NOT_ACTIVE;
+ }
+
+ public void simulate(){
+ 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);
+ Vector3f newPosition;
+
+ //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:
+// isIdle = true;
+// if(hasMovementTree){
+// if(movementTree.getState() != MovementTreeState.IDLE){
+// isIdle = false;
+// }
+// }
+// if(hasAttackTree){
+// if(attackTree.getState() != AttackTreeState.IDLE){
+// isIdle = false;
+// }
+// }
+// if(!isIdle){
+// state = IdleTreeState.NOT_IDLE;
+// }
+// break;
+// case NOT_ACTIVE:
+// isIdle = true;
+// if(hasAttackTree){
+// if(attackTree.getState() != AttackTreeState.IDLE){
+// isIdle = false;
+// }
+// }
+// if(isIdle){
+// state = IdleTreeState.IDLE;
+// }
+// break;
+// }
+ }
+
+ public void addNetworkMessage(EntityMessage networkMessage) {
+ networkMessageQueue.add(networkMessage);
+ }
+
+}
diff --git a/src/main/java/electrosphere/entity/state/IdleTree.java b/src/main/java/electrosphere/entity/state/IdleTree.java
index c5219640..a544ea91 100644
--- a/src/main/java/electrosphere/entity/state/IdleTree.java
+++ b/src/main/java/electrosphere/entity/state/IdleTree.java
@@ -1,10 +1,11 @@
package electrosphere.entity.state;
+import electrosphere.entity.state.movement.MovementTree;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.AttackTree.AttackTreeState;
-import electrosphere.entity.state.MovementTree.MovementTreeState;
+import electrosphere.entity.state.movement.MovementTree.MovementTreeState;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.Actor;
diff --git a/src/main/java/electrosphere/entity/state/movement/Impulse.java b/src/main/java/electrosphere/entity/state/movement/Impulse.java
new file mode 100644
index 00000000..123ab728
--- /dev/null
+++ b/src/main/java/electrosphere/entity/state/movement/Impulse.java
@@ -0,0 +1,28 @@
+package electrosphere.entity.state.movement;
+
+import org.joml.Vector3f;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class Impulse {
+
+ Vector3f direction;
+ float force;
+
+ public Impulse(Vector3f dir, float force){
+ this.force = force;
+ this.direction = dir;
+ }
+
+ public Vector3f getDirection() {
+ return direction;
+ }
+
+ public float getForce() {
+ return force;
+ }
+
+
+}
diff --git a/src/main/java/electrosphere/entity/state/MovementTree.java b/src/main/java/electrosphere/entity/state/movement/MovementTree.java
similarity index 51%
rename from src/main/java/electrosphere/entity/state/MovementTree.java
rename to src/main/java/electrosphere/entity/state/movement/MovementTree.java
index 8c30ba11..0357fb58 100644
--- a/src/main/java/electrosphere/entity/state/MovementTree.java
+++ b/src/main/java/electrosphere/entity/state/movement/MovementTree.java
@@ -1,8 +1,12 @@
-package electrosphere.entity.state;
+package electrosphere.entity.state.movement;
+import com.bulletphysics.collision.dispatch.CollisionObject;
+import com.bulletphysics.dynamics.RigidBody;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
+import electrosphere.game.collision.PhysicsUtils;
+import electrosphere.game.collision.collidable.Collidable;
import electrosphere.main.Globals;
import electrosphere.net.NetUtils;
import electrosphere.net.parser.net.message.EntityMessage;
@@ -10,6 +14,7 @@ import electrosphere.renderer.Actor;
import electrosphere.renderer.anim.Animation;
import electrosphere.renderer.Model;
import java.util.LinkedList;
+import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@@ -32,6 +37,9 @@ public class MovementTree {
Entity parent;
+ CollisionObject body;
+ Collidable collidable;
+
CopyOnWriteArrayList networkMessageQueue = new CopyOnWriteArrayList();
long lastUpdateTime = 0;
@@ -46,6 +54,11 @@ public class MovementTree {
return state;
}
+ public void setCollisionObject(CollisionObject body, Collidable collidable){
+ this.body = body;
+ this.collidable = collidable;
+ }
+
public void start(){
//TODO: check if can start moving
state = MovementTreeState.STARTUP;
@@ -67,7 +80,9 @@ public class MovementTree {
// Model entityModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(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){
@@ -123,6 +138,12 @@ public class MovementTree {
}
}
+ //handle impulses
+ for(Impulse impulse : collidable.getImpulses()){
+ collidable.getImpulses().remove(impulse);
+ position.add(impulse.direction.mul(impulse.force));
+ }
+
//state machine
switch(state){
case STARTUP:
@@ -140,46 +161,53 @@ public class MovementTree {
velocity = maxNaturalVelocity;
state = MovementTreeState.MOVE;
}
+// body.applyCentralForce(PhysicsUtils.jomlToVecmathVector3f(new Vector3f(movementVector.x,0,movementVector.z).normalize().mul(velocity)));
+ EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), new Vector3f(movementVector.x,0,movementVector.z));
//move the entity
- newPosition = new Vector3f(position).add(new Vector3f(movementVector).mul(velocity)).add(0,-9.8f,0);
+ newPosition = new Vector3f(position).add(new Vector3f(movementVector).mul(velocity));
//check/update if collision
if(!Globals.collisionEngine.checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
newPosition = Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
}
- //actually update
- EntityUtils.getPosition(parent).set(newPosition);
- EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), movementVector);
- if(Globals.RUN_SERVER){
- Globals.server.broadcastMessage(
- EntityMessage.constructmoveUpdateMessage(
- parent.getId(),
- System.currentTimeMillis(),
- newPosition.x,
- newPosition.y,
- newPosition.z,
- movementVector.x,
- movementVector.y,
- movementVector.z,
- velocity,
- 0
- )
- );
- } else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
- Globals.clientConnection.queueOutgoingMessage(
- EntityMessage.constructmoveUpdateMessage(
- parent.getId(),
- System.currentTimeMillis(),
- newPosition.x,
- newPosition.y,
- newPosition.z,
- movementVector.x,
- movementVector.y,
- movementVector.z,
- velocity,
- 0
- )
- );
- }
+// //actually update
+ position.set(newPosition);
+ rotation.rotationTo(new Vector3f(0,0,1), movementVector);
+
+ bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(newPosition),1.0f);
+ body.setWorldTransform(new com.bulletphysics.linearmath.Transform(bodyTransformMatrix));
+
+
+// if(Globals.RUN_SERVER){
+// Globals.server.broadcastMessage(
+// EntityMessage.constructmoveUpdateMessage(
+// parent.getId(),
+// System.currentTimeMillis(),
+// newPosition.x,
+// newPosition.y,
+// newPosition.z,
+// movementVector.x,
+// movementVector.y,
+// movementVector.z,
+// velocity,
+// 0
+// )
+// );
+// } else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
+// Globals.clientConnection.queueOutgoingMessage(
+// EntityMessage.constructmoveUpdateMessage(
+// parent.getId(),
+// System.currentTimeMillis(),
+// newPosition.x,
+// newPosition.y,
+// newPosition.z,
+// movementVector.x,
+// movementVector.y,
+// movementVector.z,
+// velocity,
+// 0
+// )
+// );
+// }
break;
case MOVE:
//check if can restart animation
@@ -190,45 +218,52 @@ public class MovementTree {
entityActor.incrementAnimationTime(0.01);
}
}
+ Vector3f force = new Vector3f(movementVector).normalize().mul(velocity);
+// body.applyCentralForce(PhysicsUtils.jomlToVecmathVector3f(force));
+ EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), new Vector3f(movementVector.x,0,movementVector.z));
//check if can move forward (collision engine)
//if can, move forward by entity movement stats
- newPosition = new Vector3f(position).add(new Vector3f(movementVector).mul(velocity)).add(0,-9.8f,0);
+ newPosition = new Vector3f(position).add(new Vector3f(movementVector).mul(velocity));
if(!Globals.collisionEngine.checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
newPosition = Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
}
- EntityUtils.getPosition(parent).set(newPosition);
- EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), movementVector);
- if(Globals.RUN_SERVER){
- Globals.server.broadcastMessage(
- EntityMessage.constructmoveUpdateMessage(
- parent.getId(),
- System.currentTimeMillis(),
- newPosition.x,
- newPosition.y,
- newPosition.z,
- movementVector.x,
- movementVector.y,
- movementVector.z,
- velocity,
- 1
- )
- );
- } else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
- Globals.clientConnection.queueOutgoingMessage(
- EntityMessage.constructmoveUpdateMessage(
- parent.getId(),
- System.currentTimeMillis(),
- newPosition.x,
- newPosition.y,
- newPosition.z,
- movementVector.x,
- movementVector.y,
- movementVector.z,
- velocity,
- 1
- )
- );
- }
+ position.set(newPosition);
+ rotation.rotationTo(new Vector3f(0,0,1), movementVector);
+
+ bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(newPosition),1.0f);
+ body.setWorldTransform(new com.bulletphysics.linearmath.Transform(bodyTransformMatrix));
+
+// if(Globals.RUN_SERVER){
+// Globals.server.broadcastMessage(
+// EntityMessage.constructmoveUpdateMessage(
+// parent.getId(),
+// System.currentTimeMillis(),
+// newPosition.x,
+// newPosition.y,
+// newPosition.z,
+// movementVector.x,
+// movementVector.y,
+// movementVector.z,
+// velocity,
+// 1
+// )
+// );
+// } else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
+// Globals.clientConnection.queueOutgoingMessage(
+// EntityMessage.constructmoveUpdateMessage(
+// parent.getId(),
+// System.currentTimeMillis(),
+// newPosition.x,
+// newPosition.y,
+// newPosition.z,
+// movementVector.x,
+// movementVector.y,
+// movementVector.z,
+// velocity,
+// 1
+// )
+// );
+// }
break;
case SLOWDOWN:
//run slowdown code
@@ -245,55 +280,65 @@ public class MovementTree {
velocity = 0;
state = MovementTreeState.IDLE;
}
+// body.applyCentralForce(PhysicsUtils.jomlToVecmathVector3f(new Vector3f(movementVector).mul(-1.0f).normalize().mul(velocity)));
+ EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), new Vector3f(movementVector.x,0,movementVector.z));
//move the entity
- newPosition = new Vector3f(position).add(new Vector3f(movementVector).mul(velocity)).add(0,-9.8f,0);
+ newPosition = new Vector3f(position).add(new Vector3f(movementVector).mul(velocity));
if(!Globals.collisionEngine.checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
newPosition = Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
}
- EntityUtils.getPosition(parent).set(newPosition);
- EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), movementVector);
- if(Globals.RUN_SERVER){
- Globals.server.broadcastMessage(
- EntityMessage.constructmoveUpdateMessage(
- parent.getId(),
- System.currentTimeMillis(),
- newPosition.x,
- newPosition.y,
- newPosition.z,
- movementVector.x,
- movementVector.y,
- movementVector.z,
- velocity,
- 2
- )
- );
- } else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
- Globals.clientConnection.queueOutgoingMessage(
- EntityMessage.constructmoveUpdateMessage(
- parent.getId(),
- System.currentTimeMillis(),
- newPosition.x,
- newPosition.y,
- newPosition.z,
- movementVector.x,
- movementVector.y,
- movementVector.z,
- velocity,
- 2
- )
- );
- }
+ position.set(newPosition);
+ rotation.rotationTo(new Vector3f(0,0,1), movementVector);
+
+ bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(newPosition),1.0f);
+ body.setWorldTransform(new com.bulletphysics.linearmath.Transform(bodyTransformMatrix));
+
+// if(Globals.RUN_SERVER){
+// Globals.server.broadcastMessage(
+// EntityMessage.constructmoveUpdateMessage(
+// parent.getId(),
+// System.currentTimeMillis(),
+// newPosition.x,
+// newPosition.y,
+// newPosition.z,
+// movementVector.x,
+// movementVector.y,
+// movementVector.z,
+// velocity,
+// 2
+// )
+// );
+// } else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){
+// Globals.clientConnection.queueOutgoingMessage(
+// EntityMessage.constructmoveUpdateMessage(
+// parent.getId(),
+// System.currentTimeMillis(),
+// newPosition.x,
+// newPosition.y,
+// newPosition.z,
+// movementVector.x,
+// movementVector.y,
+// movementVector.z,
+// velocity,
+// 2
+// )
+// );
+// }
break;
case IDLE:
+// body.clearForces();
// if(entityActor != null){
// if(!entityActor.isPlayingAnimation() || !entityActor.getCurrentAnimation().equals(Animation.ANIMATION_IDLE_1)){
// entityActor.playAnimation(Animation.ANIMATION_IDLE_1);
// entityActor.incrementAnimationTime(0.01);
// }
// }
- if(Globals.collisionEngine.gravityCheck(Globals.commonWorldData, parent)){
- EntityUtils.getPosition(parent).set(Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData,parent,new Vector3f(position.x,position.y - 9.8f,position.z)));
- }
+// if(Globals.collisionEngine.gravityCheck(Globals.commonWorldData, parent)){
+// position.set(Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData,parent,new Vector3f(position.x,position.y - 9.8f,position.z)));
+// }
+ position.set(new Vector3f(position.x,position.y - 0.1f,position.z));
+ bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(position),1.0f);
+ body.setWorldTransform(new com.bulletphysics.linearmath.Transform(bodyTransformMatrix));
break;
}
}
diff --git a/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java
new file mode 100644
index 00000000..f8c82a2a
--- /dev/null
+++ b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java
@@ -0,0 +1,68 @@
+package electrosphere.entity.types.collision;
+
+import com.bulletphysics.collision.dispatch.CollisionObject;
+import com.bulletphysics.collision.shapes.CylinderShape;
+import electrosphere.entity.Entity;
+import electrosphere.entity.EntityDataStrings;
+import electrosphere.game.collision.PhysicsUtils;
+import electrosphere.game.collision.collidable.Collidable;
+import electrosphere.main.Globals;
+import org.joml.Quaternionf;
+import org.joml.Vector3f;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class CollisionObjUtils {
+
+ public static Entity spawnCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation){
+ Entity rVal = new Entity();
+
+ CollisionObject planeObject = PhysicsUtils.getPlaneObject(scale);
+ javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
+ PhysicsUtils.jomlToVecmathQuaternionf(rotation),
+ PhysicsUtils.jomlToVecmathVector3f(position),
+ 1.0f);
+ planeObject.setWorldTransform(new com.bulletphysics.linearmath.Transform(planeTransform));
+ Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
+ Globals.collisionEngine.registerCollisionObject(planeObject, collidable);
+ Globals.collisionEngine.registerStructurePhysicsEntity(rVal);
+
+ rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true);
+ rVal.putData(EntityDataStrings.DATA_STRING_POSITION, position);
+ rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, rotation);
+ rVal.putData(EntityDataStrings.DATA_STRING_SCALE, scale);
+ rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, planeObject);
+ rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
+
+ Globals.entityManager.registerEntity(rVal);
+ return rVal;
+ }
+
+
+ public static Entity spawnCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation){
+ Entity rVal = new Entity();
+
+ CollisionObject cubeObject = PhysicsUtils.getCubeObject(scale);
+ javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
+ PhysicsUtils.jomlToVecmathQuaternionf(rotation),
+ PhysicsUtils.jomlToVecmathVector3f(position),
+ 1.0f);
+ cubeObject.setWorldTransform(new com.bulletphysics.linearmath.Transform(planeTransform));
+ Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
+ Globals.collisionEngine.registerCollisionObject(cubeObject, collidable);
+ Globals.collisionEngine.registerStructurePhysicsEntity(rVal);
+
+ rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true);
+ rVal.putData(EntityDataStrings.DATA_STRING_POSITION, position);
+ rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, rotation);
+ rVal.putData(EntityDataStrings.DATA_STRING_SCALE, scale);
+ rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, cubeObject);
+ rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
+
+ Globals.entityManager.registerEntity(rVal);
+ return rVal;
+ }
+
+}
diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java
index 4b8eadaf..7440ac0a 100644
--- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java
+++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java
@@ -1,9 +1,11 @@
package electrosphere.entity.types.creature;
+import com.bulletphysics.collision.dispatch.CollisionObject;
+import com.bulletphysics.dynamics.RigidBody;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
-import electrosphere.entity.state.MovementTree;
+import electrosphere.entity.state.movement.MovementTree;
import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.game.server.creature.type.CreatureType;
@@ -11,7 +13,10 @@ import electrosphere.game.server.creature.type.MovementSystem;
import electrosphere.entity.state.AttackTree;
import electrosphere.entity.state.IdleTree;
import electrosphere.entity.types.life.LifeState;
+import electrosphere.game.collision.PhysicsUtils;
+import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.server.creature.type.AttackMove;
+import electrosphere.game.server.creature.type.PhysicsObject;
import electrosphere.main.Globals;
import electrosphere.main.Main;
import electrosphere.net.parser.net.message.EntityMessage;
@@ -69,6 +74,24 @@ public class CreatureUtils {
break;
}
}
+ if(rawType.getPhysicsObject() != null){
+ PhysicsObject physicsTemplate = rawType.getPhysicsObject();
+ switch(physicsTemplate.getType()){
+ case "CYLINDER":
+ CollisionObject rigidBody = PhysicsUtils.getCylinderBody(1f, new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
+ Collidable collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
+ rVal.putData(EntityDataStrings.PHYSICS_RIGID_BODY, rigidBody);
+ rVal.putData(EntityDataStrings.PHYSICS_RIGID_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
+ rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
+ Globals.collisionEngine.registerPhysicsEntity(rVal);
+ Globals.collisionEngine.registerDynamicPhysicsEntity(rVal);
+ Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);
+ if(rVal.getDataKeys().contains(EntityDataStrings.DATA_STRING_MOVEMENT_BT)){
+ CreatureUtils.getEntityMovementTree(rVal).setCollisionObject(rigidBody, collidable);
+ }
+ break;
+ }
+ }
for(String token : rawType.getTokens()){
switch(token){
case "BLENDER_TRANSFORM":
@@ -177,4 +200,15 @@ public class CreatureUtils {
public static IdleTree getIdleTree(Entity e){
return (IdleTree)e.getData(EntityDataStrings.IDLE_TREE);
}
+
+ public static CollisionObject getCreatureRigidBody(Entity e){
+ return (CollisionObject)e.getData(EntityDataStrings.PHYSICS_RIGID_BODY);
+ }
+
+ public static void positionCharacter(Entity e, Vector3f position){
+ EntityUtils.getPosition(e).set(position);
+ Quaternionf rotation = EntityUtils.getRotation(e);
+ CollisionObject body = getCreatureRigidBody(e);
+ PhysicsUtils.setRigidBodyTransform(position, rotation, body);
+ }
}
diff --git a/src/main/java/electrosphere/entity/types/item/ItemUtils.java b/src/main/java/electrosphere/entity/types/item/ItemUtils.java
index 9008136d..d6fb7e1b 100644
--- a/src/main/java/electrosphere/entity/types/item/ItemUtils.java
+++ b/src/main/java/electrosphere/entity/types/item/ItemUtils.java
@@ -3,7 +3,7 @@ package electrosphere.entity.types.item;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
-import electrosphere.entity.state.MovementTree;
+import electrosphere.entity.state.movement.MovementTree;
import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.game.server.creature.type.CreatureType;
diff --git a/src/main/java/electrosphere/entity/types/structure/StructureUtils.java b/src/main/java/electrosphere/entity/types/structure/StructureUtils.java
new file mode 100644
index 00000000..04c63f1f
--- /dev/null
+++ b/src/main/java/electrosphere/entity/types/structure/StructureUtils.java
@@ -0,0 +1,46 @@
+package electrosphere.entity.types.structure;
+
+import electrosphere.entity.Entity;
+import electrosphere.entity.EntityDataStrings;
+import electrosphere.entity.EntityUtils;
+import electrosphere.entity.types.collision.CollisionObjUtils;
+import electrosphere.game.collision.collidable.Collidable;
+import electrosphere.game.server.structure.model.CollisionObjectTemplate;
+import electrosphere.game.server.structure.model.StructureType;
+import electrosphere.main.Globals;
+import org.joml.Matrix4f;
+import org.joml.Quaternionf;
+import org.joml.Vector3f;
+import org.joml.Vector4f;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class StructureUtils {
+
+
+ public static Entity spawnBasicStructure(String type, Vector3f position, Quaternionf rotation){
+ StructureType rawType = Globals.structureTypeMap.getType(type);
+ Entity rVal = EntityUtils.spawnDrawableEntity(rawType.getModelPath());
+ EntityUtils.getPosition(rVal).set(position);
+ EntityUtils.getRotation(rVal).set(rotation);
+ for(CollisionObjectTemplate template : rawType.getCollision()){
+ switch(template.getType()){
+ case CollisionObjectTemplate.TYPE_CUBE:
+ Matrix4f rotationTransform = new Matrix4f().rotate(rotation);
+ Vector4f rotatedPosition = rotationTransform.transform(new Vector4f(template.getPositionX(),template.getPositionY(),template.getPositionZ(),1.0f));
+ Vector3f cubePosition = new Vector3f(position).add(rotatedPosition.x,rotatedPosition.y,rotatedPosition.z);
+ Quaternionf cubeRotation = new Quaternionf(rotation).mul(new Quaternionf(template.getRotationX(),template.getRotationY(),template.getRotationZ(),template.getRotationW())).normalize();
+ CollisionObjUtils.spawnCollisionCube(new Vector3f(template.getScaleX(),template.getScaleY(),template.getScaleZ()), cubePosition, cubeRotation);
+// Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
+// Globals.collisionEngine.registerPhysicsEntity(rVal);
+// Globals.collisionEngine.registerCollisionObject(rigidBody, collidable);
+ break;
+ case CollisionObjectTemplate.TYPE_PLANE:
+ throw new UnsupportedOperationException("Haven't implemented plane collision on structures");
+ }
+ }
+ return rVal;
+ }
+}
diff --git a/src/main/java/electrosphere/game/client/drawcell/DrawCell.java b/src/main/java/electrosphere/game/client/drawcell/DrawCell.java
index 492d3638..096f412a 100644
--- a/src/main/java/electrosphere/game/client/drawcell/DrawCell.java
+++ b/src/main/java/electrosphere/game/client/drawcell/DrawCell.java
@@ -2,6 +2,7 @@ package electrosphere.game.client.drawcell;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
+import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.terrain.processing.TerrainInterpolator;
import electrosphere.logger.LoggerInterface;
import electrosphere.main.Globals;
@@ -30,6 +31,7 @@ public class DrawCell {
+
DrawCell(){
}
@@ -80,6 +82,8 @@ public class DrawCell {
modelEntity = EntityUtils.spawnDrawableEntity(terrainModelPath);
LoggerInterface.loggerRenderer.INFO("New cell @ " + cellX * dynamicInterpolationRatio + "," + cellY * dynamicInterpolationRatio);
EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio));
+ PhysicsUtils.attachTerrainRigidBody(modelEntity,heightmap);
+ Globals.collisionEngine.registerPhysicsEntity(modelEntity);
}
public void retireCell(){
diff --git a/src/main/java/electrosphere/game/client/drawcell/DrawCellManager.java b/src/main/java/electrosphere/game/client/drawcell/DrawCellManager.java
index 9ecaef19..6b19ed93 100644
--- a/src/main/java/electrosphere/game/client/drawcell/DrawCellManager.java
+++ b/src/main/java/electrosphere/game/client/drawcell/DrawCellManager.java
@@ -45,6 +45,8 @@ public class DrawCellManager {
int drawStepdownInterval = 3;
int drawStepdownValue = 5;
+ int worldBoundDiscreteMin = 0;
+ int worldBoundDiscreteMax = 0;
//metadata about the game world
ClientWorldData clientWorldData;
@@ -60,6 +62,7 @@ public class DrawCellManager {
public DrawCellManager(ClientWorldData clientWorldData, ClientTerrainManager clientTerrainManager, int discreteX, int discreteY){
this.clientWorldData = clientWorldData;
+ worldBoundDiscreteMax = (int)(this.clientWorldData.getWorldBoundMax().x / this.clientWorldData.getDynamicInterpolationRatio() * 1.0f);
this.clientTerrainManager = clientTerrainManager;
this.miniCellWidth = miniCellWidth;
cells = new DrawCell[drawRadius * 2 + 1][drawRadius * 2 + 1];
@@ -280,7 +283,9 @@ public class DrawCellManager {
public void shiftChunksNegX(){
for(int y = 0; y < drawRadius * 2 + 1; y++){
- cells[drawRadius * 2][y].retireCell();
+ if(cells[drawRadius * 2][y] != null){
+ cells[drawRadius * 2][y].retireCell();
+ }
}
for(int x = drawRadius * 2; x > 0; x--){
for(int y = 0; y < drawRadius * 2 + 1; y++){
@@ -297,7 +302,9 @@ public class DrawCellManager {
public void shiftChunksPosX(){
for(int y = 0; y < drawRadius * 2 + 1; y++){
- cells[0][y].retireCell();
+ if(cells[0][y] != null){
+ cells[0][y].retireCell();
+ }
}
for(int x = 0; x < drawRadius * 2; x++){
for(int y = 0; y < drawRadius * 2 + 1; y++){
@@ -314,7 +321,9 @@ public class DrawCellManager {
public void shiftChunksNegY(){
for(int x = 0; x < drawRadius * 2 + 1; x++){
- cells[x][drawRadius * 2].retireCell();
+ if(cells[x][drawRadius * 2] != null){
+ cells[x][drawRadius * 2].retireCell();
+ }
}
for(int x = 0; x < drawRadius * 2 + 1; x++){
for(int y = drawRadius * 2; y > 0; y--){
@@ -331,7 +340,9 @@ public class DrawCellManager {
public void shiftChunksPosY(){
for(int x = 0; x < drawRadius * 2 + 1; x++){
- cells[x][0].retireCell();
+ if(cells[x][0] != null){
+ cells[x][0].retireCell();
+ }
}
for(int x = 0; x < drawRadius * 2 + 1; x++){
for(int y = 0; y < drawRadius * 2; y++){
diff --git a/src/main/java/electrosphere/game/collision/CollisionEngine.java b/src/main/java/electrosphere/game/collision/CollisionEngine.java
index df09f16d..7b8a46cd 100644
--- a/src/main/java/electrosphere/game/collision/CollisionEngine.java
+++ b/src/main/java/electrosphere/game/collision/CollisionEngine.java
@@ -2,12 +2,17 @@ package electrosphere.game.collision;
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
import com.bulletphysics.collision.broadphase.DbvtBroadphase;
+import com.bulletphysics.collision.broadphase.Dispatcher;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.CollisionObject;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
+import com.bulletphysics.collision.narrowphase.ManifoldPoint;
+import com.bulletphysics.collision.narrowphase.PersistentManifold;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
+import com.bulletphysics.dynamics.DynamicsWorld;
+import com.bulletphysics.dynamics.InternalTickCallback;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
@@ -16,7 +21,9 @@ import com.bulletphysics.linearmath.Transform;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
+import electrosphere.entity.state.movement.Impulse;
import electrosphere.entity.types.hitbox.HitboxData;
+import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.server.world.ServerWorldData;
import java.util.ArrayList;
import java.util.List;
@@ -28,27 +35,66 @@ import org.joml.Vector3f;
*/
public class CollisionEngine {
+ DiscreteDynamicsWorld world;
+ SequentialImpulseConstraintSolver solver;
BroadphaseInterface broadphase;
DefaultCollisionConfiguration collisionConfiguration;
CollisionDispatcher dispatcher;
List collisionEntities = new ArrayList();
+ List physicsEntities = new ArrayList();
+ List dynamicPhysicsEntities = new ArrayList();
+ List structurePhysicsEntities = new ArrayList();
+ List collisionObject = new ArrayList();
public CollisionEngine(){
broadphase = new DbvtBroadphase();
collisionConfiguration = new DefaultCollisionConfiguration();
dispatcher = new CollisionDispatcher(collisionConfiguration);
- SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
- DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
+ solver = new SequentialImpulseConstraintSolver();
+ world = new DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
- CollisionShape boxShape = new BoxShape(new javax.vecmath.Vector3f(1,1,1));
- float mass = 1.0f;
- DefaultMotionState fallMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f(0,50,0),1.0f)));
- RigidBodyConstructionInfo boxShapeRigidBodyCI = new RigidBodyConstructionInfo(mass, fallMotionState, boxShape);
- RigidBody boxRigidBody = new RigidBody(boxShapeRigidBodyCI);
+// CollisionShape boxShape = new BoxShape(new javax.vecmath.Vector3f(1,1,1));
+// float mass = 1.0f;
+// DefaultMotionState fallMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f(0,50,0),1.0f)));
+// RigidBodyConstructionInfo boxShapeRigidBodyCI = new RigidBodyConstructionInfo(mass, fallMotionState, boxShape);
+// RigidBody boxRigidBody = new RigidBody(boxShapeRigidBodyCI);
+//
+// world.addRigidBody(boxRigidBody);
-
- world.addRigidBody(boxRigidBody);
+ world.setInternalTickCallback(new InternalTickCallback(){
+ @Override
+ public void internalTick(DynamicsWorld dw, float f) {
+ Dispatcher dispatcher = dw.getDispatcher();
+ int manifoldCount = dispatcher.getNumManifolds();
+ for (int i = 0; i < manifoldCount; i++) {
+ PersistentManifold manifold = dispatcher.getManifoldByIndexInternal(i);
+ // The following two lines are optional.
+ CollisionObject object1 = (CollisionObject)manifold.getBody0();
+ CollisionObject object2 = (CollisionObject)manifold.getBody1();
+ Collidable physicsObject1 = (Collidable)object1.getUserPointer();
+ Collidable physicsObject2 = (Collidable)object2.getUserPointer();
+ boolean hit = false;
+ Vector3f normal = null;
+ float magnitude = 0.0f;
+ for (int j = 0; j < manifold.getNumContacts(); j++) {
+ ManifoldPoint contactPoint = manifold.getContactPoint(j);
+ if (contactPoint.getDistance() < 0.0f) {
+ magnitude = contactPoint.getDistance();
+ hit = true;
+ normal = new Vector3f(contactPoint.normalWorldOnB.x,contactPoint.normalWorldOnB.y,contactPoint.normalWorldOnB.z);
+ break;
+ }
+ }
+ if (hit) {
+ resolveCollision(physicsObject1,physicsObject2, normal, magnitude);
+ resolveCollision(physicsObject2,physicsObject1, new Vector3f(normal).mul(-1.0f), magnitude);
+// System.out.println("HIT + " + normal);
+ // Collision happened between physicsObject1 and physicsObject2. Collision normal is in variable 'normal'.
+ }
+ }
+ }
+ }, world);
//https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=11507
//https://www.google.com/search?client=firefox-b-1-d&q=bullet+set+position+and+check+if+collision
@@ -56,6 +102,26 @@ public class CollisionEngine {
}
+ public static void resolveCollision(Collidable impactor, Collidable receiver, Vector3f normal, float magnitude){
+ switch(receiver.getType()){
+ case Collidable.TYPE_CREATURE:
+ switch(impactor.getType()){
+ case Collidable.TYPE_TERRAIN:
+// System.out.println("Terrain-creature collision: " + normal + " mag:" + realMagnitude);
+ receiver.addImpulse(new Impulse(new Vector3f(0,1.0f,0), -1.0f * magnitude));
+ break;
+ case Collidable.TYPE_CREATURE:
+ receiver.addImpulse(new Impulse(normal,magnitude));
+ break;
+ case Collidable.TYPE_STRUCTURE:
+ receiver.addImpulse(new Impulse(normal, magnitude));
+ System.out.println("Structure-creature collision");
+ break;
+ }
+ break;
+ }
+ }
+
/**
*
@@ -76,15 +142,19 @@ public class CollisionEngine {
){
return false;
}
- //
- // are we below the terrain?
- //
- if(w.getElevationAtPoint(positionToCheck) > positionToCheck.y){
- return false;
- }
+// //
+// // are we below the terrain?
+// //
+// if(w.getElevationAtPoint(positionToCheck) > positionToCheck.y){
+// return false;
+// }
return rVal;
}
+ public void simulatePhysics(float time){
+ world.stepSimulation(time);
+ }
+
/**
*
* @param e the entity that's trying to move
@@ -143,6 +213,54 @@ public class CollisionEngine {
}
}
+ public void registerPhysicsEntity(Entity physicsEntity){
+ physicsEntities.add(physicsEntity);
+ }
+
+ public List getPhysicsEntities(){
+ return physicsEntities;
+ }
+
+ public void registerDynamicPhysicsEntity(Entity dynamicEntity){
+ dynamicPhysicsEntities.add(dynamicEntity);
+ }
+
+ public List getDynamicPhysicsEntities(){
+ return dynamicPhysicsEntities;
+ }
+
+ public void registerStructurePhysicsEntity(Entity structureEntity){
+ structurePhysicsEntities.add(structureEntity);
+ }
+
+ public List getStructurePhysicsEntities(){
+ return structurePhysicsEntities;
+ }
+
+ public void updateDynamicObjectTransforms(){
+ for(Entity dynamicEntity : dynamicPhysicsEntities){
+ CollisionObject rigidBody = (CollisionObject)dynamicEntity.getData(EntityDataStrings.PHYSICS_RIGID_BODY);
+ Vector3f offset = (Vector3f)dynamicEntity.getData(EntityDataStrings.PHYSICS_RIGID_BODY_OFFSET);
+ Vector3f newPosition = PhysicsUtils.getRigidBodyPosition(rigidBody).add(offset);
+// System.out.println(rigidBody + " position " + newPosition);
+// System.out.println("Linear velocity: " + rigidBody.getLinearVelocity(new javax.vecmath.Vector3f()));
+ EntityUtils.getPosition(dynamicEntity).set(newPosition);
+ }
+ }
+
+ public void registerCollisionObject(CollisionObject object, Collidable collidable){
+ world.addCollisionObject(object);
+ object.setUserPointer(collidable);
+ collisionObject.add(object);
+ }
+
+ public void listBodyPositions(){
+ for(CollisionObject body : collisionObject){
+ System.out.println(body);
+ System.out.println(PhysicsUtils.getRigidBodyPosition(body));
+ }
+ }
+
/*
Check if the entity is being accelerated by gravity
*/
diff --git a/src/main/java/electrosphere/game/collision/PhysicsUtils.java b/src/main/java/electrosphere/game/collision/PhysicsUtils.java
new file mode 100644
index 00000000..647077f3
--- /dev/null
+++ b/src/main/java/electrosphere/game/collision/PhysicsUtils.java
@@ -0,0 +1,361 @@
+package electrosphere.game.collision;
+
+import com.bulletphysics.collision.dispatch.CollisionObject;
+import com.bulletphysics.collision.shapes.BoxShape;
+import com.bulletphysics.collision.shapes.BvhTriangleMeshShape;
+import com.bulletphysics.collision.shapes.CylinderShape;
+import com.bulletphysics.collision.shapes.IndexedMesh;
+import com.bulletphysics.collision.shapes.TriangleIndexVertexArray;
+import com.bulletphysics.dynamics.RigidBody;
+import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
+import com.bulletphysics.linearmath.DefaultMotionState;
+import com.bulletphysics.linearmath.Transform;
+import electrosphere.entity.Entity;
+import electrosphere.entity.EntityDataStrings;
+import electrosphere.entity.EntityUtils;
+import electrosphere.game.collision.collidable.Collidable;
+import electrosphere.main.Globals;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import org.joml.Quaternionf;
+import org.joml.Vector3f;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class PhysicsUtils {
+
+ /**
+ * Constructor for rigid body:
+ * http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/CylinderShape.html
+ * Creates a sphere where the dimensions are twice the size of the vector passed in
+ * ie diameter = x * 2 or z * 2
+ * @param entity
+ * @param halfDimensions
+ */
+ public static void attachCylinderRigidBody(Entity entity, Vector3f halfDimensions){
+ new com.bulletphysics.collision.shapes.CylinderShape(new javax.vecmath.Vector3f(halfDimensions.x,halfDimensions.y,halfDimensions.z));
+ }
+
+
+ public static RigidBody attachTerrainRigidBody(Entity terrain, float[][] heightfield){
+
+ Vector3f position = EntityUtils.getPosition(terrain);
+
+ int arrayLength = heightfield.length;
+ int arrayWidth = heightfield[0].length;
+
+ /*
+ Traditional buffer code not working for some reason
+ the approach of
+ https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider
+ works much better
+ IDK why
+ */
+
+ int numberTriangles = (arrayLength - 1) * (arrayWidth - 1) * 2;
+ int triangleStride = 0;
+
+ int numberVertices = arrayLength * arrayWidth;
+ int vertexStride = 0;
+
+ float[] vertices = new float[numberVertices * 3];
+ int vertexInserterPos = 0;
+ int[] indices = new int[numberTriangles * 3];
+ int indexInserterPos = 0;
+
+ for(int x = 0; x < arrayLength; x++){
+ for(int y = 0; y < arrayWidth; y++){
+ vertices[vertexInserterPos] = x;
+ vertexInserterPos++;
+ vertices[vertexInserterPos] = heightfield[x][y] - 0.4f;
+ vertexInserterPos++;
+ vertices[vertexInserterPos] = y;
+ vertexInserterPos++;
+ if(x < arrayLength - 1 && y < arrayWidth - 1){
+ //if we should also add a triangle index
+ /*
+ as copied from ModelUtil's terrain mesh generation function
+ faces.put((x / stride + 0) * actualHeight + (y / stride + 0));
+ faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
+ faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
+ faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
+ faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
+ faces.put((x / stride + 1) * actualHeight + (y / stride + 1));
+ */
+ indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 0);
+ indexInserterPos++;
+ indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1);
+ indexInserterPos++;
+ indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0);
+ indexInserterPos++;
+ indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0);
+ indexInserterPos++;
+ indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1);
+ indexInserterPos++;
+ indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 1);
+ indexInserterPos++;
+ }
+ }
+ }
+
+
+ javax.vecmath.Vector3f aabbMin = new javax.vecmath.Vector3f();
+ javax.vecmath.Vector3f aabbMax = new javax.vecmath.Vector3f();
+
+
+
+
+ //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/IndexedMesh.html
+ com.bulletphysics.collision.shapes.IndexedMesh indexedMesh = new com.bulletphysics.collision.shapes.IndexedMesh();
+
+ indexedMesh.numTriangles = indices.length / 3;
+ indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
+ indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
+ indexedMesh.triangleIndexStride = 3 * Float.BYTES;
+
+ indexedMesh.numVertices = vertices.length / 3;
+ indexedMesh.vertexBase = ByteBuffer.allocateDirect(vertices.length*Float.BYTES).order(ByteOrder.nativeOrder());
+ indexedMesh.vertexBase.asFloatBuffer().put(vertices);
+ indexedMesh.vertexStride = 3 * Float.BYTES;
+
+
+
+
+
+
+ //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
+ com.bulletphysics.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new com.bulletphysics.collision.shapes.TriangleIndexVertexArray();
+ triangleIndexArray.addIndexedMesh(indexedMesh); //this assumes the scalar type is integer (assumes bytebuffer is actually integer
+// triangleIndexArray.calculateAabbBruteForce(aabbMin, aabbMax);
+
+
+
+ //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
+ com.bulletphysics.collision.shapes.BvhTriangleMeshShape terrainShape = new com.bulletphysics.collision.shapes.BvhTriangleMeshShape(
+ triangleIndexArray,
+ true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
+ );
+
+// terrainShape.localGetSupportingVertex(new javax.vecmath.Vector3f(1,0,0), aabbMin);
+// terrainShape.recalcLocalAabb();
+// terrainShape.getLocalAabbMin(aabbMin);
+// terrainShape.getLocalAabbMax(aabbMax);
+
+
+ DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f(position.x,position.y,position.z),1.0f)));
+ RigidBodyConstructionInfo terrainRigidBodyCI = new RigidBodyConstructionInfo(0, defaultMotionState, terrainShape);
+ RigidBody terrainRigidBody = new RigidBody(terrainRigidBodyCI);
+
+ terrainRigidBody.setFriction(1f);
+
+
+ Globals.collisionEngine.registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
+
+// terrainRigidBody.getAabb(aabbMin, aabbMax);
+
+// System.out.println("aabbMin: " + aabbMin + " aabbMax: " + aabbMax);
+
+
+ terrain.putData(EntityDataStrings.PHYSICS_RIGID_BODY, terrainRigidBody);
+
+ return terrainRigidBody;
+
+ }
+
+
+ public static void addTestPlaneRigidBody(){
+
+ /*
+ Traditional buffer code not working for some reason
+ the approach of
+ https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider
+ works much better
+ IDK why
+ */
+
+ int[] indices = {
+ 0, 1, 3,
+ 1, 2, 3
+ };
+
+ float[] coords = {
+ 0, 0, 0,
+ 100, 0, 0,
+ 0, 0, 100,
+ 100, 0, 100
+ };
+
+
+ IndexedMesh indexedMesh = new IndexedMesh();
+ indexedMesh.numTriangles = indices.length / 3;
+ indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
+ indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
+ indexedMesh.triangleIndexStride = 3 * Float.BYTES;
+ indexedMesh.numVertices = coords.length / 3;
+ indexedMesh.vertexBase = ByteBuffer.allocateDirect(coords.length*Float.BYTES).order(ByteOrder.nativeOrder());
+ indexedMesh.vertexBase.asFloatBuffer().put(coords);
+ indexedMesh.vertexStride = 3 * Float.BYTES;
+
+
+
+ javax.vecmath.Vector3f aabbMin = new javax.vecmath.Vector3f();
+ javax.vecmath.Vector3f aabbMax = new javax.vecmath.Vector3f();
+
+
+ //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
+ com.bulletphysics.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new com.bulletphysics.collision.shapes.TriangleIndexVertexArray(
+// numberTriangles,
+// triangleData,
+// triangleStride,
+// numberVertices,
+// vertexData,
+// vertexStride
+ );
+ triangleIndexArray.addIndexedMesh(indexedMesh);
+// triangleIndexArray.setScaling(new javax.vecmath.Vector3f(1.0f,1.0f,1.0f));
+
+
+
+ //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
+ com.bulletphysics.collision.shapes.BvhTriangleMeshShape terrainShape = new com.bulletphysics.collision.shapes.BvhTriangleMeshShape(
+ triangleIndexArray,
+ true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
+ );
+
+
+ DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f(0,0,0),1.0f)));
+ RigidBodyConstructionInfo terrainRigidBodyCI = new RigidBodyConstructionInfo(0, defaultMotionState, terrainShape);
+ RigidBody terrainRigidBody = new RigidBody(terrainRigidBodyCI);
+
+
+
+// Globals.collisionEngine.registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
+
+ terrainRigidBody.getAabb(aabbMin, aabbMax);
+
+ }
+
+ public static Vector3f getRigidBodyPosition(CollisionObject body){
+ javax.vecmath.Vector3f transform = new javax.vecmath.Vector3f(0,0,0);
+ body.getWorldTransform(new com.bulletphysics.linearmath.Transform()).transform(transform);
+// body.getMotionState().getWorldTransform(new com.bulletphysics.linearmath.Transform()).transform(transform);
+ return vecmathToJomlVector3f(transform);
+ }
+
+ public static Quaternionf getRigidBodyRotation(RigidBody body){
+ return vecmathtoJomlQuaternionf(body.getMotionState().getWorldTransform(new com.bulletphysics.linearmath.Transform()).getRotation(new javax.vecmath.Quat4f()));
+ }
+
+ public static Vector3f vecmathToJomlVector3f(javax.vecmath.Vector3f vector){
+ return new Vector3f(vector.x,vector.y,vector.z);
+ }
+
+ public static Quaternionf vecmathtoJomlQuaternionf(javax.vecmath.Quat4f quaternion){
+ return new Quaternionf(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
+ }
+
+ public static javax.vecmath.Vector3f jomlToVecmathVector3f(Vector3f vector){
+ return new javax.vecmath.Vector3f(vector.x, vector.y, vector.z);
+ }
+
+ public static javax.vecmath.Quat4f jomlToVecmathQuaternionf(Quaternionf quaternion){
+ return new javax.vecmath.Quat4f(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
+ }
+
+ public static void setRigidBodyTransform(Vector3f position, Quaternionf rotation, CollisionObject body){
+ com.bulletphysics.linearmath.Transform transform = new com.bulletphysics.linearmath.Transform();
+
+ javax.vecmath.Matrix4f transformMatrix = new javax.vecmath.Matrix4f();
+ transformMatrix.setIdentity();
+
+ transformMatrix.setTranslation(new javax.vecmath.Vector3f(position.x, position.y, position.z));
+ transformMatrix.setRotation(new javax.vecmath.Quat4f(rotation.x,rotation.y,rotation.z,rotation.w));
+ transform.set(transformMatrix);
+
+
+ //https://docs.oracle.com/cd/E17802_01/j2se/javase/technologies/desktop/java3d/forDevelopers/j3dapi/javax/vecmath/Quat4f.html
+ //constructor is x,y,z,w
+// transform.setRotation(new javax.vecmath.Quat4f(rotation.x,rotation.y,rotation.z,rotation.w));
+
+ body.setWorldTransform(transform);
+ }
+
+// public static RigidBody getUnitCylinderRigidBody(float mass){
+// CylinderShape cylinderShape = new CylinderShape(jomlToVecmathVector3f(new Vector3f(1.0f,1.0f,1.0f)));
+// DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,1,0,1),new javax.vecmath.Vector3f(0,0,0),1.0f)));
+// RigidBodyConstructionInfo cylinderRigidBodyCI = new RigidBodyConstructionInfo(mass, defaultMotionState, cylinderShape);
+// RigidBody cylinderRigidBody = new RigidBody(cylinderRigidBodyCI);
+//// cylinderRigidBody.setMassProps(mass, PhysicsUtils.jomlToVecmathVector3f(new Vector3f(1.0f,1.0f,1.0f)));
+// cylinderRigidBody.clearForces();
+// return cylinderRigidBody;
+// }
+
+ public static CollisionObject getCylinderBody(float mass, Vector3f dimensions){
+ CylinderShape cylinderShape = new CylinderShape(jomlToVecmathVector3f(dimensions));
+// DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,1,0,1),new javax.vecmath.Vector3f(0,0,0),1.0f)));
+// RigidBodyConstructionInfo cylinderRigidBodyCI = new RigidBodyConstructionInfo(mass, defaultMotionState, cylinderShape);
+// RigidBody cylinderRigidBody = new RigidBody(cylinderRigidBodyCI);
+ CollisionObject cylinderCollisionObject = new CollisionObject();
+ cylinderCollisionObject.setCollisionShape(cylinderShape);
+// cylinderRigidBody.setAngularFactor(1.0f);
+// cylinderRigidBody.setFriction(0.8f);
+ return cylinderCollisionObject;
+ }
+
+ public static CollisionObject getPlaneObject(Vector3f dimensions){
+ int[] indices = {
+ 0, 1, 3,
+ 1, 2, 3
+ };
+
+ float[] coords = {
+ -1 * dimensions.x, 0, -1 * dimensions.z,
+ 1 * dimensions.x, 0, -1 * dimensions.z,
+ -1 * dimensions.x, 0, 1 * dimensions.z,
+ 1 * dimensions.x, 0, 1 * dimensions.z
+ };
+
+ IndexedMesh indexedMesh = new IndexedMesh();
+ indexedMesh.numTriangles = indices.length / 3;
+ indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
+ indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
+ indexedMesh.triangleIndexStride = 3 * Float.BYTES;
+ indexedMesh.numVertices = coords.length / 3;
+ indexedMesh.vertexBase = ByteBuffer.allocateDirect(coords.length*Float.BYTES).order(ByteOrder.nativeOrder());
+ indexedMesh.vertexBase.asFloatBuffer().put(coords);
+ indexedMesh.vertexStride = 3 * Float.BYTES;
+
+
+
+ //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
+ TriangleIndexVertexArray triangleIndexArray = new TriangleIndexVertexArray();
+ triangleIndexArray.addIndexedMesh(indexedMesh);
+// triangleIndexArray.setScaling(new javax.vecmath.Vector3f(1.0f,1.0f,1.0f));
+
+
+
+ //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
+ BvhTriangleMeshShape planeShape = new BvhTriangleMeshShape(
+ triangleIndexArray,
+ true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
+ );
+
+
+ CollisionObject planeCollisionObject = new CollisionObject();
+ planeCollisionObject.setCollisionShape(planeShape);
+
+ return planeCollisionObject;
+ }
+
+
+ public static CollisionObject getCubeObject(Vector3f dimensions){
+ BoxShape boxShape = new BoxShape(jomlToVecmathVector3f(dimensions));
+ CollisionObject boxCollisionObject = new CollisionObject();
+ boxCollisionObject.setCollisionShape(boxShape);
+ return boxCollisionObject;
+ }
+}
diff --git a/src/main/java/electrosphere/game/collision/collidable/Collidable.java b/src/main/java/electrosphere/game/collision/collidable/Collidable.java
index 93afa638..2e47b517 100644
--- a/src/main/java/electrosphere/game/collision/collidable/Collidable.java
+++ b/src/main/java/electrosphere/game/collision/collidable/Collidable.java
@@ -1,5 +1,14 @@
package electrosphere.game.collision.collidable;
+import com.bulletphysics.collision.shapes.CollisionShape;
+import com.bulletphysics.dynamics.RigidBody;
+import electrosphere.entity.Entity;
+import electrosphere.entity.state.movement.Impulse;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import org.joml.Vector3f;
+
/**
*
@@ -7,6 +16,37 @@ package electrosphere.game.collision.collidable;
*/
public class Collidable {
+ Entity parent;
+ String type;
+
+ List impulses = new CopyOnWriteArrayList();
+
+ public static final String TYPE_TERRAIN = "terrain";
+ public static final String TYPE_CREATURE = "creature";
+ public static final String TYPE_STRUCTURE = "structure";
+
+
+ public Collidable(Entity parent, String type){
+ this.parent = parent;
+ this.type = type;
+ }
+
+ public List getImpulses() {
+ return impulses;
+ }
+
+ public void addImpulse(Impulse impulse) {
+ impulses.add(impulse);
+ }
+
+ public Entity getParent() {
+ return parent;
+ }
+
+ public String getType() {
+ return type;
+ }
+
}
diff --git a/src/main/java/electrosphere/game/server/ai/creature/MindlessAttacker.java b/src/main/java/electrosphere/game/server/ai/creature/MindlessAttacker.java
index d605bdab..9b223236 100644
--- a/src/main/java/electrosphere/game/server/ai/creature/MindlessAttacker.java
+++ b/src/main/java/electrosphere/game/server/ai/creature/MindlessAttacker.java
@@ -4,7 +4,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.AttackTree;
-import electrosphere.entity.state.MovementTree;
+import electrosphere.entity.state.movement.MovementTree;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.server.ai.AI;
import electrosphere.main.Globals;
diff --git a/src/main/java/electrosphere/game/server/creature/type/CreatureType.java b/src/main/java/electrosphere/game/server/creature/type/CreatureType.java
index a6471b77..5a67cc9c 100644
--- a/src/main/java/electrosphere/game/server/creature/type/CreatureType.java
+++ b/src/main/java/electrosphere/game/server/creature/type/CreatureType.java
@@ -9,6 +9,7 @@ public class CreatureType {
List hitboxes;
List tokens;
List movementSystems;
+ PhysicsObject physicsObject;
List attackMoves;
HealthSystem healthSystem;
String modelPath;
@@ -44,6 +45,10 @@ public class CreatureType {
public HealthSystem getHealthSystem() {
return healthSystem;
}
+
+ public PhysicsObject getPhysicsObject() {
+ return physicsObject;
+ }
diff --git a/src/main/java/electrosphere/game/server/creature/type/PhysicsObject.java b/src/main/java/electrosphere/game/server/creature/type/PhysicsObject.java
new file mode 100644
index 00000000..6b459593
--- /dev/null
+++ b/src/main/java/electrosphere/game/server/creature/type/PhysicsObject.java
@@ -0,0 +1,49 @@
+package electrosphere.game.server.creature.type;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class PhysicsObject {
+
+ String type;
+
+ float dimension1;
+ float dimension2;
+ float dimension3;
+
+ float offsetX;
+ float offsetY;
+ float offsetZ;
+
+ public String getType() {
+ return type;
+ }
+
+ public float getDimension1() {
+ return dimension1;
+ }
+
+ public float getDimension2() {
+ return dimension2;
+ }
+
+ public float getDimension3() {
+ return dimension3;
+ }
+
+ public float getOffsetX() {
+ return offsetX;
+ }
+
+ public float getOffsetY() {
+ return offsetY;
+ }
+
+ public float getOffsetZ() {
+ return offsetZ;
+ }
+
+
+
+}
diff --git a/src/main/java/electrosphere/game/server/structure/model/CollisionObjectTemplate.java b/src/main/java/electrosphere/game/server/structure/model/CollisionObjectTemplate.java
new file mode 100644
index 00000000..edd12839
--- /dev/null
+++ b/src/main/java/electrosphere/game/server/structure/model/CollisionObjectTemplate.java
@@ -0,0 +1,74 @@
+package electrosphere.game.server.structure.model;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class CollisionObjectTemplate {
+
+ String type;
+ public static final String TYPE_CUBE = "CUBE";
+ public static final String TYPE_PLANE = "PLANE";
+
+
+ float positionX;
+ float positionY;
+ float positionZ;
+
+ float scaleX;
+ float scaleY;
+ float scaleZ;
+
+ float rotationW;
+ float rotationX;
+ float rotationY;
+ float rotationZ;
+
+ public String getType() {
+ return type;
+ }
+
+ public float getPositionX() {
+ return positionX;
+ }
+
+ public float getPositionY() {
+ return positionY;
+ }
+
+ public float getPositionZ() {
+ return positionZ;
+ }
+
+ public float getScaleX() {
+ return scaleX;
+ }
+
+ public float getScaleY() {
+ return scaleY;
+ }
+
+ public float getScaleZ() {
+ return scaleZ;
+ }
+
+ public float getRotationW() {
+ return rotationW;
+ }
+
+ public float getRotationX() {
+ return rotationX;
+ }
+
+ public float getRotationY() {
+ return rotationY;
+ }
+
+ public float getRotationZ() {
+ return rotationZ;
+ }
+
+
+
+
+}
diff --git a/src/main/java/electrosphere/game/server/structure/model/StructureType.java b/src/main/java/electrosphere/game/server/structure/model/StructureType.java
new file mode 100644
index 00000000..31d31b66
--- /dev/null
+++ b/src/main/java/electrosphere/game/server/structure/model/StructureType.java
@@ -0,0 +1,30 @@
+package electrosphere.game.server.structure.model;
+
+import java.util.List;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class StructureType {
+
+ String modelPath;
+ String name;
+
+ List collision;
+
+ public String getModelPath() {
+ return modelPath;
+ }
+
+ public List getCollision() {
+ return collision;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+
+
+}
diff --git a/src/main/java/electrosphere/game/server/structure/model/StructureTypeMap.java b/src/main/java/electrosphere/game/server/structure/model/StructureTypeMap.java
new file mode 100644
index 00000000..520efb30
--- /dev/null
+++ b/src/main/java/electrosphere/game/server/structure/model/StructureTypeMap.java
@@ -0,0 +1,28 @@
+package electrosphere.game.server.structure.model;
+
+import java.util.List;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class StructureTypeMap {
+ List structures;
+
+ public List getStructures() {
+ return structures;
+ }
+
+ public StructureType getType(String name){
+ StructureType rVal = null;
+ for(StructureType type : structures){
+ if(type.getName().equals(name)){
+ rVal = type;
+ break;
+ }
+ }
+ return rVal;
+ }
+
+
+}
diff --git a/src/main/java/electrosphere/game/server/world/datacell/DataCellManager.java b/src/main/java/electrosphere/game/server/world/datacell/DataCellManager.java
index 56553926..026d853b 100644
--- a/src/main/java/electrosphere/game/server/world/datacell/DataCellManager.java
+++ b/src/main/java/electrosphere/game/server/world/datacell/DataCellManager.java
@@ -8,8 +8,11 @@ import java.util.List;
* @author satellite
*/
public class DataCellManager {
+
List loadedDataCells = new LinkedList();
+ DataCell[][] dataCells;
+
public DataCellManager() {
}
diff --git a/src/main/java/electrosphere/game/server/world/virtualcell/VirtualCellManager.java b/src/main/java/electrosphere/game/server/world/virtualcell/VirtualCellManager.java
new file mode 100644
index 00000000..4f122c68
--- /dev/null
+++ b/src/main/java/electrosphere/game/server/world/virtualcell/VirtualCellManager.java
@@ -0,0 +1,15 @@
+package electrosphere.game.server.world.virtualcell;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class VirtualCellManager {
+
+ VirtualCell[][] virtualCells;
+
+ public VirtualCellManager() {
+
+ }
+
+}
diff --git a/src/main/java/electrosphere/game/state/MicroSimulation.java b/src/main/java/electrosphere/game/state/MicroSimulation.java
index 2766b243..00bd1f39 100644
--- a/src/main/java/electrosphere/game/state/MicroSimulation.java
+++ b/src/main/java/electrosphere/game/state/MicroSimulation.java
@@ -5,7 +5,7 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.AttackTree;
import electrosphere.entity.state.IdleTree;
-import electrosphere.entity.state.MovementTree;
+import electrosphere.entity.state.movement.MovementTree;
import electrosphere.entity.state.ParticleTree;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.hitbox.HitboxUtils;
@@ -30,6 +30,12 @@ public class MicroSimulation {
}
public void simulate(){
+ //simulate bullet physics engine step
+ Globals.collisionEngine.simulatePhysics(deltaTime);
+ //update dynamic entity positions calculated by bullet
+// Globals.collisionEngine.updateDynamicObjectTransforms();
+ //list dynamic object positions
+// Globals.collisionEngine.listBodyPositions();
//simulate ai
Globals.aiManager.simulate();
//update actor animations
diff --git a/src/main/java/electrosphere/main/Globals.java b/src/main/java/electrosphere/main/Globals.java
index 98b1c201..07a4ad70 100644
--- a/src/main/java/electrosphere/main/Globals.java
+++ b/src/main/java/electrosphere/main/Globals.java
@@ -21,9 +21,12 @@ import electrosphere.engine.LoadingThread;
import electrosphere.game.server.ai.AIManager;
import electrosphere.game.server.creature.type.model.CreatureTypeMap;
import electrosphere.game.server.item.type.model.ItemTypeMap;
+import electrosphere.game.server.structure.model.StructureTypeMap;
import electrosphere.game.state.MacroSimulation;
import electrosphere.game.server.terrain.manager.ServerTerrainManager;
import electrosphere.game.server.world.ServerWorldData;
+import electrosphere.game.server.world.datacell.DataCellManager;
+import electrosphere.game.server.world.virtualcell.VirtualCellManager;
import electrosphere.game.state.MicroSimulation;
import electrosphere.menu.Menu;
import electrosphere.net.client.ClientNetworking;
@@ -100,7 +103,10 @@ public class Globals {
//
public static ServerWorldData serverWorldData;
public static CreatureTypeMap creatureMap;
+ public static StructureTypeMap structureTypeMap;
public static ItemTypeMap itemMap;
+ VirtualCellManager virtualCellManager;
+ DataCellManager dataCellManager;
@@ -246,6 +252,8 @@ public class Globals {
// } catch (IOException ex) { ex.printStackTrace(); } //TODO: handle better :tm:
//init creature type map
initCreatureTypeMap();
+ //init structure type map
+ initStructureTypeMap();
//init item type map
initItemTypeMap();
//create entity manager
@@ -260,6 +268,8 @@ public class Globals {
hitboxManager = new HitboxManager();
//ai manager
aiManager = new AIManager();
+ //collision engine
+ collisionEngine = new CollisionEngine();
}
public static void initDefaultGraphicalResources(){
@@ -293,6 +303,12 @@ public class Globals {
assetManager.addModelPathToQueue("Models/unitsphere_grey.fbx");
//init smallcube
assetManager.addModelPathToQueue("Models/SmallCube.fbx");
+ //init unit cylinder
+ assetManager.addModelPathToQueue("Models/unitcylinder.fbx");
+ //init unit plane
+ assetManager.addModelPathToQueue("Models/unitplane.fbx");
+ //init unit plane
+ assetManager.addModelPathToQueue("Models/unitcube.fbx");
//as these assets are required for the renderer to work, we go ahead and
//load them into memory now. The loading time penalty is worth it I think.
@@ -306,4 +322,8 @@ public class Globals {
static void initItemTypeMap(){
itemMap = FileLoadingUtils.loadObjectFromAssetPath("Data/items.json", ItemTypeMap.class);
}
+
+ static void initStructureTypeMap(){
+ structureTypeMap = FileLoadingUtils.loadObjectFromAssetPath("Data/structures.json", StructureTypeMap.class);
+ }
}
diff --git a/src/main/java/electrosphere/main/Main.java b/src/main/java/electrosphere/main/Main.java
index de8b1fec..03257f25 100644
--- a/src/main/java/electrosphere/main/Main.java
+++ b/src/main/java/electrosphere/main/Main.java
@@ -9,7 +9,7 @@ import electrosphere.renderer.Model;
import electrosphere.renderer.RenderUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
-import electrosphere.entity.state.MovementTree;
+import electrosphere.entity.state.movement.MovementTree;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.attach.AttachUtils;
diff --git a/src/main/java/electrosphere/net/server/ServerConnectionHandler.java b/src/main/java/electrosphere/net/server/ServerConnectionHandler.java
index 1b6e303e..3322a4c8 100644
--- a/src/main/java/electrosphere/net/server/ServerConnectionHandler.java
+++ b/src/main/java/electrosphere/net/server/ServerConnectionHandler.java
@@ -32,6 +32,7 @@ import java.util.logging.Logger;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.crypto.stream.CryptoInputStream;
import org.apache.commons.crypto.stream.CryptoOutputStream;
+import org.joml.Vector3f;
/**
*
@@ -95,7 +96,7 @@ public class ServerConnectionHandler implements Runnable {
//spawn player in world
Entity newPlayerCharacter = CreatureUtils.spawnBasicCreature("Human");
playerCharacterID = newPlayerCharacter.getId();
- EntityUtils.getPosition(newPlayerCharacter).set(Globals.spawnPoint.x,0,Globals.spawnPoint.z);
+ CreatureUtils.positionCharacter(newPlayerCharacter, new Vector3f(Globals.spawnPoint.x,3,Globals.spawnPoint.z));
//spawn player sword
Entity sword = ItemUtils.spawnBasicItem("Katana");
AttachUtils.attachEntityToEntityAtBone(newPlayerCharacter, sword, "Bone.031");
diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java
index b995a515..88db4d7b 100644
--- a/src/main/java/electrosphere/renderer/RenderingEngine.java
+++ b/src/main/java/electrosphere/renderer/RenderingEngine.java
@@ -6,6 +6,7 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.entity.types.hitbox.HitboxUtils;
+import electrosphere.game.server.creature.type.PhysicsObject;
import electrosphere.logger.LoggerInterface;
import electrosphere.main.Globals;
import static electrosphere.main.Main.deltaTime;
@@ -17,6 +18,7 @@ import electrosphere.renderer.framebuffer.Renderbuffer;
import electrosphere.renderer.texture.Texture;
import electrosphere.renderer.ui.Widget;
import org.joml.Matrix4f;
+import org.joml.Quaternionf;
import org.joml.Vector3f;
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR;
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR;
@@ -80,6 +82,7 @@ public class RenderingEngine {
static Framebuffer lightDepthBuffer;
public static boolean renderHitboxes = false;
+ public static boolean renderPhysics = true;
ShaderProgram activeProgram;
@@ -362,6 +365,55 @@ public class RenderingEngine {
}
}
+ if(renderPhysics){
+ Model physicsGraphicsModel;
+ for(Entity physicsEntity : Globals.collisionEngine.getDynamicPhysicsEntities()){
+ PhysicsObject template = (PhysicsObject)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE);
+ switch(template.getType()){
+ case "CYLINDER":
+ if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcylinder.fbx")) != null){
+ Vector3f position = EntityUtils.getPosition(physicsEntity);
+ modelTransformMatrix.identity();
+ modelTransformMatrix.translate(new Vector3f(position));
+// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
+ modelTransformMatrix.scale(template.getDimension1(),template.getDimension2(),template.getDimension3());
+ physicsGraphicsModel.modelMatrix = modelTransformMatrix;
+ physicsGraphicsModel.draw(true, true, false, true, true, true, true);
+ }
+ break;
+ }
+ }
+ for(Entity physicsEntity : Globals.collisionEngine.getStructurePhysicsEntities()){
+ if(physicsEntity.getDataKeys().contains(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE)){
+ if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){
+ Vector3f position = EntityUtils.getPosition(physicsEntity);
+ Vector3f scale = EntityUtils.getScale(physicsEntity);
+ Quaternionf rotation = EntityUtils.getRotation(physicsEntity);
+ modelTransformMatrix.identity();
+ modelTransformMatrix.translate(new Vector3f(position));
+ modelTransformMatrix.rotate(rotation);
+// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
+ modelTransformMatrix.scale(scale);
+ physicsGraphicsModel.modelMatrix = modelTransformMatrix;
+ physicsGraphicsModel.draw(true, true, false, true, true, true, true);
+ }
+ } else if(physicsEntity.getDataKeys().contains(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE)){
+ if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){
+ Vector3f position = EntityUtils.getPosition(physicsEntity);
+ Vector3f scale = EntityUtils.getScale(physicsEntity);
+ Quaternionf rotation = EntityUtils.getRotation(physicsEntity);
+ modelTransformMatrix.identity();
+ modelTransformMatrix.translate(new Vector3f(position));
+ modelTransformMatrix.rotate(rotation);
+// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
+ modelTransformMatrix.scale(scale);
+ physicsGraphicsModel.modelMatrix = modelTransformMatrix;
+ physicsGraphicsModel.draw(true, true, false, true, true, true, true);
+ }
+ }
+ }
+ }
+
// glBindVertexArray(0);
diff --git a/src/main/java/electrosphere/renderer/ui/UIUtils.java b/src/main/java/electrosphere/renderer/ui/UIUtils.java
new file mode 100644
index 00000000..bff8b574
--- /dev/null
+++ b/src/main/java/electrosphere/renderer/ui/UIUtils.java
@@ -0,0 +1,8 @@
+package electrosphere.renderer.ui;
+
+public class UIUtils {
+
+ public static void initUIComponents(){
+
+ }
+}
diff --git a/src/main/java/electrosphere/renderer/ui/transparenttextbox/TextBox.java b/src/main/java/electrosphere/renderer/ui/transparenttextbox/TextBox.java
new file mode 100644
index 00000000..84161888
--- /dev/null
+++ b/src/main/java/electrosphere/renderer/ui/transparenttextbox/TextBox.java
@@ -0,0 +1,91 @@
+package electrosphere.renderer.ui.transparenttextbox;
+
+import electrosphere.main.Globals;
+import electrosphere.renderer.Model;
+import electrosphere.renderer.assetmanager.AssetDataStrings;
+import electrosphere.renderer.ui.Widget;
+import electrosphere.renderer.ui.font.FontUtils;
+import org.joml.Vector3f;
+
+public class TextBox extends Widget{
+
+
+ int positionX;
+ int positionY;
+ int width;
+ int height;
+ String text;
+ boolean editable;
+
+ Vector3f scalar;
+
+ public TextBox(int positionX, int positionY, int width, int height, String text, boolean render, boolean editable) {
+ super(positionX,positionY,width,height,render,Widget.WidgetType.TEXT_BOX);
+ this.positionX = positionX;
+ this.positionY = positionY;
+ this.width = width;
+ this.height = height;
+ this.text = text;
+ scalar = new Vector3f(1,1,1);
+ }
+
+ public TextBox(int positionX, int positionY, int width, int height, String text, boolean render, boolean editable, Vector3f scalar) {
+ super(positionX,positionY,width,height,render,Widget.WidgetType.TEXT_BOX);
+ this.positionX = positionX;
+ this.positionY = positionY;
+ this.width = width;
+ this.height = height;
+ this.text = text;
+ this.scalar = scalar;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public boolean isEditable() {
+ return editable;
+ }
+
+ public void setEditable(boolean editable) {
+ this.editable = editable;
+ }
+
+
+ @Override
+ public void draw(){
+ throw new UnsupportedOperationException("Transparent Text box draw function not implemented yet oop");
+// float ndcX = (float)positionX/Globals.WINDOW_WIDTH;
+// float ndcY = (float)positionY/Globals.WINDOW_HEIGHT;
+// float ndcWidth = (float)width/Globals.WINDOW_WIDTH;
+// float ndcHeight = (float)height/Globals.WINDOW_HEIGHT;
+// //monowidth for the moment
+// float charWidth = ndcWidth/cols;
+// float charHeight = ndcHeight/rows;
+// for(int y = 0; y < rows; y++){
+// for(int x = 0; x < cols; x++){
+// char toDraw = ' ';
+// if(x + y * cols < text.length()){
+// toDraw = text.charAt(x + y * cols);
+// }
+// Vector3f characterPosition = new Vector3f(ndcX + x * charWidth,ndcY + y * charHeight,0);
+// Vector3f characterDimensions = new Vector3f(charWidth,charHeight,0);
+// Vector3f bitMapPosition = FontUtils.getPositionOfCharacter(toDraw);
+// Vector3f bitMapDimension = FontUtils.getDimensionOfCharacter(toDraw);
+// Model charModel = Globals.assetManager.fetchModel(AssetDataStrings.ASSET_STRING_BITMAP_FONT);
+// if(charModel != null && toDraw != ' '){
+// charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "mPosition", characterPosition);
+// charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "mDimension", characterDimensions);
+// charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "tPosition", bitMapPosition);
+// charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "tDimension", bitMapDimension);
+// charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "color", color);
+// charModel.drawUI();
+// }
+// }
+// }
+ }
+}
diff --git a/src/main/java/electrosphere/renderer/ui/transparenttextbox/TextBoxUtils.java b/src/main/java/electrosphere/renderer/ui/transparenttextbox/TextBoxUtils.java
new file mode 100644
index 00000000..ce50c48e
--- /dev/null
+++ b/src/main/java/electrosphere/renderer/ui/transparenttextbox/TextBoxUtils.java
@@ -0,0 +1,9 @@
+package electrosphere.renderer.ui.transparenttextbox;
+
+/**
+ *
+ * @author amaterasu
+ */
+public class TextBoxUtils {
+
+}