server-side geom colliders
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-21 18:52:41 -04:00
parent 639fdde8fa
commit cbd5c98e0a
6 changed files with 470 additions and 237 deletions

View File

@ -1928,6 +1928,7 @@ Fix town placement structure-road intersection test
(05/21/2025) (05/21/2025)
Kinematic collision templates now use geoms instead of setting kinematic (on client) Kinematic collision templates now use geoms instead of setting kinematic (on client)
Geom-only collidables on server

View File

@ -25,6 +25,7 @@ import org.ode4j.ode.DGeom.DNearCallback;
import org.ode4j.ode.DJoint; import org.ode4j.ode.DJoint;
import org.ode4j.ode.DJointGroup; import org.ode4j.ode.DJointGroup;
import org.ode4j.ode.DMass; import org.ode4j.ode.DMass;
import org.ode4j.ode.DPlane;
import org.ode4j.ode.DRay; import org.ode4j.ode.DRay;
import org.ode4j.ode.DSpace; import org.ode4j.ode.DSpace;
import org.ode4j.ode.DSphere; import org.ode4j.ode.DSphere;
@ -94,16 +95,31 @@ public class CollisionEngine {
*/ */
public static final double DEFAULT_INTERACT_DISTANCE = 5.0; public static final double DEFAULT_INTERACT_DISTANCE = 5.0;
//world data that the collision engine leverages for position correction and the like /**
CollisionWorldData collisionWorldData; * world data that the collision engine leverages for position correction and the like
*/
private CollisionWorldData collisionWorldData;
//Ode-specific stuff /**
* The world object
*/
private DWorld world; private DWorld world;
/**
* The main space in the world
*/
private DSpace space; private DSpace space;
/**
* Lock for thread-safeing all ODE calls
*/
private static ReentrantLock spaceLock = new ReentrantLock(); private static ReentrantLock spaceLock = new ReentrantLock();
/**
* The contact group for caching collisions between collision and physics calls
*/
private DJointGroup contactgroup; private DJointGroup contactgroup;
// maximum number of contact points per body
/** /**
* <p> Maximum number of contact points per body </p> * <p> Maximum number of contact points per body </p>
* <p><b> Note: </b></p> * <p><b> Note: </b></p>
@ -114,38 +130,57 @@ public class CollisionEngine {
*/ */
private static final int MAX_CONTACTS = 64; private static final int MAX_CONTACTS = 64;
//The list of dbodies ode should be tracking /**
List<DBody> bodies = new ArrayList<DBody>(); * The list of dbodies ode should be tracking
*/
private List<DBody> bodies = new ArrayList<DBody>();
//This is used to relate DBody's back to their collidables so that when the library detects a collision, the callback can know which collidables are involved. /**
Map<DBody,Collidable> bodyPointerMap = new HashMap<DBody,Collidable>(); * This is used to relate DBody's back to their collidables so that when the library detects a collision, the callback can know which collidables are involved.
*/
private Map<DBody,Collidable> bodyPointerMap = new HashMap<DBody,Collidable>();
//The list of all collidables the engine is currently tracking /**
List<Collidable> collidableList = new ArrayList<Collidable>(); * This is used to relate DGeom's back to their collidables so that when the library detects a collision, the callback can know which collidables are involved.
*/
private Map<DGeom,Collidable> geomPointerMap = new HashMap<DGeom,Collidable>();
/**
* The list of all collidables the engine is currently tracking
*/
private List<Collidable> collidableList = new ArrayList<Collidable>();
/** /**
* Dynamic spatial offset applied to all operations on the space. * Dynamic spatial offset applied to all operations on the space.
* This is used for world origin rebasing. * This is used for world origin rebasing.
* This makes physics behave more consistently by moving far out objects to center around 0,0,0. * This makes physics behave more consistently by moving far out objects to center around 0,0,0.
*/ */
Vector3d floatingOrigin = new Vector3d(0,0,0); private Vector3d floatingOrigin = new Vector3d(0,0,0);
//callbacks for collision check /**
RayCastCallback rayCastCallback = new RayCastCallback(); * callbacks for collision check
*/
private RayCastCallback rayCastCallback = new RayCastCallback();
//the collision resolution callback /**
CollisionResolutionCallback collisionResolutionCallback; * the collision resolution callback
*/
//buffer for collisions private CollisionResolutionCallback collisionResolutionCallback;
DContactBuffer contacts = null;
/** /**
* The body that contains all static shapes * The body that contains all static shapes
*/ */
DBody staticBody; private DBody staticBody;
// Callback for any near collisions in the broadphase of the collision check /**
* Callback for any near collisions in the broadphase of the collision check
*/
private DNearCallback nearCallback; private DNearCallback nearCallback;
/**
* The base plane of the physics engine
*/
private DPlane basePlane = null;
/** /**
* Constructor * Constructor
@ -160,7 +195,7 @@ public class CollisionEngine {
// world.setCFM(1e-10); // world.setCFM(1e-10);
//base plane //base plane
OdeHelper.createPlane(space, 0, 1, 0, 0); basePlane = OdeHelper.createPlane(space, 0, 1, 0, 0);
//static body //static body
staticBody = this.createDBody(); staticBody = this.createDBody();
@ -271,6 +306,9 @@ public class CollisionEngine {
public void simulatePhysics(float time){ public void simulatePhysics(float time){
Globals.profiler.beginCpuSample("physics"); Globals.profiler.beginCpuSample("physics");
spaceLock.lock(); spaceLock.lock();
// remove all contact joints
contactgroup.empty();
//main simulation
for(int i = 0; i < PHYSICS_SIMULATION_RESOLUTION; i++){ for(int i = 0; i < PHYSICS_SIMULATION_RESOLUTION; i++){
Globals.profiler.beginCpuSample("collide"); Globals.profiler.beginCpuSample("collide");
OdeHelper.spaceCollide(space, 0, nearCallback); OdeHelper.spaceCollide(space, 0, nearCallback);
@ -295,6 +333,7 @@ public class CollisionEngine {
public void collide(){ public void collide(){
Globals.profiler.beginCpuSample("physics"); Globals.profiler.beginCpuSample("physics");
spaceLock.lock(); spaceLock.lock();
contactgroup.empty();
Globals.profiler.beginCpuSample("collide"); Globals.profiler.beginCpuSample("collide");
OdeHelper.spaceCollide(space, 0, nearCallback); OdeHelper.spaceCollide(space, 0, nearCallback);
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
@ -336,19 +375,52 @@ public class CollisionEngine {
} }
//if collision is between static and disabled, skip //if collision is between static and disabled, skip
if(o1.getCategoryBits() == Collidable.TYPE_STATIC_BIT && !b2.isEnabled()){ if(o1.getCategoryBits() == Collidable.TYPE_STATIC_BIT && b2 != null && !b2.isEnabled()){
return; return;
} }
if(o2.getCategoryBits() == Collidable.TYPE_STATIC_BIT && !b1.isEnabled()){ if(o2.getCategoryBits() == Collidable.TYPE_STATIC_BIT && b1 != null && !b1.isEnabled()){
return; return;
} }
Collidable c1 = bodyPointerMap.get(b1); //check if we're colliding against the base plane
Collidable c2 = bodyPointerMap.get(b2); if(o1 == this.basePlane || o2 == this.basePlane){
if(c1 == null || c2 == null){
return; return;
} }
//get the collidables for each geom
Collidable c1 = null;
if(b1 != null){
c1 = bodyPointerMap.get(b1);
} else if(o1.getBody() == null) {
c1 = geomPointerMap.get(o1);
}
Collidable c2 = null;
if(b2 != null){
c2 = bodyPointerMap.get(b2);
} else if(o2.getBody() == null) {
c2 = geomPointerMap.get(o2);
}
//make sure we have collidables for both
if(c1 == null || c2 == null){
String message = "Collidable is undefined!\n" +
o1 + " \n" +
o2 + " \n" +
b1 + " \n" +
b2 + " \n" +
c1 + " \n" +
c2 + " \n" +
"Obj 1 pointers:\n" +
this.bodyPointerMap.get(b1) + " \n" +
this.geomPointerMap.get(o1) + " \n" +
"Obj 2 pointers:\n" +
this.bodyPointerMap.get(b2) + " \n" +
this.geomPointerMap.get(o2) + " \n" +
""
;
throw new Error(message);
}
Globals.profiler.beginAggregateCpuSample("CollisionEngine.nearCallback - try collisions"); Globals.profiler.beginAggregateCpuSample("CollisionEngine.nearCallback - try collisions");
try { try {
//creates a buffer to store potential collisions //creates a buffer to store potential collisions
@ -415,14 +487,20 @@ public class CollisionEngine {
// //
//add contact to contact group //add contact to contact group
DJoint c = OdeHelper.createContactJoint(world,contactgroup,contact); DJoint c = OdeHelper.createContactJoint(world,contactgroup,contact);
c.attach(b1,b2); if(b1 == null){
c.attach(b2,null);
} else if(b2 == null){
c.attach(b1,null);
} else {
c.attach(b1,b2);
}
// Use the default collision resolution // Use the default collision resolution
if(collisionResolutionCallback == null) { if(collisionResolutionCallback == null) {
CollisionEngine.resolveCollision( CollisionEngine.resolveCollision(
contact.geom, contact.geom,
bodyPointerMap.get(o1.getBody()), c1,
bodyPointerMap.get(o2.getBody()), c2,
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0), PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0), PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
PhysicsUtils.odeVecToJomlVec(contact.geom.pos), PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
@ -430,8 +508,8 @@ public class CollisionEngine {
); );
CollisionEngine.resolveCollision( CollisionEngine.resolveCollision(
contact.geom, contact.geom,
bodyPointerMap.get(o2.getBody()), c1,
bodyPointerMap.get(o1.getBody()), c2,
PhysicsUtils.odeVecToJomlVec(contact.geom.normal), PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
PhysicsUtils.odeVecToJomlVec(contact.fdir1), PhysicsUtils.odeVecToJomlVec(contact.fdir1),
PhysicsUtils.odeVecToJomlVec(contact.geom.pos), PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
@ -443,8 +521,8 @@ public class CollisionEngine {
contact.geom, contact.geom,
o1, o1,
o2, o2,
bodyPointerMap.get(o1.getBody()), c1,
bodyPointerMap.get(o2.getBody()), c2,
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0), PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0), PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
PhysicsUtils.odeVecToJomlVec(contact.geom.pos), PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
@ -454,8 +532,8 @@ public class CollisionEngine {
contact.geom, contact.geom,
o2, o2,
o1, o1,
bodyPointerMap.get(o2.getBody()), c2,
bodyPointerMap.get(o1.getBody()), c1,
PhysicsUtils.odeVecToJomlVec(contact.geom.normal), PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
PhysicsUtils.odeVecToJomlVec(contact.fdir1), PhysicsUtils.odeVecToJomlVec(contact.fdir1),
PhysicsUtils.odeVecToJomlVec(contact.geom.pos), PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
@ -566,6 +644,14 @@ public class CollisionEngine {
newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody); newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody);
} else { } else {
newRotation = PhysicsUtils.getGeomRotation(geom); newRotation = PhysicsUtils.getGeomRotation(geom);
if(geom instanceof DCylinder || geom instanceof DCapsule){
newRotation.rotateX(-Math.PI/2.0);
}
}
if(geom != null){
CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(physicsEntity);
suggestedPosition.sub(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ());
newRotation.mul(new Quaterniond(template.getRotX(),template.getRotY(),template.getRotZ(),template.getRotW()).invert());
} }
EntityUtils.getPosition(physicsEntity).set(suggestedPosition); EntityUtils.getPosition(physicsEntity).set(suggestedPosition);
EntityUtils.getRotation(physicsEntity).set(newRotation); EntityUtils.getRotation(physicsEntity).set(newRotation);
@ -612,6 +698,11 @@ public class CollisionEngine {
Vector3d existingPosition = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()); Vector3d existingPosition = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition());
rigidBody.setPosition(PhysicsUtils.jomlVecToOdeVec(existingPosition.add(delta))); rigidBody.setPosition(PhysicsUtils.jomlVecToOdeVec(existingPosition.add(delta)));
} }
DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
if(geom != null){
Vector3d existingPosition = PhysicsUtils.odeVecToJomlVec(geom.getPosition());
geom.setPosition(PhysicsUtils.jomlVecToOdeVec(existingPosition.add(delta)));
}
} }
} }
spaceLock.unlock(); spaceLock.unlock();
@ -624,6 +715,9 @@ public class CollisionEngine {
* @param collidable The corresponding collidable * @param collidable The corresponding collidable
*/ */
public void registerCollisionObject(DBody body, Collidable collidable){ public void registerCollisionObject(DBody body, Collidable collidable){
if(collidable == null){
throw new Error("Collidable is null!");
}
spaceLock.lock(); spaceLock.lock();
this.registerPhysicsObject(body); this.registerPhysicsObject(body);
bodyPointerMap.put(body,collidable); bodyPointerMap.put(body,collidable);
@ -631,6 +725,21 @@ public class CollisionEngine {
spaceLock.unlock(); spaceLock.unlock();
} }
/**
* Registers a collision object with the server
* @param geom The geom
* @param collidable The corresponding collidable
*/
public void registerCollisionObject(DGeom geom, Collidable collidable){
if(collidable == null){
throw new Error("Collidable is null!");
}
spaceLock.lock();
geomPointerMap.put(geom,collidable);
collidableList.add(collidable);
spaceLock.unlock();
}
/** /**
* Deregisters a collidable from the physics engine * Deregisters a collidable from the physics engine
* @param collidable The collidable * @param collidable The collidable
@ -765,7 +874,6 @@ public class CollisionEngine {
while(geomIterator.hasNext()){ while(geomIterator.hasNext()){
DGeom geom = geomIterator.next(); DGeom geom = geomIterator.next();
space.remove(geom); space.remove(geom);
geom.DESTRUCTOR();
geom.destroy(); geom.destroy();
} }
//destroy all joints //destroy all joints
@ -1102,8 +1210,12 @@ public class CollisionEngine {
*/ */
protected void setGeomTransform(DGeom geom, Vector3d position, Quaterniond rotation){ protected void setGeomTransform(DGeom geom, Vector3d position, Quaterniond rotation){
spaceLock.lock(); spaceLock.lock();
geom.setPosition(position.x, position.y, position.z); geom.setPosition(position.x - this.floatingOrigin.x, position.y - this.floatingOrigin.y, position.z - this.floatingOrigin.z);
geom.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation)); if(geom instanceof DCylinder || geom instanceof DCapsule){
geom.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(new Quaterniond(rotation).rotateX(Math.PI/2.0)));
} else {
geom.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
}
spaceLock.unlock(); spaceLock.unlock();
} }

