Collision/physics engine

This commit is contained in:
austin 2021-07-19 01:21:46 -04:00
parent f585af6fad
commit 0f4a764470
41 changed files with 1647 additions and 161 deletions

View File

@ -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",

140
assets/Data/structures.json Normal file
View File

@ -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
}
]
}
]
}

BIN
assets/Models/unitcube.fbx Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/Models/unitplane.fbx Normal file

Binary file not shown.

View File

@ -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"
]
}
}
}

15
pom.xml
View File

@ -87,13 +87,26 @@
<version>2.8.6</version>
</dependency>
<!--
manual: http://www.cs.kent.edu/~ruttan/GameEngines/lectures/Bullet_User_Manual
because their docs ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/CylinderShape.html ) suck
source: https://github.com/jbullet-maven/jbullet/tree/master/src/main/java/com/bulletphysics
-->
<dependency>
<groupId>cz.advel.jbullet</groupId>
<artifactId>jbullet</artifactId>
<version>20101010-1</version>
</dependency>
<!--
Potential alternative binding for bullet ?
<dependency>
<groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx-bullet</artifactId>
<version>1.10.0</version>
</dependency>
-->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-crypto -->
<dependency>
<groupId>org.apache.commons</groupId>

View File

@ -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;

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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";

View File

@ -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;

View File

@ -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<EntityMessage> 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);
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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<EntityMessage> 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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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(){

View File

@ -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++){

View File

@ -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<Entity> collisionEntities = new ArrayList();
List<Entity> physicsEntities = new ArrayList();
List<Entity> dynamicPhysicsEntities = new ArrayList();
List<Entity> structurePhysicsEntities = new ArrayList();
List<CollisionObject> 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<Entity> getPhysicsEntities(){
return physicsEntities;
}
public void registerDynamicPhysicsEntity(Entity dynamicEntity){
dynamicPhysicsEntities.add(dynamicEntity);
}
public List<Entity> getDynamicPhysicsEntities(){
return dynamicPhysicsEntities;
}
public void registerStructurePhysicsEntity(Entity structureEntity){
structurePhysicsEntities.add(structureEntity);
}
public List<Entity> 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
*/

View File

@ -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;
}
}

View File

@ -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<Impulse> 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<Impulse> getImpulses() {
return impulses;
}
public void addImpulse(Impulse impulse) {
impulses.add(impulse);
}
public Entity getParent() {
return parent;
}
public String getType() {
return type;
}
}

View File

@ -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;

View File

@ -9,6 +9,7 @@ public class CreatureType {
List<HitboxData> hitboxes;
List<String> tokens;
List<MovementSystem> movementSystems;
PhysicsObject physicsObject;
List<AttackMove> attackMoves;
HealthSystem healthSystem;
String modelPath;
@ -44,6 +45,10 @@ public class CreatureType {
public HealthSystem getHealthSystem() {
return healthSystem;
}
public PhysicsObject getPhysicsObject() {
return physicsObject;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,30 @@
package electrosphere.game.server.structure.model;
import java.util.List;
/**
*
* @author amaterasu
*/
public class StructureType {
String modelPath;
String name;
List<CollisionObjectTemplate> collision;
public String getModelPath() {
return modelPath;
}
public List<CollisionObjectTemplate> getCollision() {
return collision;
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,28 @@
package electrosphere.game.server.structure.model;
import java.util.List;
/**
*
* @author amaterasu
*/
public class StructureTypeMap {
List<StructureType> structures;
public List<StructureType> 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;
}
}

View File

@ -8,8 +8,11 @@ import java.util.List;
* @author satellite
*/
public class DataCellManager {
List<DataCell> loadedDataCells = new LinkedList();
DataCell[][] dataCells;
public DataCellManager() {
}

View File

@ -0,0 +1,15 @@
package electrosphere.game.server.world.virtualcell;
/**
*
* @author amaterasu
*/
public class VirtualCellManager {
VirtualCell[][] virtualCells;
public VirtualCellManager() {
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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");

View File

@ -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);

View File

@ -0,0 +1,8 @@
package electrosphere.renderer.ui;
public class UIUtils {
public static void initUIComponents(){
}
}

View File

@ -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();
// }
// }
// }
}
}

View File

@ -0,0 +1,9 @@
package electrosphere.renderer.ui.transparenttextbox;
/**
*
* @author amaterasu
*/
public class TextBoxUtils {
}