Physics consolidation

This commit is contained in:
austin 2023-11-05 12:28:19 -05:00
parent 4d15ff3ed5
commit b4426c413b
23 changed files with 540 additions and 790 deletions

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file #maven.buildNumber.plugin properties file
#Sat Sep 02 19:48:14 EDT 2023 #Sun Nov 05 10:58:49 EST 2023
buildNumber=11 buildNumber=12

View File

@ -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. [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

View File

@ -7,10 +7,14 @@ The goal of the physics engine is to wrap around the collision engine to allow p
## Major Usage Notes ## Major Usage Notes
Check Collision Engine Usage Notes as well. They are pretty relevant typically.
## Main Classes ## 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 ## Future Goals
- Library Scoped Physics Objects - Create an item, ball, etc, that uses the Ode4J physics calculations to figure out its next position.

View File

@ -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;
}
}

View File

@ -61,6 +61,7 @@ public class CollisionEngine {
//world data that the collision engine leverages for position correction and the like //world data that the collision engine leverages for position correction and the like
CollisionWorldData collisionWorldData; CollisionWorldData collisionWorldData;
//Ode-specific stuff
private DWorld world; private DWorld world;
private DSpace space; private DSpace space;
private Semaphore spaceLock = new Semaphore(1); 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 private static final int MAX_CONTACTS = 1; // maximum number of contact points per body
List<Entity> collisionEntities = new ArrayList<Entity>(); //The list of dbodies ode should be tracking
List<Entity> physicsEntities = new ArrayList<Entity>();
List<Entity> dynamicPhysicsEntities = new ArrayList<Entity>();
List<Entity> structurePhysicsEntities = new ArrayList<Entity>();
List<DBody> bodies = new ArrayList<DBody>(); List<DBody> bodies = new ArrayList<DBody>();
//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<DBody,Collidable> bodyPointerMap = new HashMap<DBody,Collidable>(); Map<DBody,Collidable> bodyPointerMap = new HashMap<DBody,Collidable>();
//The list of all collidables the engine is currently tracking
List<Collidable> collidableList = new ArrayList<Collidable>(); List<Collidable> collidableList = new ArrayList<Collidable>();
//callbacks for collision check //callbacks for collision check
RayCastCallback rayCastCallback = new RayCastCallback(); RayCastCallback rayCastCallback = new RayCastCallback();
//physics damping
static final float linearDamping = 0.02f; static final float linearDamping = 0.02f;
public CollisionEngine(){ public CollisionEngine(){
@ -157,6 +160,10 @@ public class CollisionEngine {
} }
} }
public List<Collidable> getCollidables(){
return collidableList;
}
/** /**
* *
@ -322,14 +329,6 @@ public class CollisionEngine {
} }
public void registerCollidableEntity(Entity collidable){
collisionEntities.add(collidable);
}
public List<Entity> getCollisionEntities(){
return collisionEntities;
}
/** /**
* Sets the collision world data * Sets the collision world data
* @param collisionWorldData 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); * Main function to resynchronize entity positions with physics object positions after impulses are applied.
} */
public List<Entity> 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<Entity> getDynamicPhysicsEntities(){
return dynamicPhysicsEntities;
}
public void registerStructurePhysicsEntity(Entity structureEntity){
structurePhysicsEntities.add(structureEntity);
}
public List<Entity> getStructurePhysicsEntities(){
return structurePhysicsEntities;
}
public void updateDynamicObjectTransforms(){ public void updateDynamicObjectTransforms(){
for(Entity dynamicEntity : dynamicPhysicsEntities){ for(Collidable collidable : collidableList){
DBody rigidBody = (DBody)dynamicEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); Entity physicsEntity = collidable.getParent();
Vector3d offset = (Vector3d)dynamicEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET); 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); Vector3d newPosition = PhysicsUtils.getRigidBodyPosition(rigidBody).sub(offset);
Quaterniond newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody); Quaterniond newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody);
// System.out.println(rigidBody + " position " + newPosition); EntityUtils.getPosition(physicsEntity).set(newPosition);
// System.out.println("Linear velocity: " + rigidBody.getLinearVelocity(new javax.vecmath.Vector3f())); EntityUtils.getRotation(physicsEntity).set(newRotation);
EntityUtils.getPosition(dynamicEntity).set(newPosition);
EntityUtils.getRotation(dynamicEntity).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. * 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){ public void destroyEntityThatHasPhysics(Entity e){
//make uncollidable //make uncollidable
if(e.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY)){ if(e.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY)){
DBody rigidBody = (DBody)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); DBody rigidBody = (DBody)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
deregisterPhysicsObject(rigidBody); deregisterPhysicsObject(rigidBody);
} }
deregisterCollidableEntity(e);
} }
/** /**

View File

@ -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;
}
}

View File

@ -1,240 +1,17 @@
package electrosphere.collision; package electrosphere.collision;
import java.nio.IntBuffer;
import org.joml.Quaterniond; import org.joml.Quaterniond;
import org.joml.Vector3d; 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.DQuaternion;
import org.ode4j.math.DQuaternionC; import org.ode4j.math.DQuaternionC;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import org.ode4j.ode.DBox;
import org.ode4j.ode.DCylinder;
import org.ode4j.ode.DMass; 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 * Utilities for leveraging the collision system to perform physics
*/ */
public class PhysicsUtils { 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 * Gets the current position of a rigid body as a joml vector
* @param body The dbody * @param body The dbody
@ -291,53 +68,6 @@ public class PhysicsUtils {
collisionEngine.setBodyTransform(body, position, rotation); 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 * Creates a mass in the physics space from the body and mass value input
* @param collisionEngine The collision engine to create the mass in * @param collisionEngine The collision engine to create the mass in

View File

@ -1,6 +1,7 @@
package electrosphere.engine.assetmanager; package electrosphere.engine.assetmanager;
import electrosphere.audio.AudioBuffer; import electrosphere.audio.AudioBuffer;
import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.CollisionEngine; import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.renderer.Mesh; import electrosphere.renderer.Mesh;
@ -77,7 +78,7 @@ public class AssetManager {
physicsMeshesToLoad.remove(physicsMeshQueueItem); physicsMeshesToLoad.remove(physicsMeshQueueItem);
physicsMeshesLoadedIntoMemory.put( physicsMeshesLoadedIntoMemory.put(
getCollisionMeshMapKey(physicsMeshQueueItem.collisionEngine,currentPath), getCollisionMeshMapKey(physicsMeshQueueItem.collisionEngine,currentPath),
PhysicsUtils.generateRigidBodyFromAIScene(physicsMeshQueueItem.collisionEngine,aiScene) CollisionBodyCreation.generateRigidBodyFromAIScene(physicsMeshQueueItem.collisionEngine,aiScene)
); );
} }
} }