View File

@ -58,8 +58,6 @@ public class PhysicsEntityUtils {
* @param physicsTemplate The collidable template * @param physicsTemplate The collidable template
*/ */
public static void clientAttachCollidableTemplate(Entity rVal, CollidableTemplate physicsTemplate){ public static void clientAttachCollidableTemplate(Entity rVal, CollidableTemplate physicsTemplate){
DBody rigidBody = null;
DGeom geom = null;
Collidable collidable; Collidable collidable;
double mass = 1.0f; double mass = 1.0f;
CollisionEngine engine = Globals.clientState.clientSceneWrapper.getCollisionEngine(); CollisionEngine engine = Globals.clientState.clientSceneWrapper.getCollisionEngine();
@ -71,6 +69,7 @@ public class PhysicsEntityUtils {
categoryBit = Collidable.TYPE_STATIC_BIT; categoryBit = Collidable.TYPE_STATIC_BIT;
} }
if(physicsTemplate.getKinematic()){ if(physicsTemplate.getKinematic()){
DGeom geom = null;
switch(physicsTemplate.getType()){ switch(physicsTemplate.getType()){
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: { case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
@ -97,8 +96,8 @@ public class PhysicsEntityUtils {
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
engine.registerCollisionObject(geom, collidable);
} break; } break;
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: { case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
// //
@ -125,8 +124,8 @@ public class PhysicsEntityUtils {
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
engine.registerCollisionObject(geom, collidable);
} break; } break;
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: { case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
// //
@ -156,11 +155,12 @@ public class PhysicsEntityUtils {
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
engine.registerCollisionObject(geom, collidable);
} break; } break;
} }
} else { } else {
DBody rigidBody = null;
switch(physicsTemplate.getType()){ switch(physicsTemplate.getType()){
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: { case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
@ -359,10 +359,10 @@ public class PhysicsEntityUtils {
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break; } break;
} }
} //if we successfully attached the body, add a sync tree
//if we successfully attached the body, add a sync tree if(rigidBody != null){
if(rigidBody != null){ ClientPhysicsSyncTree.attachTree(rVal);
ClientPhysicsSyncTree.attachTree(rVal); }
} }
} }
@ -374,7 +374,6 @@ public class PhysicsEntityUtils {
* @param physicsTemplate The collidable template * @param physicsTemplate The collidable template
*/ */
public static void serverAttachCollidableTemplate(Realm realm, Entity rVal, CollidableTemplate physicsTemplate){ public static void serverAttachCollidableTemplate(Realm realm, Entity rVal, CollidableTemplate physicsTemplate){
DBody rigidBody = null;
Collidable collidable; Collidable collidable;
double mass = 1.0f; double mass = 1.0f;
if(physicsTemplate.getMass() != null){ if(physicsTemplate.getMass() != null){
@ -384,208 +383,308 @@ public class PhysicsEntityUtils {
if(physicsTemplate.getKinematic()){ if(physicsTemplate.getKinematic()){
categoryBit = Collidable.TYPE_STATIC_BIT; categoryBit = Collidable.TYPE_STATIC_BIT;
} }
switch(physicsTemplate.getType()){ if(physicsTemplate.getKinematic()){
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: { DGeom geom = null;
switch(physicsTemplate.getType()){
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
// //
//create dbody //create dbody
rigidBody = CollisionBodyCreation.createCylinderBody( geom = CollisionBodyCreation.createCylinderShape(
realm.getCollisionEngine(),
physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setCylinderMass(
realm.getCollisionEngine(), realm.getCollisionEngine(),
rigidBody,
mass,
physicsTemplate.getDimension1(), physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(), physicsTemplate.getDimension2(),
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()), categoryBit
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 //create collidable and attach tracking
CollisionBodyCreation.setOffsetPosition( collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
realm.getCollisionEngine(), PhysicsEntityUtils.setDGeom(rVal, geom);
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
// //
//create collidable and attach tracking //store data
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true); Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
if(physicsTemplate.getLinearFriction() != null){ physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
collidable.getSurfaceParams().setLinearFriction(physicsTemplate.getLinearFriction()); physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
} 1, 1, 1 //scale
if(physicsTemplate.getRollingFriction() != null){ );
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction()); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
} rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
PhysicsEntityUtils.setDBody(rVal,rigidBody);
// rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//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); ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
realm.getCollisionEngine().registerCollisionObject(geom, collidable);
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); } break;
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
} break; //
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: { //create dbody
// geom = CollisionBodyCreation.createCubeShape(
//create dbody
rigidBody = CollisionBodyCreation.createCubeBody(
realm.getCollisionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setBoxMass(
realm.getCollisionEngine(), realm.getCollisionEngine(),
rigidBody,
mass,
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()), new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()), categoryBit
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 //create collidable and attach tracking
CollisionBodyCreation.setOffsetPosition( collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
realm.getCollisionEngine(), PhysicsEntityUtils.setDGeom(rVal, geom);
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
// //
//create collidable and attach tracking //store data
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true); Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
if(physicsTemplate.getLinearFriction() != null){ physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
collidable.getSurfaceParams().setLinearFriction(physicsTemplate.getLinearFriction()); physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
} 1, 1, 1 //scale
if(physicsTemplate.getRollingFriction() != null){ );
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction()); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
} rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
PhysicsEntityUtils.setDBody(rVal,rigidBody);
// rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//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); ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
realm.getCollisionEngine().registerCollisionObject(geom, collidable);
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); } break;
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
} break; //
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: { //create dbody
// geom = CollisionBodyCreation.createCapsuleShape(
//create dbody
rigidBody = CollisionBodyCreation.createCapsuleBody(
realm.getCollisionEngine(),
physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setCapsuleMass(
realm.getCollisionEngine(), realm.getCollisionEngine(),
rigidBody,
mass,
physicsTemplate.getDimension1(), physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(), physicsTemplate.getDimension2(),
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()), categoryBit
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 //create collidable and attach tracking
CollisionBodyCreation.setOffsetPosition( collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
realm.getCollisionEngine(), PhysicsEntityUtils.setDGeom(rVal, geom);
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
// //
//create collidable and attach tracking //store data
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true); Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
if(physicsTemplate.getLinearFriction() != null){ physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
collidable.getSurfaceParams().setLinearFriction(physicsTemplate.getLinearFriction()); physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
} 1, 1, 1 //scale
if(physicsTemplate.getRollingFriction() != null){ );
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction()); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
} rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
PhysicsEntityUtils.setDBody(rVal,rigidBody);
// rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//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); ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
realm.getCollisionEngine().registerCollisionObject(geom, collidable);
} break;
}
} else {
DBody rigidBody = null;
switch(physicsTemplate.getType()){
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); //
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); //create dbody
} break; rigidBody = CollisionBodyCreation.createCylinderBody(
} realm.getCollisionEngine(),
//if we successfully attached the body, add a sync tree physicsTemplate.getDimension1(),
if(rigidBody != null){ physicsTemplate.getDimension2(),
ServerPhysicsSyncTree.attachTree(rVal); 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);
}
} }
} }

