Collision/physics engine
This commit is contained in:
parent
f585af6fad
commit
0f4a764470
@ -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
140
assets/Data/structures.json
Normal 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
BIN
assets/Models/unitcube.fbx
Normal file
Binary file not shown.
BIN
assets/Models/unitcylinder.fbx
Normal file
BIN
assets/Models/unitcylinder.fbx
Normal file
Binary file not shown.
BIN
assets/Models/unitplane.fbx
Normal file
BIN
assets/Models/unitplane.fbx
Normal file
Binary file not shown.
@ -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
15
pom.xml
@ -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>
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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";
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
122
src/main/java/electrosphere/entity/state/GravityTree.java
Normal file
122
src/main/java/electrosphere/entity/state/GravityTree.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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(){
|
||||
|
||||
@ -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++){
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
361
src/main/java/electrosphere/game/collision/PhysicsUtils.java
Normal file
361
src/main/java/electrosphere/game/collision/PhysicsUtils.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -8,8 +8,11 @@ import java.util.List;
|
||||
* @author satellite
|
||||
*/
|
||||
public class DataCellManager {
|
||||
|
||||
List<DataCell> loadedDataCells = new LinkedList();
|
||||
|
||||
DataCell[][] dataCells;
|
||||
|
||||
public DataCellManager() {
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package electrosphere.game.server.world.virtualcell;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class VirtualCellManager {
|
||||
|
||||
VirtualCell[][] virtualCells;
|
||||
|
||||
public VirtualCellManager() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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);
|
||||
|
||||
8
src/main/java/electrosphere/renderer/ui/UIUtils.java
Normal file
8
src/main/java/electrosphere/renderer/ui/UIUtils.java
Normal file
@ -0,0 +1,8 @@
|
||||
package electrosphere.renderer.ui;
|
||||
|
||||
public class UIUtils {
|
||||
|
||||
public static void initUIComponents(){
|
||||
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package electrosphere.renderer.ui.transparenttextbox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class TextBoxUtils {
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user