diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 12c49bba..c6a4cd0c 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1930,6 +1930,9 @@ Fix town placement structure-road intersection test Kinematic collision templates now use geoms instead of setting kinematic (on client) Geom-only collidables on server +(05/22/2025) +Block colliders leveraging spaces +Scene view debug window diff --git a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiWindowMacros.java b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiWindowMacros.java index 3995a7dd..3ae24c01 100644 --- a/src/main/java/electrosphere/client/ui/menu/debug/ImGuiWindowMacros.java +++ b/src/main/java/electrosphere/client/ui/menu/debug/ImGuiWindowMacros.java @@ -13,6 +13,7 @@ import electrosphere.client.ui.menu.debug.perf.ImGuiMemory; import electrosphere.client.ui.menu.debug.perf.ImGuiNetworkMonitor; import electrosphere.client.ui.menu.debug.render.ImGuiRenderer; import electrosphere.client.ui.menu.debug.render.ImGuiUIFramework; +import electrosphere.client.ui.menu.debug.scene.ImGuiSceneWindow; import electrosphere.client.ui.menu.debug.server.ImGuiAI; import electrosphere.client.ui.menu.debug.server.ImGuiFluidMonitor; import electrosphere.client.ui.menu.debug.server.ImGuiGriddedManager; @@ -67,6 +68,7 @@ public class ImGuiWindowMacros { ImGuiMemory.createMemoryDebugWindow(); ImGuiEditorWindows.initEditorWindows(); ImGuiClientServices.createClientServicesWindow(); + ImGuiSceneWindow.createChunkMonitorWindow(); } /** @@ -149,6 +151,9 @@ public class ImGuiWindowMacros { if(ImGui.button("Client Entity Debug")){ ImGuiEntityMacros.clientEntityListWindow.setOpen(true); } + if(ImGui.button("Client Scene")){ + ImGuiSceneWindow.viewScene(Globals.clientState.clientScene, Globals.clientState.clientSceneWrapper.getCollisionEngine()); + } //controls state debug if(ImGui.button("Control State Debug")){ ImGuiControls.controlsWindow.setOpen(true); @@ -187,6 +192,9 @@ public class ImGuiWindowMacros { if(ImGui.button("Gridded Data Cell Monitor")){ ImGuiGriddedManager.griddedManagerWindow.setOpen(true); } + if(ImGui.button("Server Scene")){ + ImGuiSceneWindow.viewScene(null, Globals.serverState.realmManager.first().getCollisionEngine()); + } //memory usage if(ImGui.button("Memory Usage")){ ImGuiMemory.memoryWindow.setOpen(!ImGuiMemory.memoryWindow.isOpen()); diff --git a/src/main/java/electrosphere/client/ui/menu/debug/scene/ImGuiSceneWindow.java b/src/main/java/electrosphere/client/ui/menu/debug/scene/ImGuiSceneWindow.java new file mode 100644 index 00000000..8e8b23c3 --- /dev/null +++ b/src/main/java/electrosphere/client/ui/menu/debug/scene/ImGuiSceneWindow.java @@ -0,0 +1,59 @@ +package electrosphere.client.ui.menu.debug.scene; + +import electrosphere.collision.CollisionEngine; +import electrosphere.engine.Globals; +import electrosphere.entity.scene.Scene; +import electrosphere.renderer.ui.imgui.ImGuiWindow; +import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; +import imgui.ImGui; + +/** + * Views a scene + */ +public class ImGuiSceneWindow { + + /** + * The target scene + */ + public static Scene targetScene; + + /** + * The associated collision engine + */ + public static CollisionEngine targetCollisionEngine; + + /** + * Window for scene data + */ + public static ImGuiWindow sceneWindow; + + /** + * Scene view + */ + public static void createChunkMonitorWindow(){ + sceneWindow = new ImGuiWindow("Scene Data"); + + sceneWindow.setCallback(new ImGuiWindowCallback() { + @Override + public void exec() { + if(targetCollisionEngine != null && ImGui.collapsingHeader("Collision Engine")){ + ImGui.text(targetCollisionEngine.getStatus()); + } + } + }); + sceneWindow.setOpen(false); + Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(sceneWindow); + } + + /** + * Views a scene + * @param scene The scene + * @param engine The collision engine associated with the scene (optional) + */ + public static void viewScene(Scene scene, CollisionEngine engine){ + ImGuiSceneWindow.targetScene = scene; + ImGuiSceneWindow.targetCollisionEngine = engine; + sceneWindow.setOpen(true); + } + +} diff --git a/src/main/java/electrosphere/collision/CollisionBodyCreation.java b/src/main/java/electrosphere/collision/CollisionBodyCreation.java index aa7b0804..09042e07 100644 --- a/src/main/java/electrosphere/collision/CollisionBodyCreation.java +++ b/src/main/java/electrosphere/collision/CollisionBodyCreation.java @@ -16,6 +16,7 @@ import org.ode4j.ode.DCapsule; import org.ode4j.ode.DCylinder; import org.ode4j.ode.DGeom; import org.ode4j.ode.DMass; +import org.ode4j.ode.DSpace; import org.ode4j.ode.DSphere; import org.ode4j.ode.DTriMesh; @@ -296,6 +297,22 @@ public class CollisionBodyCreation { return body; } + /** + * Creates an ode collider from a terrain chunk data object + * @param data The terrain data + * @return The geom + */ + public static DGeom generateGeomFromTerrainData(CollisionEngine collisionEngine, TriGeomData data, long categoryBits){ + DGeom geom = null; + + //create trimesh + if(data.getFaceElements().length > 0){ + geom = collisionEngine.createTrimeshGeom(data.getVertices(),data.getFaceElements(),categoryBits); + } + + return geom; + } + /** * Creates an ode DBody from a mesh data set containing multiple shapes * @param data The mesh data data @@ -325,6 +342,24 @@ public class CollisionBodyCreation { return body; } + /** + * Creates an ode DBody from a mesh data set containing multiple shapes + * @param data The mesh data data + * @return The DBody + */ + public static DGeom generateColliderFromMultiShapeMeshData(CollisionEngine collisionEngine, MultiShapeTriGeomData data, long categoryBits){ + DSpace multishape = collisionEngine.createSpace(); + + //create trimeshes + for(TriGeomData shapeData : data.getData()){ + if(shapeData.getFaceElements().length > 0){ + collisionEngine.createTrimeshGeom(shapeData.getVertices(),shapeData.getFaceElements(),categoryBits,multishape); + } + } + + return multishape; + } + /** * Generates a body from an AIScene * @param scene The AIScene to generate a rigid body off of diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index 55c59ab7..31100424 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -404,10 +404,13 @@ public class CollisionEngine { //make sure we have collidables for both if(c1 == null || c2 == null){ String message = "Collidable is undefined!\n" + + "Geoms:\n" + o1 + " \n" + o2 + " \n" + + "Bodies:\n" + b1 + " \n" + b2 + " \n" + + "Colliders:\n" + c1 + " \n" + c2 + " \n" + "Obj 1 pointers:\n" + @@ -621,18 +624,21 @@ public class CollisionEngine { public void updateDynamicObjectTransforms(){ Globals.profiler.beginCpuSample("updateDynamicObjectTransforms"); spaceLock.lock(); + Matrix4d inverseTransform = new Matrix4d(); if(this.collisionWorldData != null){ for(Collidable collidable : collidableList){ if(collidable.getParentTracksCollidable()){ Entity physicsEntity = collidable.getParent(); DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity); DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity); - Matrix4d inverseTransform = new Matrix4d(); Vector4d rawPos = null; + inverseTransform.identity(); if(rigidBody != null){ rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()).add(this.floatingOrigin),1)); } else if(geom != null){ rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(geom.getPosition()).add(this.floatingOrigin),1)); + } else { + continue; } Vector3d calculatedPosition = new Vector3d(rawPos.x,rawPos.y,rawPos.z); Vector3d suggestedPosition = this.suggestMovementPosition(collisionWorldData, calculatedPosition); @@ -650,8 +656,10 @@ public class CollisionEngine { } if(geom != null){ CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(physicsEntity); - suggestedPosition.sub(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); - newRotation.mul(new Quaterniond(template.getRotX(),template.getRotY(),template.getRotZ(),template.getRotW()).invert()); + if(template != null){ + suggestedPosition.sub(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); + newRotation.mul(new Quaterniond(template.getRotX(),template.getRotY(),template.getRotZ(),template.getRotW()).invert()); + } } EntityUtils.getPosition(physicsEntity).set(suggestedPosition); EntityUtils.getRotation(physicsEntity).set(newRotation); @@ -668,7 +676,7 @@ public class CollisionEngine { public void rebaseWorldOrigin(){ Globals.profiler.beginCpuSample("rebaseWorldOrigin"); spaceLock.lock(); - if(this.collisionWorldData != null && this.floatingOrigin.x == 0 && this.floatingOrigin.z == 0){ + if(this.collisionWorldData != null){ int collected = 0; Vector3d newOrigin = new Vector3d(); //calculate new origin @@ -686,6 +694,32 @@ public class CollisionEngine { } collected++; } + DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity); + if(geom != null){ + if(geom instanceof DSpace space){ + for(DGeom child : space.getGeoms()){ + Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(child.getPosition()); + if(collected == 0){ + newOrigin.set(currentBodyOffset); + } else { + float percentExisting = collected / (float)(collected + 1); + float percentNew = 1.0f - percentExisting; + newOrigin = newOrigin.mul(percentExisting).add(currentBodyOffset.mul(percentNew)); + } + collected++; + } + } else { + Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(geom.getPosition()); + if(collected == 0){ + newOrigin.set(currentBodyOffset); + } else { + float percentExisting = collected / (float)(collected + 1); + float percentNew = 1.0f - percentExisting; + newOrigin = newOrigin.mul(percentExisting).add(currentBodyOffset.mul(percentNew)); + } + collected++; + } + } } Vector3d delta = new Vector3d(this.floatingOrigin).sub(newOrigin); this.floatingOrigin = this.floatingOrigin.set(newOrigin); @@ -700,8 +734,15 @@ public class CollisionEngine { } DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity); if(geom != null){ - Vector3d existingPosition = PhysicsUtils.odeVecToJomlVec(geom.getPosition()); - geom.setPosition(PhysicsUtils.jomlVecToOdeVec(existingPosition.add(delta))); + if(geom instanceof DSpace space){ + for(DGeom child : space.getGeoms()){ + Vector3d existingPosition = PhysicsUtils.odeVecToJomlVec(child.getPosition()); + child.setPosition(PhysicsUtils.jomlVecToOdeVec(existingPosition.add(delta))); + } + } else { + Vector3d existingPosition = PhysicsUtils.odeVecToJomlVec(geom.getPosition()); + geom.setPosition(PhysicsUtils.jomlVecToOdeVec(existingPosition.add(delta))); + } } } } @@ -740,6 +781,23 @@ public class CollisionEngine { spaceLock.unlock(); } + /** + * Registers a collision object with the server + * @param geoms The list of geoms + * @param collidable The corresponding collidable + */ + public void registerCollisionObject(List geoms, Collidable collidable){ + if(collidable == null){ + throw new Error("Collidable is null!"); + } + spaceLock.lock(); + for(DGeom geom : geoms){ + geomPointerMap.put(geom,collidable); + } + collidableList.add(collidable); + spaceLock.unlock(); + } + /** * Deregisters a collidable from the physics engine * @param collidable The collidable @@ -751,6 +809,17 @@ public class CollisionEngine { collidableList.remove(collidable); spaceLock.unlock(); } + + /** + * Deregisters a collidable from the physics engine + * @param collidable The collidable + */ + public void deregisterCollisionObject(DGeom geom, Collidable collidable){ + spaceLock.lock(); + geomPointerMap.remove(geom); + collidableList.remove(collidable); + spaceLock.unlock(); + } public void listBodyPositions(){ for(DBody body : bodies){ @@ -890,6 +959,21 @@ public class CollisionEngine { } spaceLock.unlock(); } + + /** + * Destroys a geom + * @param body The DGeom to destroy + */ + protected void destroyDGeom(DGeom geom){ + spaceLock.lock(); + try { + geom.destroy(); + } catch (NullPointerException ex){ + LoggerInterface.loggerEngine.ERROR(ex); + spaceLock.unlock(); + } + spaceLock.unlock(); + } /** * Destroys the physics on an entity @@ -906,6 +990,20 @@ public class CollisionEngine { e.removeData(EntityDataStrings.PHYSICS_COLLISION_BODY); this.destroyDBody(rigidBody); } + if(PhysicsEntityUtils.containsDGeom(e)){ + DGeom geom = PhysicsEntityUtils.getDGeom(e); + if(geom == null){ + throw new Error("DGeom key set to null rigid body! " + geom); + } + if(geom instanceof DSpace space){ + for(DGeom child : space.getGeoms()){ + this.destroyDGeom(child); + } + } + this.deregisterCollisionObject(geom,PhysicsEntityUtils.getCollidable(e)); + e.removeData(EntityDataStrings.PHYSICS_GEOM); + this.destroyDGeom(geom); + } if(ServerPhysicsSyncTree.hasTree(e)){ ServerPhysicsSyncTree.detachTree(e, ServerPhysicsSyncTree.getTree(e)); } @@ -954,7 +1052,7 @@ public class CollisionEngine { spaceLock.unlock(); return rVal; } - + /** * Creates a trimesh from a given set of vertices and indices * @param verts The vertices @@ -962,6 +1060,30 @@ public class CollisionEngine { * @return The DTriMesh */ protected DTriMesh createTrimeshGeom(float[] verts, int[] indices, long categoryBits){ + spaceLock.lock(); + DTriMeshData data = OdeHelper.createTriMeshData(); + data.build(verts, indices); + final int preprocessFlags = + (1 << DTriMeshData.dTRIDATAPREPROCESS_BUILD.CONCAVE_EDGES) | + (1 << DTriMeshData.dTRIDATAPREPROCESS_BUILD.FACE_ANGLES) | + (1 << DTriMeshData.dTRIDATAPREPROCESS_FACE_ANGLES_EXTRA__MAX) + ; + data.preprocess2(preprocessFlags,null); + DTriMesh rVal = OdeHelper.createTriMesh(this.space, data); + rVal.setTrimeshData(data); + rVal.setCategoryBits(categoryBits); + spaceLock.unlock(); + return rVal; + } + + /** + * Creates a trimesh from a given set of vertices and indices + * @param verts The vertices + * @param indices The indices + * @param space The space to create it within + * @return The DTriMesh + */ + protected DTriMesh createTrimeshGeom(float[] verts, int[] indices, long categoryBits, DSpace space){ spaceLock.lock(); DTriMeshData data = OdeHelper.createTriMeshData(); data.build(verts, indices); @@ -1031,6 +1153,18 @@ public class CollisionEngine { return capsuleGeom; } + /** + * Creates a space + * @return The space + */ + protected DSpace createSpace(){ + spaceLock.lock(); + DSpace rVal = OdeHelper.createSimpleSpace(); + this.space.add(rVal); + spaceLock.unlock(); + return rVal; + } + /** * Creates a DBody. Can optionally be passed DGeom objects to be attached to the body when it is created. * @param geom The geometry objects to attach to the body on creation @@ -1210,11 +1344,17 @@ public class CollisionEngine { */ protected void setGeomTransform(DGeom geom, Vector3d position, Quaterniond rotation){ spaceLock.lock(); - geom.setPosition(position.x - this.floatingOrigin.x, position.y - this.floatingOrigin.y, position.z - this.floatingOrigin.z); - if(geom instanceof DCylinder || geom instanceof DCapsule){ - geom.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(new Quaterniond(rotation).rotateX(Math.PI/2.0))); + if(geom instanceof DSpace space){ + for(DGeom child : space.getGeoms()){ + this.setGeomTransform(child, position, rotation); + } } else { - geom.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation)); + geom.setPosition(position.x - this.floatingOrigin.x, position.y - this.floatingOrigin.y, position.z - this.floatingOrigin.z); + if(geom instanceof DCylinder || geom instanceof DCapsule){ + geom.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(new Quaterniond(rotation).rotateX(Math.PI/2.0))); + } else { + geom.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation)); + } } spaceLock.unlock(); } @@ -1331,6 +1471,22 @@ public class CollisionEngine { protected void attachGeomToBody(DBody body, DGeom geom){ geom.setBody(body); } + + /** + * Gets the status of the collision engine + * @return The status of the collision engine + */ + public String getStatus(){ + String message = "" + + "Bodies: " + this.bodies.size() + "\n" + + "Body Ptrs: " + this.bodyPointerMap.size() + "\n" + + "Geom Ptrs: " + this.geomPointerMap.size() + "\n" + + "Collidables: " + this.collidableList.size() + "\n" + + "Space geom count: " + this.space.getNumGeoms() + "\n" + + "" + ; + return message; + } /** diff --git a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java index c759f5f6..ebc78930 100644 --- a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java +++ b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java @@ -704,6 +704,20 @@ public class PhysicsEntityUtils { terrain.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); } + /** + * [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 void clientAttachTriGeomCollider(Entity terrain, TriGeomData data){ + DGeom terrainGeom = CollisionBodyCreation.generateGeomFromTerrainData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT); + Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false); + PhysicsEntityUtils.setCollidable(terrain, collidable); + Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainGeom, collidable); + PhysicsEntityUtils.setDGeom(terrain,terrainGeom); + } + /** * [CLIENT ONLY] Given an entity and a multi-shape trimesh description, create physics for the shapes and attach it to the entity * @param terrain The entity @@ -719,6 +733,20 @@ public class PhysicsEntityUtils { terrain.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); } + /** + * [CLIENT ONLY] Given an entity and a multi-shape trimesh description, create physics for the shapes and attach it to the entity + * @param terrain The entity + * @param data The trimesh description + * @return The collider created (note, attachment has already been performed) + */ + public static void clientAttachMultiShapeTriGeomCollider(Entity terrain, MultiShapeTriGeomData data){ + DGeom terrainBody = CollisionBodyCreation.generateColliderFromMultiShapeMeshData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT); + Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false); + PhysicsEntityUtils.setCollidable(terrain, collidable); + Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable); + PhysicsEntityUtils.setDGeom(terrain,terrainBody); + } + /** * [SERVER ONLY] Given an entity and a terrain chunk description, create physics for the chunk and attach it to the entity @@ -737,6 +765,24 @@ public class PhysicsEntityUtils { 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 DGeom serverAttachTriGeomCollider(Entity terrain, TriGeomData data){ + Realm realm = Globals.serverState.realmManager.getEntityRealm(terrain); + DGeom terrainCollider = CollisionBodyCreation.generateGeomFromTerrainData(realm.getCollisionEngine(),data,Collidable.TYPE_STATIC_BIT); + + Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false); + PhysicsEntityUtils.setCollidable(terrain, collidable); + realm.getCollisionEngine().registerCollisionObject(terrainCollider, collidable); + PhysicsEntityUtils.setDGeom(terrain,terrainCollider); + + return terrainCollider; + } + /** * [SERVER ONLY] Given an entity and a multi-shape trimesh description, create physics for the shapes and attach it to the entity * @param terrain The entity @@ -754,6 +800,24 @@ public class PhysicsEntityUtils { return terrainBody; } + /** + * [SERVER ONLY] Given an entity and a multi-shape trimesh description, create physics for the shapes and attach it to the entity + * @param terrain The entity + * @param data The trimesh description + * @return The rigid body created (note, attachment has already been performed) + */ + public static DGeom serverAttachMultiShapeTriGeomCollider(Entity terrain, MultiShapeTriGeomData data){ + Realm realm = Globals.serverState.realmManager.getEntityRealm(terrain); + DGeom terrainBody = CollisionBodyCreation.generateColliderFromMultiShapeMeshData(realm.getCollisionEngine(),data,Collidable.TYPE_STATIC_BIT); + + Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false); + PhysicsEntityUtils.setCollidable(terrain, collidable); + realm.getCollisionEngine().registerCollisionObject(terrainBody, collidable); + PhysicsEntityUtils.setDGeom(terrain,terrainBody); + + return terrainBody; + } + /** * Repositions all active physics-scoped entities on a given realm * @param collisionEngine The realm's collision engine @@ -828,6 +892,15 @@ public class PhysicsEntityUtils { return (DBody)entity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); } + /** + * Checks if the entity contains a dgeom + * @param entity the entity + * @return true if contains, false otherwise + */ + public static boolean containsDGeom(Entity entity){ + return entity.containsKey(EntityDataStrings.PHYSICS_GEOM); + } + /** * Sets the static geom on the entity * @param entity The entity @@ -867,6 +940,15 @@ public class PhysicsEntityUtils { return (Collidable)entity.getData(EntityDataStrings.PHYSICS_COLLIDABLE); } + /** + * Gets the collidable attached to the entity + * @param entity The entity + * @param collidable The collidable + */ + public static void setCollidable(Entity entity, Collidable collidable){ + entity.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); + } + /** * Enables a body * @param collisionEngine The collision engine diff --git a/src/main/java/electrosphere/entity/state/collidable/ClientCollidableTree.java b/src/main/java/electrosphere/entity/state/collidable/ClientCollidableTree.java index 17455378..35c0c616 100644 --- a/src/main/java/electrosphere/entity/state/collidable/ClientCollidableTree.java +++ b/src/main/java/electrosphere/entity/state/collidable/ClientCollidableTree.java @@ -1,24 +1,16 @@ package electrosphere.entity.state.collidable; -import org.joml.AABBd; import org.joml.Quaterniond; import org.joml.Vector3d; -import org.joml.Vector3i; import org.ode4j.ode.DBody; -import org.ode4j.ode.DCapsule; -import electrosphere.client.block.BlockChunkData; -import electrosphere.client.scene.ClientWorldData; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; -import electrosphere.collision.physics.CollisionResult; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; -import electrosphere.entity.types.collision.CollisionObjUtils; -import electrosphere.util.math.CollisionUtils; /** * Client collidable tree @@ -28,17 +20,17 @@ public class ClientCollidableTree implements BehaviorTree { /** * The parent entity of this tree */ - Entity parent; + private Entity parent; /** * The body for this tree */ - DBody body; + protected DBody body; /** * The collidable for this tree */ - Collidable collidable; + protected Collidable collidable; /** * Constructor @@ -75,89 +67,89 @@ public class ClientCollidableTree implements BehaviorTree { PhysicsUtils.setRigidBodyTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), newPosition, rotation, body); //capsule-specific block collision logic - if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){ - //get capsule params - DCapsule capsuleGeom = (DCapsule)body.getFirstGeom(); - double length = capsuleGeom.getLength(); - double halfLength = length / 2.0; - double radius = capsuleGeom.getRadius(); - Vector3d bodyOffset = PhysicsUtils.odeVecToJomlVec(body.getFirstGeom().getOffsetPosition()); + // if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){ + // //get capsule params + // DCapsule capsuleGeom = (DCapsule)body.getFirstGeom(); + // double length = capsuleGeom.getLength(); + // double halfLength = length / 2.0; + // double radius = capsuleGeom.getRadius(); + // Vector3d bodyOffset = PhysicsUtils.odeVecToJomlVec(body.getFirstGeom().getOffsetPosition()); - //entity spatial transforms - Vector3d entRealPos = EntityUtils.getPosition(parent); - Quaterniond entRot = EntityUtils.getRotation(parent); + // //entity spatial transforms + // Vector3d entRealPos = EntityUtils.getPosition(parent); + // Quaterniond entRot = EntityUtils.getRotation(parent); - //start and end of capsule - Vector3d realStart = new Vector3d(0,-halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset); - Vector3d realEnd = new Vector3d(0,halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset); + // //start and end of capsule + // Vector3d realStart = new Vector3d(0,-halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset); + // Vector3d realEnd = new Vector3d(0,halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset); - //block position of body - Vector3d blockPos = ClientWorldData.clampRealToBlock(entRealPos); - Vector3d currBlockPos = new Vector3d(); + // //block position of body + // Vector3d blockPos = ClientWorldData.clampRealToBlock(entRealPos); + // Vector3d currBlockPos = new Vector3d(); - //get dims to scan along (ceil to overcompensate -- better to over scan than underscan) - int halfRadBlockLen = (int)Math.ceil(halfLength / BlockChunkData.BLOCK_SIZE_MULTIPLIER); - int radBlockLen = (int)Math.ceil(radius / BlockChunkData.BLOCK_SIZE_MULTIPLIER); + // //get dims to scan along (ceil to overcompensate -- better to over scan than underscan) + // int halfRadBlockLen = (int)Math.ceil(halfLength / BlockChunkData.BLOCK_SIZE_MULTIPLIER); + // int radBlockLen = (int)Math.ceil(radius / BlockChunkData.BLOCK_SIZE_MULTIPLIER); - //final corrected position - Vector3d corrected = new Vector3d(entRealPos); + // //final corrected position + // Vector3d corrected = new Vector3d(entRealPos); - //scan for all potential blocks - for(int x = -radBlockLen; x <= radBlockLen; x++){ - for(int z = -radBlockLen; z <= radBlockLen; z++){ - for(int y = -halfRadBlockLen; y <= halfRadBlockLen; y++){ - currBlockPos.set(blockPos).add( - x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, - y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, - z * BlockChunkData.BLOCK_SIZE_MULTIPLIER - ); - Vector3i chunkPos = ClientWorldData.convertRealToChunkSpace(currBlockPos); - Vector3i entBlockPos = ClientWorldData.convertRealToLocalBlockSpace(currBlockPos); + // //scan for all potential blocks + // for(int x = -radBlockLen; x <= radBlockLen; x++){ + // for(int z = -radBlockLen; z <= radBlockLen; z++){ + // for(int y = -halfRadBlockLen; y <= halfRadBlockLen; y++){ + // currBlockPos.set(blockPos).add( + // x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, + // y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, + // z * BlockChunkData.BLOCK_SIZE_MULTIPLIER + // ); + // Vector3i chunkPos = ClientWorldData.convertRealToChunkSpace(currBlockPos); + // Vector3i entBlockPos = ClientWorldData.convertRealToLocalBlockSpace(currBlockPos); - //error check bounds - if(chunkPos.x < 0 || chunkPos.y < 0 || chunkPos.z < 0){ - continue; - } + // //error check bounds + // if(chunkPos.x < 0 || chunkPos.y < 0 || chunkPos.z < 0){ + // continue; + // } - //get block data for block to check - BlockChunkData data = Globals.clientState.clientBlockManager.getChunkDataAtWorldPoint(chunkPos, BlockChunkData.LOD_FULL_RES); - if(data != null){ - //check type of voxel to skip math - short type = data.getType(entBlockPos.x, entBlockPos.y, entBlockPos.z); - if(type != BlockChunkData.BLOCK_TYPE_EMPTY){ + // //get block data for block to check + // BlockChunkData data = Globals.clientState.clientBlockManager.getChunkDataAtWorldPoint(chunkPos, BlockChunkData.LOD_FULL_RES); + // if(data != null){ + // //check type of voxel to skip math + // short type = data.getType(entBlockPos.x, entBlockPos.y, entBlockPos.z); + // if(type != BlockChunkData.BLOCK_TYPE_EMPTY){ - //AABB for the voxel - AABBd voxelBox = new AABBd( - currBlockPos.x, - currBlockPos.y, - currBlockPos.z, - currBlockPos.x + BlockChunkData.BLOCK_SIZE_MULTIPLIER, - currBlockPos.y + BlockChunkData.BLOCK_SIZE_MULTIPLIER, - currBlockPos.z + BlockChunkData.BLOCK_SIZE_MULTIPLIER - ); + // //AABB for the voxel + // AABBd voxelBox = new AABBd( + // currBlockPos.x, + // currBlockPos.y, + // currBlockPos.z, + // currBlockPos.x + BlockChunkData.BLOCK_SIZE_MULTIPLIER, + // currBlockPos.y + BlockChunkData.BLOCK_SIZE_MULTIPLIER, + // currBlockPos.z + BlockChunkData.BLOCK_SIZE_MULTIPLIER + // ); - //actually collision check - CollisionResult collisionResult = CollisionUtils.collideCapsuleAABB(realStart, realEnd, radius, voxelBox); - if(collisionResult != null){ - double pen = collisionResult.getPenetration(); - double forceMul = pen * 0.3; - Vector3d normal = collisionResult.getNormal().mul(forceMul); - if(normal != null){ - // body.addForce(normal.x, normal.y, normal.z); - //correct the position of the capsule - corrected.add(normal); - } - } - } - } - } - } - } + // //actually collision check + // CollisionResult collisionResult = CollisionUtils.collideCapsuleAABB(realStart, realEnd, radius, voxelBox); + // if(collisionResult != null){ + // double pen = collisionResult.getPenetration(); + // double forceMul = pen * 0.3; + // Vector3d normal = collisionResult.getNormal().mul(forceMul); + // if(normal != null){ + // // body.addForce(normal.x, normal.y, normal.z); + // //correct the position of the capsule + // corrected.add(normal); + // } + // } + // } + // } + // } + // } + // } - //apply correction - CollisionObjUtils.clientPositionCharacter(parent, newPosition, entRot); - } + // //apply correction + // CollisionObjUtils.clientPositionCharacter(parent, newPosition, entRot); + // } } /** diff --git a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java index 7483dd2a..2ed47177 100644 --- a/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java +++ b/src/main/java/electrosphere/entity/state/collidable/ServerCollidableTree.java @@ -1,28 +1,13 @@ package electrosphere.entity.state.collidable; -import electrosphere.client.block.BlockChunkData; -import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; -import electrosphere.collision.physics.CollisionResult; -import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; -import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.gravity.ServerGravityTree; import electrosphere.entity.state.movement.fall.ServerFallTree; -import electrosphere.entity.types.collision.CollisionObjUtils; -import electrosphere.server.datacell.Realm; -import electrosphere.server.datacell.ServerWorldData; -import electrosphere.server.datacell.interfaces.VoxelCellManager; -import electrosphere.util.math.CollisionUtils; -import org.joml.AABBd; -import org.joml.Quaterniond; -import org.joml.Vector3d; -import org.joml.Vector3i; import org.ode4j.ode.DBody; -import org.ode4j.ode.DCapsule; /** * Server collidable tree @@ -32,17 +17,17 @@ public class ServerCollidableTree implements BehaviorTree { /** * The parent of the collidable */ - Entity parent; + private Entity parent; /** * The body */ - DBody body; + protected DBody body; /** * The collidable */ - Collidable collidable; + private Collidable collidable; /** @@ -76,92 +61,92 @@ public class ServerCollidableTree implements BehaviorTree { } //capsule-specific block collision logic - if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){ - Realm realm = Globals.serverState.realmManager.getEntityRealm(parent); - if(realm.getDataCellManager() instanceof VoxelCellManager){ - VoxelCellManager voxelCellManager = (VoxelCellManager)realm.getDataCellManager(); + // if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){ + // Realm realm = Globals.serverState.realmManager.getEntityRealm(parent); + // if(realm.getDataCellManager() instanceof VoxelCellManager){ + // VoxelCellManager voxelCellManager = (VoxelCellManager)realm.getDataCellManager(); - //get capsule params - DCapsule capsuleGeom = (DCapsule)body.getFirstGeom(); - double length = capsuleGeom.getLength(); - double halfLength = length / 2.0; - double radius = capsuleGeom.getRadius(); - Vector3d bodyOffset = PhysicsUtils.odeVecToJomlVec(body.getFirstGeom().getOffsetPosition()); + // //get capsule params + // DCapsule capsuleGeom = (DCapsule)body.getFirstGeom(); + // double length = capsuleGeom.getLength(); + // double halfLength = length / 2.0; + // double radius = capsuleGeom.getRadius(); + // Vector3d bodyOffset = PhysicsUtils.odeVecToJomlVec(body.getFirstGeom().getOffsetPosition()); - //entity spatial transforms - Vector3d entRealPos = EntityUtils.getPosition(parent); - Quaterniond entRot = EntityUtils.getRotation(parent); + // //entity spatial transforms + // Vector3d entRealPos = EntityUtils.getPosition(parent); + // Quaterniond entRot = EntityUtils.getRotation(parent); - //start and end of capsule - Vector3d realStart = new Vector3d(0,-halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset); - Vector3d realEnd = new Vector3d(0,halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset); + // //start and end of capsule + // Vector3d realStart = new Vector3d(0,-halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset); + // Vector3d realEnd = new Vector3d(0,halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset); - //block position of body - Vector3d blockPos = ServerWorldData.clampRealToBlock(entRealPos); - Vector3d currBlockPos = new Vector3d(); + // //block position of body + // Vector3d blockPos = ServerWorldData.clampRealToBlock(entRealPos); + // Vector3d currBlockPos = new Vector3d(); - //get dims to scan along (ceil to overcompensate -- better to over scan than underscan) - int halfRadBlockLen = (int)Math.ceil(halfLength / BlockChunkData.BLOCK_SIZE_MULTIPLIER); - int radBlockLen = (int)Math.ceil(radius / BlockChunkData.BLOCK_SIZE_MULTIPLIER); + // //get dims to scan along (ceil to overcompensate -- better to over scan than underscan) + // int halfRadBlockLen = (int)Math.ceil(halfLength / BlockChunkData.BLOCK_SIZE_MULTIPLIER); + // int radBlockLen = (int)Math.ceil(radius / BlockChunkData.BLOCK_SIZE_MULTIPLIER); - //final corrected position - Vector3d corrected = new Vector3d(entRealPos); + // //final corrected position + // Vector3d corrected = new Vector3d(entRealPos); - //scan for all potential blocks - for(int x = -radBlockLen; x <= radBlockLen; x++){ - for(int z = -radBlockLen; z <= radBlockLen; z++){ - for(int y = -halfRadBlockLen; y <= halfRadBlockLen; y++){ - currBlockPos.set(blockPos).add( - x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, - y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, - z * BlockChunkData.BLOCK_SIZE_MULTIPLIER - ); - Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(currBlockPos); - Vector3i entBlockPos = ServerWorldData.convertRealToLocalBlockSpace(currBlockPos); + // //scan for all potential blocks + // for(int x = -radBlockLen; x <= radBlockLen; x++){ + // for(int z = -radBlockLen; z <= radBlockLen; z++){ + // for(int y = -halfRadBlockLen; y <= halfRadBlockLen; y++){ + // currBlockPos.set(blockPos).add( + // x * BlockChunkData.BLOCK_SIZE_MULTIPLIER, + // y * BlockChunkData.BLOCK_SIZE_MULTIPLIER, + // z * BlockChunkData.BLOCK_SIZE_MULTIPLIER + // ); + // Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(currBlockPos); + // Vector3i entBlockPos = ServerWorldData.convertRealToLocalBlockSpace(currBlockPos); - //error check bounds - if(chunkPos.x < 0 || chunkPos.y < 0 || chunkPos.z < 0){ - continue; - } + // //error check bounds + // if(chunkPos.x < 0 || chunkPos.y < 0 || chunkPos.z < 0){ + // continue; + // } - //get block data for block to check - BlockChunkData data = voxelCellManager.getBlocksAtPosition(chunkPos); - short type = data.getType(entBlockPos.x, entBlockPos.y, entBlockPos.z); + // //get block data for block to check + // BlockChunkData data = voxelCellManager.getBlocksAtPosition(chunkPos); + // short type = data.getType(entBlockPos.x, entBlockPos.y, entBlockPos.z); - if(type != BlockChunkData.BLOCK_TYPE_EMPTY){ + // if(type != BlockChunkData.BLOCK_TYPE_EMPTY){ - //AABB for the voxel - AABBd voxelBox = new AABBd( - currBlockPos.x, - currBlockPos.y, - currBlockPos.z, - currBlockPos.x + BlockChunkData.BLOCK_SIZE_MULTIPLIER, - currBlockPos.y + BlockChunkData.BLOCK_SIZE_MULTIPLIER, - currBlockPos.z + BlockChunkData.BLOCK_SIZE_MULTIPLIER - ); + // //AABB for the voxel + // AABBd voxelBox = new AABBd( + // currBlockPos.x, + // currBlockPos.y, + // currBlockPos.z, + // currBlockPos.x + BlockChunkData.BLOCK_SIZE_MULTIPLIER, + // currBlockPos.y + BlockChunkData.BLOCK_SIZE_MULTIPLIER, + // currBlockPos.z + BlockChunkData.BLOCK_SIZE_MULTIPLIER + // ); - //actually collision check - CollisionResult collisionResult = CollisionUtils.collideCapsuleAABB(realStart, realEnd, radius, voxelBox); - if(collisionResult != null){ - double pen = collisionResult.getPenetration(); - double forceMul = pen * 0.3; - Vector3d normal = collisionResult.getNormal().mul(forceMul); - if(normal != null){ - // body.addForce(normal.x, normal.y, normal.z); - //correct the position of the capsule - corrected.add(normal); - } - } - } - } - } - } + // //actually collision check + // CollisionResult collisionResult = CollisionUtils.collideCapsuleAABB(realStart, realEnd, radius, voxelBox); + // if(collisionResult != null){ + // double pen = collisionResult.getPenetration(); + // double forceMul = pen * 0.3; + // Vector3d normal = collisionResult.getNormal().mul(forceMul); + // if(normal != null){ + // // body.addForce(normal.x, normal.y, normal.z); + // //correct the position of the capsule + // corrected.add(normal); + // } + // } + // } + // } + // } + // } - //apply correction - CollisionObjUtils.serverPositionCharacter(parent, corrected); - } - } + // //apply correction + // CollisionObjUtils.serverPositionCharacter(parent, corrected); + // } + // } } diff --git a/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java index c3f46a56..2050781c 100644 --- a/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java +++ b/src/main/java/electrosphere/entity/types/collision/CollisionObjUtils.java @@ -83,12 +83,21 @@ public class CollisionObjUtils { } if(geom != null){ CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(e); - PhysicsUtils.setGeomTransform( - collisionEngine, - new Vector3d(position).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()), - rotation, - geom - ); + if(template == null){ + PhysicsUtils.setGeomTransform( + collisionEngine, + position, + rotation, + geom + ); + } else { + PhysicsUtils.setGeomTransform( + collisionEngine, + new Vector3d(position).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()), + rotation, + geom + ); + } } } @@ -107,12 +116,21 @@ public class CollisionObjUtils { DGeom geom = PhysicsEntityUtils.getDGeom(e); if(geom != null){ CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(e); - PhysicsUtils.setGeomTransform( - Globals.clientState.clientSceneWrapper.getCollisionEngine(), - new Vector3d(position).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()), - rotation, - geom - ); + if(template == null){ + PhysicsUtils.setGeomTransform( + Globals.clientState.clientSceneWrapper.getCollisionEngine(), + new Vector3d(position), + rotation, + geom + ); + } else { + PhysicsUtils.setGeomTransform( + Globals.clientState.clientSceneWrapper.getCollisionEngine(), + new Vector3d(position).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()), + rotation, + geom + ); + } } } diff --git a/src/main/java/electrosphere/entity/types/terrain/BlockChunkEntity.java b/src/main/java/electrosphere/entity/types/terrain/BlockChunkEntity.java index 832123de..7dafb65d 100644 --- a/src/main/java/electrosphere/entity/types/terrain/BlockChunkEntity.java +++ b/src/main/java/electrosphere/entity/types/terrain/BlockChunkEntity.java @@ -8,7 +8,7 @@ import java.util.concurrent.Executors; import org.joml.Quaterniond; import org.joml.Vector3d; -import org.ode4j.ode.DBody; +import org.ode4j.ode.DGeom; import electrosphere.client.block.BlockChunkData; import electrosphere.client.block.cells.BlockDrawCell; @@ -78,7 +78,7 @@ public class BlockChunkEntity { })); EntityCreationUtils.makeEntityDrawablePreexistingModel(solidsEnt, modelPath); if(levelOfDetail == BlockChunkData.LOD_FULL_RES){ - PhysicsEntityUtils.clientAttachMultiShapeTriGeomRigidBody(solidsEnt, data); + PhysicsEntityUtils.clientAttachMultiShapeTriGeomCollider(solidsEnt, data); CollisionObjUtils.clientPositionCharacter(solidsEnt, new Vector3d(EntityUtils.getPosition(solidsEnt)), new Quaterniond()); } else { EntityCreationUtils.bypassShadowPass(solidsEnt); @@ -129,7 +129,7 @@ public class BlockChunkEntity { })); EntityCreationUtils.makeEntityDrawablePreexistingModel(transparentEnt, modelPath); if(levelOfDetail == BlockChunkData.LOD_FULL_RES){ - PhysicsEntityUtils.clientAttachMultiShapeTriGeomRigidBody(transparentEnt, data); + PhysicsEntityUtils.clientAttachMultiShapeTriGeomCollider(transparentEnt, data); CollisionObjUtils.clientPositionCharacter(transparentEnt, new Vector3d(EntityUtils.getPosition(transparentEnt)), new Quaterniond()); } else { EntityCreationUtils.bypassShadowPass(transparentEnt); @@ -182,12 +182,12 @@ public class BlockChunkEntity { */ public static void serverCreateBlockChunkEntity(Entity entity, BlockMeshData blockChunkData){ if(blockChunkData.getVertices().length > 0){ - PhysicsEntityUtils.serverAttachMultiShapeTriGeomRigidBody(entity, blockChunkData); + PhysicsEntityUtils.serverAttachMultiShapeTriGeomCollider(entity, blockChunkData); Realm realm = Globals.serverState.realmManager.getEntityRealm(entity); - DBody terrainBody = PhysicsEntityUtils.getDBody(entity); + DGeom terrainCollider = PhysicsEntityUtils.getDGeom(entity); Vector3d entityPos = EntityUtils.getPosition(entity); Quaterniond entityRot = EntityUtils.getRotation(entity); - PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), entityPos, entityRot, terrainBody); + PhysicsUtils.setGeomTransform(realm.getCollisionEngine(), entityPos, entityRot, terrainCollider); entity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); CommonEntityUtils.setEntityType(entity, EntityType.ENGINE); } diff --git a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java index 7f23c2de..543a24f6 100644 --- a/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java +++ b/src/main/java/electrosphere/entity/types/terrain/TerrainChunk.java @@ -6,7 +6,7 @@ import java.util.concurrent.Executors; import org.joml.Quaterniond; import org.joml.Vector3d; import org.joml.Vector3i; -import org.ode4j.ode.DBody; +import org.ode4j.ode.DGeom; import electrosphere.client.block.BlockChunkData; import electrosphere.client.terrain.cells.ClientDrawCellManager; @@ -73,7 +73,7 @@ public class TerrainChunk { String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas, notifyTarget, toDelete); EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath); if(levelOfDetail == BlockChunkData.LOD_FULL_RES && data.getFaceElements().length > 0){ - PhysicsEntityUtils.clientAttachTriGeomRigidBody(rVal, data); + PhysicsEntityUtils.clientAttachTriGeomCollider(rVal, data); Vector3d finalPos = new Vector3d(EntityUtils.getPosition(rVal)); CollisionObjUtils.clientPositionCharacter(rVal, finalPos, new Quaterniond()); } else { @@ -131,11 +131,11 @@ public class TerrainChunk { if(data.getVertices().length > 0){ Realm realm = Globals.serverState.realmManager.getEntityRealm(entity); if(realm != null){ - PhysicsEntityUtils.serverAttachTriGeomRigidBody(entity, data); - DBody terrainBody = PhysicsEntityUtils.getDBody(entity); + PhysicsEntityUtils.serverAttachTriGeomCollider(entity, data); + DGeom terrainGeom = PhysicsEntityUtils.getDGeom(entity); Vector3d entityPos = EntityUtils.getPosition(entity); Quaterniond entityRot = EntityUtils.getRotation(entity); - PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), entityPos, entityRot, terrainBody); + PhysicsUtils.setGeomTransform(realm.getCollisionEngine(), entityPos, entityRot, terrainGeom); entity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); CommonEntityUtils.setEntityType(entity, EntityType.ENGINE); } diff --git a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java index cb9a2a77..c2a31e98 100644 --- a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java +++ b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java @@ -94,10 +94,12 @@ public class PhysicsDataCell { return; } - //generate + //generate terrain this.terrainChunkData = TerrainChunk.serverGenerateTerrainChunkData(weights, types); TerrainChunk.serverCreateTerrainChunkEntity(localPhysicsEnt, this.terrainChunkData); localPhysicsEnt.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true); + + //generate blocks this.blockData = BlockMeshgen.rasterize(this.blockChunk); BlockChunkEntity.serverCreateBlockChunkEntity(localBlockPhysicsEntity, this.blockData); localBlockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);