View File

@ -9,6 +9,7 @@ import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.data.entity.collidable.CollidableTemplate;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
@ -75,10 +76,20 @@ public class CollisionObjUtils {
EntityUtils.getPosition(e).set(position); EntityUtils.getPosition(e).set(position);
Quaterniond rotation = EntityUtils.getRotation(e); Quaterniond rotation = EntityUtils.getRotation(e);
DBody body = PhysicsEntityUtils.getDBody(e); DBody body = PhysicsEntityUtils.getDBody(e);
DGeom geom = PhysicsEntityUtils.getDGeom(e);
CollisionEngine collisionEngine = Globals.serverState.realmManager.getEntityRealm(e).getCollisionEngine(); CollisionEngine collisionEngine = Globals.serverState.realmManager.getEntityRealm(e).getCollisionEngine();
if(body != null){ if(body != null){
PhysicsUtils.setRigidBodyTransform(collisionEngine, position, rotation, body); PhysicsUtils.setRigidBodyTransform(collisionEngine, position, rotation, body);
} }
if(geom != null){
CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(e);
PhysicsUtils.setGeomTransform(
collisionEngine,
new Vector3d(position).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()),
rotation,
geom
);
}
} }
/** /**
@ -95,7 +106,13 @@ public class CollisionObjUtils {
} }
DGeom geom = PhysicsEntityUtils.getDGeom(e); DGeom geom = PhysicsEntityUtils.getDGeom(e);
if(geom != null){ if(geom != null){
PhysicsUtils.setGeomTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), position, rotation, geom); CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(e);
PhysicsUtils.setGeomTransform(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
new Vector3d(position).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()),
rotation,
geom
);
} }
} }

View File

@ -33,43 +33,45 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
//basic error checking //basic error checking
if(impactorEntity == null){ if(impactorEntity == null){
throw new IllegalStateException("Impactor's entity is null"); throw new Error("Impactor's entity is null");
} }
if(receiverEntity == null){ if(receiverEntity == null){
throw new IllegalStateException("Receiver's entity is null"); throw new Error("Receiver's entity is null");
} }
if(!HitboxCollectionState.hasHitboxState(impactorEntity)){ if(!HitboxCollectionState.hasHitboxState(impactorEntity)){
throw new IllegalStateException("Impactor state is null"); throw new Error("Impactor state is null");
} }
if(!HitboxCollectionState.hasHitboxState(receiverEntity)){ if(!HitboxCollectionState.hasHitboxState(receiverEntity)){
throw new IllegalStateException("Receiver state is null"); throw new Error("Receiver state is null");
} }
if(impactorGeom == null){ if(impactorGeom == null){
throw new IllegalStateException("Impactor geom is null"); throw new Error("Impactor geom is null");
} }
if(receiverGeom == null){ if(receiverGeom == null){
throw new IllegalStateException("Receiver geom is null"); throw new Error("Receiver geom is null");
} }
if(!impactorState.getGeometries().contains(impactorGeom)){ if(!impactorState.getGeometries().contains(impactorGeom)){
boolean receiverStateContainsGeom = receiverState.getGeometries().contains(impactorGeom);
String message = "Impactor geom has wrong parent assigned!\n" + String message = "Impactor geom has wrong parent assigned!\n" +
"Problem geom: " + impactorGeom + "\n" + "Problem geom: " + impactorGeom + "\n" +
"All geometries tracked: " + impactorState.getGeometries() + "n\"" "All geometries tracked: " + impactorState.getGeometries() + "\n" +
"Receiver contains impactor: " + receiverStateContainsGeom + "\n"
; ;
throw new IllegalStateException(message); throw new Error(message);
} }
if(impactorShapeStatus == null){ if(impactorShapeStatus == null){
String message = "Impactor shape status is null\n" + String message = "Impactor shape status is null\n" +
"Problem geom: " + impactorGeom + "\n" + "Problem geom: " + impactorGeom + "\n" +
"All geometries tracked: " + impactorState.getGeometries() + "n\"" "All geometries tracked: " + impactorState.getGeometries() + "n\""
; ;
throw new IllegalStateException(message); throw new Error(message);
} }
if(receiverShapeStatus == null){ if(receiverShapeStatus == null){
String message = "Receiver shape status is null\n" + String message = "Receiver shape status is null\n" +
"Problem geom: " + receiverGeom + "\n" + "Problem geom: " + receiverGeom + "\n" +
"All geometries tracked: " + receiverState.getGeometries() + "n\"" "All geometries tracked: " + receiverState.getGeometries() + "n\""
; ;
throw new IllegalStateException(message); throw new Error(message);
} }

View File

@ -64,7 +64,9 @@ public class MicroSimulation {
//sum collidable impulses //sum collidable impulses
Set<Entity> collidables = dataCell.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE); Set<Entity> collidables = dataCell.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE);
for(Entity collidable : collidables){ for(Entity collidable : collidables){
ServerCollidableTree.getServerCollidableTree(collidable).simulate((float)Globals.engineState.timekeeper.getSimFrameTime()); if(ServerCollidableTree.hasServerCollidableTree(collidable)){
ServerCollidableTree.getServerCollidableTree(collidable).simulate((float)Globals.engineState.timekeeper.getSimFrameTime());
}
} }
//update actor transform caches //update actor transform caches
poseableEntities = dataCell.getScene().getEntitiesWithTag(EntityTags.POSEABLE); poseableEntities = dataCell.getScene().getEntitiesWithTag(EntityTags.POSEABLE);