View File

@ -16,7 +16,7 @@ import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.creature.type.CollidableTemplate; import electrosphere.game.data.collidable.CollidableTemplate;
/** /**
* *

View File

@ -12,7 +12,7 @@ import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.debug.DebugVisualizerUtils; import electrosphere.entity.types.debug.DebugVisualizerUtils;
import electrosphere.entity.types.item.ItemUtils; 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 electrosphere.server.datacell.Realm;
import org.joml.Matrix4f; import org.joml.Matrix4f;

View File

@ -6,6 +6,7 @@ import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.CollisionEngine; import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
@ -28,11 +29,10 @@ public class CollisionObjUtils {
float mass = 1.0f; 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); PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, planeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(planeObject, collidable); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(planeObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); 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; 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); PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), position, rotation, planeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
realm.getCollisionEngine().registerCollisionObject(planeObject, collidable); realm.getCollisionEngine().registerCollisionObject(planeObject, collidable);
realm.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); 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; 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); PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, cubeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); 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; 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); PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), position, rotation, cubeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable); realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
realm.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); 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(); Entity rVal = EntityCreationUtils.createClientSpatialEntity();
float mass = 1.0f; 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); PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, cubeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CYLINDER, true); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CYLINDER, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); 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)); Entity rVal = EntityCreationUtils.createServerEntity(realm, new Vector3d(position));
float mass = 1.0f; 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); PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), position, rotation, cubeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE); Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable); realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
realm.getCollisionEngine().registerStructurePhysicsEntity(rVal);
rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CYLINDER, true); rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CYLINDER, true);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z)); 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); Collidable collidable = new Collidable(entity, collidableType);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(collisionObject, collidable); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(collisionObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(entity);
entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject); entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject);
//update world transform of collision object //update world transform of collision object
@ -335,7 +329,6 @@ public class CollisionObjUtils {
Realm realm = Globals.realmManager.getEntityRealm(entity); Realm realm = Globals.realmManager.getEntityRealm(entity);
realm.getCollisionEngine().registerCollisionObject(collisionObject, collidable); realm.getCollisionEngine().registerCollisionObject(collisionObject, collidable);
realm.getCollisionEngine().registerPhysicsEntity(entity);
entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject); entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject);
//update world transform of collision object //update world transform of collision object

View File

@ -8,6 +8,8 @@ import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
@ -47,7 +49,7 @@ import electrosphere.entity.state.rotator.ServerRotatorTree;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.entity.types.hitbox.HitboxUtils; 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.CreatureType;
import electrosphere.game.data.creature.type.SprintSystem; import electrosphere.game.data.creature.type.SprintSystem;
import electrosphere.game.data.creature.type.attack.AttackMove; import electrosphere.game.data.creature.type.attack.AttackMove;
@ -78,55 +80,9 @@ import electrosphere.server.poseactor.PoseActorUtils;
import electrosphere.util.Utilities; import electrosphere.util.Utilities;
/** /**
* * Utilities for creating creatures on the client and server
* @author amaterasu
*/ */
public class CreatureUtils { 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 * Spawns a client-side creature entity
@ -154,69 +110,10 @@ public class CreatureUtils {
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST, hitboxList); rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST, hitboxList);
rVal.putData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST, hurtboxList); rVal.putData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST, hurtboxList);
} }
//Physics object
if(rawType.getCollidable() != null){ if(rawType.getCollidable() != null){
CollidableTemplate physicsTemplate = rawType.getCollidable(); CollidableTemplate physicsTemplate = rawType.getCollidable();
DBody rigidBody; PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate);
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;
}
} }
// //
// //
@ -513,64 +410,7 @@ public class CreatureUtils {
} }
if(rawType.getCollidable() != null){ if(rawType.getCollidable() != null){
CollidableTemplate physicsTemplate = rawType.getCollidable(); CollidableTemplate physicsTemplate = rawType.getCollidable();
DBody rigidBody; PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate);
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;
}
} }
// //
// //

