kinematic geom colliders on client
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-21 17:04:24 -04:00
parent b47503b996
commit 639fdde8fa
10 changed files with 395 additions and 193 deletions

View File

@ -1926,6 +1926,8 @@ Place buildings along roads
Fix town placement structure-road intersection test Fix town placement structure-road intersection test
(05/21/2025)
Kinematic collision templates now use geoms instead of setting kinematic (on client)

View File

@ -112,7 +112,9 @@ public class ClientSimulation {
//sum collidable impulses //sum collidable impulses
Globals.profiler.beginCpuSample("collidable logic"); Globals.profiler.beginCpuSample("collidable logic");
for(Entity collidable : Globals.clientState.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){ for(Entity collidable : Globals.clientState.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){
ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.engineState.timekeeper.getSimFrameTime()); if(ClientCollidableTree.hasClientCollidableTree(collidable)){
ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.engineState.timekeeper.getSimFrameTime());
}
} }
// //
//clear collidable impulse lists //clear collidable impulse lists

View File

@ -133,6 +133,29 @@ public class CollisionBodyCreation {
return collisionEngine.createCapsuleGeom(radius, length, categoryBits); return collisionEngine.createCapsuleGeom(radius, length, categoryBits);
} }
/**
* Creates a capsule shape
* @param collisionEngine The collision engine
* @param radius the radius of the capsule
* @param length the length of the capsule
* @param categoryBits the category bits for the shape
* @return the capsule shape
*/
public static DCapsule createCylinderShape(CollisionEngine collisionEngine, double radius, double length, long categoryBits){
return collisionEngine.createCapsuleGeom(radius, length, categoryBits);
}
/**
* Creates the cube shape
* @param collisionEngine The collision engine
* @param dimensions The dimensions of the cube
* @param categoryBits The category bits
* @return The cube shape
*/
public static DBox createCubeShape(CollisionEngine collisionEngine, Vector3d dimensions, long categoryBits){
return collisionEngine.createCubeGeom(dimensions, categoryBits);
}
/** /**
* Sets the mass on the dbody * Sets the mass on the dbody
* @param collisionEngine The collision engine * @param collisionEngine The collision engine

View File

@ -548,14 +548,25 @@ public class CollisionEngine {
if(collidable.getParentTracksCollidable()){ if(collidable.getParentTracksCollidable()){
Entity physicsEntity = collidable.getParent(); Entity physicsEntity = collidable.getParent();
DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity); DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity);
DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
Matrix4d inverseTransform = new Matrix4d(); Matrix4d inverseTransform = new Matrix4d();
Vector4d rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()).add(this.floatingOrigin),1)); Vector4d rawPos = null;
if(rigidBody != null){
rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()).add(this.floatingOrigin),1));
} else if(geom != null){
rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(geom.getPosition()).add(this.floatingOrigin),1));
}
Vector3d calculatedPosition = new Vector3d(rawPos.x,rawPos.y,rawPos.z); Vector3d calculatedPosition = new Vector3d(rawPos.x,rawPos.y,rawPos.z);
Vector3d suggestedPosition = this.suggestMovementPosition(collisionWorldData, calculatedPosition); Vector3d suggestedPosition = this.suggestMovementPosition(collisionWorldData, calculatedPosition);
if(calculatedPosition.distance(suggestedPosition) > 0){ if(calculatedPosition.distance(suggestedPosition) > 0){
collidable.addImpulse(new Impulse(new Vector3d(), new Vector3d(), new Vector3d(), 0, Collidable.TYPE_WORLD_BOUND)); collidable.addImpulse(new Impulse(new Vector3d(), new Vector3d(), new Vector3d(), 0, Collidable.TYPE_WORLD_BOUND));
} }
Quaterniond newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody); Quaterniond newRotation = null;
if(rigidBody != null){
newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody);
} else {
newRotation = PhysicsUtils.getGeomRotation(geom);
}
EntityUtils.getPosition(physicsEntity).set(suggestedPosition); EntityUtils.getPosition(physicsEntity).set(suggestedPosition);
EntityUtils.getRotation(physicsEntity).set(newRotation); EntityUtils.getRotation(physicsEntity).set(newRotation);
} }
@ -1076,13 +1087,26 @@ public class CollisionEngine {
* @param position The position * @param position The position
* @param rotation The rotation * @param rotation The rotation
*/ */
protected void setGeomTransform(DGeom geom, Vector3d position, Quaterniond rotation){ protected void setGeomOffsetTransform(DGeom geom, Vector3d position, Quaterniond rotation){
spaceLock.lock(); spaceLock.lock();
geom.setOffsetPosition(position.x, position.y, position.z); geom.setOffsetPosition(position.x, position.y, position.z);
geom.setOffsetQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation)); geom.setOffsetQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
spaceLock.unlock(); spaceLock.unlock();
} }
/**
* Sets the transform of a geometry (local to the parent)
* @param geom The geometry
* @param position The position
* @param rotation The rotation
*/
protected void setGeomTransform(DGeom geom, Vector3d position, Quaterniond rotation){
spaceLock.lock();
geom.setPosition(position.x, position.y, position.z);
geom.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
spaceLock.unlock();
}
/** /**
* Corrects the initial axis of eg cylinders or capsules * Corrects the initial axis of eg cylinders or capsules
* @param geom the geometry to correct * @param geom the geometry to correct

View File

@ -59,8 +59,10 @@ public class PhysicsEntityUtils {
*/ */
public static void clientAttachCollidableTemplate(Entity rVal, CollidableTemplate physicsTemplate){ public static void clientAttachCollidableTemplate(Entity rVal, CollidableTemplate physicsTemplate){
DBody rigidBody = null; DBody rigidBody = null;
DGeom geom = null;
Collidable collidable; Collidable collidable;
double mass = 1.0f; double mass = 1.0f;
CollisionEngine engine = Globals.clientState.clientSceneWrapper.getCollisionEngine();
if(physicsTemplate.getMass() != null){ if(physicsTemplate.getMass() != null){
mass = physicsTemplate.getMass(); mass = physicsTemplate.getMass();
} }
@ -68,203 +70,295 @@ 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: { switch(physicsTemplate.getType()){
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
// //
//create dbody //create dbody
rigidBody = CollisionBodyCreation.createCylinderBody( geom = CollisionBodyCreation.createCylinderShape(
Globals.clientState.clientSceneWrapper.getCollisionEngine(), engine,
physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setCylinderMass(
Globals.clientState.clientSceneWrapper.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(Globals.clientState.clientSceneWrapper.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
// //
//set offset from center of entity position //create collidable and link to structures
CollisionBodyCreation.setOffsetPosition( collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
Globals.clientState.clientSceneWrapper.getCollisionEngine(), PhysicsEntityUtils.setDGeom(rVal, geom);
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
// //
//create collidable and link to structures //store values
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true); Matrix4d offsetTransform = new Matrix4d().translationRotate(
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
} );
if(physicsTemplate.getRollingFriction() != null){ rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
collidable.getSurfaceParams().setRollingFriction(physicsTemplate.getRollingFriction()); rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
}
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
PhysicsEntityUtils.setDBody(rVal,rigidBody);
// Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
//store values Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
Matrix4d offsetTransform = new Matrix4d().translationRotate( } break;
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW() //rotate //
); //create dbody
if(physicsTemplate.isAngularlyStatic()){ geom = CollisionBodyCreation.createCubeShape(
Globals.clientState.clientSceneWrapper.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.CLIENT_COLLIDABLE_TREE, tree);
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
//
//create dbody
rigidBody = CollisionBodyCreation.createCubeBody(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setBoxMass(
Globals.clientState.clientSceneWrapper.getCollisionEngine(), Globals.clientState.clientSceneWrapper.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(Globals.clientState.clientSceneWrapper.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
// //
//set offset from center of entity position //create collidable and link to structures
CollisionBodyCreation.setOffsetPosition( collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
Globals.clientState.clientSceneWrapper.getCollisionEngine(), PhysicsEntityUtils.setDGeom(rVal,geom);
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
// //
//create collidable and link to structures //store values
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);
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
PhysicsEntityUtils.setDBody(rVal,rigidBody);
// Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
//store values Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
Matrix4d offsetTransform = new Matrix4d().translationRotateScale( } break;
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate //
1, 1, 1 //scale //create dbody
); geom = CollisionBodyCreation.createCapsuleShape(
if(physicsTemplate.isAngularlyStatic()){
Globals.clientState.clientSceneWrapper.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.CLIENT_COLLIDABLE_TREE, tree);
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
//
//create dbody
rigidBody = CollisionBodyCreation.createCapsuleBody(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setCapsuleMass(
Globals.clientState.clientSceneWrapper.getCollisionEngine(), Globals.clientState.clientSceneWrapper.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(Globals.clientState.clientSceneWrapper.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
// //
//set offset from center of entity position //create collidable and link to structures
CollisionBodyCreation.setOffsetPosition( collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
Globals.clientState.clientSceneWrapper.getCollisionEngine(), PhysicsEntityUtils.setDGeom(rVal,geom);
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
// //
//create collidable and link to structures //store values
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);
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
PhysicsEntityUtils.setDBody(rVal,rigidBody);
// rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
//store values
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()){
Globals.clientState.clientSceneWrapper.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.CLIENT_COLLIDABLE_TREE, tree);
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
}
} else {
switch(physicsTemplate.getType()){
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); //
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); //create dbody
} break; rigidBody = CollisionBodyCreation.createCylinderBody(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setCylinderMass(
Globals.clientState.clientSceneWrapper.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(Globals.clientState.clientSceneWrapper.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
//
//set offset from center of entity position
CollisionBodyCreation.setOffsetPosition(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
//
//create collidable and link to structures
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());
}
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
PhysicsEntityUtils.setDBody(rVal,rigidBody);
//
//store values
Matrix4d offsetTransform = new Matrix4d().translationRotate(
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW() //rotate
);
if(physicsTemplate.isAngularlyStatic()){
Globals.clientState.clientSceneWrapper.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.CLIENT_COLLIDABLE_TREE, tree);
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
//
//create dbody
rigidBody = CollisionBodyCreation.createCubeBody(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setBoxMass(
Globals.clientState.clientSceneWrapper.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(Globals.clientState.clientSceneWrapper.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
//
//set offset from center of entity position
CollisionBodyCreation.setOffsetPosition(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
//
//create collidable and link to structures
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());
}
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
PhysicsEntityUtils.setDBody(rVal,rigidBody);
//
//store values
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()){
Globals.clientState.clientSceneWrapper.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.CLIENT_COLLIDABLE_TREE, tree);
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
//
//create dbody
rigidBody = CollisionBodyCreation.createCapsuleBody(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setCapsuleMass(
Globals.clientState.clientSceneWrapper.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(Globals.clientState.clientSceneWrapper.getCollisionEngine(), rigidBody, true, LINEAR_THRESHOLD, ANGULAR_THRESHOLD, STEP_THRESHOLD);
//
//set offset from center of entity position
CollisionBodyCreation.setOffsetPosition(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
rigidBody,
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
);
//
//create collidable and link to structures
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());
}
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
PhysicsEntityUtils.setDBody(rVal,rigidBody);
//
//store values
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()){
Globals.clientState.clientSceneWrapper.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.CLIENT_COLLIDABLE_TREE, tree);
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} 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){
@ -635,13 +729,34 @@ public class PhysicsEntityUtils {
return (DBody)entity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); return (DBody)entity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
} }
/**
* Sets the static geom on the entity
* @param entity The entity
* @param geom The static geom
*/
public static void setDGeom(Entity entity, DGeom geom){
if(geom == null){
throw new Error("Trying to set null geom!");
}
entity.putData(EntityDataStrings.PHYSICS_GEOM, geom);
}
/**
* Gets the geom attached to the entity
* @param entity The entity
* @return The geom if it exists, null otherwise
*/
public static DGeom getDGeom(Entity entity){
return (DGeom)entity.getData(EntityDataStrings.PHYSICS_GEOM);
}
/** /**
* Sets the position of a DGeom * Sets the position of a DGeom
* @param collisionEngine the collision engine * @param collisionEngine the collision engine
* @param geom the geometry * @param geom the geometry
*/ */
public static void setGeometryPosition(CollisionEngine collisionEngine, DGeom geom, Vector3d position, Quaterniond rotation){ public static void setGeometryOffsetPosition(CollisionEngine collisionEngine, DGeom geom, Vector3d position, Quaterniond rotation){
collisionEngine.setGeomTransform(geom, position, rotation); collisionEngine.setGeomOffsetTransform(geom, position, rotation);
} }
/** /**

View File

@ -7,6 +7,7 @@ import org.ode4j.math.DMatrix3;
import org.ode4j.math.DQuaternion; import org.ode4j.math.DQuaternion;
import org.ode4j.math.DQuaternionC; import org.ode4j.math.DQuaternionC;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import org.ode4j.ode.DGeom;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.data.entity.collidable.CollidableTemplate; import electrosphere.data.entity.collidable.CollidableTemplate;
@ -24,6 +25,15 @@ public class PhysicsUtils {
public static Quaterniond getRigidBodyRotation(DBody body){ public static Quaterniond getRigidBodyRotation(DBody body){
return odeQuatToJomlQuat(body.getQuaternion()); return odeQuatToJomlQuat(body.getQuaternion());
} }
/**
* Gets the rotation of the geom as a joml quaternion
* @param geom The geom
* @return The rotation
*/
public static Quaterniond getGeomRotation(DGeom geom){
return odeQuatToJomlQuat(geom.getQuaternion());
}
/** /**
* Converts an Ode vector to a joml vector * Converts an Ode vector to a joml vector
@ -86,6 +96,17 @@ public class PhysicsUtils {
collisionEngine.setBodyTransform(body, position, rotation); collisionEngine.setBodyTransform(body, position, rotation);
} }
/**
* Sets the transform of a geom
* @param collisionEngine The engine
* @param position The position
* @param rotation The rotation
* @param geom The geom
*/
public static void setGeomTransform(CollisionEngine collisionEngine, Vector3d position, Quaterniond rotation, DGeom geom){
collisionEngine.setGeomTransform(geom, position, rotation);
}
/** /**
* Synchronizes the data on a body * Synchronizes the data on a body
* @param body The body * @param body The body

View File

@ -13,21 +13,30 @@ import java.util.List;
*/ */
public class Collidable { public class Collidable {
//The entity this collidable is attached to /**
Entity parent; * The entity this collidable is attached to
//The type of collidable */
String type; private Entity parent;
//If true, once impulses are applied to the collidable, have the parent entity resynchronize its position with the collidable /**
boolean parentTracksCollidable = true; * The type of collidable
*/
private String type;
/**
* If true, once impulses are applied to the collidable, have the parent entity resynchronize its position with the collidable
*/
private boolean parentTracksCollidable = true;
//The impulses to be applied to this collidable /**
List<Impulse> impulses = new LinkedList<Impulse>(); * The impulses to be applied to this collidable
*/
private List<Impulse> impulses = new LinkedList<Impulse>();
/** /**
* The params for the surface of this collidable when a collision occurs * The params for the surface of this collidable when a collision occurs
*/ */
SurfaceParams surfaceParams; private SurfaceParams surfaceParams;
//these should have corresponding category bits along with them //these should have corresponding category bits along with them
public static final String TYPE_STATIC = "static"; public static final String TYPE_STATIC = "static";

View File

@ -133,6 +133,7 @@ public class EntityDataStrings {
Physics Entity Physics Entity
*/ */
public static final String PHYSICS_COLLISION_BODY = "physicsRigidBody"; public static final String PHYSICS_COLLISION_BODY = "physicsRigidBody";
public static final String PHYSICS_GEOM = "physicsGeom";
public static final String PHYSICS_COLLISION_BODY_TRANSFORM = "physicsRigidBodyTransform"; // the transform matrix from origin of entity to origin of physics body public static final String PHYSICS_COLLISION_BODY_TRANSFORM = "physicsRigidBodyTransform"; // the transform matrix from origin of entity to origin of physics body
public static final String PHYSICS_COLLIDABLE = "physicsCollidable"; public static final String PHYSICS_COLLIDABLE = "physicsCollidable";
public static final String PHYSICS_MODEL_TEMPLATE = "physicsModelTemplate"; public static final String PHYSICS_MODEL_TEMPLATE = "physicsModelTemplate";

View File

@ -442,7 +442,7 @@ public class HitboxCollectionState {
* @param bonePosition The position of the bone * @param bonePosition The position of the bone
*/ */
private void updateStaticCapsulePosition(CollisionEngine collisionEngine, DGeom geom, HitboxState shapeStatus){ private void updateStaticCapsulePosition(CollisionEngine collisionEngine, DGeom geom, HitboxState shapeStatus){
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, new Vector3d(), new Quaterniond(0.707,0,0,0.707)); PhysicsEntityUtils.setGeometryOffsetPosition(collisionEngine, geom, new Vector3d(), new Quaterniond(0.707,0,0,0.707));
} }
/** /**
@ -474,7 +474,7 @@ public class HitboxCollectionState {
Vector3d hitboxPos = AttachUtils.calculateBoneAttachmentLocalPosition(offsetPosition, offsetRotation, bonePositionD, boneRotation, parentPosition, parentRotation, parentScale); Vector3d hitboxPos = AttachUtils.calculateBoneAttachmentLocalPosition(offsetPosition, offsetRotation, bonePositionD, boneRotation, parentPosition, parentRotation, parentScale);
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, hitboxPos, new Quaterniond()); PhysicsEntityUtils.setGeometryOffsetPosition(collisionEngine, geom, hitboxPos, new Quaterniond());
} }
/** /**
@ -549,7 +549,7 @@ public class HitboxCollectionState {
} }
geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), hitboxState.getHitboxData().getRadius(), length, Collidable.TYPE_OBJECT_BIT); geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), hitboxState.getHitboxData().getRadius(), length, Collidable.TYPE_OBJECT_BIT);
CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom); CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom);
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, bodyPosition, worldRotation); PhysicsEntityUtils.setGeometryOffsetPosition(collisionEngine, geom, bodyPosition, worldRotation);
} else { } else {
//called first time the hitbox updates position //called first time the hitbox updates position
this.destroyGeom(collisionEngine, geom); this.destroyGeom(collisionEngine, geom);

View File

@ -3,6 +3,7 @@ package electrosphere.entity.types.collision;
import org.joml.Quaterniond; import org.joml.Quaterniond;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import org.ode4j.ode.DGeom;
import electrosphere.collision.CollisionEngine; import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsEntityUtils;
@ -92,6 +93,10 @@ public class CollisionObjUtils {
if(body != null){ if(body != null){
PhysicsUtils.setRigidBodyTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), position, rotation, body); PhysicsUtils.setRigidBodyTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), position, rotation, body);
} }
DGeom geom = PhysicsEntityUtils.getDGeom(e);
if(geom != null){
PhysicsUtils.setGeomTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), position, rotation, geom);
}
} }
public static Collidable getCollidable(Entity e){ public static Collidable getCollidable(Entity e){