diff --git a/buildNumber.properties b/buildNumber.properties index 7feb3fe9..230e65c4 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sat Sep 02 19:48:14 EDT 2023 -buildNumber=11 +#Sun Nov 05 10:58:49 EST 2023 +buildNumber=12 diff --git a/docs/src/physics/collision.md b/docs/src/physics/collision.md index 3c90b125..7c4b8d6e 100644 --- a/docs/src/physics/collision.md +++ b/docs/src/physics/collision.md @@ -52,6 +52,8 @@ The big case for this engine is the main physics system. The goal is to provide [Collidable.java](@ref #electrosphere.collision.collidable.Collidable) - Contains the collision information for a single object in a given collision system. Stores both the description of the collidable (is it a tree, a frog, or the ground, etc) as well as a list of impulses to be applied. +[CollisionBodyCreation.java](@ref #electrosphere.collision.CollisionBodyCreation) - Contains functions for creating rigid bodies of different types (cube, sphere, trimesh, etc) + @@ -99,6 +101,20 @@ Each client scene creates a collision engine for physics on connection. Each sce +## Terminology + - Physics Entity + - Dynamic Physics Entity + - Collision Object - A collidable + + + + + + + + + + diff --git a/docs/src/physics/physics.md b/docs/src/physics/physics.md index 5f10e002..8b134750 100644 --- a/docs/src/physics/physics.md +++ b/docs/src/physics/physics.md @@ -7,10 +7,14 @@ The goal of the physics engine is to wrap around the collision engine to allow p ## Major Usage Notes +Check Collision Engine Usage Notes as well. They are pretty relevant typically. ## Main Classes +[PhysicsEntityUtils.java](@ref #electrosphere.collision.PhysicsEntityUtils) - Contains functions for creating and attaching rigid bodies to entities so that they obey physics. + +[PhysicsUtils.java](@ref #electrosphere.collision.PhysicsUtils) - Contains utilities for physics operations (unit transforms, etc) @@ -18,6 +22,15 @@ The goal of the physics engine is to wrap around the collision engine to allow p +## Examples + + + + + + + + ## Future Goals - + - Library Scoped Physics Objects - Create an item, ball, etc, that uses the Ode4J physics calculations to figure out its next position. \ No newline at end of file diff --git a/src/main/java/electrosphere/collision/CollisionBodyCreation.java b/src/main/java/electrosphere/collision/CollisionBodyCreation.java new file mode 100644 index 00000000..63ef03cc --- /dev/null +++ b/src/main/java/electrosphere/collision/CollisionBodyCreation.java @@ -0,0 +1,161 @@ +package electrosphere.collision; + +import java.nio.IntBuffer; + +import org.joml.Vector3d; +import org.lwjgl.PointerBuffer; +import org.lwjgl.assimp.AIFace; +import org.lwjgl.assimp.AIMesh; +import org.lwjgl.assimp.AIScene; +import org.lwjgl.assimp.AIVector3D; +import org.ode4j.ode.DBody; +import org.ode4j.ode.DBox; +import org.ode4j.ode.DCylinder; +import org.ode4j.ode.DSphere; +import org.ode4j.ode.DTriMesh; + +import electrosphere.entity.types.terrain.TerrainChunkData; + +/** + * Utilities for creating types of rigid bodies + */ +public class CollisionBodyCreation { + + + + //The width of a plane rigid body + //It's really a box under the hood + static final double PLANE_WIDTH = 0.3; + + /** + * Creates a plane DBody. Dimensions x and z control the length and width of the plane; + * @param dimensions The dimensions of the plane + * @return The DBody + */ + public static DBody createPlaneBody(CollisionEngine collisionEngine, Vector3d dimensions){ + DBox geom = collisionEngine.createCubeGeom(new Vector3d(dimensions.x,PLANE_WIDTH,dimensions.z)); + return collisionEngine.createDBody(geom); + } + + /** + * Creates a cube DBody. Dimensions controlled by the dimensions vector. + * @param collisionEngine The collision engine to create the body inside of + * @param dimensions The dimensions of the cube + * @return The DBody + */ + public static DBody createCubeBody(CollisionEngine collisionEngine, Vector3d dimensions){ + DBox geom = collisionEngine.createCubeGeom(new Vector3d(dimensions)); + return collisionEngine.createDBody(geom); + } + + /** + * Creates a cylinder DBody. Dimensions controlled by the dimensions vector. + * @param collisionEngine The collision engine to create the body inside of + * @param dimensions The dimensions of the cube + * @return The DBody + */ + public static DBody createCylinderBody(CollisionEngine collisionEngine, double radius, double length){ + DCylinder geom = collisionEngine.createCylinderGeom(radius,length); + return collisionEngine.createDBody(geom); + } + + /** + * Creates a sphere body in the collision engine + * @param collisionEngine The collision engine + * @param radius The radius of the sphere + * @return The DBody + */ + public static DBody createSphereBody(CollisionEngine collisionEngine, double radius){ + DSphere geom = collisionEngine.createSphereGeom(radius); + return collisionEngine.createDBody(geom); + } + + + /** + * Creates an ode DBody from a terrain chunk data object + * @param data The terrain data + * @return The DBody + */ + public static DBody generateBodyFromTerrainData(CollisionEngine collisionEngine, TerrainChunkData data){ + DBody body = null; + + //create data + int numberTriangles = data.getFaceElements().size() / 3; + int numberVertices = data.getVertices().size() / 3; + + float[] vertices = new float[numberVertices * 3]; + int vertexInserterPos = 0; + int[] indices = new int[numberTriangles * 3]; + int indexInserterPos = 0; + + for(float vertexValue : data.getVertices()){ + vertices[vertexInserterPos] = vertexValue; + vertexInserterPos++; + } + + for(int element : data.getFaceElements()){ + indices[indexInserterPos] = element; + indexInserterPos++; + } + + //create trimesh + if(vertices.length > 0){ + DTriMesh triMesh = collisionEngine.createTrimeshGeom(vertices,indices); + body = collisionEngine.createDBody(triMesh); + } + + return body; + } + + /** + * Generates a body from an AIScene + * @param scene The AIScene to generate a rigid body off of + * @return A rigid body based on the AIScene + */ + public static DBody generateRigidBodyFromAIScene(CollisionEngine collisionEngine, AIScene scene){ + + DBody body = collisionEngine.createDBody(null); + + PointerBuffer meshesBuffer = scene.mMeshes(); + while(meshesBuffer.hasRemaining()){ + float[] verts; + int numVertices; + int[] indices; + int numTriangles; + + AIMesh aiMesh = AIMesh.create(meshesBuffer.get()); + //allocate array for vertices + numVertices = aiMesh.mNumVertices(); + verts = new float[numVertices * 3]; + //read vertices + AIVector3D.Buffer vertexBuffer = aiMesh.mVertices(); + int vertPos = 0; + while(vertexBuffer.hasRemaining()){ + AIVector3D vector = vertexBuffer.get(); + verts[vertPos+0] = vector.x(); + verts[vertPos+1] = vector.y(); + verts[vertPos+2] = vector.z(); + vertPos = vertPos + 3; + } + numTriangles = aiMesh.mNumFaces(); + indices = new int[numTriangles * 3]; + int indicesPos = 0; + //read faces + AIFace.Buffer faceBuffer = aiMesh.mFaces(); + while(faceBuffer.hasRemaining()){ + AIFace currentFace = faceBuffer.get(); + IntBuffer indexBuffer = currentFace.mIndices(); + while(indexBuffer.hasRemaining()){ + int index = indexBuffer.get(); + indices[indicesPos] = index; + indicesPos++; + } + } + DTriMesh meshGeom = collisionEngine.createTrimeshGeom(verts, indices); + meshGeom.setBody(body); + } + + return body; + } + +} diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index 4f7014c6..6c26c724 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -61,6 +61,7 @@ public class CollisionEngine { //world data that the collision engine leverages for position correction and the like CollisionWorldData collisionWorldData; + //Ode-specific stuff private DWorld world; private DSpace space; private Semaphore spaceLock = new Semaphore(1); @@ -68,17 +69,19 @@ public class CollisionEngine { private static final int MAX_CONTACTS = 1; // maximum number of contact points per body - List collisionEntities = new ArrayList(); - List physicsEntities = new ArrayList(); - List dynamicPhysicsEntities = new ArrayList(); - List structurePhysicsEntities = new ArrayList(); + //The list of dbodies ode should be tracking List bodies = new ArrayList(); + + //This is used to relate DBody's back to their collidables so that when the library detects a collision, the callback can know which collidables are involved. Map bodyPointerMap = new HashMap(); + + //The list of all collidables the engine is currently tracking List collidableList = new ArrayList(); //callbacks for collision check RayCastCallback rayCastCallback = new RayCastCallback(); + //physics damping static final float linearDamping = 0.02f; public CollisionEngine(){ @@ -156,6 +159,10 @@ public class CollisionEngine { collidable.clear(); } } + + public List getCollidables(){ + return collidableList; + } /** @@ -322,14 +329,6 @@ public class CollisionEngine { } - public void registerCollidableEntity(Entity collidable){ - collisionEntities.add(collidable); - } - - public List getCollisionEntities(){ - return collisionEntities; - } - /** * Sets the collision world data * @param collisionWorldData The collision world data @@ -352,48 +351,18 @@ public class CollisionEngine { } } - public void registerPhysicsEntity(Entity physicsEntity){ - physicsEntities.add(physicsEntity); - } - - public List getPhysicsEntities(){ - return physicsEntities; - } - - public void deregisterPhysicsEntity(Entity physicsEntity){ - physicsEntities.remove(physicsEntity); - } - - public void registerDynamicPhysicsEntity(Entity dynamicEntity){ - dynamicPhysicsEntities.add(dynamicEntity); - } - - public void deregisterDynamicPhysicsEntity(Entity dynamicEntity){ - dynamicPhysicsEntities.remove(dynamicEntity); - } - - public List getDynamicPhysicsEntities(){ - return dynamicPhysicsEntities; - } - - public void registerStructurePhysicsEntity(Entity structureEntity){ - structurePhysicsEntities.add(structureEntity); - } - - public List getStructurePhysicsEntities(){ - return structurePhysicsEntities; - } - + /** + * Main function to resynchronize entity positions with physics object positions after impulses are applied. + */ public void updateDynamicObjectTransforms(){ - for(Entity dynamicEntity : dynamicPhysicsEntities){ - DBody rigidBody = (DBody)dynamicEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); - Vector3d offset = (Vector3d)dynamicEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET); + for(Collidable collidable : collidableList){ + Entity physicsEntity = collidable.getParent(); + DBody rigidBody = (DBody)physicsEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); + Vector3d offset = (Vector3d)physicsEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET); Vector3d newPosition = PhysicsUtils.getRigidBodyPosition(rigidBody).sub(offset); Quaterniond newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody); -// System.out.println(rigidBody + " position " + newPosition); -// System.out.println("Linear velocity: " + rigidBody.getLinearVelocity(new javax.vecmath.Vector3f())); - EntityUtils.getPosition(dynamicEntity).set(newPosition); - EntityUtils.getRotation(dynamicEntity).set(newRotation); + EntityUtils.getPosition(physicsEntity).set(newPosition); + EntityUtils.getRotation(physicsEntity).set(newRotation); } } @@ -410,15 +379,6 @@ public class CollisionEngine { } } - /* - Check if the entity is being accelerated by gravity - */ - // public boolean gravityCheck(CommonWorldData w, Entity e){ - // double worldHeight = w.getElevationAtPoint(EntityUtils.getPosition(e)); - // double entityHeight = EntityUtils.getPosition(e).y; - // return entityHeight > worldHeight + 0.1f; - // } - /** * Casts a ray into the scene and returns the first entity that the ray collides with. @@ -539,28 +499,12 @@ public class CollisionEngine { } } - public void deregisterCollidableEntity(Entity e){ - if(collisionEntities.contains(e)){ - collisionEntities.remove(e); - } - if(physicsEntities.contains(e)){ - physicsEntities.remove(e); - } - if(dynamicPhysicsEntities.contains(e)){ - dynamicPhysicsEntities.remove(e); - } - if(structurePhysicsEntities.contains(e)){ - structurePhysicsEntities.remove(e); - } - } - public void destroyEntityThatHasPhysics(Entity e){ //make uncollidable if(e.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY)){ DBody rigidBody = (DBody)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); deregisterPhysicsObject(rigidBody); } - deregisterCollidableEntity(e); } /** diff --git a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java new file mode 100644 index 00000000..89081b73 --- /dev/null +++ b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java @@ -0,0 +1,270 @@ +package electrosphere.collision; + +import org.joml.Matrix4f; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.ode4j.ode.DBody; +import org.ode4j.ode.DTriMesh; + +import electrosphere.collision.collidable.Collidable; +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.state.collidable.ClientCollidableTree; +import electrosphere.entity.state.collidable.ServerCollidableTree; +import electrosphere.entity.types.terrain.TerrainChunkData; +import electrosphere.game.data.collidable.CollidableTemplate; +import electrosphere.server.datacell.Realm; +import electrosphere.server.datacell.utils.ServerEntityTagUtils; + +/** + * Utilities for performing physics-related operations on entities (particularly attaching physics to them in the first place) + */ +public class PhysicsEntityUtils { + + /** + * [CLIENT ONLY] Attaches a collidable template to a given entity + * @param rVal The entity + * @param physicsTemplate The collidable template + */ + public static void clientAttachCollidableTemplate(Entity rVal, CollidableTemplate physicsTemplate){ + DBody rigidBody; + Collidable collidable; + float mass = 1.0f; + Matrix4f inertiaTensor; + Vector3f scale; + switch(physicsTemplate.getType()){ + case "CYLINDER": { + rigidBody = CollisionBodyCreation.createCylinderBody( + Globals.clientSceneWrapper.getCollisionEngine(), + physicsTemplate.getDimension1(), + physicsTemplate.getDimension2() + ); + collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); + ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody); + rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); + rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); + rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); + rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); + rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree); + + scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); + rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); + //inertia tensor + //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html + 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()); + + Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); + Globals.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); + } break; + case "CUBE": { + rigidBody = CollisionBodyCreation.createCubeBody( + Globals.clientSceneWrapper.getCollisionEngine(), + new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()) + ); + collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); + ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody); + rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); + rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); + rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); + rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); + rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree); + + scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); + rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); + //inertia tensor + //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html + inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); + rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); + + Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); + Globals.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); + } break; + } + } + + + /** + * [SERVER ONLY] Attaches a collidable template to a given entity + * @param realm The realm the entity is inside of + * @param rVal The entity + * @param physicsTemplate The collidable template + */ + public static void serverAttachCollidableTemplate(Realm realm, Entity rVal, CollidableTemplate physicsTemplate){ + DBody rigidBody; + Collidable collidable; + float mass = 1.0f; + Matrix4f inertiaTensor; + Vector3f scale; + switch(physicsTemplate.getType()){ + case "CYLINDER": { + rigidBody = CollisionBodyCreation.createCylinderBody( + realm.getCollisionEngine(), + physicsTemplate.getDimension1(), + physicsTemplate.getDimension2() + ); + collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); + ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody); + rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); + rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); + rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); + rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); + rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree); + + scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); + rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); + //inertia tensor + //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html + 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()); + + realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); + ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); + } break; + case "CUBE": { + rigidBody = CollisionBodyCreation.createCubeBody(realm.getCollisionEngine(),new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3())); + collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); + ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody); + rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); + rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); + rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); + rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); + rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree); + + scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); + rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); + //inertia tensor + //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html + inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); + rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); + + realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); + ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); + } break; + } + } + + + + + /** + * [CLIENT ONLY] Attaches a heightmap dbody to an entity + * @param terrain The terrain entity + * @param heightfield The heightfield values + * @return The DBody created + */ + public static DBody clientAttachTerrainRigidBody(Entity terrain, CollisionEngine collisionEngine, float[][] heightfield){ + Vector3d position = EntityUtils.getPosition(terrain); + int arrayLength = heightfield.length; + int arrayWidth = heightfield[0].length; + float collisionMargin = 0.08f; + + /* + Traditional buffer code not working for some reason + the approach of + https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider + works much better + IDK why + */ + + int numberTriangles = (arrayLength - 1) * (arrayWidth - 1) * 2; + int triangleStride = 0; + + int numberVertices = arrayLength * arrayWidth; + int vertexStride = 0; + + float[] vertices = new float[numberVertices * 3]; + int vertexInserterPos = 0; + int[] indices = new int[numberTriangles * 3]; + int indexInserterPos = 0; + + for(int x = 0; x < arrayLength; x++){ + for(int y = 0; y < arrayWidth; y++){ + vertices[vertexInserterPos] = x; + vertexInserterPos++; + vertices[vertexInserterPos] = heightfield[x][y] - collisionMargin; + vertexInserterPos++; + vertices[vertexInserterPos] = y; + vertexInserterPos++; + if(x < arrayLength - 1 && y < arrayWidth - 1){ + //if we should also add a triangle index + /* + as copied from ModelUtil's terrain mesh generation function + faces.put((x / stride + 0) * actualHeight + (y / stride + 0)); + faces.put((x / stride + 0) * actualHeight + (y / stride + 1)); + faces.put((x / stride + 1) * actualHeight + (y / stride + 0)); + faces.put((x / stride + 1) * actualHeight + (y / stride + 0)); + faces.put((x / stride + 0) * actualHeight + (y / stride + 1)); + faces.put((x / stride + 1) * actualHeight + (y / stride + 1)); + */ + indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 0); + indexInserterPos++; + indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1); + indexInserterPos++; + indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0); + indexInserterPos++; + indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0); + indexInserterPos++; + indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1); + indexInserterPos++; + indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 1); + indexInserterPos++; + } + } + } + + DTriMesh triMesh = collisionEngine.createTrimeshGeom(vertices,indices); + DBody body = collisionEngine.createDBody(triMesh); + + Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(body, new Collidable(terrain,Collidable.TYPE_TERRAIN)); + terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, body); + + return body; + } + + + /** + * [CLIENT ONLY] Given an entity and a terrain chunk description, create physics for the chunk and attach it to the entity + * @param terrain The entity + * @param data The terrain description + * @return The rigid body created (note, attachment has already been performed) + */ + public static DBody clientAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){ + Vector3d position = EntityUtils.getPosition(terrain); + DBody terrainBody = CollisionBodyCreation.generateBodyFromTerrainData(Globals.clientSceneWrapper.getCollisionEngine(), data); + + + Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_TERRAIN)); + terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainBody); + + return terrainBody; + } + + + /** + * [SERVER ONLY] Given an entity and a terrain chunk description, create physics for the chunk and attach it to the entity + * @param terrain The entity + * @param data The terrain description + * @return The rigid body created (note, attachment has already been performed) + */ + public static DBody serverAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){ + Vector3d position = EntityUtils.getPosition(terrain); + Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain); + DBody terrainBody = CollisionBodyCreation.generateBodyFromTerrainData(terrainRealm.getCollisionEngine(),data); + + terrainRealm.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_TERRAIN)); + terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainBody); + + return terrainBody; + } + +} diff --git a/src/main/java/electrosphere/collision/PhysicsUtils.java b/src/main/java/electrosphere/collision/PhysicsUtils.java index b48fcfcd..031630d8 100644 --- a/src/main/java/electrosphere/collision/PhysicsUtils.java +++ b/src/main/java/electrosphere/collision/PhysicsUtils.java @@ -1,240 +1,17 @@ package electrosphere.collision; -import java.nio.IntBuffer; - import org.joml.Quaterniond; import org.joml.Vector3d; -import org.lwjgl.PointerBuffer; -import org.lwjgl.assimp.AIFace; -import org.lwjgl.assimp.AIMesh; -import org.lwjgl.assimp.AIScene; -import org.lwjgl.assimp.AIVector3D; import org.ode4j.math.DQuaternion; import org.ode4j.math.DQuaternionC; import org.ode4j.ode.DBody; -import org.ode4j.ode.DBox; -import org.ode4j.ode.DCylinder; import org.ode4j.ode.DMass; -import org.ode4j.ode.DPlane; -import org.ode4j.ode.DSphere; -import org.ode4j.ode.DTriMesh; - -import electrosphere.collision.collidable.Collidable; -import electrosphere.engine.Globals; -import electrosphere.entity.Entity; -import electrosphere.entity.EntityDataStrings; -import electrosphere.entity.EntityUtils; -import electrosphere.entity.types.terrain.TerrainChunkData; -import electrosphere.server.datacell.Realm; /** * Utilities for leveraging the collision system to perform physics */ public class PhysicsUtils { - - /** - * Attaches a heightmap dbody to an entity - * @param terrain The terrain entity - * @param heightfield The heightfield values - * @return The DBody created - */ - public static DBody clientAttachTerrainRigidBody(Entity terrain, CollisionEngine collisionEngine, float[][] heightfield){ - - Vector3d position = EntityUtils.getPosition(terrain); - - int arrayLength = heightfield.length; - int arrayWidth = heightfield[0].length; - - float collisionMargin = 0.08f; - - /* - Traditional buffer code not working for some reason - the approach of - https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider - works much better - IDK why - */ - - int numberTriangles = (arrayLength - 1) * (arrayWidth - 1) * 2; - int triangleStride = 0; - - int numberVertices = arrayLength * arrayWidth; - int vertexStride = 0; - - float[] vertices = new float[numberVertices * 3]; - int vertexInserterPos = 0; - int[] indices = new int[numberTriangles * 3]; - int indexInserterPos = 0; - - for(int x = 0; x < arrayLength; x++){ - for(int y = 0; y < arrayWidth; y++){ - vertices[vertexInserterPos] = x; - vertexInserterPos++; - vertices[vertexInserterPos] = heightfield[x][y] - collisionMargin; - vertexInserterPos++; - vertices[vertexInserterPos] = y; - vertexInserterPos++; - if(x < arrayLength - 1 && y < arrayWidth - 1){ - //if we should also add a triangle index - /* - as copied from ModelUtil's terrain mesh generation function - faces.put((x / stride + 0) * actualHeight + (y / stride + 0)); - faces.put((x / stride + 0) * actualHeight + (y / stride + 1)); - faces.put((x / stride + 1) * actualHeight + (y / stride + 0)); - faces.put((x / stride + 1) * actualHeight + (y / stride + 0)); - faces.put((x / stride + 0) * actualHeight + (y / stride + 1)); - faces.put((x / stride + 1) * actualHeight + (y / stride + 1)); - */ - indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 0); - indexInserterPos++; - indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1); - indexInserterPos++; - indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0); - indexInserterPos++; - indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0); - indexInserterPos++; - indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1); - indexInserterPos++; - indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 1); - indexInserterPos++; - } - } - } - - - - DTriMesh triMesh = collisionEngine.createTrimeshGeom(vertices,indices); - - DBody body = collisionEngine.createDBody(triMesh); - - Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(body, new Collidable(terrain,Collidable.TYPE_TERRAIN)); - - terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, body); - - return body; - } - - - public static DBody clientAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){ - - Vector3d position = EntityUtils.getPosition(terrain); - - DBody terrainBody = generateBodyFromTerrainData(Globals.clientSceneWrapper.getCollisionEngine(), data); - - - Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_TERRAIN)); - - terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainBody); - - return terrainBody; - } - - - public static DBody serverAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){ - - Vector3d position = EntityUtils.getPosition(terrain); - Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain); - - DBody terrainBody = generateBodyFromTerrainData(terrainRealm.getCollisionEngine(),data); - - - - terrainRealm.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_TERRAIN)); - - terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainBody); - - return terrainBody; - } - - - /** - * Creates an ode DBody from a terrain chunk data object - * @param data The terrain data - * @return The DBody - */ - private static DBody generateBodyFromTerrainData(CollisionEngine collisionEngine, TerrainChunkData data){ - DBody body = null; - - //create data - int numberTriangles = data.getFaceElements().size() / 3; - int numberVertices = data.getVertices().size() / 3; - - float[] vertices = new float[numberVertices * 3]; - int vertexInserterPos = 0; - int[] indices = new int[numberTriangles * 3]; - int indexInserterPos = 0; - - for(float vertexValue : data.getVertices()){ - vertices[vertexInserterPos] = vertexValue; - vertexInserterPos++; - } - - for(int element : data.getFaceElements()){ - indices[indexInserterPos] = element; - indexInserterPos++; - } - - //create trimesh - if(vertices.length > 0){ - DTriMesh triMesh = collisionEngine.createTrimeshGeom(vertices,indices); - body = collisionEngine.createDBody(triMesh); - } - - return body; - } - - /** - * Generates a body from an AIScene - * @param scene The AIScene to generate a rigid body off of - * @return A rigid body based on the AIScene - */ - public static DBody generateRigidBodyFromAIScene(CollisionEngine collisionEngine, AIScene scene){ - - DBody body = collisionEngine.createDBody(null); - - PointerBuffer meshesBuffer = scene.mMeshes(); - while(meshesBuffer.hasRemaining()){ - float[] verts; - int numVertices; - int[] indices; - int numTriangles; - - AIMesh aiMesh = AIMesh.create(meshesBuffer.get()); - //allocate array for vertices - numVertices = aiMesh.mNumVertices(); - verts = new float[numVertices * 3]; - //read vertices - AIVector3D.Buffer vertexBuffer = aiMesh.mVertices(); - int vertPos = 0; - while(vertexBuffer.hasRemaining()){ - AIVector3D vector = vertexBuffer.get(); - verts[vertPos+0] = vector.x(); - verts[vertPos+1] = vector.y(); - verts[vertPos+2] = vector.z(); - vertPos = vertPos + 3; - } - numTriangles = aiMesh.mNumFaces(); - indices = new int[numTriangles * 3]; - int indicesPos = 0; - //read faces - AIFace.Buffer faceBuffer = aiMesh.mFaces(); - while(faceBuffer.hasRemaining()){ - AIFace currentFace = faceBuffer.get(); - IntBuffer indexBuffer = currentFace.mIndices(); - while(indexBuffer.hasRemaining()){ - int index = indexBuffer.get(); - indices[indicesPos] = index; - indicesPos++; - } - } - DTriMesh meshGeom = collisionEngine.createTrimeshGeom(verts, indices); - meshGeom.setBody(body); - } - - return body; - } - /** * Gets the current position of a rigid body as a joml vector * @param body The dbody @@ -290,53 +67,6 @@ public class PhysicsUtils { public static void setRigidBodyTransform(CollisionEngine collisionEngine, Vector3d position, Quaterniond rotation, DBody body){ collisionEngine.setBodyTransform(body, position, rotation); } - - //The width of a plane rigid body - //It's really a box under the hood - static final double PLANE_WIDTH = 0.3; - - /** - * Creates a plane DBody. Dimensions x and z control the length and width of the plane; - * @param dimensions The dimensions of the plane - * @return The DBody - */ - public static DBody createPlaneBody(CollisionEngine collisionEngine, Vector3d dimensions){ - DBox geom = collisionEngine.createCubeGeom(new Vector3d(dimensions.x,PLANE_WIDTH,dimensions.z)); - return collisionEngine.createDBody(geom); - } - - /** - * Creates a cube DBody. Dimensions controlled by the dimensions vector. - * @param collisionEngine The collision engine to create the body inside of - * @param dimensions The dimensions of the cube - * @return The DBody - */ - public static DBody createCubeBody(CollisionEngine collisionEngine, Vector3d dimensions){ - DBox geom = collisionEngine.createCubeGeom(new Vector3d(dimensions)); - return collisionEngine.createDBody(geom); - } - - /** - * Creates a cylinder DBody. Dimensions controlled by the dimensions vector. - * @param collisionEngine The collision engine to create the body inside of - * @param dimensions The dimensions of the cube - * @return The DBody - */ - public static DBody createCylinderBody(CollisionEngine collisionEngine, double radius, double length){ - DCylinder geom = collisionEngine.createCylinderGeom(radius,length); - return collisionEngine.createDBody(geom); - } - - /** - * Creates a sphere body in the collision engine - * @param collisionEngine The collision engine - * @param radius The radius of the sphere - * @return The DBody - */ - public static DBody createSphereBody(CollisionEngine collisionEngine, double radius){ - DSphere geom = collisionEngine.createSphereGeom(radius); - return collisionEngine.createDBody(geom); - } /** * Creates a mass in the physics space from the body and mass value input diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java index c1df6a31..2bb56fd7 100644 --- a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java +++ b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java @@ -1,6 +1,7 @@ package electrosphere.engine.assetmanager; import electrosphere.audio.AudioBuffer; +import electrosphere.collision.CollisionBodyCreation; import electrosphere.collision.CollisionEngine; import electrosphere.collision.PhysicsUtils; import electrosphere.renderer.Mesh; @@ -77,7 +78,7 @@ public class AssetManager { physicsMeshesToLoad.remove(physicsMeshQueueItem); physicsMeshesLoadedIntoMemory.put( getCollisionMeshMapKey(physicsMeshQueueItem.collisionEngine,currentPath), - PhysicsUtils.generateRigidBodyFromAIScene(physicsMeshQueueItem.collisionEngine,aiScene) + CollisionBodyCreation.generateRigidBodyFromAIScene(physicsMeshQueueItem.collisionEngine,aiScene) ); } } diff --git a/src/main/java/electrosphere/entity/state/collidable/ClientCollidableTree.java b/src/main/java/electrosphere/entity/state/collidable/ClientCollidableTree.java index 13e4afd7..278144bb 100644 --- a/src/main/java/electrosphere/entity/state/collidable/ClientCollidableTree.java +++ b/src/main/java/electrosphere/entity/state/collidable/ClientCollidableTree.java @@ -16,7 +16,7 @@ import electrosphere.entity.state.BehaviorTree; import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.item.ItemUtils; -import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.collidable.CollidableTemplate; /** * diff --git a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java index 21e756e9..4633eccf 100644 --- a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java +++ b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java @@ -12,7 +12,7 @@ import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.debug.DebugVisualizerUtils; import electrosphere.entity.types.item.ItemUtils; -import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.server.datacell.Realm; import org.joml.Matrix4f; diff --git a/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java index 797e4036..a122fcc4 100644 --- a/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java +++ b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java @@ -6,6 +6,7 @@ import org.joml.Vector3d; import org.joml.Vector3f; import org.ode4j.ode.DBody; +import electrosphere.collision.CollisionBodyCreation; import electrosphere.collision.CollisionEngine; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; @@ -28,11 +29,10 @@ public class CollisionObjUtils { float mass = 1.0f; - DBody planeObject = PhysicsUtils.createPlaneBody(Globals.clientSceneWrapper.getCollisionEngine(),new Vector3d(scale)); + DBody planeObject = CollisionBodyCreation.createPlaneBody(Globals.clientSceneWrapper.getCollisionEngine(),new Vector3d(scale)); PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, planeObject); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(planeObject, collidable); - Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true); rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); @@ -55,11 +55,10 @@ public class CollisionObjUtils { float mass = 1.0f; - DBody planeObject = PhysicsUtils.createPlaneBody(realm.getCollisionEngine(),new Vector3d(scale)); + DBody planeObject = CollisionBodyCreation.createPlaneBody(realm.getCollisionEngine(),new Vector3d(scale)); PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), position, rotation, planeObject); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); realm.getCollisionEngine().registerCollisionObject(planeObject, collidable); - realm.getCollisionEngine().registerStructurePhysicsEntity(rVal); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true); rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); @@ -83,11 +82,10 @@ public class CollisionObjUtils { float mass = 1.0f; - DBody cubeObject = PhysicsUtils.createCubeBody(Globals.clientSceneWrapper.getCollisionEngine(),new Vector3d(scale)); + DBody cubeObject = CollisionBodyCreation.createCubeBody(Globals.clientSceneWrapper.getCollisionEngine(),new Vector3d(scale)); PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, cubeObject); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable); - Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true); rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); @@ -110,11 +108,10 @@ public class CollisionObjUtils { float mass = 1.0f; - DBody cubeObject = PhysicsUtils.createCubeBody(realm.getCollisionEngine(),new Vector3d(scale)); + DBody cubeObject = CollisionBodyCreation.createCubeBody(realm.getCollisionEngine(),new Vector3d(scale)); PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), position, rotation, cubeObject); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable); - realm.getCollisionEngine().registerStructurePhysicsEntity(rVal); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true); rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); @@ -136,11 +133,10 @@ public class CollisionObjUtils { Entity rVal = EntityCreationUtils.createClientSpatialEntity(); float mass = 1.0f; - DBody cubeObject = PhysicsUtils.createCylinderBody(Globals.clientSceneWrapper.getCollisionEngine(),scale.x,scale.y); + DBody cubeObject = CollisionBodyCreation.createCylinderBody(Globals.clientSceneWrapper.getCollisionEngine(),scale.x,scale.y); PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, cubeObject); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable); - Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CYLINDER, true); rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); @@ -165,11 +161,10 @@ public class CollisionObjUtils { Entity rVal = EntityCreationUtils.createServerEntity(realm, new Vector3d(position)); float mass = 1.0f; - DBody cubeObject = PhysicsUtils.createCylinderBody(realm.getCollisionEngine(),scale.x,scale.y); + DBody cubeObject = CollisionBodyCreation.createCylinderBody(realm.getCollisionEngine(),scale.x,scale.y); PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), position, rotation, cubeObject); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable); - realm.getCollisionEngine().registerStructurePhysicsEntity(rVal); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CYLINDER, true); rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); @@ -303,7 +298,6 @@ public class CollisionObjUtils { Collidable collidable = new Collidable(entity, collidableType); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(collisionObject, collidable); - Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(entity); entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject); //update world transform of collision object @@ -335,7 +329,6 @@ public class CollisionObjUtils { Realm realm = Globals.realmManager.getEntityRealm(entity); realm.getCollisionEngine().registerCollisionObject(collisionObject, collidable); - realm.getCollisionEngine().registerPhysicsEntity(entity); entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject); //update world transform of collision object diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index d0f3f478..ef4b50e2 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -8,6 +8,8 @@ import org.joml.Vector3d; import org.joml.Vector3f; import org.ode4j.ode.DBody; +import electrosphere.collision.CollisionBodyCreation; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; @@ -47,7 +49,7 @@ import electrosphere.entity.state.rotator.ServerRotatorTree; import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.entity.types.hitbox.HitboxUtils; -import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.SprintSystem; import electrosphere.game.data.creature.type.attack.AttackMove; @@ -78,55 +80,9 @@ import electrosphere.server.poseactor.PoseActorUtils; import electrosphere.util.Utilities; /** - * - * @author amaterasu + * Utilities for creating creatures on the client and server */ public class CreatureUtils { -// public static Entity spawnBasicCreature(int creatureId, float acceleration, float maxVelocity){ -// Entity rVal = new Entity(); -// rVal.putData(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE, true); -// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, Globals.entityTypeMap.get(creatureId).getModelPath()); -// Globals.assetManager.addModelPathToQueue(Globals.entityTypeMap.get(creatureId).getModelPath()); -// rVal.putData(EntityDataStrings.DATA_STRING_CREATURE_TYPE, creatureId); -// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3f(0,0,0)); -// rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().rotateAxis((float)0, new Vector3f(1,0,0))); -// rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1)); -// rVal.putData(EntityDataStrings.DATA_STRING_MOVEMENT_BT, new MovementTree(rVal)); -// rVal.putData(EntityDataStrings.DATA_STRING_MOVEMENT_VECTOR, new Vector3f(0,0,0)); -// rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, maxVelocity); -// rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, acceleration); -// rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f); -// Globals.entityManager.registerEntity(rVal); -// Globals.entityManager.registerDrawableEntity(rVal); -// Globals.entityManager.registerMoveableEntity(rVal); -// return rVal; -// } - - // /** - // * Spawns a server-side creature entity - // * @param type The type of creature - // * @param template The creature template if applicable - // * @param realm The realm to spawn the creature in - // * @param position The position to place the creature at - // * @return The creature entity - // */ - // public static Entity serverSpawnCreature(String type, CreatureTemplate template, Realm realm, Vector3d position){ - // Entity rVal = EntityCreationUtils.createServerEntity(realm, position); - // spawnBasicCreature(rVal, type, template, true); - // return rVal; - // } - - // /** - // * Spawns a client-side creature entity - // * @param type The type of creature - // * @param template The creature template if applicable - // * @return The creature entity - // */ - // public static Entity clientSpawnCreature(String type, CreatureTemplate template){ - // Entity rVal = EntityCreationUtils.createClientEntity(); - // spawnBasicCreature(rVal, type, template, false); - // return rVal; - // } /** * Spawns a client-side creature entity @@ -154,69 +110,10 @@ public class CreatureUtils { rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST, hitboxList); rVal.putData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST, hurtboxList); } + //Physics object if(rawType.getCollidable() != null){ CollidableTemplate physicsTemplate = rawType.getCollidable(); - DBody rigidBody; - Collidable collidable; - float mass = 1.0f; - Matrix4f inertiaTensor; - Vector3f scale; - switch(physicsTemplate.getType()){ - case "CYLINDER": { - rigidBody = PhysicsUtils.createCylinderBody( - Globals.clientSceneWrapper.getCollisionEngine(), - physicsTemplate.getDimension1(), - physicsTemplate.getDimension2() - ); - collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); - ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - 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()); - - Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal); - Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - Globals.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); - } break; - case "CUBE": { - rigidBody = PhysicsUtils.createCubeBody( - Globals.clientSceneWrapper.getCollisionEngine(), - new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()) - ); - collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); - ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); - - Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal); - Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - Globals.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE); - } break; - } + PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate); } // // @@ -513,64 +410,7 @@ public class CreatureUtils { } if(rawType.getCollidable() != null){ CollidableTemplate physicsTemplate = rawType.getCollidable(); - DBody rigidBody; - Collidable collidable; - float mass = 1.0f; - Matrix4f inertiaTensor; - Vector3f scale; - switch(physicsTemplate.getType()){ - case "CYLINDER": { - rigidBody = PhysicsUtils.createCylinderBody( - realm.getCollisionEngine(), - physicsTemplate.getDimension1(), - physicsTemplate.getDimension2() - ); - collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); - ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - 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()); - - realm.getCollisionEngine().registerPhysicsEntity(rVal); - realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); - } break; - case "CUBE": { - rigidBody = PhysicsUtils.createCubeBody(realm.getCollisionEngine(),new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3())); - collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); - ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); - - realm.getCollisionEngine().registerPhysicsEntity(rVal); - realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); - } break; - } + PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate); } // // diff --git a/src/main/java/electrosphere/entity/types/item/ItemUtils.java b/src/main/java/electrosphere/entity/types/item/ItemUtils.java index 8677894f..c856f39b 100644 --- a/src/main/java/electrosphere/entity/types/item/ItemUtils.java +++ b/src/main/java/electrosphere/entity/types/item/ItemUtils.java @@ -10,6 +10,8 @@ import org.ode4j.ode.DBody; import org.ode4j.ode.DSpace; import org.ode4j.ode.DWorld; +import electrosphere.collision.CollisionBodyCreation; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; @@ -24,7 +26,7 @@ import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.state.gravity.ServerGravityTree; import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.entity.types.hitbox.HitboxUtils; -import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.game.data.item.type.EquipWhitelist; import electrosphere.game.data.item.type.Item; import electrosphere.game.data.item.type.WeaponData; @@ -64,70 +66,12 @@ public class ItemUtils { rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass()); rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData); } + //physics if(item.getCollidable() != null){ CollidableTemplate physicsTemplate = item.getCollidable(); - DBody rigidBody; - Collidable collidable; - float mass = 1.0f; - Matrix4f inertiaTensor; - Vector3f scale; - DWorld dWorld = Globals.clientSceneWrapper.getCollisionEngine().getDWorld(); - DSpace dSpace = Globals.clientSceneWrapper.getCollisionEngine().getSpace(); - switch(physicsTemplate.getType()){ - case "CYLINDER": - rigidBody = PhysicsUtils.createCylinderBody( - Globals.clientSceneWrapper.getCollisionEngine(), - physicsTemplate.getDimension1(), - physicsTemplate.getDimension2() - ); - collidable = new Collidable(rVal, Collidable.TYPE_ITEM); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, new ClientCollidableTree(rVal,collidable,rigidBody)); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - 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()); - - Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal); - Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.COLLIDABLE); - break; - case "CUBE": - rigidBody = PhysicsUtils.createCubeBody( - Globals.clientSceneWrapper.getCollisionEngine(), - new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()) - ); - collidable = new Collidable(rVal, Collidable.TYPE_ITEM); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, new ClientCollidableTree(rVal,collidable,rigidBody)); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); - - Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal); - Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.COLLIDABLE); - break; - } + PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate); } + //tokens for(String token : item.getTokens()){ switch(token){ case "BLENDER_TRANSFORM": @@ -195,65 +139,12 @@ public class ItemUtils { rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass()); rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData); } + //physics if(item.getCollidable() != null){ CollidableTemplate physicsTemplate = item.getCollidable(); - DBody rigidBody; - Collidable collidable; - float mass = 1.0f; - Matrix4f inertiaTensor; - Vector3f scale; - switch(physicsTemplate.getType()){ - case "CYLINDER": - rigidBody = PhysicsUtils.createCylinderBody( - realm.getCollisionEngine(), - physicsTemplate.getDimension1(), - physicsTemplate.getDimension2() - ); - collidable = new Collidable(rVal, Collidable.TYPE_ITEM); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, new ServerCollidableTree(rVal,collidable,rigidBody)); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - 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()); - - realm.getCollisionEngine().registerPhysicsEntity(rVal); - realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); - break; - case "CUBE": - rigidBody = PhysicsUtils.createCubeBody(realm.getCollisionEngine(),new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3())); - collidable = new Collidable(rVal, Collidable.TYPE_ITEM); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, new ServerCollidableTree(rVal,collidable,rigidBody)); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); - - realm.getCollisionEngine().registerPhysicsEntity(rVal); - realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); - break; - } + PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate); } + //tokens for(String token : item.getTokens()){ switch(token){ case "BLENDER_TRANSFORM": diff --git a/src/main/java/electrosphere/entity/types/object/ObjectUtils.java b/src/main/java/electrosphere/entity/types/object/ObjectUtils.java index 21626760..2b8b5e4d 100644 --- a/src/main/java/electrosphere/entity/types/object/ObjectUtils.java +++ b/src/main/java/electrosphere/entity/types/object/ObjectUtils.java @@ -5,6 +5,8 @@ import org.joml.Vector3d; import org.joml.Vector3f; import org.ode4j.ode.DBody; +import electrosphere.collision.CollisionBodyCreation; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; @@ -25,7 +27,7 @@ import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.inventory.ServerInventoryState; import electrosphere.entity.state.inventory.UnrelationalInventoryState; import electrosphere.entity.types.collision.CollisionObjUtils; -import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.game.data.object.type.ObjectData; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorUtils; @@ -72,71 +74,14 @@ public class ObjectUtils { } break; } } + // //main entity construction + //physics if(rawType.getCollidable() != null){ CollidableTemplate physicsTemplate = rawType.getCollidable(); - DBody rigidBody; - Collidable collidable; - float mass = 1.0f; - Matrix4f inertiaTensor; - Vector3f scale; - switch(physicsTemplate.getType()){ - case "CYLINDER": { - rigidBody = PhysicsUtils.createCylinderBody( - Globals.clientSceneWrapper.getCollisionEngine(), - physicsTemplate.getDimension1(), - physicsTemplate.getDimension2() - ); - collidable = new Collidable(rVal, Collidable.TYPE_OBJECT); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic); - rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - 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()); - - Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal); - Globals.clientSceneWrapper.getScene().registerBehaviorTree(tree); - Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - } break; - case "CUBE": { - rigidBody = PhysicsUtils.createCubeBody( - Globals.clientSceneWrapper.getCollisionEngine(), - new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()) - ); - collidable = new Collidable(rVal, Collidable.TYPE_OBJECT); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic); - rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); - - Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(rVal); - Globals.clientSceneWrapper.getScene().registerBehaviorTree(tree); - Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - } break; - } - Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.COLLIDABLE); + PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate); } + //tokens for(String token : rawType.getTokens()){ switch(token){ case "BLENDER_TRANSFORM": @@ -226,71 +171,14 @@ public class ObjectUtils { } break; } } + // //main entity construction + //physics if(rawType.getCollidable() != null){ CollidableTemplate physicsTemplate = rawType.getCollidable(); - DBody rigidBody; - Collidable collidable; - float mass = 1.0f; - Matrix4f inertiaTensor; - Vector3f scale; - switch(physicsTemplate.getType()){ - case "CYLINDER": { - rigidBody = PhysicsUtils.createCylinderBody( - realm.getCollisionEngine(), - physicsTemplate.getDimension1(), - physicsTemplate.getDimension2() - ); - collidable = new Collidable(rVal, Collidable.TYPE_OBJECT); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic); - rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html - 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()); - - realm.getCollisionEngine().registerPhysicsEntity(rVal); - ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, tree); - realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - } break; - case "CUBE": { - rigidBody = PhysicsUtils.createCubeBody( - realm.getCollisionEngine(), - new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()) - ); - collidable = new Collidable(rVal, Collidable.TYPE_OBJECT); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); - rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ())); - rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); - rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); - ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody, collisionMakeDynamic); - rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree); - - scale = new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()); - rVal.putData(EntityDataStrings.PHYSICS_MASS, mass); - //inertia tensor - //https://hepweb.ucsd.edu/ph110b/110b_notes/node26.html - inertiaTensor = new Matrix4f().identity().scale(mass * scale.x * scale.x / 6.0f).m33(1); - rVal.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); - - realm.getCollisionEngine().registerPhysicsEntity(rVal); - ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, tree); - realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable); - } break; - } - realm.getCollisionEngine().registerDynamicPhysicsEntity(rVal); - ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE); + PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate); } + //tokens for(String token : rawType.getTokens()){ switch(token){ case "BLENDER_TRANSFORM": diff --git a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java index c0c58d35..80f20f3f 100644 --- a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java +++ b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java @@ -3,6 +3,7 @@ package electrosphere.entity.types.terrain; import org.joml.Vector3d; import electrosphere.client.terrain.manager.ClientTerrainManager; +import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityCreationUtils; @@ -32,7 +33,7 @@ public class TerrainChunk { Entity rVal = EntityCreationUtils.createClientSpatialEntity(); EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath); if(data.vertices.size() > 0 && levelOfDetail < 1){ - PhysicsUtils.clientAttachTerrainChunkRigidBody(rVal, data); + PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data); } rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); @@ -55,7 +56,7 @@ public class TerrainChunk { Entity rVal = EntityCreationUtils.createServerEntity(realm, position); if(data.vertices.size() > 0){ - PhysicsUtils.serverAttachTerrainChunkRigidBody(rVal, data); + PhysicsEntityUtils.serverAttachTerrainChunkRigidBody(rVal, data); rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); ServerEntityUtils.initiallyPositionEntity(realm, rVal, position); // physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true); diff --git a/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java b/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java index f152efad..e68b5220 100644 --- a/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java +++ b/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java @@ -16,6 +16,7 @@ import org.joml.Vector4d; import org.joml.Vector4f; import org.ode4j.ode.DBody; +import electrosphere.collision.CollisionBodyCreation; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; @@ -111,7 +112,7 @@ public class ProceduralTree { instancedActor.setAttribute(baseSizeAttribute, 1.0f); //attach physics - DBody rigidBody = PhysicsUtils.createCylinderBody( + DBody rigidBody = CollisionBodyCreation.createCylinderBody( Globals.clientSceneWrapper.getCollisionEngine(), treeModel.getPhysicsBody().getDimension1(), treeModel.getPhysicsBody().getDimension2() @@ -124,8 +125,6 @@ public class ProceduralTree { trunkChild.putData(EntityDataStrings.PHYSICS_MASS, TREE_MASS); - Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(trunkChild); - Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(trunkChild); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); diff --git a/src/main/java/electrosphere/game/data/creature/type/CollidableTemplate.java b/src/main/java/electrosphere/game/data/collidable/CollidableTemplate.java similarity index 85% rename from src/main/java/electrosphere/game/data/creature/type/CollidableTemplate.java rename to src/main/java/electrosphere/game/data/collidable/CollidableTemplate.java index 851a059d..d835badb 100644 --- a/src/main/java/electrosphere/game/data/creature/type/CollidableTemplate.java +++ b/src/main/java/electrosphere/game/data/collidable/CollidableTemplate.java @@ -1,8 +1,7 @@ -package electrosphere.game.data.creature.type; +package electrosphere.game.data.collidable; /** - * - * @author amaterasu + * A template for a rigid body that should be attached to an entity */ public class CollidableTemplate { diff --git a/src/main/java/electrosphere/game/data/creature/type/CreatureType.java b/src/main/java/electrosphere/game/data/creature/type/CreatureType.java index 745c15c7..d14d2bb6 100644 --- a/src/main/java/electrosphere/game/data/creature/type/CreatureType.java +++ b/src/main/java/electrosphere/game/data/creature/type/CreatureType.java @@ -1,6 +1,7 @@ package electrosphere.game.data.creature.type; import electrosphere.entity.types.hitbox.HitboxData; +import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.game.data.creature.type.attack.AttackMove; import electrosphere.game.data.creature.type.attack.AttackMoveResolver; import electrosphere.game.data.creature.type.equip.EquipPoint; diff --git a/src/main/java/electrosphere/game/data/foliage/type/TreeModel.java b/src/main/java/electrosphere/game/data/foliage/type/TreeModel.java index 71755e30..e3216f0c 100644 --- a/src/main/java/electrosphere/game/data/foliage/type/TreeModel.java +++ b/src/main/java/electrosphere/game/data/foliage/type/TreeModel.java @@ -1,6 +1,6 @@ package electrosphere.game.data.foliage.type; -import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.collidable.CollidableTemplate; /** * Describes characteristics about a type of tree (how do the limbs dispere, where to the leaves start growing, how sturdy is it, etc) diff --git a/src/main/java/electrosphere/game/data/item/type/Item.java b/src/main/java/electrosphere/game/data/item/type/Item.java index ff98b41c..431c0670 100644 --- a/src/main/java/electrosphere/game/data/item/type/Item.java +++ b/src/main/java/electrosphere/game/data/item/type/Item.java @@ -1,7 +1,8 @@ package electrosphere.game.data.item.type; import electrosphere.entity.types.hitbox.HitboxData; -import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.collidable.CollidableTemplate; + import java.util.List; public class Item { diff --git a/src/main/java/electrosphere/game/data/object/type/ObjectData.java b/src/main/java/electrosphere/game/data/object/type/ObjectData.java index 1276aabb..8f69a4e1 100644 --- a/src/main/java/electrosphere/game/data/object/type/ObjectData.java +++ b/src/main/java/electrosphere/game/data/object/type/ObjectData.java @@ -1,7 +1,7 @@ package electrosphere.game.data.object.type; import electrosphere.entity.types.hitbox.HitboxData; -import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.game.data.graphics.GraphicsTemplate; import java.util.List; diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index 4a0af0b4..b7362c44 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -75,6 +75,7 @@ import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; +import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; @@ -83,7 +84,7 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.entity.types.hitbox.HitboxUtils; -import electrosphere.game.data.creature.type.CollidableTemplate; +import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum; import electrosphere.renderer.actor.Actor; @@ -927,7 +928,8 @@ public class RenderingEngine { if(Globals.userSettings.graphicsDebugDrawPhysicsObjects()){ Model physicsGraphicsModel; - for(Entity physicsEntity : Globals.clientSceneWrapper.getCollisionEngine().getDynamicPhysicsEntities()){ + for(Collidable collidable : Globals.clientSceneWrapper.getCollisionEngine().getCollidables()){ + Entity physicsEntity = collidable.getParent(); if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){ CollidableTemplate template = (CollidableTemplate)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); switch(template.getType()){ @@ -964,7 +966,8 @@ public class RenderingEngine { } } } - for(Entity physicsEntity : Globals.clientSceneWrapper.getCollisionEngine().getStructurePhysicsEntities()){ + for(Collidable collidable : Globals.clientSceneWrapper.getCollisionEngine().getCollidables()){ + Entity physicsEntity = collidable.getParent(); if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){ if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE)){ if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){ diff --git a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java index b016c386..5f8bcf00 100644 --- a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java +++ b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java @@ -33,7 +33,7 @@ import org.joml.Vector3i; import org.ode4j.ode.DBody; /** - * An entity containing physics for a given chunk on the server + * An entity which contains physics for terrain for a given chunk on the server */ public class PhysicsDataCell { @@ -104,7 +104,6 @@ public class PhysicsDataCell { public void destroyPhysics(){ Realm realm = Globals.realmManager.getEntityRealm(physicsEntity); - realm.getCollisionEngine().deregisterCollidableEntity(physicsEntity); realm.getCollisionEngine().deregisterRigidBody((DBody)physicsObject); }