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
(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
Globals.profiler.beginCpuSample("collidable logic");
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

View File

@ -133,6 +133,29 @@ public class CollisionBodyCreation {
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
* @param collisionEngine The collision engine

View File

@ -548,14 +548,25 @@ public class CollisionEngine {
if(collidable.getParentTracksCollidable()){
Entity physicsEntity = collidable.getParent();
DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity);
DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
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 suggestedPosition = this.suggestMovementPosition(collisionWorldData, calculatedPosition);
if(calculatedPosition.distance(suggestedPosition) > 0){
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.getRotation(physicsEntity).set(newRotation);
}
@ -1076,13 +1087,26 @@ public class CollisionEngine {
* @param position The position
* @param rotation The rotation
*/
protected void setGeomTransform(DGeom geom, Vector3d position, Quaterniond rotation){
protected void setGeomOffsetTransform(DGeom geom, Vector3d position, Quaterniond rotation){
spaceLock.lock();
geom.setOffsetPosition(position.x, position.y, position.z);
geom.setOffsetQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
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
* @param geom the geometry to correct

View File

@ -59,8 +59,10 @@ public class PhysicsEntityUtils {
*/
public static void clientAttachCollidableTemplate(Entity rVal, CollidableTemplate physicsTemplate){
DBody rigidBody = null;
DGeom geom = null;
Collidable collidable;
double mass = 1.0f;
CollisionEngine engine = Globals.clientState.clientSceneWrapper.getCollisionEngine();
if(physicsTemplate.getMass() != null){
mass = physicsTemplate.getMass();
}
@ -68,203 +70,295 @@ public class PhysicsEntityUtils {
if(physicsTemplate.getKinematic()){
categoryBit = Collidable.TYPE_STATIC_BIT;
}
switch(physicsTemplate.getType()){
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
if(physicsTemplate.getKinematic()){
switch(physicsTemplate.getType()){
case CollidableTemplate.COLLIDABLE_TYPE_CYLINDER: {
//
//create dbody
rigidBody = CollisionBodyCreation.createCylinderBody(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(),
categoryBit
);
if(physicsTemplate.getMass() != null){
CollisionBodyCreation.setCylinderMass(
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
rigidBody,
mass,
//
//create dbody
geom = CollisionBodyCreation.createCylinderShape(
engine,
physicsTemplate.getDimension1(),
physicsTemplate.getDimension2(),
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()),
new Quaterniond(physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW())
categoryBit
);
}
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);
PhysicsEntityUtils.setDGeom(rVal, geom);
//
//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
);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
//
//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().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
//
//create dbody
geom = CollisionBodyCreation.createCubeShape(
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())
categoryBit
);
}
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);
PhysicsEntityUtils.setDGeom(rVal,geom);
//
//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
);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
//
//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().registerCollisionObject(rigidBody, collidable);
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
//
//create dbody
geom = CollisionBodyCreation.createCapsuleShape(
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())
categoryBit
);
}
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);
PhysicsEntityUtils.setDGeom(rVal,geom);
//
//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
);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
//
//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);
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);
} break;
//
//create dbody
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(rigidBody != null){
@ -635,13 +729,34 @@ public class PhysicsEntityUtils {
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
* @param collisionEngine the collision engine
* @param geom the geometry
*/
public static void setGeometryPosition(CollisionEngine collisionEngine, DGeom geom, Vector3d position, Quaterniond rotation){
collisionEngine.setGeomTransform(geom, position, rotation);
public static void setGeometryOffsetPosition(CollisionEngine collisionEngine, DGeom geom, Vector3d position, Quaterniond 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.DQuaternionC;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DGeom;
import electrosphere.collision.collidable.Collidable;
import electrosphere.data.entity.collidable.CollidableTemplate;
@ -24,6 +25,15 @@ public class PhysicsUtils {
public static Quaterniond getRigidBodyRotation(DBody body){
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
@ -86,6 +96,17 @@ public class PhysicsUtils {
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
* @param body The body

View File

@ -13,21 +13,30 @@ import java.util.List;
*/
public class Collidable {
//The entity this collidable is attached to
Entity parent;
//The type of collidable
String type;
/**
* The entity this collidable is attached to
*/
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
*/
SurfaceParams surfaceParams;
private SurfaceParams surfaceParams;
//these should have corresponding category bits along with them
public static final String TYPE_STATIC = "static";

View File

@ -133,6 +133,7 @@ public class EntityDataStrings {
Physics Entity
*/
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_COLLIDABLE = "physicsCollidable";
public static final String PHYSICS_MODEL_TEMPLATE = "physicsModelTemplate";

View File

@ -442,7 +442,7 @@ public class HitboxCollectionState {
* @param bonePosition The position of the bone
*/
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);
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);
CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom);
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, bodyPosition, worldRotation);
PhysicsEntityUtils.setGeometryOffsetPosition(collisionEngine, geom, bodyPosition, worldRotation);
} else {
//called first time the hitbox updates position
this.destroyGeom(collisionEngine, geom);

View File

@ -3,6 +3,7 @@ package electrosphere.entity.types.collision;
import org.joml.Quaterniond;
import org.joml.Vector3d;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DGeom;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsEntityUtils;
@ -92,6 +93,10 @@ public class CollisionObjUtils {
if(body != null){
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){