View File

@ -10,6 +10,8 @@ import org.ode4j.ode.DBody;
import org.ode4j.ode.DSpace; import org.ode4j.ode.DSpace;
import org.ode4j.ode.DWorld; import org.ode4j.ode.DWorld;
import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
@ -24,7 +26,7 @@ import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree; import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.entity.types.hitbox.HitboxUtils; 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.EquipWhitelist;
import electrosphere.game.data.item.type.Item; import electrosphere.game.data.item.type.Item;
import electrosphere.game.data.item.type.WeaponData; 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_CLASS,weaponData.getWeaponClass());
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData); rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
} }
//physics
if(item.getCollidable() != null){ if(item.getCollidable() != null){
CollidableTemplate physicsTemplate = item.getCollidable(); CollidableTemplate physicsTemplate = item.getCollidable();
DBody rigidBody; PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate);
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;
}
} }
//tokens
for(String token : item.getTokens()){ for(String token : item.getTokens()){
switch(token){ switch(token){
case "BLENDER_TRANSFORM": case "BLENDER_TRANSFORM":
@ -195,65 +139,12 @@ public class ItemUtils {
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass()); rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData); rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
} }
//physics
if(item.getCollidable() != null){ if(item.getCollidable() != null){
CollidableTemplate physicsTemplate = item.getCollidable(); CollidableTemplate physicsTemplate = item.getCollidable();
DBody rigidBody; PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate);
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;
}
} }
//tokens
for(String token : item.getTokens()){ for(String token : item.getTokens()){
switch(token){ switch(token){
case "BLENDER_TRANSFORM": case "BLENDER_TRANSFORM":

View File

@ -5,6 +5,8 @@ import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals; 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.ServerInventoryState;
import electrosphere.entity.state.inventory.UnrelationalInventoryState; import electrosphere.entity.state.inventory.UnrelationalInventoryState;
import electrosphere.entity.types.collision.CollisionObjUtils; 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.game.data.object.type.ObjectData;
import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorUtils; import electrosphere.renderer.actor.ActorUtils;
@ -72,71 +74,14 @@ public class ObjectUtils {
} break; } break;
} }
} }
//
//main entity construction //main entity construction
//physics
if(rawType.getCollidable() != null){ if(rawType.getCollidable() != null){
CollidableTemplate physicsTemplate = rawType.getCollidable(); CollidableTemplate physicsTemplate = rawType.getCollidable();
DBody rigidBody; PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate);
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);
} }
//tokens
for(String token : rawType.getTokens()){ for(String token : rawType.getTokens()){
switch(token){ switch(token){
case "BLENDER_TRANSFORM": case "BLENDER_TRANSFORM":
@ -226,71 +171,14 @@ public class ObjectUtils {
} break; } break;
} }
} }
//
//main entity construction //main entity construction
//physics
if(rawType.getCollidable() != null){ if(rawType.getCollidable() != null){
CollidableTemplate physicsTemplate = rawType.getCollidable(); CollidableTemplate physicsTemplate = rawType.getCollidable();
DBody rigidBody; PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate);
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);
} }
//tokens
for(String token : rawType.getTokens()){ for(String token : rawType.getTokens()){
switch(token){ switch(token){
case "BLENDER_TRANSFORM": case "BLENDER_TRANSFORM":

View File

@ -3,6 +3,7 @@ package electrosphere.entity.types.terrain;
import org.joml.Vector3d; import org.joml.Vector3d;
import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.client.terrain.manager.ClientTerrainManager;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityCreationUtils;
@ -32,7 +33,7 @@ public class TerrainChunk {
Entity rVal = EntityCreationUtils.createClientSpatialEntity(); Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath); EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
if(data.vertices.size() > 0 && levelOfDetail < 1){ if(data.vertices.size() > 0 && levelOfDetail < 1){
PhysicsUtils.clientAttachTerrainChunkRigidBody(rVal, data); PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data);
} }
rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
@ -55,7 +56,7 @@ public class TerrainChunk {
Entity rVal = EntityCreationUtils.createServerEntity(realm, position); Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
if(data.vertices.size() > 0){ if(data.vertices.size() > 0){
PhysicsUtils.serverAttachTerrainChunkRigidBody(rVal, data); PhysicsEntityUtils.serverAttachTerrainChunkRigidBody(rVal, data);
rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); rVal.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
ServerEntityUtils.initiallyPositionEntity(realm, rVal, position); ServerEntityUtils.initiallyPositionEntity(realm, rVal, position);
// physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true); // physicsObject = PhysicsUtils.attachTerrainRigidBody(physicsEntity,heightmap,true);

View File

@ -16,6 +16,7 @@ import org.joml.Vector4d;
import org.joml.Vector4f; import org.joml.Vector4f;
import org.ode4j.ode.DBody; import org.ode4j.ode.DBody;
import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
@ -111,7 +112,7 @@ public class ProceduralTree {
instancedActor.setAttribute(baseSizeAttribute, 1.0f); instancedActor.setAttribute(baseSizeAttribute, 1.0f);
//attach physics //attach physics
DBody rigidBody = PhysicsUtils.createCylinderBody( DBody rigidBody = CollisionBodyCreation.createCylinderBody(
Globals.clientSceneWrapper.getCollisionEngine(), Globals.clientSceneWrapper.getCollisionEngine(),
treeModel.getPhysicsBody().getDimension1(), treeModel.getPhysicsBody().getDimension1(),
treeModel.getPhysicsBody().getDimension2() treeModel.getPhysicsBody().getDimension2()
@ -124,8 +125,6 @@ public class ProceduralTree {
trunkChild.putData(EntityDataStrings.PHYSICS_MASS, TREE_MASS); trunkChild.putData(EntityDataStrings.PHYSICS_MASS, TREE_MASS);
Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(trunkChild);
Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(trunkChild);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);

View File

@ -1,8 +1,7 @@
package electrosphere.game.data.creature.type; package electrosphere.game.data.collidable;
/** /**
* * A template for a rigid body that should be attached to an entity
* @author amaterasu
*/ */
public class CollidableTemplate { public class CollidableTemplate {

View File

@ -1,6 +1,7 @@
package electrosphere.game.data.creature.type; package electrosphere.game.data.creature.type;
import electrosphere.entity.types.hitbox.HitboxData; 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.AttackMove;
import electrosphere.game.data.creature.type.attack.AttackMoveResolver; import electrosphere.game.data.creature.type.attack.AttackMoveResolver;
import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.game.data.creature.type.equip.EquipPoint;

View File

@ -1,6 +1,6 @@
package electrosphere.game.data.foliage.type; 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) * Describes characteristics about a type of tree (how do the limbs dispere, where to the leaves start growing, how sturdy is it, etc)

View File

@ -1,7 +1,8 @@
package electrosphere.game.data.item.type; package electrosphere.game.data.item.type;
import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.game.data.creature.type.CollidableTemplate; import electrosphere.game.data.collidable.CollidableTemplate;
import java.util.List; import java.util.List;
public class Item { public class Item {

View File

@ -1,7 +1,7 @@
package electrosphere.game.data.object.type; package electrosphere.game.data.object.type;
import electrosphere.entity.types.hitbox.HitboxData; 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 electrosphere.game.data.graphics.GraphicsTemplate;
import java.util.List; import java.util.List;

View File

@ -75,6 +75,7 @@ import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL30;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
@ -83,7 +84,7 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.entity.types.hitbox.HitboxUtils; 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.logger.LoggerInterface;
import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum; import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum;
import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.Actor;
@ -927,7 +928,8 @@ public class RenderingEngine {
if(Globals.userSettings.graphicsDebugDrawPhysicsObjects()){ if(Globals.userSettings.graphicsDebugDrawPhysicsObjects()){
Model physicsGraphicsModel; 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)){ if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){
CollidableTemplate template = (CollidableTemplate)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); CollidableTemplate template = (CollidableTemplate)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE);
switch(template.getType()){ 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((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){
if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE)){ if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE)){
if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){ if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){

View File

@ -33,7 +33,7 @@ import org.joml.Vector3i;
import org.ode4j.ode.DBody; 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 { public class PhysicsDataCell {
@ -104,7 +104,6 @@ public class PhysicsDataCell {
public void destroyPhysics(){ public void destroyPhysics(){
Realm realm = Globals.realmManager.getEntityRealm(physicsEntity); Realm realm = Globals.realmManager.getEntityRealm(physicsEntity);
realm.getCollisionEngine().deregisterCollidableEntity(physicsEntity);
realm.getCollisionEngine().deregisterRigidBody((DBody)physicsObject); realm.getCollisionEngine().deregisterRigidBody((DBody)physicsObject);
} }