diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index 42e1aaa9..7085227b 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -127,8 +127,8 @@ "movementSystems" : [ { "type" : "GROUND", - "acceleration" : 100.0, - "maxVelocity" : 3.5, + "acceleration" : 5000.0, + "maxVelocity" : 500.5, "animationStartup" : { "name" : "Jog", "length" : 1, @@ -161,8 +161,8 @@ }, { "type" : "JUMP", - "jumpFrames" : 30, - "jumpForce" : 0.05, + "jumpFrames" : 3, + "jumpForce" : 1000, "animationJump" : { "name" : "Jump", "length" : 1, @@ -274,7 +274,7 @@ "rotZ": 0, "rotW": 1, "offsetX" : 0, - "offsetY" : 0.45, + "offsetY" : 0.4, "offsetZ" : 0 }, "attackMoves" : [ diff --git a/buildNumber.properties b/buildNumber.properties index 1ae05278..3887b797 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Thu Mar 21 19:58:26 EDT 2024 -buildNumber=79 +#Sat Mar 23 16:53:49 EDT 2024 +buildNumber=80 diff --git a/docs/src/highlevel-design/economics/economicsindex.md b/docs/src/highlevel-design/economics/economicsindex.md new file mode 100644 index 00000000..607d3d54 --- /dev/null +++ b/docs/src/highlevel-design/economics/economicsindex.md @@ -0,0 +1,6 @@ +@page economicsindex Economics + +[TOC] +- @subpage merchantguilds +- @subpage ports + diff --git a/docs/src/highlevel-design/economics/merchantguilds.md b/docs/src/highlevel-design/economics/merchantguilds.md new file mode 100644 index 00000000..49a68e96 --- /dev/null +++ b/docs/src/highlevel-design/economics/merchantguilds.md @@ -0,0 +1,8 @@ +@page merchantguilds Merchant Guilds + +What function do they provide? + +How are they physically represented? + +Where do you go to start one? + diff --git a/docs/src/highlevel-design/economics/ports.md b/docs/src/highlevel-design/economics/ports.md new file mode 100644 index 00000000..64a156f1 --- /dev/null +++ b/docs/src/highlevel-design/economics/ports.md @@ -0,0 +1,10 @@ +@page ports Ports + +Buying boats + +Selling boats + +Queueing shipping voyages + +Portmaster's Building + diff --git a/docs/src/highlevel-design/highleveldesignindex.md b/docs/src/highlevel-design/highleveldesignindex.md index 82ed8deb..3d4875c2 100644 --- a/docs/src/highlevel-design/highleveldesignindex.md +++ b/docs/src/highlevel-design/highleveldesignindex.md @@ -14,4 +14,6 @@ Discussion of, at a high game-design level, how everything should work and conne - @subpage itemsindex - @subpage puzzleindex - @subpage fluidindex -- @subpage locomotion \ No newline at end of file +- @subpage locomotion +- @subpage economicsindex +- @subpage structuresandbuildings \ No newline at end of file diff --git a/docs/src/highlevel-design/locations/biomeideas.md b/docs/src/highlevel-design/locations/biomeideas.md index 784eb79b..f2473b82 100644 --- a/docs/src/highlevel-design/locations/biomeideas.md +++ b/docs/src/highlevel-design/locations/biomeideas.md @@ -21,6 +21,7 @@ - Overgrown (dense) - Mushroom - Jungle + - Giant Frozen Taiga (supermassive snow covered pine trees, snow permanently on ground) ## Rolling Hills diff --git a/docs/src/highlevel-design/locations/biomesindex.md b/docs/src/highlevel-design/locations/biomesindex.md index 64caf8b1..a5b9ca76 100644 --- a/docs/src/highlevel-design/locations/biomesindex.md +++ b/docs/src/highlevel-design/locations/biomesindex.md @@ -3,4 +3,5 @@ [TOC] - @subpage biomeideas - @subpage largelocationideas - - @subpage macrolocationideas \ No newline at end of file + - @subpage macrolocationideas + - @subpage smalllocations \ No newline at end of file diff --git a/docs/src/highlevel-design/locations/smalllocations.md b/docs/src/highlevel-design/locations/smalllocations.md new file mode 100644 index 00000000..bca6f0d8 --- /dev/null +++ b/docs/src/highlevel-design/locations/smalllocations.md @@ -0,0 +1,42 @@ +@page smalllocations Small Locations + +Little locations to provide immediate points of interest for the player to spring between + +## Puzzle teleporters + +## Shrines, torii, etc + - Churches, monestaries, etc that provide resting places for traveleers + - Taverns + +## Outposts, Observation Posts + +## Bandit Camps + +## Small cave networks + +## Grottos + +## Plant bundles/collection points +Berry bushes +Clusters of ferns +Fruit trees + +## Wild animal packs +Herds like cows, deer, horses +Communal hunters like wolves +Solitary animals like bears + +## Ore veins + +## Mazes full of minotaur + +## Crypts + +## Ruins + +## Obelisks + +## Magical Anomalies + +## Natural crafting stations + diff --git a/docs/src/highlevel-design/macrosimulation/macrosimtimeline.md b/docs/src/highlevel-design/macrosimulation/macrosimtimeline.md index 4dca7e4c..d8ef3721 100644 --- a/docs/src/highlevel-design/macrosimulation/macrosimtimeline.md +++ b/docs/src/highlevel-design/macrosimulation/macrosimtimeline.md @@ -1,8 +1,10 @@ @page macrosimtimeline Macro Simulation Timeline +## Origins + ## Age of Gods -## First Interregnum +## Interregnum ## Age of Exploration diff --git a/docs/src/highlevel-design/puzzles/puzzleideas.md b/docs/src/highlevel-design/puzzles/puzzleideas.md index c10b7a74..556700f6 100644 --- a/docs/src/highlevel-design/puzzles/puzzleideas.md +++ b/docs/src/highlevel-design/puzzles/puzzleideas.md @@ -8,4 +8,9 @@ Use spring to launch object into target Correctly ordering blocks to press a button -Maze that uses teleportation spell to confuse in three dimensions \ No newline at end of file +Maze that uses teleportation spell to confuse in three dimensions + +Maze on the ceiling to navigate invisible platforms + +Pendulums to carry ball to switch that it opens a door with + diff --git a/docs/src/highlevel-design/structures/structuresandbuildings.md b/docs/src/highlevel-design/structures/structuresandbuildings.md index 1edd349d..9d74ba29 100644 --- a/docs/src/highlevel-design/structures/structuresandbuildings.md +++ b/docs/src/highlevel-design/structures/structuresandbuildings.md @@ -5,4 +5,6 @@ For this, I think we're going to try for 0.25 meter cube voxels in a separate me 0.25 meter cubed voxels are going to be 256kb/chunk uncompressed. That's 250mb/1000 chunks Problems to be solved: -LOD alongside terrain marching cubes \ No newline at end of file +LOD alongside terrain marching cubes + +When in building mode, have the ability to place 'parts', ie a section of wall, a section of roof, a beam, etc \ No newline at end of file diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index fd01fb48..7fb9e1a1 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -179,6 +179,9 @@ Fix Frustum Culling for skybox Fix Character creation preview not working +(03/23/2024) +Physics-controlled objects system + # TODO @@ -190,8 +193,6 @@ Level loading/saving + Basic Editor - Menu of types of entities to spawn - Button to spawn them at cursor -Physics-controlled objects system - Shader library system - Abiltiy to include the shader library in individual files (ie implement #include) diff --git a/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java b/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java index 26d75cfb..05078274 100644 --- a/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java +++ b/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java @@ -52,7 +52,7 @@ public class FluidCellManager { int drawStepdownInterval = 3; int drawStepdownValue = 25; - double drawRadius = 200; + double drawRadius = 50; int physicsRadius = 3; diff --git a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java index e85c7e4e..0e3a4c75 100644 --- a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java +++ b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java @@ -64,6 +64,15 @@ public class ClientSceneWrapper { return serverToClientIdMap.get(serverId); } + /** + * Checks if the scene wrapper contains the provided server id + * @param serverId The server id + * @return true if the map contains that id, false otherwise + */ + public boolean containsServerId(int serverId){ + return serverToClientIdMap.containsKey(serverId); + } + /** * Returns true if the server->client map contains a given id diff --git a/src/main/java/electrosphere/client/sim/ClientSimulation.java b/src/main/java/electrosphere/client/sim/ClientSimulation.java index 99adc243..ac9835e2 100644 --- a/src/main/java/electrosphere/client/sim/ClientSimulation.java +++ b/src/main/java/electrosphere/client/sim/ClientSimulation.java @@ -1,6 +1,8 @@ package electrosphere.client.sim; import electrosphere.client.targeting.crosshair.Crosshair; +import electrosphere.collision.PhysicsEntityUtils; +import electrosphere.collision.PhysicsUtils; import electrosphere.engine.Globals; import electrosphere.engine.Main; import electrosphere.entity.Entity; @@ -25,6 +27,7 @@ public class ClientSimulation { public void simulate(){ //simulate bullet physics engine step Globals.clientSceneWrapper.getCollisionEngine().simulatePhysics((float)Globals.timekeeper.getSimFrameTime()); + Globals.clientSceneWrapper.getCollisionEngine().updateDynamicObjectTransforms(); //update actor animations for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){ Actor currentActor = EntityUtils.getActor(currentEntity); diff --git a/src/main/java/electrosphere/collision/CollisionBodyCreation.java b/src/main/java/electrosphere/collision/CollisionBodyCreation.java index c9611657..815c7b4f 100644 --- a/src/main/java/electrosphere/collision/CollisionBodyCreation.java +++ b/src/main/java/electrosphere/collision/CollisionBodyCreation.java @@ -14,6 +14,7 @@ import org.ode4j.ode.DBox; import org.ode4j.ode.DCylinder; import org.ode4j.ode.DSphere; import org.ode4j.ode.DTriMesh; +import org.ode4j.ode.OdeHelper; import electrosphere.entity.types.terrain.TerrainChunkData; @@ -80,6 +81,29 @@ public class CollisionBodyCreation { return collisionEngine.createDBody(geom); } + /** + * Sets the provided body to be a kinematic body (no gravity applied) + * @param collisionEngine The collision engine + * @param body The body + */ + public static void setKinematic(CollisionEngine collisionEngine, DBody body){ + collisionEngine.setKinematic(body); + } + + /** + * Sets the gravity mode of the body + * @param collisionEngine the collision engine + * @param body the body + * @param gravityMode the gravity mode value + */ + public static void setGravityMode(CollisionEngine collisionEngine, DBody body, boolean gravityMode){ + collisionEngine.setGravityMode(body, gravityMode); + } + + public static void addMass(CollisionEngine collisionEngine, DBody body){ + + } + /** * Creates an ode DBody from a terrain chunk data object diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index 3705719d..6d230da3 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -43,10 +43,12 @@ import org.ode4j.ode.DSphere; import org.ode4j.ode.DTriMesh; import org.ode4j.ode.DTriMeshData; import org.ode4j.ode.DWorld; +import org.ode4j.ode.OdeConstants; import org.ode4j.ode.OdeHelper; import electrosphere.collision.RayCastCallback.RayCastCallbackData; import electrosphere.collision.collidable.Collidable; +import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; @@ -71,7 +73,7 @@ public class CollisionEngine { private static Semaphore spaceLock = new Semaphore(1); private DJointGroup contactgroup; - private static final int MAX_CONTACTS = 1; // maximum number of contact points per body + private static final int MAX_CONTACTS = 10; // maximum number of contact points per body //The list of dbodies ode should be tracking List bodies = new ArrayList(); @@ -91,6 +93,7 @@ public class CollisionEngine { public CollisionEngine(){ world = OdeHelper.createWorld(); space = OdeHelper.createBHVSpace(Collidable.TYPE_STATIC_BIT); + world.setGravity(0,-3,0); contactgroup = OdeHelper.createJointGroup(); } @@ -210,9 +213,11 @@ public class CollisionEngine { */ public void simulatePhysics(float time){ spaceLock.acquireUninterruptibly(); - space.collide(0,nearCallback); + OdeHelper.spaceCollide(space, 0, nearCallback); // space.collide2(space, collisionWorldData, nearCallback); - // world.quickStep(ENGINE_STEP_SIZE); + + //simulate physics + world.quickStep(ENGINE_STEP_SIZE); // remove all contact joints contactgroup.empty(); @@ -247,12 +252,13 @@ public class CollisionEngine { DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box for (int i=0; i 0 && - !Double.isNaN(impulse.getCollisionPoint().x) && - !Double.isNaN(impulse.getCollisionPoint().y) && - !Double.isNaN(impulse.getCollisionPoint().z) && - !Double.isNaN(impulse.getDirection().x) && - !Double.isNaN(impulse.getDirection().y) && - !Double.isNaN(impulse.getDirection().z) && - ItemUtils.isItem(parent) - ){ - // Vector3d collisionPoint = new Vector3d(impulse.getCollisionPoint()).normalize(); - Vector3d collisionPoint = new Vector3d(impulse.getWorldPoint()).sub(position); - Vector3d forceDir = new Vector3d(impulse.getDirection()).normalize(); - Vector3d torqueVec = new Vector3d(collisionPoint).cross(forceDir).normalize(); - // double torqueMag = Math.abs(impulse.force); - double torqueMag = Math.sqrt(impulse.getCollisionPoint().length()) * impulse.getForce(); - if(impulse.getType().equals(Collidable.TYPE_TERRAIN)){ - torqueMag = torqueMag * 3; - } - torqueMag = torqueMag * 10; - // } else { - // torqueMag = 0; - // } - // if(impulse.type.matches(Collidable.TYPE_ITEM) && ItemUtils.isItem(parent)){ - // // System.out.println(rotation); - // if(impulse.collisionPoint.x < 0){ - // // System.out.println("Impulse collision point: " + impulse.getCollisionPoint() + " direction: " + impulse.getDirection() + " => " + new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection())); - // cumulativeTorque.add(new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection())); - // } - // } else { - // // angularVelocity.add(new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection()),1.0); - // cumulativeTorque.add(new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection())); - // } - if(impulse.type.matches(Collidable.TYPE_CREATURE)){ - // System.out.println("Impulse: " + impulse.getCollisionPoint() + " x " + impulse.getDirection() + " ->f " + impulse.force); - // incrementer++; - // if(incrementer > 5){ - // Globals.microSimulation.freeze(); - // } else if(incrementer <= 5){ - // // Globals.controlHandler.showMouse(); - // Vector3d pos = impulse.getWorldPoint(); - // // pos = new Vector3d(position).add(impulse.getCollisionPoint()).mul(1,0,1); - // DebugVisualizerUtils.spawnVectorVisualizer(impulse.getWorldPoint(), new Vector3d(torqueVec)); - // } - // System.out.println("Impulse: " + torqueVec + " " + torqueMag); - } - // if(CreatureUtils.isCreature(parent) && forceDir.y < 0.5){ - // System.out.println(collisionPoint + " x " + forceDir + " => " + torqueVec + " " + torqueMag); - // } - Quaterniond impulseRotation = new Quaterniond().rotationAxis(torqueMag * DELTA_T,torqueVec.x,torqueVec.y,torqueVec.z); - if(angularVelocity.lengthSquared() > 0.001){ - angularVelocity.mul(impulseRotation); - } else { - angularVelocity.set(impulseRotation); - } - // angularVelocity.add(new Vector4d((float)torqueVec.x,(float)torqueVec.y,(float)torqueVec.z,(float)torqueMag)); - // cumulativeTorque.add(new Vector4d((float)torqueVec.x,(float)torqueVec.y,(float)torqueVec.z,(float)torqueMag)); - } - offsetVector.add(impulseForce); } - // if(ItemUtils.isItem(parent) && cumulativeTorque.w > 0.001){ - // System.out.println(cumulativeTorque); - // } - //friction - // if(angularVelocity.lengthSquared() > 0.001){ - // angularVelocity.slerp(new Quaterniond(0,0,0,1), 0.03); - // // angularVelocity.scale((float)(Math.sqrt(angularVelocity.lengthSquared()) * 0.9)); - // // System.out.println(angularVelocity); - // } - // // if(cumulativeTorque.w > 0.001){ - // // Vector4f holder = inverseInertiaTensor.transform(new Vector4f((float)cumulativeTorque.x,(float)cumulativeTorque.y,(float)cumulativeTorque.z,(float)cumulativeTorque.w)); - // // cumulativeTorque = new Vector4d(holder.x,holder.y,holder.z,holder.w); - // // angularVelocity = angularVelocity.add(cumulativeTorque).normalize(); - // // cumulativeTorque.set(0,0,0,0); - // // // Vector3d normalizedTorqueDir = new Vector3d(cumulativeTorque.x,cumulativeTorque.y,cumulativeTorque.z).normalize(); - // // // double newMag = cumulativeTorque.w * 0.9; - // // // cumulativeTorque.set(normalizedTorqueDir.x,normalizedTorqueDir.y,normalizedTorqueDir.z,newMag); - // // } - // if(angularVelocity.lengthSquared() > 0.001){ - // // System.out.println("-" + rotation); - // Quaterniond newRotation = new Quaterniond(rotation).mul(angularVelocity).normalize(); - // // if(new Quaternionf(newRotation).add(new Quaternionf(rotation).conjugate()).lengthSquared() > 0.2){ - // // newRotation.w = Math.copySign(newRotation.w, rotation.w); - // // newRotation.x = Math.copySign(newRotation.x, rotation.x); - // // newRotation.y = Math.copySign(newRotation.y, rotation.y); - // // newRotation.z = Math.copySign(newRotation.z, rotation.z); - // // } - // rotation.set(newRotation); - // // System.out.println("=" + rotation); - // } - // if(inverseInertiaTensor != null && angularVelocity.w > 0.01){ - // // Vector4f angularMomentum = inverseInertiaTensor.transform(new Vector4f((float)cumulativeTorque.x,(float)cumulativeTorque.x,(float)cumulativeTorque.x,(float)cumulativeTorque.w)); - // // Quaternionf nextRotation = new Quaternionf(rotation).mul(new Quaternionf(angularMomentum.x,angularMomentum.y,angularMomentum.z,angularMomentum.w).scale(0.001f)).normalize(); - // // rotation = nextRotation; - // // rotation.mul(new Quaternionf((float)angularMomentum.x,(float)angularMomentum.y,(float)angularMomentum.z,(float)angularMomentum.w / 0.01f)); - // // if(ItemUtils.isItem(parent)){ - // // System.out.println("cumulative quat: " + cumulativeTorque); - // // } - // rotation.x = rotation.x + rotation.x * (float)(angularVelocity.x * angularVelocity.w) * 0.01f; - // rotation.y = rotation.y + rotation.y * (float)(angularVelocity.y * angularVelocity.w) * 0.01f; - // rotation.z = rotation.z + rotation.z * (float)(angularVelocity.z * angularVelocity.w) * 0.01f; - // rotation.w = 1; - // // rotation.w = rotation.w + rotation.w * (float)cumulativeTorque.w * 0.001f; - // rotation.normalize(); - // } - - //the reasoning here is that if we have something above something else and it's pushing it into the terrain, - //we should instead just not push into terrain and push along terrain - if(hitTerrain && offsetVector.y < 0){ - offsetVector.y = 0; + //bound to world bounds + if(newPosition.x < Globals.clientWorldData.getWorldBoundMin().x){ + newPosition.x = Globals.clientWorldData.getWorldBoundMin().x; } - - //make sure we're in a valid (World bounds) position - if(applyImpulses){ - newPosition.add(offsetVector); + if(newPosition.y < Globals.clientWorldData.getWorldBoundMin().y){ + newPosition.y = Globals.clientWorldData.getWorldBoundMin().y; } - if(!Globals.clientSceneWrapper.getCollisionEngine().checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){ - newPosition = Globals.clientSceneWrapper.getCollisionEngine().suggestMovementPosition(Globals.commonWorldData, parent, newPosition); + if(newPosition.z < Globals.clientWorldData.getWorldBoundMin().z){ + newPosition.z = Globals.clientWorldData.getWorldBoundMin().z; } - position.set(newPosition); - - //update collision engine of this thing's position - CollidableTemplate template = (CollidableTemplate)parent.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); - Matrix4d physicsBodyTransform = PhysicsEntityUtils.getEntityCollidableTransform(parent); - Vector3f parentScale = EntityUtils.getScale(parent); - Matrix4d parentTransform = new Matrix4d(); - // calculate new transform for current entity - parentTransform.identity() - .translate(position) - .rotate(rotation) - .scale(parentScale.x,parentScale.y,parentScale.z) - .mul(physicsBodyTransform); - //transform bone space - Vector4d rigidBodyPositionRaw = parentTransform.transform(new Vector4d(0,0,0,1)); - Vector3d rigidBodyPosition = new Vector3d(rigidBodyPositionRaw.x,rigidBodyPositionRaw.y,rigidBodyPositionRaw.z); - Quaterniond rigidBodyRotation = parentTransform.getUnnormalizedRotation(new Quaterniond()).normalize(); - Vector3d rigidBodyScale = new Vector3d(parentScale); - PhysicsUtils.setRigidBodyTransform( - Globals.clientSceneWrapper.getCollisionEngine(), - template, - rigidBodyPosition, - rigidBodyRotation, - rigidBodyScale, - body - ); + PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), newPosition, rotation, body); } /** @@ -237,10 +99,6 @@ public class ClientCollidableTree implements BehaviorTree { this.body = body; this.collidable = collidable; } - - public double getAngularVelocityMagnitude(){ - return angularVelocity.lengthSquared(); - } public static boolean hasClientCollidableTree(Entity e){ return e.containsKey(EntityDataStrings.CLIENT_COLLIDABLE_TREE); diff --git a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java index 912c230c..5dc368a8 100644 --- a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java +++ b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java @@ -14,6 +14,7 @@ import electrosphere.entity.types.debug.DebugVisualizerUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.server.datacell.Realm; +import electrosphere.server.datacell.utils.DataCellSearchUtils; import org.joml.Matrix4f; import org.joml.Quaterniond; @@ -33,12 +34,8 @@ public class ServerCollidableTree implements BehaviorTree { Entity parent; DBody body; Collidable collidable; - Quaterniond angularVelocity = new Quaterniond(0,0,0,0); - Vector4d cumulativeTorque = new Vector4d(0,0,0,0); - boolean applyImpulses = true; - static final float DELTA_T = 0.01f; public ServerCollidableTree(Entity e, Collidable collidable, DBody body){ parent = e; @@ -58,7 +55,6 @@ public class ServerCollidableTree implements BehaviorTree { public void simulate(float deltaTime){ Vector3d position = EntityUtils.getPosition(parent); Quaterniond rotation = EntityUtils.getRotation(parent); - Matrix4f inverseInertiaTensor = CollisionObjUtils.getInverseInertiaTensor(parent); Vector3d offsetVector = new Vector3d(); Vector3d newPosition = new Vector3d(position); //have we hit a terrain impulse? @@ -66,7 +62,6 @@ public class ServerCollidableTree implements BehaviorTree { //handle impulses for(Impulse impulse : collidable.getImpulses()){ // collidable.getImpulses().remove(impulse); - Vector3d impulseForce = new Vector3d(impulse.getDirection()).mul(impulse.getForce()); if(impulse.type.matches(Collidable.TYPE_TERRAIN)){ hitTerrain = true; // System.out.println("Impulse force: " + impulseForce); @@ -83,136 +78,19 @@ public class ServerCollidableTree implements BehaviorTree { ServerGravityTree.getServerGravityTree(parent).start(); } } - if( - impulse.getCollisionPoint().length() > 0 && - !Double.isNaN(impulse.getCollisionPoint().x) && - !Double.isNaN(impulse.getCollisionPoint().y) && - !Double.isNaN(impulse.getCollisionPoint().z) && - !Double.isNaN(impulse.getDirection().x) && - !Double.isNaN(impulse.getDirection().y) && - !Double.isNaN(impulse.getDirection().z) && - ItemUtils.isItem(parent) - ){ - // Vector3d collisionPoint = new Vector3d(impulse.getCollisionPoint()).normalize(); - Vector3d collisionPoint = new Vector3d(impulse.getWorldPoint()).sub(position); - Vector3d forceDir = new Vector3d(impulse.getDirection()).normalize(); - Vector3d torqueVec = new Vector3d(collisionPoint).cross(forceDir).normalize(); - // double torqueMag = Math.abs(impulse.force); - double torqueMag = Math.sqrt(impulse.getCollisionPoint().length()) * impulse.getForce(); - if(impulse.getType().equals(Collidable.TYPE_TERRAIN)){ - torqueMag = torqueMag * 3; - } - torqueMag = torqueMag * 10; - // } else { - // torqueMag = 0; - // } - // if(impulse.type.matches(Collidable.TYPE_ITEM) && ItemUtils.isItem(parent)){ - // // System.out.println(rotation); - // if(impulse.collisionPoint.x < 0){ - // // System.out.println("Impulse collision point: " + impulse.getCollisionPoint() + " direction: " + impulse.getDirection() + " => " + new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection())); - // cumulativeTorque.add(new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection())); - // } - // } else { - // // angularVelocity.add(new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection()),1.0); - // cumulativeTorque.add(new Vector3d(impulse.getCollisionPoint()).cross(impulse.getDirection())); - // } - if(impulse.type.matches(Collidable.TYPE_CREATURE)){ - // System.out.println("Impulse: " + impulse.getCollisionPoint() + " x " + impulse.getDirection() + " ->f " + impulse.force); - // incrementer++; - // if(incrementer > 5){ - // Globals.microSimulation.freeze(); - // } else if(incrementer <= 5){ - // // Globals.controlHandler.showMouse(); - // Vector3d pos = impulse.getWorldPoint(); - // // pos = new Vector3d(position).add(impulse.getCollisionPoint()).mul(1,0,1); - // DebugVisualizerUtils.spawnVectorVisualizer(impulse.getWorldPoint(), new Vector3d(torqueVec)); - // } - // System.out.println("Impulse: " + torqueVec + " " + torqueMag); - } - // if(CreatureUtils.isCreature(parent) && forceDir.y < 0.5){ - // System.out.println(collisionPoint + " x " + forceDir + " => " + torqueVec + " " + torqueMag); - // } - Quaterniond impulseRotation = new Quaterniond().rotationAxis(torqueMag * DELTA_T,torqueVec.x,torqueVec.y,torqueVec.z); - if(angularVelocity.lengthSquared() > 0.001){ - angularVelocity.mul(impulseRotation); - } else { - angularVelocity.set(impulseRotation); - } - // angularVelocity.add(new Vector4d((float)torqueVec.x,(float)torqueVec.y,(float)torqueVec.z,(float)torqueMag)); - // cumulativeTorque.add(new Vector4d((float)torqueVec.x,(float)torqueVec.y,(float)torqueVec.z,(float)torqueMag)); - } - offsetVector.add(impulseForce); } - // if(ItemUtils.isItem(parent) && cumulativeTorque.w > 0.001){ - // System.out.println(cumulativeTorque); - // } - //friction - if(angularVelocity.lengthSquared() > 0.001){ - angularVelocity.slerp(new Quaterniond(0,0,0,1), 0.03); - // angularVelocity.scale((float)(Math.sqrt(angularVelocity.lengthSquared()) * 0.9)); - // System.out.println(angularVelocity); + Realm realm = Globals.realmManager.getEntityRealm(parent); + //bound to world bounds + if(newPosition.x < Globals.serverWorldData.getWorldBoundMin().x){ + newPosition.x = Globals.serverWorldData.getWorldBoundMin().x; } - // if(cumulativeTorque.w > 0.001){ - // Vector4f holder = inverseInertiaTensor.transform(new Vector4f((float)cumulativeTorque.x,(float)cumulativeTorque.y,(float)cumulativeTorque.z,(float)cumulativeTorque.w)); - // cumulativeTorque = new Vector4d(holder.x,holder.y,holder.z,holder.w); - // angularVelocity = angularVelocity.add(cumulativeTorque).normalize(); - // cumulativeTorque.set(0,0,0,0); - // // Vector3d normalizedTorqueDir = new Vector3d(cumulativeTorque.x,cumulativeTorque.y,cumulativeTorque.z).normalize(); - // // double newMag = cumulativeTorque.w * 0.9; - // // cumulativeTorque.set(normalizedTorqueDir.x,normalizedTorqueDir.y,normalizedTorqueDir.z,newMag); - // } - if(angularVelocity.lengthSquared() > 0.001){ - // System.out.println("-" + rotation); - Quaterniond newRotation = new Quaterniond(rotation).mul(angularVelocity).normalize(); - // if(new Quaternionf(newRotation).add(new Quaternionf(rotation).conjugate()).lengthSquared() > 0.2){ - // newRotation.w = Math.copySign(newRotation.w, rotation.w); - // newRotation.x = Math.copySign(newRotation.x, rotation.x); - // newRotation.y = Math.copySign(newRotation.y, rotation.y); - // newRotation.z = Math.copySign(newRotation.z, rotation.z); - // } - rotation.set(newRotation); - // System.out.println("=" + rotation); + if(newPosition.y < Globals.serverWorldData.getWorldBoundMin().y){ + newPosition.y = Globals.serverWorldData.getWorldBoundMin().y; } - // if(inverseInertiaTensor != null && angularVelocity.w > 0.01){ - // // Vector4f angularMomentum = inverseInertiaTensor.transform(new Vector4f((float)cumulativeTorque.x,(float)cumulativeTorque.x,(float)cumulativeTorque.x,(float)cumulativeTorque.w)); - // // Quaternionf nextRotation = new Quaternionf(rotation).mul(new Quaternionf(angularMomentum.x,angularMomentum.y,angularMomentum.z,angularMomentum.w).scale(0.001f)).normalize(); - // // rotation = nextRotation; - // // rotation.mul(new Quaternionf((float)angularMomentum.x,(float)angularMomentum.y,(float)angularMomentum.z,(float)angularMomentum.w / 0.01f)); - // // if(ItemUtils.isItem(parent)){ - // // System.out.println("cumulative quat: " + cumulativeTorque); - // // } - // rotation.x = rotation.x + rotation.x * (float)(angularVelocity.x * angularVelocity.w) * 0.01f; - // rotation.y = rotation.y + rotation.y * (float)(angularVelocity.y * angularVelocity.w) * 0.01f; - // rotation.z = rotation.z + rotation.z * (float)(angularVelocity.z * angularVelocity.w) * 0.01f; - // rotation.w = 1; - // // rotation.w = rotation.w + rotation.w * (float)cumulativeTorque.w * 0.001f; - // rotation.normalize(); - // } - - //the reasoning here is that if we have something above something else and it's pushing it into the terrain, - //we should instead just not push into terrain and push along terrain - if(hitTerrain && offsetVector.y < 0){ - offsetVector.y = 0; + if(newPosition.z < Globals.serverWorldData.getWorldBoundMin().z){ + newPosition.z = Globals.serverWorldData.getWorldBoundMin().z; } - - //make sure we're in a valid (World bounds) position - if(applyImpulses){ - newPosition.add(offsetVector); - } - Realm parentRealm = Globals.realmManager.getEntityRealm(parent); - if(!parentRealm.getCollisionEngine().checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){ - newPosition = parentRealm.getCollisionEngine().suggestMovementPosition(Globals.commonWorldData, parent, newPosition); - } - position.set(newPosition); - - //update collision engine of this thing's position - CollidableTemplate template = (CollidableTemplate)parent.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); - PhysicsUtils.setRigidBodyTransform( - parentRealm.getCollisionEngine(), - new Vector3d(position.x + template.getOffsetX(),position.y + template.getOffsetY(),position.z + template.getOffsetZ()), - rotation, - body - ); + PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), newPosition, rotation, body); } @@ -226,10 +104,6 @@ public class ServerCollidableTree implements BehaviorTree { this.collidable = collidable; } - public double getAngularVelocityMagnitude(){ - return angularVelocity.lengthSquared(); - } - public static boolean hasServerCollidableTree(Entity e){ return e.containsKey(EntityDataStrings.SERVER_COLLIDABLE_TREE); } diff --git a/src/main/java/electrosphere/entity/state/gravity/ClientGravityTree.java b/src/main/java/electrosphere/entity/state/gravity/ClientGravityTree.java index 712e3921..2cf95433 100644 --- a/src/main/java/electrosphere/entity/state/gravity/ClientGravityTree.java +++ b/src/main/java/electrosphere/entity/state/gravity/ClientGravityTree.java @@ -48,9 +48,6 @@ public class ClientGravityTree implements BehaviorTree { int frameCurrent = 0; int fallFrame = 1; - float gravityVelocity = 0; - float gravityAccel = 0.0007f; - DBody body; Collidable collidable; @@ -112,34 +109,6 @@ public class ClientGravityTree implements BehaviorTree { collidableTree = ClientCollidableTree.getClientCollidableTree(parent); } - //parse attached network messages -// for(EntityMessage message : networkMessageQueue){ -// networkMessageQueue.remove(message); -//// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ()); -// switch(message.getMessageSubtype()){ -// case ATTACKUPDATE: -// switch(message.gettreeState()){ -// case 0: -// state = IdleTreeState.IDLE; -// break; -// case 1: -// state = IdleTreeState.NOT_IDLE; -// break; -// } -// EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ()); -// CreatureUtils.setMovementVector(parent, new Vector3f(message.getrotationX(),message.getrotationY(),message.getrotationZ())); -// break; -// } -// } - - //Basically if we're still spinning keep applying gravity - boolean angularVelocityLow = true; - if(collidableTree != null){ - if(collidableTree.getAngularVelocityMagnitude() > 0.0001){ - angularVelocityLow = false; - } - } - //state machine switch(state){ @@ -158,7 +127,6 @@ public class ClientGravityTree implements BehaviorTree { fallTree.land(); } frameCurrent = 0; - gravityVelocity = 0; } else { //animation nonsense frameCurrent++; @@ -169,32 +137,6 @@ public class ClientGravityTree implements BehaviorTree { } } - //actual gravity calculations - if(gravityVelocity < gravityConstant){ - gravityVelocity = gravityVelocity + gravityAccel; - } - if(gravityVelocity > gravityConstant){ - gravityVelocity = gravityConstant; - } - float gravityDif = gravityVelocity * (float)Math.pow(1.0f - linearDamping,deltaTime * 2); - // Vector3d newGravityPos = new Vector3d(position.x,position.y - gravityDif,position.z); - // Entity terrainHit = Globals.clientSceneWrapper.getCollisionEngine().rayCast( - // position, - // new Vector3d(0,-1,0), - // gravityDif, - // CollisionMasks.terrainMask - // ); - // float hitFraction = Globals.clientSceneWrapper.getCollisionEngine().sweepTest(body, new Vector3f((float)position.x,(float)position.y,(float)position.z), new Vector3f((float)newGravityPos.x,(float)newGravityPos.y,(float)newGravityPos.z)); -// if(hitFraction >= 0){ -// collidable.addImpulse(new Impulse(new Vector3d(0,-1,0),gravityDif * hitFraction,"gravity")); -// position.set(new Vector3d(position.x,position.y - gravityDif * hitFraction,position.z)); -// } else { -// position.set(new Vector3d(position.x,position.y - gravityDif,position.z)); -// } - // if(hitFraction < 0){ - // hitFraction = 1; - // } - collidable.addImpulse(new Impulse(new Vector3d(0,-1,0), new Vector3d(0,0,0), new Vector3d(position), gravityDif,"gravity")); } break; case NOT_ACTIVE: diff --git a/src/main/java/electrosphere/entity/state/gravity/ServerGravityTree.java b/src/main/java/electrosphere/entity/state/gravity/ServerGravityTree.java index f5749639..36c718f2 100644 --- a/src/main/java/electrosphere/entity/state/gravity/ServerGravityTree.java +++ b/src/main/java/electrosphere/entity/state/gravity/ServerGravityTree.java @@ -46,9 +46,6 @@ public class ServerGravityTree implements BehaviorTree { int frameCurrent = 0; int fallFrame = 1; - float gravityVelocity = 0; - float gravityAccel = 0.0007f; - DBody body; Collidable collidable; @@ -130,23 +127,12 @@ public class ServerGravityTree implements BehaviorTree { // } // } - //Basically if we're still spinning keep applying gravity - boolean angularVelocityLow = true; - if(collidableTree != null){ - if(collidableTree.getAngularVelocityMagnitude() > 0.0001){ - angularVelocityLow = false; - } - } - //state machine switch(state){ case ACTIVE: if(hadGroundCollision()){ setState(GravityTreeState.NOT_ACTIVE); - if(!hadStructureCollision()){ -// position.set(new Vector3d(position.x,Globals.commonWorldData.getElevationAtPoint(position) + 0.0001f,position.z)); - } ServerJumpTree jumpTree; if((jumpTree = ServerJumpTree.getServerJumpTree(parent))!=null){ jumpTree.land(); @@ -156,7 +142,6 @@ public class ServerGravityTree implements BehaviorTree { fallTree.land(); } frameCurrent = 0; - gravityVelocity = 0; } else { //animation nonsense frameCurrent++; @@ -166,28 +151,6 @@ public class ServerGravityTree implements BehaviorTree { fallTree.start(); } } - - //actual gravity calculations - if(gravityVelocity < gravityConstant){ - gravityVelocity = gravityVelocity + gravityAccel; - } - if(gravityVelocity > gravityConstant){ - gravityVelocity = gravityConstant; - } - float gravityDif = gravityVelocity * (float)Math.pow(1.0f - linearDamping,deltaTime * 2); - // Vector3d newGravityPos = new Vector3d(position.x,position.y - gravityDif,position.z); - // Realm parentRealm = Globals.realmManager.getEntityRealm(parent); - // float hitFraction = parentRealm.getCollisionEngine().sweepTest(body, new Vector3f((float)position.x,(float)position.y,(float)position.z), new Vector3f((float)newGravityPos.x,(float)newGravityPos.y,(float)newGravityPos.z)); -// if(hitFraction >= 0){ -// collidable.addImpulse(new Impulse(new Vector3d(0,-1,0),gravityDif * hitFraction,"gravity")); -// position.set(new Vector3d(position.x,position.y - gravityDif * hitFraction,position.z)); -// } else { -// position.set(new Vector3d(position.x,position.y - gravityDif,position.z)); -// } - // if(hitFraction < 0){ - // hitFraction = 1; - // } - collidable.addImpulse(new Impulse(new Vector3d(0,-1,0), new Vector3d(0,0,0), new Vector3d(position), gravityDif,"gravity")); } break; case NOT_ACTIVE: diff --git a/src/main/java/electrosphere/entity/state/idle/IdleTree.java b/src/main/java/electrosphere/entity/state/idle/IdleTree.java index 534bea6c..a9d13505 100644 --- a/src/main/java/electrosphere/entity/state/idle/IdleTree.java +++ b/src/main/java/electrosphere/entity/state/idle/IdleTree.java @@ -6,6 +6,7 @@ import electrosphere.entity.state.attack.AttackTree; import electrosphere.entity.state.movement.AirplaneMovementTree; import electrosphere.entity.state.movement.groundmove.GroundMovementTree; import electrosphere.entity.state.movement.groundmove.GroundMovementTree.MovementTreeState; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; diff --git a/src/main/java/electrosphere/entity/state/movement/JumpTree.java b/src/main/java/electrosphere/entity/state/movement/JumpTree.java index 9af87117..4dd1e2ef 100644 --- a/src/main/java/electrosphere/entity/state/movement/JumpTree.java +++ b/src/main/java/electrosphere/entity/state/movement/JumpTree.java @@ -1,7 +1,11 @@ package electrosphere.entity.state.movement; import org.joml.Vector3d; +import org.ode4j.math.DVector3C; +import org.ode4j.ode.DBody; +import electrosphere.collision.PhysicsEntityUtils; +import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; @@ -40,12 +44,12 @@ public class JumpTree implements BehaviorTree { } public void start(){ - if(state == JumpState.INACTIVE){ + // if(state == JumpState.INACTIVE){ state = JumpState.ACTIVE; currentFrame = 0; currentJumpForce = jumpForce; GravityUtils.clientAttemptActivateGravity(parent); - } + // } } @Override @@ -62,8 +66,12 @@ public class JumpTree implements BehaviorTree { } currentFrame++; currentJumpForce = currentJumpForce * jumpFalloff; + //stop body falling if it is + DBody body = PhysicsEntityUtils.getDBody(parent); + DVector3C linearVelocity = body.getLinearVel(); + body.setLinearVel(linearVelocity.get0(), 0, linearVelocity.get2()); //push parent up - CollisionObjUtils.getCollidable(parent).addImpulse(new Impulse(new Vector3d(0,1,0), new Vector3d(0,0,0), new Vector3d(EntityUtils.getPosition(parent)), currentJumpForce, Collidable.TYPE_FORCE)); + body.addForce(0, currentJumpForce, 0); //potentially disable if(currentFrame >= jumpFrames){ state = JumpState.AWAITING_LAND; diff --git a/src/main/java/electrosphere/entity/state/movement/ServerJumpTree.java b/src/main/java/electrosphere/entity/state/movement/ServerJumpTree.java index 62311330..a720ec0d 100644 --- a/src/main/java/electrosphere/entity/state/movement/ServerJumpTree.java +++ b/src/main/java/electrosphere/entity/state/movement/ServerJumpTree.java @@ -1,7 +1,10 @@ package electrosphere.entity.state.movement; import org.joml.Vector3d; +import org.ode4j.math.DVector3C; +import org.ode4j.ode.DBody; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; @@ -62,8 +65,12 @@ public class ServerJumpTree implements BehaviorTree { } currentFrame++; currentJumpForce = currentJumpForce * jumpFalloff; + //stop body falling if it is + DBody body = PhysicsEntityUtils.getDBody(parent); + DVector3C linearVelocity = body.getLinearVel(); + body.setLinearVel(linearVelocity.get0(), 0, linearVelocity.get2()); //push parent up - CollisionObjUtils.getCollidable(parent).addImpulse(new Impulse(new Vector3d(0,1,0), new Vector3d(0,0,0), new Vector3d(EntityUtils.getPosition(parent)), currentJumpForce, Collidable.TYPE_FORCE)); + body.addForce(0, currentJumpForce, 0); //potentially disable if(currentFrame >= jumpFrames){ state = JumpState.AWAITING_LAND; diff --git a/src/main/java/electrosphere/entity/state/movement/groundmove/GroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/groundmove/GroundMovementTree.java index 58235b37..eb0c64be 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/GroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/GroundMovementTree.java @@ -4,12 +4,15 @@ import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.state.gravity.GravityUtils; import electrosphere.collision.CollisionEngine; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; import electrosphere.engine.Main; import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.creature.CreatureUtils; +import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; @@ -35,6 +38,9 @@ import org.joml.Quaterniond; import org.joml.Quaternionf; import org.joml.Vector3d; import org.joml.Vector3f; +import org.ode4j.math.DVector3; +import org.ode4j.math.DVector3C; +import org.ode4j.ode.DBody; /* Behavior tree for movement in an entity @@ -162,6 +168,8 @@ public class GroundMovementTree implements BehaviorTree { Vector3d position = EntityUtils.getPosition(parent); Vector3d facingVector = CreatureUtils.getFacingVector(parent); Vector3d movementVector = new Vector3d(facingVector); + DBody body = PhysicsEntityUtils.getDBody(parent); + DVector3C linearVelocity = body.getLinearVel(); switch(facing){ case FORWARD: movementVector.normalize(); @@ -193,6 +201,11 @@ public class GroundMovementTree implements BehaviorTree { // float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera); Quaterniond movementQuaternion = new Quaterniond().rotationTo(new Vector3d(0,0,1), new Vector3d(facingVector.x,0,facingVector.z)).normalize(); Quaterniond rotation = EntityUtils.getRotation(parent); + //TODO: optimize away and document (I know for the moment if this exception isn't here it will bite me in the ass later) + if(facingVector.length() == 0){ + throw new IllegalStateException("Facing vector length is 0. This will break ODE4J"); + } + rotation.set(movementQuaternion); //parse attached network messages for(EntityMessage message : networkMessageQueue){ @@ -239,6 +252,7 @@ public class GroundMovementTree implements BehaviorTree { // } //we want to always update the server facing vector with where the client says they're facing EntityUtils.getRotation(parent).set(message.getrotationX(),message.getrotationY(),message.getrotationZ(),message.getrotationW()); + CollisionObjUtils.clientPositionCharacter(parent, position); // CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ())); break; } @@ -272,9 +286,13 @@ public class GroundMovementTree implements BehaviorTree { state = MovementTreeState.MOVE; } CreatureUtils.setVelocity(parent, velocity); -// //actually update - collidable.addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Globals.timekeeper.getSimFrameTime(), "movement")); -// position.set(newPosition); + //actually update + body.setLinearVel( + movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), + linearVelocity.get1(), + movementVector.z * velocity * Globals.timekeeper.getSimFrameTime() + ); + body.setAngularVel(0, 0, 0); rotation.set(movementQuaternion); GravityUtils.clientAttemptActivateGravity(parent); @@ -298,8 +316,12 @@ public class GroundMovementTree implements BehaviorTree { velocity = maxNaturalVelocity; CreatureUtils.setVelocity(parent, velocity); } - collidable.addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Globals.timekeeper.getSimFrameTime(), "movement")); -// position.set(newPosition); + body.setLinearVel( + movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), + linearVelocity.get1(), + movementVector.z * velocity * Globals.timekeeper.getSimFrameTime() + ); + body.setAngularVel(0, 0, 0); rotation.set(movementQuaternion); GravityUtils.clientAttemptActivateGravity(parent); @@ -332,8 +354,12 @@ public class GroundMovementTree implements BehaviorTree { } } CreatureUtils.setVelocity(parent, velocity); - collidable.addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Globals.timekeeper.getSimFrameTime(), "movement")); -// position.set(newPosition); + body.setLinearVel( + movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), + linearVelocity.get1(), + movementVector.z * velocity * Globals.timekeeper.getSimFrameTime() + ); + body.setAngularVel(0, 0, 0); rotation.set(movementQuaternion); GravityUtils.clientAttemptActivateGravity(parent); diff --git a/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java index 067389fb..d6e51c1d 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java @@ -3,6 +3,7 @@ package electrosphere.entity.state.movement.groundmove; import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.state.gravity.GravityUtils; import electrosphere.collision.CollisionEngine; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; @@ -35,6 +36,8 @@ import org.joml.Quaterniond; import org.joml.Quaternionf; import org.joml.Vector3d; import org.joml.Vector3f; +import org.ode4j.math.DVector3C; +import org.ode4j.ode.DBody; /* Behavior tree for movement in an entity @@ -162,6 +165,8 @@ public class ServerGroundMovementTree implements BehaviorTree { Vector3d position = EntityUtils.getPosition(parent); Vector3d facingVector = CreatureUtils.getFacingVector(parent); Vector3d movementVector = new Vector3d(facingVector); + DBody body = PhysicsEntityUtils.getDBody(parent); + DVector3C linearVelocity = body.getLinearVel(); switch(facing){ case FORWARD: movementVector.normalize(); @@ -193,6 +198,11 @@ public class ServerGroundMovementTree implements BehaviorTree { // float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera); Quaterniond movementQuaternion = new Quaterniond().rotationTo(new Vector3d(0,0,1), new Vector3d(facingVector.x,0,facingVector.z)).normalize(); Quaterniond rotation = EntityUtils.getRotation(parent); + //TODO: optimize away and document (I know for the moment if this exception isn't here it will bite me in the ass later) + if(facingVector.length() == 0){ + throw new IllegalStateException("Facing vector length is 0. This will break ODE4J"); + } + rotation.set(movementQuaternion); //parse attached network messages for(EntityMessage message : networkMessageQueue){ @@ -264,7 +274,12 @@ public class ServerGroundMovementTree implements BehaviorTree { } CreatureUtils.setVelocity(parent, velocity); // //actually update - collidable.addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Globals.timekeeper.getSimFrameTime(), "movement")); + PhysicsEntityUtils.getDBody(parent).setLinearVel( + movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), + linearVelocity.get1(), + movementVector.z * velocity * Globals.timekeeper.getSimFrameTime() + ); + body.setAngularVel(0, 0, 0); // position.set(newPosition); rotation.set(movementQuaternion); @@ -304,7 +319,12 @@ public class ServerGroundMovementTree implements BehaviorTree { velocity = maxNaturalVelocity; CreatureUtils.setVelocity(parent, velocity); } - collidable.addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Globals.timekeeper.getSimFrameTime(), "movement")); + PhysicsEntityUtils.getDBody(parent).setLinearVel( + movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), + linearVelocity.get1(), + movementVector.z * velocity * Globals.timekeeper.getSimFrameTime() + ); + body.setAngularVel(0, 0, 0); // position.set(newPosition); rotation.set(movementQuaternion); @@ -353,7 +373,12 @@ public class ServerGroundMovementTree implements BehaviorTree { } } CreatureUtils.setVelocity(parent, velocity); - collidable.addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Globals.timekeeper.getSimFrameTime(), "movement")); + PhysicsEntityUtils.getDBody(parent).setLinearVel( + movementVector.x * velocity * Globals.timekeeper.getSimFrameTime(), + linearVelocity.get1(), + movementVector.z * velocity * Globals.timekeeper.getSimFrameTime() + ); + body.setAngularVel(0, 0, 0); // position.set(newPosition); rotation.set(movementQuaternion); diff --git a/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java index d807f3a1..bd9584d2 100644 --- a/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java +++ b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java @@ -41,10 +41,6 @@ public class CollisionObjUtils { rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, planeObject); rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f().zero(); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor); rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); return rVal; @@ -67,10 +63,6 @@ public class CollisionObjUtils { rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, planeObject); rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f().zero(); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor); rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); return rVal; @@ -94,10 +86,6 @@ public class CollisionObjUtils { rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, cubeObject); rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - Matrix4f inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); return rVal; @@ -120,10 +108,6 @@ public class CollisionObjUtils { rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, cubeObject); rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - Matrix4f inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); return rVal; @@ -145,13 +129,6 @@ public class CollisionObjUtils { rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, cubeObject); rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f(); - inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m22(mass * scale.x * scale.x / 2.0f); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); return rVal; @@ -173,13 +150,6 @@ public class CollisionObjUtils { rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, cubeObject); rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f(); - inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m22(mass * scale.x * scale.x / 2.0f); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); return rVal; @@ -193,10 +163,6 @@ public class CollisionObjUtils { float mass = 1.0f; parent.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f().zero(); - parent.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor); return rVal; } @@ -209,10 +175,6 @@ public class CollisionObjUtils { float mass = 1.0f; parent.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f().zero(); - parent.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor); return rVal; } @@ -224,10 +186,6 @@ public class CollisionObjUtils { float mass = 1.0f; parent.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - Matrix4f inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - parent.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); return rVal; } @@ -240,10 +198,6 @@ public class CollisionObjUtils { float mass = 1.0f; parent.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - Matrix4f inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - parent.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); return rVal; } @@ -255,13 +209,6 @@ public class CollisionObjUtils { float mass = 1.0f; parent.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f(); - inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m22(mass * scale.x * scale.x / 2.0f); - parent.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); return rVal; } @@ -274,13 +221,6 @@ public class CollisionObjUtils { float mass = 1.0f; parent.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f(); - inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m22(mass * scale.x * scale.x / 2.0f); - parent.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); return rVal; } @@ -306,13 +246,6 @@ public class CollisionObjUtils { entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, collisionObject); entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable); entity.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f(); - inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m22(mass * scale.x * scale.x / 2.0f); - entity.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); } /** @@ -337,13 +270,6 @@ public class CollisionObjUtils { entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, collisionObject); entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable); entity.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - Matrix4f inertiaTensor = new Matrix4f(); - inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); - inertiaTensor.m22(mass * scale.x * scale.x / 2.0f); - entity.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); } public static DBody getCollisionBody(Entity e){ @@ -377,9 +303,5 @@ public class CollisionObjUtils { return (float)e.getData(EntityDataStrings.PHYSICS_MASS); } - public static Matrix4f getInverseInertiaTensor(Entity e){ - return (Matrix4f)e.getData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR); - } - } diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index 72f8e285..c0b68e11 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -158,7 +158,7 @@ public class CreatureUtils { } //round out end of move system rVal.putData(EntityDataStrings.CLIENT_MOVEMENT_BT, moveTree); - CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,0)); + CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1)); rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, groundMovementSystem.getMaxVelocity()); rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, groundMovementSystem.getAcceleration()); rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f); @@ -216,7 +216,7 @@ public class CreatureUtils { airplaneMovementTree.setMaxRotationSpeed(airplaneMovementSystem.getMaxRotationSpeed()); //register misc stuff rVal.putData(EntityDataStrings.CLIENT_MOVEMENT_BT, airplaneMovementTree); - CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,0)); + CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1)); Globals.clientScene.registerBehaviorTree(airplaneMovementTree); Globals.clientScene.registerEntityToTag(rVal, EntityTags.MOVEABLE); } break; @@ -454,7 +454,7 @@ public class CreatureUtils { } //round out end of move system rVal.putData(EntityDataStrings.SERVER_MOVEMENT_BT, moveTree); - CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,0)); + CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1)); rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, groundMovementSystem.getMaxVelocity()); rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, groundMovementSystem.getAcceleration()); rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f); @@ -512,7 +512,7 @@ public class CreatureUtils { airplaneMovementTree.setMaxRotationSpeed(airplaneMovementSystem.getMaxRotationSpeed()); //register misc stuff rVal.putData(EntityDataStrings.SERVER_MOVEMENT_BT, airplaneMovementTree); - CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,0)); + CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1)); ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, airplaneMovementTree); ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.MOVEABLE); } break; diff --git a/src/main/java/electrosphere/entity/types/item/ItemUtils.java b/src/main/java/electrosphere/entity/types/item/ItemUtils.java index 1c4803b6..f2e77b43 100644 --- a/src/main/java/electrosphere/entity/types/item/ItemUtils.java +++ b/src/main/java/electrosphere/entity/types/item/ItemUtils.java @@ -196,9 +196,6 @@ public class ItemUtils { if(item.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY)){ item.removeData(EntityDataStrings.PHYSICS_COLLISION_BODY); } - if(item.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET)){ - item.removeData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET); - } if(item.containsKey(EntityDataStrings.PHYSICS_MODEL_TEMPLATE)){ item.removeData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); } diff --git a/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java b/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java index fe8800db..c3b102de 100644 --- a/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java +++ b/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java @@ -15,10 +15,12 @@ import org.joml.Vector3f; import org.joml.Vector4d; import org.joml.Vector4f; import org.ode4j.ode.DBody; +import org.ode4j.ode.DCylinder; import electrosphere.audio.VirtualAudioSource; import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType; import electrosphere.collision.CollisionBodyCreation; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; @@ -124,9 +126,17 @@ public class ProceduralTree { treeModel.getPhysicsBody().getDimension2(), Collidable.TYPE_STATIC_BIT ); + DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next(); + cylinder.setOffsetPosition(0,treeModel.getPhysicsBody().getOffsetY(),0); + CollisionBodyCreation.setKinematic(Globals.clientSceneWrapper.getCollisionEngine(), rigidBody); Collidable collidable = new Collidable(trunkChild, Collidable.TYPE_OBJECT); trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(0,treeModel.getPhysicsBody().getOffsetY(),0)); + Matrix4d offsetTransform = new Matrix4d().translationRotateScale( + 0,treeModel.getPhysicsBody().getOffsetY(),0, //translate + 0,0,0,1, //rotate + 1, 1, 1 //scale + ); + trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform); trunkChild.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, treeModel.getPhysicsBody()); trunkChild.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); trunkChild.putData(EntityDataStrings.PHYSICS_MASS, TREE_MASS); @@ -383,9 +393,17 @@ public class ProceduralTree { treeModel.getPhysicsBody().getDimension2(), Collidable.TYPE_STATIC_BIT ); + DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next(); + cylinder.setOffsetPosition(0,treeModel.getPhysicsBody().getOffsetY(),0); + CollisionBodyCreation.setKinematic(realm.getCollisionEngine(), rigidBody); Collidable collidable = new Collidable(trunkChild, Collidable.TYPE_FOLIAGE_STATIC); trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(0,treeModel.getPhysicsBody().getOffsetY(),0)); + Matrix4d offsetTransform = new Matrix4d().translationRotateScale( + 0,treeModel.getPhysicsBody().getOffsetY(),0, //translate + 0,0,0,1, //rotate + 1, 1, 1 //scale + ); + trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform); trunkChild.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, treeModel.getPhysicsBody()); trunkChild.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); trunkChild.putData(EntityDataStrings.PHYSICS_MASS, TREE_MASS); diff --git a/src/main/java/electrosphere/menu/ImGuiWindowMacros.java b/src/main/java/electrosphere/menu/ImGuiWindowMacros.java index ab2316f3..8b15670e 100644 --- a/src/main/java/electrosphere/menu/ImGuiWindowMacros.java +++ b/src/main/java/electrosphere/menu/ImGuiWindowMacros.java @@ -3,7 +3,11 @@ package electrosphere.menu; import java.util.HashMap; import java.util.Map; +import org.ode4j.ode.DBody; + import electrosphere.audio.VirtualAudioSource; +import electrosphere.collision.PhysicsEntityUtils; +import electrosphere.collision.PhysicsUtils; import electrosphere.controls.ControlHandler.ControlsState; import electrosphere.engine.Globals; import electrosphere.entity.EntityUtils; @@ -166,6 +170,13 @@ public class ImGuiWindowMacros { ImGui.text("Player Entity Details"); if(Globals.playerEntity != null){ ImGui.text("Position: " + EntityUtils.getPosition(Globals.playerEntity)); + DBody body = PhysicsEntityUtils.getDBody(Globals.playerEntity); + if(body != null){ + ImGui.text("Velocity: " + body.getLinearVel()); + ImGui.text("Force: " + body.getForce()); + ImGui.text("Angular Velocity: " + body.getAngularVel()); + ImGui.text("Torque: " + body.getTorque()); + } } if(ImGui.button("Toggle Player Camera Lock")){ Globals.cameraHandler.setTrackPlayerEntity(!Globals.cameraHandler.getTrackPlayerEntity()); diff --git a/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java b/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java index c7c9190c..1c1430d2 100644 --- a/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java @@ -45,7 +45,7 @@ public class EntityProtocol { LoggerInterface.loggerNetworking.DEBUG("Spawn Creature " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ()); CreatureTemplate template = Utilities.deserialize(message.getcreatureTemplate(), CreatureTemplate.class); newlySpawnedEntity = CreatureUtils.clientSpawnBasicCreature(template.getCreatureType(),template); - EntityUtils.getPosition(newlySpawnedEntity).set(message.getpositionX(),message.getpositionY(),message.getpositionZ()); + ClientEntityUtils.initiallyPositionEntity(newlySpawnedEntity, new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ())); Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID()); break; case SPAWNITEM: diff --git a/src/main/java/electrosphere/net/synchronization/ClientSynchronizationManager.java b/src/main/java/electrosphere/net/synchronization/ClientSynchronizationManager.java index 2f23b59d..ee768a7e 100644 --- a/src/main/java/electrosphere/net/synchronization/ClientSynchronizationManager.java +++ b/src/main/java/electrosphere/net/synchronization/ClientSynchronizationManager.java @@ -38,23 +38,25 @@ public class ClientSynchronizationManager { public void processMessages(){ List messagesToClear = new LinkedList(); for(SynchronizationMessage message : messages){ - messagesToClear.add(message); - switch(message.getMessageSubtype()){ - case UPDATECLIENTSTATE:{ - int bTreeId = message.getbTreeId(); - int entityId = message.getentityId(); - Entity targetEntity = Globals.clientSceneWrapper.getEntityFromServerId(entityId); - updateEntityState(targetEntity,bTreeId,message); - } break; - case ATTACHTREE:{ - int bTreeId = message.getbTreeId(); - int bTreeValue = message.getbTreeValue(); - int entityId = message.getentityId(); - } break; - case DETATCHTREE:{ - int bTreeId = message.getbTreeId(); - int entityId = message.getentityId(); - } break; + if(Globals.clientSceneWrapper.containsServerId(message.getentityId())){ + messagesToClear.add(message); + switch(message.getMessageSubtype()){ + case UPDATECLIENTSTATE:{ + int bTreeId = message.getbTreeId(); + int entityId = message.getentityId(); + Entity targetEntity = Globals.clientSceneWrapper.getEntityFromServerId(entityId); + updateEntityState(targetEntity,bTreeId,message); + } break; + case ATTACHTREE:{ + int bTreeId = message.getbTreeId(); + int bTreeValue = message.getbTreeValue(); + int entityId = message.getentityId(); + } break; + case DETATCHTREE:{ + int bTreeId = message.getbTreeId(); + int entityId = message.getentityId(); + } break; + } } } for(SynchronizationMessage message : messagesToClear){ diff --git a/src/main/java/electrosphere/server/datacell/Realm.java b/src/main/java/electrosphere/server/datacell/Realm.java index 4dbeb4dd..d1347ec8 100644 --- a/src/main/java/electrosphere/server/datacell/Realm.java +++ b/src/main/java/electrosphere/server/datacell/Realm.java @@ -158,6 +158,7 @@ public class Realm { protected void simulate(){ //simulate bullet physics engine step collisionEngine.simulatePhysics((float)Globals.timekeeper.getSimFrameTime()); + collisionEngine.updateDynamicObjectTransforms(); //main simulation dataCellManager.simulate(); //data cell manager update misc variables (player positions, unload not-in-use cells) diff --git a/src/main/java/electrosphere/server/datacell/ServerDataCell.java b/src/main/java/electrosphere/server/datacell/ServerDataCell.java index c49b996d..19df39c4 100644 --- a/src/main/java/electrosphere/server/datacell/ServerDataCell.java +++ b/src/main/java/electrosphere/server/datacell/ServerDataCell.java @@ -2,6 +2,7 @@ package electrosphere.server.datacell; import electrosphere.engine.Globals; import electrosphere.entity.Entity; +import electrosphere.entity.EntityUtils; import electrosphere.entity.Scene; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.foliage.FoliageUtils; diff --git a/src/main/java/electrosphere/server/simulation/MicroSimulation.java b/src/main/java/electrosphere/server/simulation/MicroSimulation.java index 59e4470e..2e06b071 100644 --- a/src/main/java/electrosphere/server/simulation/MicroSimulation.java +++ b/src/main/java/electrosphere/server/simulation/MicroSimulation.java @@ -47,10 +47,6 @@ public class MicroSimulation { public void simulate(ServerDataCell dataCell, HitboxManager hitboxManager){ if(dataCell.isReady()){ - //update dynamic entity positions calculated by bullet - // Globals.collisionEngine.updateDynamicObjectTransforms(); - //list dynamic object positions - // Globals.collisionEngine.listBodyPositions(); //simulate ai Globals.aiManager.simulate(); //update actor animations @@ -84,11 +80,6 @@ public class MicroSimulation { HitboxUtils.serverCollideEntities(currentHitbox); } } - //tally collidables and offset position accordingly - // for(Entity currentCollidable : Globals.entityManager.getEntitiesWithTag(EntityTags.COLLIDABLE)){ - // CollidableTree tree = CollidableTree.getCollidableTree(currentCollidable); - // tree.simulate(Main.deltaFrames); - // } //simulate behavior trees dataCell.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime()); //sum collidable impulses diff --git a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java index 8ab9eb4a..157744b9 100644 --- a/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java +++ b/src/main/java/electrosphere/server/terrain/manager/ServerTerrainManager.java @@ -235,7 +235,7 @@ public class ServerTerrainManager { returnedChunk = chunkCache.get(key); return returnedChunk; } else { - if(chunkCacheContents.size() > cacheSize){ + if(chunkCacheContents.size() >= cacheSize){ String oldChunk = chunkCacheContents.remove(chunkCacheContents.size() - 1); chunkCache.remove(oldChunk); } @@ -261,7 +261,9 @@ public class ServerTerrainManager { * @param position The position to save */ public void savePositionToDisk(Vector3i position){ - chunkDiskMap.saveToDisk(getChunk(position.x, position.y, position.z)); + if(chunkDiskMap != null){ + chunkDiskMap.saveToDisk(getChunk(position.x, position.y, position.z)); + } } /**