diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 06ba0539..60c809e0 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -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) diff --git a/src/main/java/electrosphere/client/sim/ClientSimulation.java b/src/main/java/electrosphere/client/sim/ClientSimulation.java index 5b34e963..ef0b6220 100644 --- a/src/main/java/electrosphere/client/sim/ClientSimulation.java +++ b/src/main/java/electrosphere/client/sim/ClientSimulation.java @@ -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 diff --git a/src/main/java/electrosphere/collision/CollisionBodyCreation.java b/src/main/java/electrosphere/collision/CollisionBodyCreation.java index 568d88a3..aa7b0804 100644 --- a/src/main/java/electrosphere/collision/CollisionBodyCreation.java +++ b/src/main/java/electrosphere/collision/CollisionBodyCreation.java @@ -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 diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index 41c1cb68..264ba5a4 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -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 diff --git a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java index 306f63b7..6abce99f 100644 --- a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java +++ b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java @@ -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); } /** diff --git a/src/main/java/electrosphere/collision/PhysicsUtils.java b/src/main/java/electrosphere/collision/PhysicsUtils.java index d1bba03e..24edf27c 100644 --- a/src/main/java/electrosphere/collision/PhysicsUtils.java +++ b/src/main/java/electrosphere/collision/PhysicsUtils.java @@ -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 diff --git a/src/main/java/electrosphere/collision/collidable/Collidable.java b/src/main/java/electrosphere/collision/collidable/Collidable.java index 2634b745..82ec8961 100644 --- a/src/main/java/electrosphere/collision/collidable/Collidable.java +++ b/src/main/java/electrosphere/collision/collidable/Collidable.java @@ -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 impulses = new LinkedList(); + /** + * The impulses to be applied to this collidable + */ + private List impulses = new LinkedList(); /** * 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"; diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java index fa7b0ddb..8050aedd 100644 --- a/src/main/java/electrosphere/entity/EntityDataStrings.java +++ b/src/main/java/electrosphere/entity/EntityDataStrings.java @@ -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"; diff --git a/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java b/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java index 04246d69..9a216eb3 100644 --- a/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java +++ b/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java @@ -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); diff --git a/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java index 9475a60d..f209e3aa 100644 --- a/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java +++ b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java @@ -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){