work on body position management
This commit is contained in:
parent
0b4c08796e
commit
81337d0eb9
@ -2100,6 +2100,7 @@ Actually fix pathing spinlock
|
||||
Support for observing ai entities
|
||||
ServerGroundMovementTree supports collidable entities
|
||||
ServerGroundMovementTree geom work
|
||||
ServerLODComponent replaces bodies with geometries instead of just destroying the geometries
|
||||
|
||||
|
||||
|
||||
|
||||
@ -189,7 +189,7 @@ public class ClientState {
|
||||
* Constructor
|
||||
*/
|
||||
public ClientState(){
|
||||
this.clientSceneWrapper = new ClientSceneWrapper(this.clientScene, new CollisionEngine(), CollisionEngine.create(new ClientChemistryCollisionCallback()), new CollisionEngine());
|
||||
this.clientSceneWrapper = new ClientSceneWrapper(this.clientScene, new CollisionEngine("clientPhysics"), CollisionEngine.create("clientChem", new ClientChemistryCollisionCallback()), new CollisionEngine("clientInteraction"));
|
||||
this.clientTemporalService = (ClientTemporalService)Globals.engineState.serviceManager.registerService(new ClientTemporalService());
|
||||
}
|
||||
|
||||
|
||||
@ -7,13 +7,9 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
import org.ode4j.ode.DBody;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.client.scene.ClientWorldData;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.client.ui.menu.ingame.InteractionTargetMenu;
|
||||
import electrosphere.collision.CollisionBodyCreation;
|
||||
import electrosphere.collision.CollisionEngine;
|
||||
@ -24,9 +20,7 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.types.EntityTypes.EntityType;
|
||||
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
/**
|
||||
* Manages the interaction state
|
||||
@ -90,7 +84,7 @@ public class ClientInteractionEngine {
|
||||
rVal.putData(EntityDataStrings.INTERACTION_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.INTERACTION_BODY, rigidBody);
|
||||
|
||||
Globals.clientState.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
||||
//
|
||||
@ -125,7 +119,7 @@ public class ClientInteractionEngine {
|
||||
rVal.putData(EntityDataStrings.INTERACTION_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.INTERACTION_BODY, rigidBody);
|
||||
|
||||
Globals.clientState.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
||||
//
|
||||
@ -161,7 +155,7 @@ public class ClientInteractionEngine {
|
||||
rVal.putData(EntityDataStrings.INTERACTION_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.INTERACTION_BODY, rigidBody);
|
||||
|
||||
Globals.clientState.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getInteractionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
||||
} break;
|
||||
default: {
|
||||
throw new Error("Unsupported shape type! " + physicsTemplate.getType());
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.collision;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -10,7 +11,6 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector4d;
|
||||
import org.ode4j.math.DVector3;
|
||||
import org.ode4j.ode.DBhvSpace;
|
||||
import org.ode4j.ode.DBody;
|
||||
@ -101,6 +101,11 @@ public class CollisionEngine {
|
||||
*/
|
||||
private static final double REBASE_TRIGGER_DISTANCE = 16;
|
||||
|
||||
/**
|
||||
* Maximum expected distance from local origin
|
||||
*/
|
||||
private static final double MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN = 3000;
|
||||
|
||||
/**
|
||||
* world data that the collision engine leverages for position correction and the like
|
||||
*/
|
||||
@ -188,16 +193,27 @@ public class CollisionEngine {
|
||||
*/
|
||||
private int geomCount = 0;
|
||||
|
||||
/**
|
||||
* Tracks whether the engine has rebased or not
|
||||
*/
|
||||
private boolean hasRebased = false;
|
||||
|
||||
|
||||
/**
|
||||
* buffer for storing potential collisions
|
||||
*/
|
||||
private DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS);
|
||||
|
||||
/**
|
||||
* The name of the collision engine
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public CollisionEngine(){
|
||||
public CollisionEngine(String name){
|
||||
this.name = name;
|
||||
world = OdeHelper.createWorld();
|
||||
world.setGravity(0,-GRAVITY_MAGNITUDE,0);
|
||||
world.setQuickStepNumIterations(QUICKSTEP_ITERATION_COUNT);
|
||||
@ -221,8 +237,8 @@ public class CollisionEngine {
|
||||
/**
|
||||
* Creates a collision engine with a specified callback
|
||||
*/
|
||||
public static CollisionEngine create(CollisionResolutionCallback callback){
|
||||
CollisionEngine rVal = new CollisionEngine();
|
||||
public static CollisionEngine create(String name, CollisionResolutionCallback callback){
|
||||
CollisionEngine rVal = new CollisionEngine(name);
|
||||
rVal.setCollisionResolutionCallback(callback);
|
||||
return rVal;
|
||||
}
|
||||
@ -243,13 +259,6 @@ public class CollisionEngine {
|
||||
case Collidable.TYPE_CREATURE:
|
||||
switch(impactor.getType()){
|
||||
case Collidable.TYPE_STATIC:
|
||||
// System.out.println(EntityUtils.getPosition(impactor.getParent()) + " " + EntityUtils.getPosition(receiver.getParent()));
|
||||
// System.out.println();
|
||||
// System.out.println("Terrain-creature collision: " + normal + " mag:" + magnitude);
|
||||
// if(normal.y > normal.x + normal.z){
|
||||
// normal.x = 0;
|
||||
// normal.z = 0;
|
||||
// }
|
||||
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude * 2, Collidable.TYPE_STATIC));
|
||||
break;
|
||||
case Collidable.TYPE_CREATURE:
|
||||
@ -276,8 +285,15 @@ public class CollisionEngine {
|
||||
spaceLock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of collidables
|
||||
* @return The list of collidables
|
||||
*/
|
||||
public List<Collidable> getCollidables(){
|
||||
return collidableList;
|
||||
spaceLock.lock();
|
||||
List<Collidable> rVal = Collections.unmodifiableList(this.collidableList);
|
||||
spaceLock.unlock();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -633,16 +649,16 @@ public class CollisionEngine {
|
||||
Matrix4d inverseTransform = new Matrix4d();
|
||||
if(this.collisionWorldData != null){
|
||||
for(Collidable collidable : collidableList){
|
||||
if(collidable.getParentTracksCollidable()){
|
||||
if(collidable.getParentTracksCollidable() && collidable.getReady()){
|
||||
Entity physicsEntity = collidable.getParent();
|
||||
DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity);
|
||||
DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
|
||||
Vector4d rawPos = null;
|
||||
Vector3d rawPos = null;
|
||||
inverseTransform.identity();
|
||||
if(rigidBody != null){
|
||||
rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()).add(this.floatingOrigin),1));
|
||||
rawPos = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()).add(this.floatingOrigin);
|
||||
} else if(geom != null){
|
||||
rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(geom.getPosition()).add(this.floatingOrigin),1));
|
||||
rawPos = PhysicsUtils.odeVecToJomlVec(geom.getPosition()).add(this.floatingOrigin);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -664,9 +680,21 @@ public class CollisionEngine {
|
||||
CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(physicsEntity);
|
||||
if(template != null){
|
||||
suggestedPosition.sub(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ());
|
||||
suggestedPosition = this.suggestMovementPosition(collisionWorldData, suggestedPosition);
|
||||
newRotation.mul(new Quaterniond(template.getRotX(),template.getRotY(),template.getRotZ(),template.getRotW()).invert());
|
||||
}
|
||||
}
|
||||
// if(rigidBody != null && suggestedPosition.distance(0,0,0) < 100){
|
||||
// String message = "\n" +
|
||||
// "this.floatingOrigin: " + this.floatingOrigin + "\n" +
|
||||
// "calculatedPosition: " + calculatedPosition + "\n" +
|
||||
// "suggestedPosition: " + suggestedPosition + "\n" +
|
||||
// "rawPos: " + rawPos + "\n" +
|
||||
// (rigidBody != null ? "body: " + rigidBody.getPosition() + "\n" : "\n") +
|
||||
// (geom != null ? "geom: " + geom.getPosition() + "\n" : "\n") +
|
||||
// "";
|
||||
// throw new Error(message);
|
||||
// }
|
||||
EntityUtils.getPosition(physicsEntity).set(suggestedPosition);
|
||||
EntityUtils.getRotation(physicsEntity).set(newRotation);
|
||||
}
|
||||
@ -690,49 +718,46 @@ public class CollisionEngine {
|
||||
Entity physicsEntity = collidable.getParent();
|
||||
DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity);
|
||||
if(rigidBody != null){
|
||||
Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()).add(this.floatingOrigin);
|
||||
Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition());
|
||||
// if(this.bodies.size() > 1 && currentBodyOffset.distance(0,0,0) > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN && this.hasRebased){
|
||||
// String message = "Body far outside expected range! " + currentBodyOffset + "\n";
|
||||
// message = message + this.getDebugStatus();
|
||||
// throw new Error(message);
|
||||
// }
|
||||
currentBodyOffset.add(this.floatingOrigin);
|
||||
if(collected == 0){
|
||||
newOrigin.set(currentBodyOffset);
|
||||
} else {
|
||||
float percentExisting = collected / (float)(collected + 1);
|
||||
float percentNew = 1.0f - percentExisting;
|
||||
newOrigin = newOrigin.mul(percentExisting).add(currentBodyOffset.mul(percentNew));
|
||||
newOrigin.add(currentBodyOffset);
|
||||
}
|
||||
collected++;
|
||||
}
|
||||
// DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
|
||||
// if(geom != null){
|
||||
// if(geom instanceof DSpace space){
|
||||
// for(DGeom child : space.getGeoms()){
|
||||
// Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(child.getPosition()).add(this.floatingOrigin);
|
||||
// if(collected == 0){
|
||||
// newOrigin.set(currentBodyOffset);
|
||||
// } else {
|
||||
// float percentExisting = collected / (float)(collected + 1);
|
||||
// float percentNew = 1.0f - percentExisting;
|
||||
// newOrigin = newOrigin.mul(percentExisting).add(currentBodyOffset.mul(percentNew));
|
||||
// }
|
||||
// collected++;
|
||||
// }
|
||||
// } else {
|
||||
// Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(geom.getPosition()).add(this.floatingOrigin);
|
||||
// if(collected == 0){
|
||||
// newOrigin.set(currentBodyOffset);
|
||||
// } else {
|
||||
// float percentExisting = collected / (float)(collected + 1);
|
||||
// float percentNew = 1.0f - percentExisting;
|
||||
// newOrigin = newOrigin.mul(percentExisting).add(currentBodyOffset.mul(percentNew));
|
||||
// }
|
||||
// collected++;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
if(collected > 0){
|
||||
newOrigin = newOrigin.mul(1.0/(double)collected);
|
||||
}
|
||||
newOrigin = newOrigin.round();
|
||||
Vector3d delta = new Vector3d(this.floatingOrigin);
|
||||
delta = delta.sub(newOrigin);
|
||||
|
||||
|
||||
//only perform rebase if sufficiently far away
|
||||
if(delta.length() > REBASE_TRIGGER_DISTANCE){
|
||||
//error checking
|
||||
if(collected > 1 && delta.length() > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN){
|
||||
System.out.println("newOrigin: " + newOrigin);
|
||||
System.out.println("delta: " + delta);
|
||||
throw new Error(this.getDebugStatus());
|
||||
}
|
||||
System.out.println("REbase");
|
||||
System.out.println(this.getStatus());
|
||||
System.out.println("newOrigin: " + newOrigin);
|
||||
System.out.println("delta: " + delta);
|
||||
if(delta.y > 100 || delta.y < -100){
|
||||
throw new Error(this.getDebugStatus());
|
||||
}
|
||||
|
||||
|
||||
this.floatingOrigin = newOrigin;
|
||||
//apply new origin to all geoms
|
||||
//calculate new origin
|
||||
@ -757,6 +782,7 @@ public class CollisionEngine {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.hasRebased = true;
|
||||
}
|
||||
spaceLock.unlock();
|
||||
Globals.profiler.endCpuSample();
|
||||
@ -766,12 +792,37 @@ public class CollisionEngine {
|
||||
* Registers a collision object with the server
|
||||
* @param body The body
|
||||
* @param collidable The corresponding collidable
|
||||
* @param position The position of the body
|
||||
*/
|
||||
public void registerCollisionObject(DBody body, Collidable collidable){
|
||||
public void registerCollisionObject(DBody body, Collidable collidable, Vector3d position){
|
||||
if(collidable == null){
|
||||
throw new Error("Collidable is null!");
|
||||
}
|
||||
spaceLock.lock();
|
||||
// if(this.name.equals("serverPhysics") && position.distance(0,0,0) < 100){
|
||||
// throw new Error("Invalid position " + position);
|
||||
// }
|
||||
// if(this.name.equals("serverPhysics") && this.hasRebased && this.bodies.size() > 1 && position.distance(this.floatingOrigin) > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN){
|
||||
// String message = "Position invalid!\n" +
|
||||
// "position: " + position.x + "," + position.y + "," + position.z + "\n" +
|
||||
// "floating origin: " + this.floatingOrigin.x + "," + this.floatingOrigin.y + "," + this.floatingOrigin.z + "\n" +
|
||||
// "dist: " + position.distance(this.floatingOrigin) + "\n" +
|
||||
// "ent pos: " + EntityUtils.getPosition(collidable.getParent()) + "\n" +
|
||||
// this.getDebugStatus() +
|
||||
// "";
|
||||
// throw new Error(message);
|
||||
// }
|
||||
// if(this.name.equals("serverPhysics")){
|
||||
// System.out.println("Register collidable at " + position);
|
||||
// }
|
||||
|
||||
//Body transform needs to be set before the body is added to the collidable list
|
||||
//this makes sure that dynamic update transforms and floating origin work correctly
|
||||
this.setBodyTransform(body, new Vector3d(position), new Quaterniond());
|
||||
|
||||
// if(this.name.equals("serverPhysics") && (body.getPosition().get0() != position.x || body.getPosition().get1() != position.y || body.getPosition().get2() != position.z)){
|
||||
// System.out.println("Transform not set properly! " + body.getPosition() + " " + position);
|
||||
// }
|
||||
this.registerPhysicsObject(body);
|
||||
bodyPointerMap.put(body,collidable);
|
||||
collidableList.add(collidable);
|
||||
@ -1294,8 +1345,17 @@ public class CollisionEngine {
|
||||
*/
|
||||
protected void setBodyTransform(DBody body, Vector3d position, Quaterniond rotation){
|
||||
spaceLock.lock();
|
||||
|
||||
// if(this.name.equals("serverPhysics")){
|
||||
// if(position.distance(0,0,0) < 100){
|
||||
// throw new Error("Reposition server body " + position);
|
||||
// }
|
||||
// }
|
||||
body.setPosition(position.x - this.floatingOrigin.x, position.y - this.floatingOrigin.y, position.z - this.floatingOrigin.z);
|
||||
body.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
|
||||
// if(this.name.equals("serverPhysics")){
|
||||
// System.out.println("SetBodyTransform " + body.getPosition());
|
||||
// }
|
||||
spaceLock.unlock();
|
||||
}
|
||||
|
||||
@ -1334,8 +1394,26 @@ public class CollisionEngine {
|
||||
* @param angularForce The angular force
|
||||
*/
|
||||
protected void synchronizeData(DBody body, Vector3d position, Quaterniond rotation, Vector3d linearVel, Vector3d angularVel, Vector3d linearForce, Vector3d angularForce){
|
||||
if(!this.hasRebased){
|
||||
return;
|
||||
}
|
||||
if(body != null){
|
||||
spaceLock.lock();
|
||||
|
||||
|
||||
// if(this.name.equals("clientPhysics") || this.name.equals("serverPhysics")){
|
||||
// double posX = position.x - this.floatingOrigin.x;
|
||||
// double posY = position.y - this.floatingOrigin.y;
|
||||
// double posZ = position.z - this.floatingOrigin.z;
|
||||
// if((posX > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN || posZ > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN || posX < -MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN || posZ < -MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN) && this.floatingOrigin.length() == 0 && this.hasRebased){
|
||||
// System.out.println("Sync body pos: " + posX + "," + posY + "," + posZ);
|
||||
// spaceLock.unlock();
|
||||
// return;
|
||||
// }
|
||||
// if(this.bodies.size() > 2 && this.floatingOrigin.length() == 0 && this.hasRebased){
|
||||
// throw new Error(this.getDebugStatus());
|
||||
// }
|
||||
// }
|
||||
body.setPosition(position.x - this.floatingOrigin.x, position.y - this.floatingOrigin.y, position.z - this.floatingOrigin.z);
|
||||
body.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
|
||||
body.setLinearVel(PhysicsUtils.jomlVecToOdeVec(linearVel));
|
||||
@ -1355,6 +1433,19 @@ public class CollisionEngine {
|
||||
*/
|
||||
protected void setBodyTransform(DBody body, CollidableTemplate template, Vector3d position, Quaterniond rotation, Vector3d scale){
|
||||
spaceLock.lock();
|
||||
// if(this.name.equals("clientPhysics") || this.name.equals("serverPhysics")){
|
||||
// double posX = position.x - this.floatingOrigin.x;
|
||||
// double posY = position.y - this.floatingOrigin.y;
|
||||
// double posZ = position.z - this.floatingOrigin.z;
|
||||
// if((posX > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN || posZ > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN || posX < -MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN || posZ < -MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN) && this.floatingOrigin.length() == 0 && this.hasRebased){
|
||||
// System.out.println("Set body pos: " + posX + "," + posY + "," + posZ);
|
||||
// spaceLock.unlock();
|
||||
// return;
|
||||
// }
|
||||
// if(this.bodies.size() > 2 && this.floatingOrigin.length() == 0 && this.hasRebased){
|
||||
// throw new Error(this.getDebugStatus());
|
||||
// }
|
||||
// }
|
||||
body.setPosition(position.x - this.floatingOrigin.x, position.y - this.floatingOrigin.y, position.z - this.floatingOrigin.z);
|
||||
body.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
|
||||
DGeom firstGeom = body.getFirstGeom();
|
||||
@ -1537,6 +1628,7 @@ public class CollisionEngine {
|
||||
*/
|
||||
public String getStatus(){
|
||||
String message = "" +
|
||||
"Name: " + this.name + "\n" +
|
||||
"Bodies: " + this.bodies.size() + "\n" +
|
||||
"Body Ptrs: " + this.bodyPointerMap.size() + "\n" +
|
||||
"Geom Ptrs: " + this.geomPointerMap.size() + "\n" +
|
||||
@ -1549,6 +1641,22 @@ public class CollisionEngine {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status of the collision engine
|
||||
* @return The status of the collision engine
|
||||
*/
|
||||
public String getDebugStatus(){
|
||||
String message = this.getStatus();
|
||||
for(Collidable collidable : collidableList){
|
||||
DBody rigidBody = PhysicsEntityUtils.getDBody(collidable.getParent());
|
||||
if(rigidBody != null){
|
||||
Vector3d existingPosition = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition());
|
||||
message = message + existingPosition.x + "," + existingPosition.y + "," + existingPosition.z + "\n";
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the floating origin of the collision engine
|
||||
* @return The floating origin
|
||||
|
||||
@ -234,7 +234,7 @@ public class PhysicsEntityUtils {
|
||||
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
||||
@ -298,7 +298,7 @@ public class PhysicsEntityUtils {
|
||||
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
||||
@ -364,7 +364,7 @@ public class PhysicsEntityUtils {
|
||||
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||
} break;
|
||||
}
|
||||
@ -385,8 +385,9 @@ public class PhysicsEntityUtils {
|
||||
* @param realm The realm the entity is inside of
|
||||
* @param rVal The entity
|
||||
* @param physicsTemplate The collidable template
|
||||
* @param position the position of the body
|
||||
*/
|
||||
public static void serverAttachCollidableTemplate(Realm realm, Entity rVal, CollidableTemplate physicsTemplate){
|
||||
public static void serverAttachCollidableTemplate(Realm realm, Entity rVal, CollidableTemplate physicsTemplate, Vector3d position){
|
||||
Collidable collidable;
|
||||
double mass = 1.0f;
|
||||
if(physicsTemplate.getMass() != null){
|
||||
@ -398,6 +399,237 @@ public class PhysicsEntityUtils {
|
||||
}
|
||||
CollisionEngine.lockOde();
|
||||
if(physicsTemplate.getKinematic()){
|
||||
PhysicsEntityUtils.serverAttachGeom(realm,rVal,physicsTemplate);
|
||||
} else {
|
||||
DBody rigidBody = null;
|
||||
switch(physicsTemplate.getType()){
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
|
||||
|
||||
//
|
||||
//create dbody
|
||||
rigidBody = CollisionBodyCreation.createCylinderBody(
|
||||
realm.getCollisionEngine(),
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
categoryBit
|
||||
);
|
||||
if(physicsTemplate.getMass() != null){
|
||||
CollisionBodyCreation.setCylinderMass(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
mass,
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()),
|
||||
new Quaterniond(physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW())
|
||||
);
|
||||
}
|
||||
CollisionBodyCreation.setAutoDisable(realm.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
|
||||
//
|
||||
//set offset from entity center
|
||||
CollisionBodyCreation.setOffsetPosition(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and attach tracking
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
if(physicsTemplate.getLinearFriction() != null){
|
||||
collidable.getSurfaceParams().setLinearFriction(physicsTemplate.getLinearFriction());
|
||||
}
|
||||
if(physicsTemplate.getRollingFriction() != null){
|
||||
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction());
|
||||
}
|
||||
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
|
||||
PhysicsEntityUtils.setDBody(rVal,rigidBody);
|
||||
|
||||
//
|
||||
//store data
|
||||
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
|
||||
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
|
||||
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
|
||||
1, 1, 1 //scale
|
||||
);
|
||||
if(physicsTemplate.isAngularlyStatic()){
|
||||
realm.getCollisionEngine().setAngularlyStatic(rigidBody, true);
|
||||
}
|
||||
if(physicsTemplate.getKinematic()){
|
||||
realm.getCollisionEngine().setKinematic(rigidBody);
|
||||
rigidBody.disable();
|
||||
}
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
|
||||
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable, position);
|
||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
||||
//
|
||||
//create dbody
|
||||
rigidBody = CollisionBodyCreation.createCubeBody(
|
||||
realm.getCollisionEngine(),
|
||||
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
|
||||
categoryBit
|
||||
);
|
||||
if(physicsTemplate.getMass() != null){
|
||||
CollisionBodyCreation.setBoxMass(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
mass,
|
||||
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()),
|
||||
new Quaterniond(physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW())
|
||||
);
|
||||
}
|
||||
CollisionBodyCreation.setAutoDisable(realm.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
|
||||
//
|
||||
//set offset from entity center
|
||||
CollisionBodyCreation.setOffsetPosition(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and attach tracking
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
if(physicsTemplate.getLinearFriction() != null){
|
||||
collidable.getSurfaceParams().setLinearFriction(physicsTemplate.getLinearFriction());
|
||||
}
|
||||
if(physicsTemplate.getRollingFriction() != null){
|
||||
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction());
|
||||
}
|
||||
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
|
||||
PhysicsEntityUtils.setDBody(rVal,rigidBody);
|
||||
|
||||
//
|
||||
//store data
|
||||
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
|
||||
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
|
||||
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
|
||||
1, 1, 1 //scale
|
||||
);
|
||||
if(physicsTemplate.isAngularlyStatic()){
|
||||
realm.getCollisionEngine().setAngularlyStatic(rigidBody, true);
|
||||
}
|
||||
if(physicsTemplate.getKinematic()){
|
||||
realm.getCollisionEngine().setKinematic(rigidBody);
|
||||
rigidBody.disable();
|
||||
}
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
|
||||
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable, position);
|
||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
||||
//
|
||||
//create dbody
|
||||
rigidBody = CollisionBodyCreation.createCapsuleBody(
|
||||
realm.getCollisionEngine(),
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
categoryBit
|
||||
);
|
||||
if(physicsTemplate.getMass() != null){
|
||||
CollisionBodyCreation.setCapsuleMass(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
mass,
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()),
|
||||
new Quaterniond(physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW())
|
||||
);
|
||||
}
|
||||
CollisionBodyCreation.setAutoDisable(realm.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
|
||||
//
|
||||
//set offset from entity center
|
||||
CollisionBodyCreation.setOffsetPosition(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and attach tracking
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
if(physicsTemplate.getLinearFriction() != null){
|
||||
collidable.getSurfaceParams().setLinearFriction(physicsTemplate.getLinearFriction());
|
||||
}
|
||||
if(physicsTemplate.getRollingFriction() != null){
|
||||
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction());
|
||||
}
|
||||
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
|
||||
PhysicsEntityUtils.setDBody(rVal,rigidBody);
|
||||
|
||||
//
|
||||
//store data
|
||||
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
|
||||
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
|
||||
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
|
||||
1, 1, 1 //scale
|
||||
);
|
||||
if(physicsTemplate.isAngularlyStatic()){
|
||||
realm.getCollisionEngine().setAngularlyStatic(rigidBody, true);
|
||||
}
|
||||
if(physicsTemplate.getKinematic()){
|
||||
realm.getCollisionEngine().setKinematic(rigidBody);
|
||||
rigidBody.disable();
|
||||
}
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
|
||||
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable, position);
|
||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
||||
} break;
|
||||
}
|
||||
//if we successfully attached the body, add a sync tree
|
||||
if(rigidBody != null){
|
||||
ServerPhysicsSyncTree.attachTree(rVal);
|
||||
if(ServerGravityTree.hasServerGravityTree(rVal)){
|
||||
ServerGravityTree.getServerGravityTree(rVal).updatePhysicsPair(PhysicsEntityUtils.getCollidable(rVal),PhysicsEntityUtils.getDBody(rVal));
|
||||
}
|
||||
}
|
||||
}
|
||||
CollisionEngine.unlockOde();
|
||||
}
|
||||
|
||||
/**
|
||||
* [SERVER ONLY] Attaches a collidable template to a given entity
|
||||
* @param realm The realm the entity is inside of
|
||||
* @param rVal The entity
|
||||
* @param physicsTemplate The collidable template
|
||||
* @return The geometry object
|
||||
*/
|
||||
public static DGeom serverAttachGeom(Realm realm, Entity rVal, CollidableTemplate physicsTemplate){
|
||||
if(physicsTemplate == null){
|
||||
throw new Error("Physics template is null!");
|
||||
}
|
||||
Collidable collidable;
|
||||
double mass = 1.0f;
|
||||
long categoryBit = Collidable.TYPE_CREATURE_BIT;
|
||||
if(physicsTemplate.getKinematic()){
|
||||
categoryBit = Collidable.TYPE_STATIC_BIT;
|
||||
}
|
||||
CollisionEngine.lockOde();
|
||||
DGeom geom = null;
|
||||
switch(physicsTemplate.getType()){
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
|
||||
@ -494,216 +726,8 @@ public class PhysicsEntityUtils {
|
||||
realm.getCollisionEngine().registerCollisionObject(geom, collidable);
|
||||
} break;
|
||||
}
|
||||
} else {
|
||||
DBody rigidBody = null;
|
||||
switch(physicsTemplate.getType()){
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
|
||||
|
||||
//
|
||||
//create dbody
|
||||
rigidBody = CollisionBodyCreation.createCylinderBody(
|
||||
realm.getCollisionEngine(),
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
categoryBit
|
||||
);
|
||||
if(physicsTemplate.getMass() != null){
|
||||
CollisionBodyCreation.setCylinderMass(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
mass,
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()),
|
||||
new Quaterniond(physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW())
|
||||
);
|
||||
}
|
||||
CollisionBodyCreation.setAutoDisable(realm.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
|
||||
//
|
||||
//set offset from entity center
|
||||
CollisionBodyCreation.setOffsetPosition(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and attach tracking
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
if(physicsTemplate.getLinearFriction() != null){
|
||||
collidable.getSurfaceParams().setLinearFriction(physicsTemplate.getLinearFriction());
|
||||
}
|
||||
if(physicsTemplate.getRollingFriction() != null){
|
||||
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction());
|
||||
}
|
||||
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
|
||||
PhysicsEntityUtils.setDBody(rVal,rigidBody);
|
||||
|
||||
//
|
||||
//store data
|
||||
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
|
||||
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
|
||||
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
|
||||
1, 1, 1 //scale
|
||||
);
|
||||
if(physicsTemplate.isAngularlyStatic()){
|
||||
realm.getCollisionEngine().setAngularlyStatic(rigidBody, true);
|
||||
}
|
||||
if(physicsTemplate.getKinematic()){
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().setKinematic(rigidBody);
|
||||
rigidBody.disable();
|
||||
}
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
|
||||
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
||||
//
|
||||
//create dbody
|
||||
rigidBody = CollisionBodyCreation.createCubeBody(
|
||||
realm.getCollisionEngine(),
|
||||
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
|
||||
categoryBit
|
||||
);
|
||||
if(physicsTemplate.getMass() != null){
|
||||
CollisionBodyCreation.setBoxMass(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
mass,
|
||||
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()),
|
||||
new Quaterniond(physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW())
|
||||
);
|
||||
}
|
||||
CollisionBodyCreation.setAutoDisable(realm.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
|
||||
//
|
||||
//set offset from entity center
|
||||
CollisionBodyCreation.setOffsetPosition(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and attach tracking
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
if(physicsTemplate.getLinearFriction() != null){
|
||||
collidable.getSurfaceParams().setLinearFriction(physicsTemplate.getLinearFriction());
|
||||
}
|
||||
if(physicsTemplate.getRollingFriction() != null){
|
||||
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction());
|
||||
}
|
||||
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
|
||||
PhysicsEntityUtils.setDBody(rVal,rigidBody);
|
||||
|
||||
//
|
||||
//store data
|
||||
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
|
||||
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
|
||||
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
|
||||
1, 1, 1 //scale
|
||||
);
|
||||
if(physicsTemplate.isAngularlyStatic()){
|
||||
realm.getCollisionEngine().setAngularlyStatic(rigidBody, true);
|
||||
}
|
||||
if(physicsTemplate.getKinematic()){
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().setKinematic(rigidBody);
|
||||
rigidBody.disable();
|
||||
}
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
|
||||
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
||||
} break;
|
||||
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
||||
//
|
||||
//create dbody
|
||||
rigidBody = CollisionBodyCreation.createCapsuleBody(
|
||||
realm.getCollisionEngine(),
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
categoryBit
|
||||
);
|
||||
if(physicsTemplate.getMass() != null){
|
||||
CollisionBodyCreation.setCapsuleMass(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
mass,
|
||||
physicsTemplate.getDimension1(),
|
||||
physicsTemplate.getDimension2(),
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()),
|
||||
new Quaterniond(physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW())
|
||||
);
|
||||
}
|
||||
CollisionBodyCreation.setAutoDisable(realm.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
|
||||
//
|
||||
//set offset from entity center
|
||||
CollisionBodyCreation.setOffsetPosition(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
|
||||
);
|
||||
|
||||
//
|
||||
//create collidable and attach tracking
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||
if(physicsTemplate.getLinearFriction() != null){
|
||||
collidable.getSurfaceParams().setLinearFriction(physicsTemplate.getLinearFriction());
|
||||
}
|
||||
if(physicsTemplate.getRollingFriction() != null){
|
||||
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction());
|
||||
}
|
||||
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
|
||||
PhysicsEntityUtils.setDBody(rVal,rigidBody);
|
||||
|
||||
//
|
||||
//store data
|
||||
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
|
||||
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
|
||||
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
|
||||
1, 1, 1 //scale
|
||||
);
|
||||
if(physicsTemplate.isAngularlyStatic()){
|
||||
realm.getCollisionEngine().setAngularlyStatic(rigidBody, true);
|
||||
}
|
||||
if(physicsTemplate.getKinematic()){
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().setKinematic(rigidBody);
|
||||
rigidBody.disable();
|
||||
}
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
|
||||
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||
|
||||
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
||||
} break;
|
||||
}
|
||||
//if we successfully attached the body, add a sync tree
|
||||
if(rigidBody != null){
|
||||
ServerPhysicsSyncTree.attachTree(rVal);
|
||||
if(ServerGravityTree.hasServerGravityTree(rVal)){
|
||||
ServerGravityTree.getServerGravityTree(rVal).updatePhysicsPair(PhysicsEntityUtils.getCollidable(rVal),PhysicsEntityUtils.getDBody(rVal));
|
||||
}
|
||||
}
|
||||
}
|
||||
CollisionEngine.unlockOde();
|
||||
return geom;
|
||||
}
|
||||
|
||||
|
||||
@ -718,7 +742,7 @@ public class PhysicsEntityUtils {
|
||||
DBody terrainBody = CollisionBodyCreation.generateBodyFromTerrainData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT);
|
||||
CollisionBodyCreation.setAutoDisable(Globals.clientState.clientSceneWrapper.getCollisionEngine(), terrainBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable, EntityUtils.getPosition(terrain));
|
||||
PhysicsEntityUtils.setDBody(terrain,terrainBody);
|
||||
CollisionEngine.unlockOde();
|
||||
terrain.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
@ -750,7 +774,7 @@ public class PhysicsEntityUtils {
|
||||
DBody terrainBody = CollisionBodyCreation.generateBodyFromMultiShapeMeshData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT);
|
||||
CollisionBodyCreation.setAutoDisable(Globals.clientState.clientSceneWrapper.getCollisionEngine(), terrainBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable, EntityUtils.getPosition(terrain));
|
||||
PhysicsEntityUtils.setDBody(terrain,terrainBody);
|
||||
terrain.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
}
|
||||
@ -781,7 +805,7 @@ public class PhysicsEntityUtils {
|
||||
DBody terrainBody = CollisionBodyCreation.generateBodyFromTerrainData(realm.getCollisionEngine(),data,Collidable.TYPE_STATIC_BIT);
|
||||
CollisionBodyCreation.setAutoDisable(realm.getCollisionEngine(), terrainBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
|
||||
realm.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_STATIC, false));
|
||||
realm.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_STATIC, false), EntityUtils.getPosition(terrain));
|
||||
PhysicsEntityUtils.setDBody(terrain,terrainBody);
|
||||
|
||||
return terrainBody;
|
||||
@ -816,7 +840,7 @@ public class PhysicsEntityUtils {
|
||||
DBody terrainBody = CollisionBodyCreation.generateBodyFromMultiShapeMeshData(realm.getCollisionEngine(),data,Collidable.TYPE_STATIC_BIT);
|
||||
CollisionBodyCreation.setAutoDisable(realm.getCollisionEngine(), terrainBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
|
||||
|
||||
realm.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_STATIC, false));
|
||||
realm.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_STATIC, false), EntityUtils.getPosition(terrain));
|
||||
PhysicsEntityUtils.setDBody(terrain,terrainBody);
|
||||
|
||||
return terrainBody;
|
||||
@ -889,6 +913,7 @@ public class PhysicsEntityUtils {
|
||||
);
|
||||
}
|
||||
PhysicsEntityUtils.setCollidable(entity, null);
|
||||
PhysicsEntityUtils.clearGeomAndBody(entity);
|
||||
Vector3d entityPos = EntityUtils.getPosition(entity);
|
||||
ServerEntityUtils.repositionEntity(entity, entityPos);
|
||||
}
|
||||
@ -962,6 +987,18 @@ public class PhysicsEntityUtils {
|
||||
return (DGeom)entity.getData(EntityDataStrings.PHYSICS_GEOM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the geom and body on an entity
|
||||
* @param entity The entity
|
||||
*/
|
||||
public static void clearGeomAndBody(Entity entity){
|
||||
if(PhysicsEntityUtils.getCollidable(entity) != null){
|
||||
throw new Error("Trying to clear geom and body on an entity that still has a collidable!");
|
||||
}
|
||||
entity.removeData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
||||
entity.removeData(EntityDataStrings.PHYSICS_GEOM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of a DGeom
|
||||
* @param collisionEngine the collision engine
|
||||
|
||||
@ -38,6 +38,11 @@ public class Collidable {
|
||||
*/
|
||||
private SurfaceParams surfaceParams;
|
||||
|
||||
/**
|
||||
* Tracks whether this collidable has been simulated or not
|
||||
*/
|
||||
private boolean ready = false;
|
||||
|
||||
//these should have corresponding category bits along with them
|
||||
public static final String TYPE_STATIC = "static";
|
||||
public static final long TYPE_STATIC_BIT = 0x1;
|
||||
@ -123,6 +128,24 @@ public class Collidable {
|
||||
impulses.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the collidable is ready or not
|
||||
* @return true if it is ready, false otherwise
|
||||
*/
|
||||
public boolean getReady() {
|
||||
return ready;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ready status of collidable
|
||||
* @param ready true if the collidable is ready, false otherwise
|
||||
*/
|
||||
public void setReady(boolean ready) {
|
||||
this.ready = ready;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ public class HitboxManager {
|
||||
* @param resolutionCallback The callback that fires when a collision occurs
|
||||
*/
|
||||
public HitboxManager(CollisionResolutionCallback resolutionCallback){
|
||||
collisionEngine = new CollisionEngine();
|
||||
collisionEngine = new CollisionEngine("hitbox");
|
||||
collisionEngine.setCollisionResolutionCallback(resolutionCallback);
|
||||
}
|
||||
|
||||
|
||||
@ -160,7 +160,7 @@ public class LoadingUtils {
|
||||
}
|
||||
//set player character template
|
||||
serverPlayerConnection.setCreatureTemplate(template);
|
||||
Character chara = Globals.serverState.characterService.createCharacter(template, serverPlayerConnection.getPlayerId());
|
||||
Character chara = Globals.serverState.characterService.createCharacter(template, serverPlayerConnection.getPlayerId(), new Vector3d());
|
||||
Globals.clientState.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage(chara.getId() + ""));
|
||||
|
||||
//set player world-space coordinates
|
||||
|
||||
@ -37,7 +37,7 @@ public class ClientEntityUtils {
|
||||
* @param entity
|
||||
* @param position
|
||||
*/
|
||||
public static void reositionEntity(Entity entity, Vector3d position, Quaterniond rotation){
|
||||
public static void repositionEntity(Entity entity, Vector3d position, Quaterniond rotation){
|
||||
//reposition entity
|
||||
CollisionObjUtils.clientPositionCharacter(entity, position, rotation);
|
||||
EntityUtils.getPosition(entity).set(position);
|
||||
|
||||
@ -115,7 +115,9 @@ public class DrawableUtils {
|
||||
});
|
||||
String path = Globals.assetManager.queuedAsset(model);
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorOfLoadingModel(path));
|
||||
if(!entity.containsKey(EntityDataStrings.DATA_STRING_POSITION)){
|
||||
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||
}
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||
@ -132,7 +134,9 @@ public class DrawableUtils {
|
||||
*/
|
||||
public static void makeEntityDrawable(Entity entity, String path){
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(path));
|
||||
if(!entity.containsKey(EntityDataStrings.DATA_STRING_POSITION)){
|
||||
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||
}
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||
|
||||
@ -131,7 +131,9 @@ public class EntityCreationUtils {
|
||||
*/
|
||||
public static void makeEntityPoseable(Entity entity, String modelPath){
|
||||
entity.putData(EntityDataStrings.POSE_ACTOR, PoseActorUtils.createPoseActorFromModelPath(modelPath));
|
||||
if(!entity.containsKey(EntityDataStrings.DATA_STRING_POSITION)){
|
||||
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||
}
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||
@ -147,7 +149,9 @@ public class EntityCreationUtils {
|
||||
*/
|
||||
public static void makeEntityDrawable(Entity entity, String modelPath){
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(modelPath));
|
||||
if(!entity.containsKey(EntityDataStrings.DATA_STRING_POSITION)){
|
||||
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||
}
|
||||
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||
|
||||
@ -40,10 +40,20 @@ public class ServerEntityUtils {
|
||||
if(position == null){
|
||||
throw new Error("Trying to set server entity position to null!");
|
||||
}
|
||||
double startX = position.x;
|
||||
double startY = position.y;
|
||||
double startZ = position.z;
|
||||
//reposition entity, if the position isn't correct then it will spawn at 0,0,0 when the synchronization part is called
|
||||
CollisionObjUtils.serverPositionCharacter(entity, position);
|
||||
//get current server data cell
|
||||
ServerDataCell cell = realm.getDataCellManager().getDataCellAtPoint(position);
|
||||
if(startX != position.x || startX != position.x || startX != position.x){
|
||||
throw new Error("Position not preserved while initially positioning entity! " + startX + "," + startY + "," + startZ + " " + position.x + "," + position.y + "," + position.z);
|
||||
}
|
||||
Vector3d entPos = EntityUtils.getPosition(entity);
|
||||
if(startX != entPos.x || startX != entPos.x || startX != entPos.x){
|
||||
throw new Error("Position not preserved while initially positioning entity! " + startX + "," + startY + "," + startZ + " " + entPos.x + "," + entPos.y + "," + entPos.z);
|
||||
}
|
||||
if(cell != null){
|
||||
//initialize server datacell tracking of this entity
|
||||
realm.initializeServerSideEntity(entity, cell);
|
||||
@ -56,6 +66,9 @@ public class ServerEntityUtils {
|
||||
//initialize server datacell tracking of this entity
|
||||
realm.initializeServerSideEntity(entity, cell);
|
||||
}
|
||||
if(startX != position.x || startX != position.x || startX != position.x){
|
||||
throw new Error("Position not preserved while initially positioning entity! " + startX + "," + startY + "," + startZ + " " + position.x + "," + position.y + "," + position.z);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,6 +83,10 @@ public class ServerEntityUtils {
|
||||
if(AttachUtils.getParent(entity) != null){
|
||||
throw new Error("Trying to reposition attached entity!");
|
||||
}
|
||||
double startX = position.x;
|
||||
double startY = position.y;
|
||||
double startZ = position.z;
|
||||
|
||||
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
|
||||
ServerWorldData worldDat = realm.getServerWorldData();
|
||||
if(
|
||||
@ -85,6 +102,11 @@ public class ServerEntityUtils {
|
||||
ServerEntityUtils.repositionEntityRecursive(realm, entity, position);
|
||||
//reposition entity
|
||||
CollisionObjUtils.serverPositionCharacter(entity, position);
|
||||
|
||||
//error checking
|
||||
if(position.x != startX || position.y != startY || position.z != startZ){
|
||||
throw new Error("Position mutated while repositioning! " + position + " " + startX + "," + startY + "," + startZ);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -57,7 +57,7 @@ public class Scene {
|
||||
/**
|
||||
* Lock for threadsafeing the scene
|
||||
*/
|
||||
ReentrantLock lock = new ReentrantLock();
|
||||
private ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
||||
@ -66,6 +66,8 @@ public class ClientCollidableTree implements BehaviorTree {
|
||||
}
|
||||
PhysicsUtils.setRigidBodyTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), newPosition, rotation, body);
|
||||
|
||||
collidable.setReady(true);
|
||||
|
||||
//capsule-specific block collision logic
|
||||
// if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){
|
||||
// //get capsule params
|
||||
|
||||
@ -60,6 +60,8 @@ public class ServerCollidableTree implements BehaviorTree {
|
||||
}
|
||||
}
|
||||
|
||||
collidable.setReady(true);
|
||||
|
||||
//capsule-specific block collision logic
|
||||
// if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){
|
||||
// Realm realm = Globals.serverState.realmManager.getEntityRealm(parent);
|
||||
|
||||
@ -86,7 +86,7 @@ public class ServerDoorState implements BehaviorTree {
|
||||
this.setState(DoorState.CLOSED);
|
||||
Realm parentRealm = Globals.serverState.realmManager.getEntityRealm(this.parent);
|
||||
Vector3d pos = EntityUtils.getPosition(this.parent);
|
||||
PhysicsEntityUtils.serverAttachCollidableTemplate(parentRealm, this.parent, PhysicsEntityUtils.getPhysicsTemplate(this.parent));
|
||||
PhysicsEntityUtils.serverAttachCollidableTemplate(parentRealm, this.parent, PhysicsEntityUtils.getPhysicsTemplate(this.parent), pos);
|
||||
ServerEntityUtils.repositionEntity(this.parent, pos);
|
||||
}
|
||||
),
|
||||
|
||||
@ -284,7 +284,8 @@ public class HitboxCollectionState {
|
||||
|
||||
//register collidable with collision engine
|
||||
this.collidable = new Collidable(this.parent, Collidable.TYPE_OBJECT, true);
|
||||
collisionEngine.registerCollisionObject(this.body, this.collidable);
|
||||
Vector3d entPos = EntityUtils.getPosition(this.parent);
|
||||
collisionEngine.registerCollisionObject(this.body, this.collidable, entPos);
|
||||
CollisionEngine.unlockOde();
|
||||
}
|
||||
|
||||
|
||||
@ -350,7 +350,6 @@ public class ServerInventoryState implements BehaviorTree {
|
||||
inventory.addItem(inventoryItem);
|
||||
//if we are the server, immediately send required packets
|
||||
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(item);
|
||||
// ServerDataCell dataCell = Globals.dataCellLocationResolver.getDataCellAtPoint(EntityUtils.getPosition(item),item);
|
||||
//broadcast destroy entityq
|
||||
dataCell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(item.getId()));
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ public class ClientLODComponent implements BehaviorTree {
|
||||
){
|
||||
CollidableTemplate physicsTemplate = commonData.getCollidable();
|
||||
PhysicsEntityUtils.clientAttachCollidableTemplate(this.parent, physicsTemplate);
|
||||
ClientEntityUtils.reositionEntity(parent, EntityUtils.getPosition(parent), EntityUtils.getRotation(parent));
|
||||
ClientEntityUtils.repositionEntity(parent, EntityUtils.getPosition(parent), EntityUtils.getRotation(parent));
|
||||
}
|
||||
}
|
||||
if(cachedLodLevel != lodLevel){
|
||||
@ -66,7 +66,7 @@ public class ClientLODComponent implements BehaviorTree {
|
||||
CommonEntityType type = CommonEntityUtils.getCommonData(this.parent);
|
||||
if(type.getCollidable() != null && PhysicsEntityUtils.getCollidable(this.parent) == null){
|
||||
PhysicsEntityUtils.clientAttachCollidableTemplate(parent, type.getCollidable());
|
||||
ClientEntityUtils.reositionEntity(parent, EntityUtils.getPosition(parent), EntityUtils.getRotation(parent));
|
||||
ClientEntityUtils.repositionEntity(parent, EntityUtils.getPosition(parent), EntityUtils.getRotation(parent));
|
||||
}
|
||||
} else if(cachedLodLevel == ServerLODComponent.LOW_RES){
|
||||
if(PhysicsEntityUtils.containsDBody(this.parent)){
|
||||
|
||||
@ -17,6 +17,7 @@ import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
|
||||
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||
import electrosphere.entity.btree.BehaviorTree;
|
||||
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||
|
||||
@ -63,7 +64,8 @@ public class ServerLODComponent implements BehaviorTree {
|
||||
Realm realm = Globals.serverState.realmManager.getEntityRealm(this.parent);
|
||||
CommonEntityType type = CommonEntityUtils.getCommonData(this.parent);
|
||||
if(type.getCollidable() != null){
|
||||
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, this.parent, type.getCollidable());
|
||||
PhysicsEntityUtils.serverDestroyPhysics(this.parent);
|
||||
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, this.parent, type.getCollidable(),EntityUtils.getPosition(parent));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -71,6 +73,14 @@ public class ServerLODComponent implements BehaviorTree {
|
||||
//make low res
|
||||
this.setLodLevel(LOW_RES);
|
||||
PhysicsEntityUtils.serverDestroyPhysics(this.parent);
|
||||
Realm realm = Globals.serverState.realmManager.getEntityRealm(parent);
|
||||
CommonEntityType type = CommonEntityUtils.getCommonData(this.parent);
|
||||
if(type.getCollidable() != null){
|
||||
if(CreatureUtils.hasControllerPlayerId(parent)){
|
||||
throw new Error("Should not be attaching a geometry to a player entity!");
|
||||
}
|
||||
PhysicsEntityUtils.serverAttachGeom(realm, parent, type.getCollidable());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ public class CollisionObjUtils {
|
||||
Vector3d position = EntityUtils.getPosition(entity);
|
||||
Quaterniond rotation = EntityUtils.getRotation(entity);
|
||||
Collidable collidable = new Collidable(entity, collidableType, true);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(collisionObject, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(collisionObject, collidable, EntityUtils.getPosition(entity));
|
||||
|
||||
PhysicsEntityUtils.setDBody(entity, collisionObject);
|
||||
|
||||
@ -55,7 +55,7 @@ public class CollisionObjUtils {
|
||||
Vector3d position = EntityUtils.getPosition(entity);
|
||||
Collidable collidable = new Collidable(entity, collidableType, true);
|
||||
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
|
||||
realm.getCollisionEngine().registerCollisionObject(collisionObject, collidable);
|
||||
realm.getCollisionEngine().registerCollisionObject(collisionObject, collidable, EntityUtils.getPosition(entity));
|
||||
|
||||
PhysicsEntityUtils.setDBody(entity, collisionObject);
|
||||
|
||||
@ -73,7 +73,15 @@ public class CollisionObjUtils {
|
||||
* @param position The server
|
||||
*/
|
||||
public static void serverPositionCharacter(Entity e, Vector3d position){
|
||||
EntityUtils.getPosition(e).set(position);
|
||||
CollisionEngine.lockOde();
|
||||
double startX = position.x;
|
||||
double startY = position.y;
|
||||
double startZ = position.z;
|
||||
Vector3d entPos = EntityUtils.getPosition(e);
|
||||
entPos.set(position);
|
||||
if(startX != entPos.x || startX != entPos.x || startX != entPos.x){
|
||||
throw new Error("Failed to position entity! " + startX + "," + startY + "," + startZ + " " + entPos.x + "," + entPos.y + "," + entPos.z);
|
||||
}
|
||||
Quaterniond rotation = EntityUtils.getRotation(e);
|
||||
DBody body = PhysicsEntityUtils.getDBody(e);
|
||||
DGeom geom = PhysicsEntityUtils.getDGeom(e);
|
||||
@ -86,7 +94,7 @@ public class CollisionObjUtils {
|
||||
if(template == null){
|
||||
PhysicsUtils.setGeomTransform(
|
||||
collisionEngine,
|
||||
position,
|
||||
new Vector3d(position),
|
||||
rotation,
|
||||
geom
|
||||
);
|
||||
@ -99,6 +107,14 @@ public class CollisionObjUtils {
|
||||
);
|
||||
}
|
||||
}
|
||||
Vector3d finalRef = EntityUtils.getPosition(e);
|
||||
if(finalRef != entPos){
|
||||
throw new Error("Reference changed while positioning character! " + entPos + " " + finalRef);
|
||||
}
|
||||
if(startX != entPos.x || startX != entPos.x || startX != entPos.x){
|
||||
throw new Error("Position not preserved while positioning entity! " + startX + "," + startY + "," + startZ + " " + entPos.x + "," + entPos.y + "," + entPos.z + " " + position);
|
||||
}
|
||||
CollisionEngine.unlockOde();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -432,6 +432,10 @@ public class CommonEntityUtils {
|
||||
*/
|
||||
public static Entity serverApplyCommonEntityTransforms(Realm realm, Vector3d position, Entity entity, CommonEntityType rawType){
|
||||
|
||||
double startX = position.x;
|
||||
double startY = position.y;
|
||||
double startZ = position.z;
|
||||
|
||||
//
|
||||
//Set typing stuff
|
||||
//
|
||||
@ -498,6 +502,9 @@ public class CommonEntityUtils {
|
||||
// Hitbox stuff
|
||||
//
|
||||
//
|
||||
if(position.x != startX || position.y != startY || position.z != startZ){
|
||||
throw new Error("Position mutated while spawning entity!");
|
||||
}
|
||||
if(rawType.getHitboxes() != null){
|
||||
HitboxCollectionState.attachHitboxState(realm.getHitboxManager(), true, entity, rawType.getHitboxes());
|
||||
}
|
||||
@ -507,9 +514,12 @@ public class CommonEntityUtils {
|
||||
//
|
||||
//
|
||||
if(rawType.getCollidable() != null){
|
||||
//actually attach collidable
|
||||
CollidableTemplate physicsTemplate = rawType.getCollidable();
|
||||
if(Globals.serverState.lodEmitterService.isFullLod(position)){
|
||||
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, entity, physicsTemplate);
|
||||
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, entity, physicsTemplate,position);
|
||||
} else {
|
||||
PhysicsEntityUtils.serverAttachGeom(realm, entity, physicsTemplate);
|
||||
}
|
||||
ServerLODComponent.attachTree(entity);
|
||||
}
|
||||
|
||||
@ -209,6 +209,11 @@ public class CreatureUtils {
|
||||
* @return The creature entity
|
||||
*/
|
||||
public static Entity serverSpawnBasicCreature(Realm realm, Vector3d position, String type, ObjectTemplate template){
|
||||
|
||||
double posX = position.x;
|
||||
double posY = position.y;
|
||||
double posZ = position.z;
|
||||
|
||||
CreatureData rawType = Globals.gameConfigCurrent.getCreatureTypeLoader().getType(type);
|
||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
|
||||
|
||||
@ -288,6 +293,11 @@ public class CreatureUtils {
|
||||
//store template on creature
|
||||
CreatureUtils.setCreatureTemplate(rVal, storedTemplate);
|
||||
|
||||
//error check position modification
|
||||
if(posX != position.x || posY != position.y || posZ != position.z){
|
||||
throw new Error("Creature has mutated position! " + posX + "," + posY + "," + posZ + " " + position.x + "," + position.y + "," + position.z);
|
||||
}
|
||||
|
||||
|
||||
//position entity
|
||||
//this needs to be called at the end of this function.
|
||||
@ -300,6 +310,10 @@ public class CreatureUtils {
|
||||
if(Globals.serverState.realmManager.getEntityRealm(rVal) == null){
|
||||
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Created creature without it being assigned to a realm!"));
|
||||
}
|
||||
//make sure position hasn't changed
|
||||
if(posX != position.x || posY != position.y || posZ != position.z){
|
||||
throw new Error("Creature has mutated position! " + posX + "," + posY + "," + posZ + " " + position.x + "," + position.y + "," + position.z);
|
||||
}
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ public class BlockChunkEntity {
|
||||
EntityCreationUtils.makeEntityDrawablePreexistingModel(solidsEnt, modelPath);
|
||||
if(levelOfDetail == BlockChunkData.LOD_FULL_RES){
|
||||
PhysicsEntityUtils.clientAttachTriGeomCollider(solidsEnt, data);
|
||||
ClientEntityUtils.reositionEntity(solidsEnt, new Vector3d(EntityUtils.getPosition(solidsEnt)), new Quaterniond());
|
||||
ClientEntityUtils.repositionEntity(solidsEnt, new Vector3d(EntityUtils.getPosition(solidsEnt)), new Quaterniond());
|
||||
} else {
|
||||
EntityCreationUtils.bypassShadowPass(solidsEnt);
|
||||
EntityCreationUtils.bypassVolumetics(solidsEnt);
|
||||
|
||||
@ -144,7 +144,7 @@ public class ProceduralTree {
|
||||
trunkChild.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
trunkChild.putData(EntityDataStrings.PHYSICS_MASS, TREE_MASS);
|
||||
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(trunkChild));
|
||||
|
||||
|
||||
//generate branches
|
||||
@ -549,7 +549,7 @@ public class ProceduralTree {
|
||||
trunkChild.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
trunkChild.putData(EntityDataStrings.PHYSICS_MASS, TREE_MASS);
|
||||
|
||||
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
|
||||
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(trunkChild));
|
||||
|
||||
return trunkChild;
|
||||
}
|
||||
|
||||
@ -38,37 +38,37 @@ public class Player {
|
||||
/**
|
||||
* The corresponding connection handler
|
||||
*/
|
||||
ServerConnectionHandler connectionHandler;
|
||||
private ServerConnectionHandler connectionHandler;
|
||||
|
||||
/**
|
||||
* The id of the player
|
||||
*/
|
||||
int id;
|
||||
private int id;
|
||||
|
||||
/**
|
||||
* The database's id of the player
|
||||
*/
|
||||
int dbId;
|
||||
private int dbId;
|
||||
|
||||
/**
|
||||
* The world position of this player
|
||||
*/
|
||||
Vector3i worldPos;
|
||||
private Vector3i worldPos;
|
||||
|
||||
/**
|
||||
* The simulation radius of this player
|
||||
*/
|
||||
int simulationRadius = DEFAULT_SIMULATION_RADIUS;
|
||||
private int simulationRadius = DEFAULT_SIMULATION_RADIUS;
|
||||
|
||||
/**
|
||||
* The player's primary entity
|
||||
*/
|
||||
Entity playerEntity;
|
||||
private Entity playerEntity;
|
||||
|
||||
/**
|
||||
* Tracks whether the player's entity has been sent or not
|
||||
*/
|
||||
boolean hasSentPlayerEntity = false;
|
||||
private boolean hasSentPlayerEntity = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
||||
@ -69,8 +69,7 @@ public class CharacterProtocol implements ServerProtocolTemplate<CharacterMessag
|
||||
case REQUESTCREATECHARACTER: {
|
||||
ObjectTemplate template = Utilities.deserialize(message.getdata(), ObjectTemplate.class);
|
||||
if(template != null){
|
||||
Character charaData = Globals.serverState.characterService.createCharacter(template, connectionHandler.getPlayer().getDBID());
|
||||
charaData.setPos(Globals.serverState.realmManager.first().getSpawnPoint());
|
||||
Character charaData = Globals.serverState.characterService.createCharacter(template, connectionHandler.getPlayer().getDBID(),Globals.serverState.realmManager.first().getSpawnPoint());
|
||||
connectionHandler.setCreatureTemplate(Utilities.deserialize(message.getdata(), ObjectTemplate.class));
|
||||
connectionHandler.setCharacterId(charaData.getId());
|
||||
connectionHandler.addMessagetoOutgoingQueue(CharacterMessage.constructResponseCreateCharacterSuccessMessage());
|
||||
|
||||
@ -145,7 +145,7 @@ public class MacroPathfindingNode implements AITreeNode {
|
||||
if(targetRaw instanceof Vector3d){
|
||||
targetPos = (Vector3d)targetRaw;
|
||||
} else if(targetRaw instanceof Entity){
|
||||
targetPos = EntityUtils.getPosition((Entity)targetRaw);
|
||||
targetPos = new Vector3d(EntityUtils.getPosition((Entity)targetRaw));
|
||||
} else if(targetRaw instanceof VirtualStructure){
|
||||
targetPos = ((VirtualStructure)targetRaw).getPos();
|
||||
} else {
|
||||
@ -173,7 +173,7 @@ public class MacroPathfindingNode implements AITreeNode {
|
||||
if(macroData == null){
|
||||
throw new Error("Macro data undefined!");
|
||||
}
|
||||
Vector3d entityPos = EntityUtils.getPosition(entity);
|
||||
Vector3d entityPos = new Vector3d(EntityUtils.getPosition(entity));
|
||||
return macroData.getPathCache().getPathingNode(entityPos);
|
||||
}
|
||||
|
||||
|
||||
@ -59,11 +59,11 @@ public class RealmManager {
|
||||
*/
|
||||
public Realm createRealm(){
|
||||
//create chemistry engine
|
||||
CollisionEngine chemistryEngine = new CollisionEngine();
|
||||
CollisionEngine chemistryEngine = new CollisionEngine("serverChem");
|
||||
chemistryEngine.setCollisionResolutionCallback(new ServerChemistryCollisionCallback());
|
||||
return new Realm(
|
||||
new ServerWorldData(),
|
||||
new CollisionEngine(),
|
||||
new CollisionEngine("serverPhysics"),
|
||||
chemistryEngine,
|
||||
new HitboxManager(new ServerHitboxResolutionCallback()),
|
||||
ServerContentManager.createServerContentManager(false, null),
|
||||
@ -77,10 +77,10 @@ public class RealmManager {
|
||||
*/
|
||||
public Realm createGriddedRealm(ServerWorldData serverWorldData, ServerContentManager serverContentManager){
|
||||
//create collision engine
|
||||
CollisionEngine collisionEngine = new CollisionEngine();
|
||||
CollisionEngine collisionEngine = new CollisionEngine("serverPhysics");
|
||||
collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
|
||||
//create chemistry engine
|
||||
CollisionEngine chemistryEngine = new CollisionEngine();
|
||||
CollisionEngine chemistryEngine = new CollisionEngine("serverChem");
|
||||
chemistryEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
|
||||
chemistryEngine.setCollisionResolutionCallback(new ServerChemistryCollisionCallback());
|
||||
//create realm
|
||||
@ -111,11 +111,11 @@ public class RealmManager {
|
||||
ServerWorldData serverWorldData = ServerWorldData.createFixedWorldData(minPoint, maxPoint);
|
||||
|
||||
//create collision engine
|
||||
CollisionEngine collisionEngine = new CollisionEngine();
|
||||
CollisionEngine collisionEngine = new CollisionEngine("serverPhysics");
|
||||
collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
|
||||
|
||||
//create chemistry engine
|
||||
CollisionEngine chemistryEngine = new CollisionEngine();
|
||||
CollisionEngine chemistryEngine = new CollisionEngine("serverChem");
|
||||
chemistryEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData));
|
||||
chemistryEngine.setCollisionResolutionCallback(new ServerChemistryCollisionCallback());
|
||||
|
||||
|
||||
@ -434,7 +434,8 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
}
|
||||
if(cell.containsPlayer(player) && !this.shouldContainPlayer(distance, playerSimulationRadius)){
|
||||
if(cell.getScene().containsEntity(player.getPlayerEntity())){
|
||||
throw new Error("Trying to remove player from a cell that contains its entity!");
|
||||
// throw new Error("Trying to remove player from a cell that contains its entity!");
|
||||
continue;
|
||||
}
|
||||
cell.removePlayer(player);
|
||||
this.broadcastDestructionToPlayer(player, cell);
|
||||
@ -566,8 +567,12 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
//don't trigger the chunk to be re-created
|
||||
Globals.profiler.beginCpuSample("GriddedDataCellManager.unloadPlayerlessChunks - Store data");
|
||||
this.loaderService.queueLocationBasedOperation(key, () -> {
|
||||
try {
|
||||
serverContentManager.saveSerializationToDisk(key, serializedEntities);
|
||||
serverTerrainManager.savePositionToDisk(worldPos);
|
||||
} catch(Throwable e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
@ -895,9 +900,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
this.loaderService.queueLocationBasedOperation(key, () -> {
|
||||
try {
|
||||
serverContentManager.generateContentForDataCell(parent, localWorldPos, rVal, cellKey);
|
||||
} catch(Error e){
|
||||
e.printStackTrace();
|
||||
} catch(Exception e){
|
||||
} catch(Throwable e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
@ -5,6 +5,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
|
||||
@ -99,8 +99,7 @@ public class CharacterUtils {
|
||||
public static Character spawnCharacter(Realm realm, Vector3d position, String race){
|
||||
Race raceData = Globals.gameConfigCurrent.getRaceMap().getRace(race);
|
||||
String creatureType = raceData.getAssociatedCreature();
|
||||
Character rVal = Globals.serverState.characterService.createCharacter(ObjectTemplate.createDefault(EntityType.CREATURE, creatureType), CharacterService.NO_PLAYER);
|
||||
rVal.setPos(position);
|
||||
Character rVal = Globals.serverState.characterService.createCharacter(ObjectTemplate.createDefault(EntityType.CREATURE, creatureType), CharacterService.NO_PLAYER, position);
|
||||
Race.setRace(rVal, Race.create(race, creatureType));
|
||||
realm.getDataCellManager().evaluateMacroObject(rVal);
|
||||
return rVal;
|
||||
|
||||
@ -30,12 +30,12 @@ public class TownPopulator {
|
||||
List<VirtualStructure> structs = town.getStructures(macroData);
|
||||
Random rand = new Random(town.getId());
|
||||
for(VirtualStructure struct : structs){
|
||||
Vector3d placePos = new Vector3d(struct.getPos()).add(1,1,1);
|
||||
ObjectTemplate template = ObjectTemplate.create(EntityType.CREATURE, "human");
|
||||
Character chara = Globals.serverState.characterService.createCharacter(template, CharacterService.NO_PLAYER);
|
||||
Character chara = Globals.serverState.characterService.createCharacter(template, CharacterService.NO_PLAYER, placePos);
|
||||
Race.setRace(chara, Globals.gameConfigCurrent.getRaceMap().getRace("human"));
|
||||
CharacterUtils.addShelter(chara, struct);
|
||||
town.addResident(chara);
|
||||
chara.setPos(new Vector3d(struct.getPos()).add(1,1,1));
|
||||
}
|
||||
|
||||
//assign jobs to created characters
|
||||
|
||||
@ -6,6 +6,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
@ -61,13 +62,15 @@ public class CharacterService extends SignalServiceImpl {
|
||||
* Creates a character in the database
|
||||
* @param template The creature template for the character
|
||||
* @param playerId The player's id
|
||||
* @param pos The position to place the character at
|
||||
*/
|
||||
public Character createCharacter(ObjectTemplate template, int playerId){
|
||||
public Character createCharacter(ObjectTemplate template, int playerId, Vector3d pos){
|
||||
if(template == null){
|
||||
throw new Error("Template is null!");
|
||||
}
|
||||
lock.lock();
|
||||
Character toStore = new Character(template);
|
||||
toStore.setPos(pos);
|
||||
toStore.setPlayerId(playerId);
|
||||
DatabaseResult result = Globals.serverState.dbController.executePreparedQuery(
|
||||
"INSERT INTO charaData (playerId,dataVal) VALUES (?,?) RETURNING id;",
|
||||
|
||||
@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
@ -165,7 +166,7 @@ public class TestEngineUtils {
|
||||
ObjectTemplate creatureTemplate = ObjectTemplate.createDefault(EntityType.CREATURE, "human");
|
||||
ServerConnectionHandler serverConnection = Globals.serverState.server.getFirstConnection();
|
||||
serverConnection.setCreatureTemplate(creatureTemplate);
|
||||
Character chara = Globals.serverState.characterService.createCharacter(creatureTemplate, serverConnection.getPlayerId());
|
||||
Character chara = Globals.serverState.characterService.createCharacter(creatureTemplate, serverConnection.getPlayerId(), new Vector3d());
|
||||
serverConnection.setCharacterId(chara.getId());
|
||||
PlayerCharacterCreation.spawnPlayerCharacter(serverConnection);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user