block colliders
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
cbd5c98e0a
commit
4e4367f915
@ -1930,6 +1930,9 @@ Fix town placement structure-road intersection test
|
|||||||
Kinematic collision templates now use geoms instead of setting kinematic (on client)
|
Kinematic collision templates now use geoms instead of setting kinematic (on client)
|
||||||
Geom-only collidables on server
|
Geom-only collidables on server
|
||||||
|
|
||||||
|
(05/22/2025)
|
||||||
|
Block colliders leveraging spaces
|
||||||
|
Scene view debug window
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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.perf.ImGuiNetworkMonitor;
|
||||||
import electrosphere.client.ui.menu.debug.render.ImGuiRenderer;
|
import electrosphere.client.ui.menu.debug.render.ImGuiRenderer;
|
||||||
import electrosphere.client.ui.menu.debug.render.ImGuiUIFramework;
|
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.ImGuiAI;
|
||||||
import electrosphere.client.ui.menu.debug.server.ImGuiFluidMonitor;
|
import electrosphere.client.ui.menu.debug.server.ImGuiFluidMonitor;
|
||||||
import electrosphere.client.ui.menu.debug.server.ImGuiGriddedManager;
|
import electrosphere.client.ui.menu.debug.server.ImGuiGriddedManager;
|
||||||
@ -67,6 +68,7 @@ public class ImGuiWindowMacros {
|
|||||||
ImGuiMemory.createMemoryDebugWindow();
|
ImGuiMemory.createMemoryDebugWindow();
|
||||||
ImGuiEditorWindows.initEditorWindows();
|
ImGuiEditorWindows.initEditorWindows();
|
||||||
ImGuiClientServices.createClientServicesWindow();
|
ImGuiClientServices.createClientServicesWindow();
|
||||||
|
ImGuiSceneWindow.createChunkMonitorWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,6 +151,9 @@ public class ImGuiWindowMacros {
|
|||||||
if(ImGui.button("Client Entity Debug")){
|
if(ImGui.button("Client Entity Debug")){
|
||||||
ImGuiEntityMacros.clientEntityListWindow.setOpen(true);
|
ImGuiEntityMacros.clientEntityListWindow.setOpen(true);
|
||||||
}
|
}
|
||||||
|
if(ImGui.button("Client Scene")){
|
||||||
|
ImGuiSceneWindow.viewScene(Globals.clientState.clientScene, Globals.clientState.clientSceneWrapper.getCollisionEngine());
|
||||||
|
}
|
||||||
//controls state debug
|
//controls state debug
|
||||||
if(ImGui.button("Control State Debug")){
|
if(ImGui.button("Control State Debug")){
|
||||||
ImGuiControls.controlsWindow.setOpen(true);
|
ImGuiControls.controlsWindow.setOpen(true);
|
||||||
@ -187,6 +192,9 @@ public class ImGuiWindowMacros {
|
|||||||
if(ImGui.button("Gridded Data Cell Monitor")){
|
if(ImGui.button("Gridded Data Cell Monitor")){
|
||||||
ImGuiGriddedManager.griddedManagerWindow.setOpen(true);
|
ImGuiGriddedManager.griddedManagerWindow.setOpen(true);
|
||||||
}
|
}
|
||||||
|
if(ImGui.button("Server Scene")){
|
||||||
|
ImGuiSceneWindow.viewScene(null, Globals.serverState.realmManager.first().getCollisionEngine());
|
||||||
|
}
|
||||||
//memory usage
|
//memory usage
|
||||||
if(ImGui.button("Memory Usage")){
|
if(ImGui.button("Memory Usage")){
|
||||||
ImGuiMemory.memoryWindow.setOpen(!ImGuiMemory.memoryWindow.isOpen());
|
ImGuiMemory.memoryWindow.setOpen(!ImGuiMemory.memoryWindow.isOpen());
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -16,6 +16,7 @@ import org.ode4j.ode.DCapsule;
|
|||||||
import org.ode4j.ode.DCylinder;
|
import org.ode4j.ode.DCylinder;
|
||||||
import org.ode4j.ode.DGeom;
|
import org.ode4j.ode.DGeom;
|
||||||
import org.ode4j.ode.DMass;
|
import org.ode4j.ode.DMass;
|
||||||
|
import org.ode4j.ode.DSpace;
|
||||||
import org.ode4j.ode.DSphere;
|
import org.ode4j.ode.DSphere;
|
||||||
import org.ode4j.ode.DTriMesh;
|
import org.ode4j.ode.DTriMesh;
|
||||||
|
|
||||||
@ -296,6 +297,22 @@ public class CollisionBodyCreation {
|
|||||||
return body;
|
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
|
* Creates an ode DBody from a mesh data set containing multiple shapes
|
||||||
* @param data The mesh data data
|
* @param data The mesh data data
|
||||||
@ -325,6 +342,24 @@ public class CollisionBodyCreation {
|
|||||||
return body;
|
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
|
* Generates a body from an AIScene
|
||||||
* @param scene The AIScene to generate a rigid body off of
|
* @param scene The AIScene to generate a rigid body off of
|
||||||
|
|||||||
@ -404,10 +404,13 @@ public class CollisionEngine {
|
|||||||
//make sure we have collidables for both
|
//make sure we have collidables for both
|
||||||
if(c1 == null || c2 == null){
|
if(c1 == null || c2 == null){
|
||||||
String message = "Collidable is undefined!\n" +
|
String message = "Collidable is undefined!\n" +
|
||||||
|
"Geoms:\n" +
|
||||||
o1 + " \n" +
|
o1 + " \n" +
|
||||||
o2 + " \n" +
|
o2 + " \n" +
|
||||||
|
"Bodies:\n" +
|
||||||
b1 + " \n" +
|
b1 + " \n" +
|
||||||
b2 + " \n" +
|
b2 + " \n" +
|
||||||
|
"Colliders:\n" +
|
||||||
c1 + " \n" +
|
c1 + " \n" +
|
||||||
c2 + " \n" +
|
c2 + " \n" +
|
||||||
"Obj 1 pointers:\n" +
|
"Obj 1 pointers:\n" +
|
||||||
@ -621,18 +624,21 @@ public class CollisionEngine {
|
|||||||
public void updateDynamicObjectTransforms(){
|
public void updateDynamicObjectTransforms(){
|
||||||
Globals.profiler.beginCpuSample("updateDynamicObjectTransforms");
|
Globals.profiler.beginCpuSample("updateDynamicObjectTransforms");
|
||||||
spaceLock.lock();
|
spaceLock.lock();
|
||||||
|
Matrix4d inverseTransform = new Matrix4d();
|
||||||
if(this.collisionWorldData != null){
|
if(this.collisionWorldData != null){
|
||||||
for(Collidable collidable : collidableList){
|
for(Collidable collidable : collidableList){
|
||||||
if(collidable.getParentTracksCollidable()){
|
if(collidable.getParentTracksCollidable()){
|
||||||
Entity physicsEntity = collidable.getParent();
|
Entity physicsEntity = collidable.getParent();
|
||||||
DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity);
|
DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity);
|
||||||
DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
|
DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
|
||||||
Matrix4d inverseTransform = new Matrix4d();
|
|
||||||
Vector4d rawPos = null;
|
Vector4d rawPos = null;
|
||||||
|
inverseTransform.identity();
|
||||||
if(rigidBody != null){
|
if(rigidBody != null){
|
||||||
rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()).add(this.floatingOrigin),1));
|
rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()).add(this.floatingOrigin),1));
|
||||||
} else if(geom != null){
|
} else if(geom != null){
|
||||||
rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.odeVecToJomlVec(geom.getPosition()).add(this.floatingOrigin),1));
|
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 calculatedPosition = new Vector3d(rawPos.x,rawPos.y,rawPos.z);
|
||||||
Vector3d suggestedPosition = this.suggestMovementPosition(collisionWorldData, calculatedPosition);
|
Vector3d suggestedPosition = this.suggestMovementPosition(collisionWorldData, calculatedPosition);
|
||||||
@ -650,8 +656,10 @@ public class CollisionEngine {
|
|||||||
}
|
}
|
||||||
if(geom != null){
|
if(geom != null){
|
||||||
CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(physicsEntity);
|
CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(physicsEntity);
|
||||||
suggestedPosition.sub(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ());
|
if(template != null){
|
||||||
newRotation.mul(new Quaterniond(template.getRotX(),template.getRotY(),template.getRotZ(),template.getRotW()).invert());
|
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.getPosition(physicsEntity).set(suggestedPosition);
|
||||||
EntityUtils.getRotation(physicsEntity).set(newRotation);
|
EntityUtils.getRotation(physicsEntity).set(newRotation);
|
||||||
@ -668,7 +676,7 @@ public class CollisionEngine {
|
|||||||
public void rebaseWorldOrigin(){
|
public void rebaseWorldOrigin(){
|
||||||
Globals.profiler.beginCpuSample("rebaseWorldOrigin");
|
Globals.profiler.beginCpuSample("rebaseWorldOrigin");
|
||||||
spaceLock.lock();
|
spaceLock.lock();
|
||||||
if(this.collisionWorldData != null && this.floatingOrigin.x == 0 && this.floatingOrigin.z == 0){
|
if(this.collisionWorldData != null){
|
||||||
int collected = 0;
|
int collected = 0;
|
||||||
Vector3d newOrigin = new Vector3d();
|
Vector3d newOrigin = new Vector3d();
|
||||||
//calculate new origin
|
//calculate new origin
|
||||||
@ -686,6 +694,32 @@ public class CollisionEngine {
|
|||||||
}
|
}
|
||||||
collected++;
|
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);
|
Vector3d delta = new Vector3d(this.floatingOrigin).sub(newOrigin);
|
||||||
this.floatingOrigin = this.floatingOrigin.set(newOrigin);
|
this.floatingOrigin = this.floatingOrigin.set(newOrigin);
|
||||||
@ -700,8 +734,15 @@ public class CollisionEngine {
|
|||||||
}
|
}
|
||||||
DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
|
DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
|
||||||
if(geom != null){
|
if(geom != null){
|
||||||
Vector3d existingPosition = PhysicsUtils.odeVecToJomlVec(geom.getPosition());
|
if(geom instanceof DSpace space){
|
||||||
geom.setPosition(PhysicsUtils.jomlVecToOdeVec(existingPosition.add(delta)));
|
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();
|
spaceLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a collision object with the server
|
||||||
|
* @param geoms The list of geoms
|
||||||
|
* @param collidable The corresponding collidable
|
||||||
|
*/
|
||||||
|
public void registerCollisionObject(List<DGeom> 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
|
* Deregisters a collidable from the physics engine
|
||||||
* @param collidable The collidable
|
* @param collidable The collidable
|
||||||
@ -751,6 +809,17 @@ public class CollisionEngine {
|
|||||||
collidableList.remove(collidable);
|
collidableList.remove(collidable);
|
||||||
spaceLock.unlock();
|
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(){
|
public void listBodyPositions(){
|
||||||
for(DBody body : bodies){
|
for(DBody body : bodies){
|
||||||
@ -890,6 +959,21 @@ public class CollisionEngine {
|
|||||||
}
|
}
|
||||||
spaceLock.unlock();
|
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
|
* Destroys the physics on an entity
|
||||||
@ -906,6 +990,20 @@ public class CollisionEngine {
|
|||||||
e.removeData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
e.removeData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
||||||
this.destroyDBody(rigidBody);
|
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)){
|
if(ServerPhysicsSyncTree.hasTree(e)){
|
||||||
ServerPhysicsSyncTree.detachTree(e, ServerPhysicsSyncTree.getTree(e));
|
ServerPhysicsSyncTree.detachTree(e, ServerPhysicsSyncTree.getTree(e));
|
||||||
}
|
}
|
||||||
@ -954,7 +1052,7 @@ public class CollisionEngine {
|
|||||||
spaceLock.unlock();
|
spaceLock.unlock();
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a trimesh from a given set of vertices and indices
|
* Creates a trimesh from a given set of vertices and indices
|
||||||
* @param verts The vertices
|
* @param verts The vertices
|
||||||
@ -962,6 +1060,30 @@ public class CollisionEngine {
|
|||||||
* @return The DTriMesh
|
* @return The DTriMesh
|
||||||
*/
|
*/
|
||||||
protected DTriMesh createTrimeshGeom(float[] verts, int[] indices, long categoryBits){
|
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();
|
spaceLock.lock();
|
||||||
DTriMeshData data = OdeHelper.createTriMeshData();
|
DTriMeshData data = OdeHelper.createTriMeshData();
|
||||||
data.build(verts, indices);
|
data.build(verts, indices);
|
||||||
@ -1031,6 +1153,18 @@ public class CollisionEngine {
|
|||||||
return capsuleGeom;
|
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.
|
* 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
|
* @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){
|
protected void setGeomTransform(DGeom geom, Vector3d position, Quaterniond rotation){
|
||||||
spaceLock.lock();
|
spaceLock.lock();
|
||||||
geom.setPosition(position.x - this.floatingOrigin.x, position.y - this.floatingOrigin.y, position.z - this.floatingOrigin.z);
|
if(geom instanceof DSpace space){
|
||||||
if(geom instanceof DCylinder || geom instanceof DCapsule){
|
for(DGeom child : space.getGeoms()){
|
||||||
geom.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(new Quaterniond(rotation).rotateX(Math.PI/2.0)));
|
this.setGeomTransform(child, position, rotation);
|
||||||
|
}
|
||||||
} else {
|
} 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();
|
spaceLock.unlock();
|
||||||
}
|
}
|
||||||
@ -1331,6 +1471,22 @@ public class CollisionEngine {
|
|||||||
protected void attachGeomToBody(DBody body, DGeom geom){
|
protected void attachGeomToBody(DBody body, DGeom geom){
|
||||||
geom.setBody(body);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -704,6 +704,20 @@ public class PhysicsEntityUtils {
|
|||||||
terrain.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
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
|
* [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 terrain The entity
|
||||||
@ -719,6 +733,20 @@ public class PhysicsEntityUtils {
|
|||||||
terrain.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
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
|
* [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;
|
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
|
* [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 terrain The entity
|
||||||
@ -754,6 +800,24 @@ public class PhysicsEntityUtils {
|
|||||||
return terrainBody;
|
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
|
* Repositions all active physics-scoped entities on a given realm
|
||||||
* @param collisionEngine The realm's collision engine
|
* @param collisionEngine The realm's collision engine
|
||||||
@ -828,6 +892,15 @@ public class PhysicsEntityUtils {
|
|||||||
return (DBody)entity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
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
|
* Sets the static geom on the entity
|
||||||
* @param entity The entity
|
* @param entity The entity
|
||||||
@ -867,6 +940,15 @@ public class PhysicsEntityUtils {
|
|||||||
return (Collidable)entity.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
|
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
|
* Enables a body
|
||||||
* @param collisionEngine The collision engine
|
* @param collisionEngine The collision engine
|
||||||
|
|||||||
@ -1,24 +1,16 @@
|
|||||||
package electrosphere.entity.state.collidable;
|
package electrosphere.entity.state.collidable;
|
||||||
|
|
||||||
import org.joml.AABBd;
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3i;
|
|
||||||
import org.ode4j.ode.DBody;
|
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.PhysicsUtils;
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.collision.physics.CollisionResult;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
|
||||||
import electrosphere.util.math.CollisionUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client collidable tree
|
* Client collidable tree
|
||||||
@ -28,17 +20,17 @@ public class ClientCollidableTree implements BehaviorTree {
|
|||||||
/**
|
/**
|
||||||
* The parent entity of this tree
|
* The parent entity of this tree
|
||||||
*/
|
*/
|
||||||
Entity parent;
|
private Entity parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The body for this tree
|
* The body for this tree
|
||||||
*/
|
*/
|
||||||
DBody body;
|
protected DBody body;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The collidable for this tree
|
* The collidable for this tree
|
||||||
*/
|
*/
|
||||||
Collidable collidable;
|
protected Collidable collidable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@ -75,89 +67,89 @@ public class ClientCollidableTree implements BehaviorTree {
|
|||||||
PhysicsUtils.setRigidBodyTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), newPosition, rotation, body);
|
PhysicsUtils.setRigidBodyTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), newPosition, rotation, body);
|
||||||
|
|
||||||
//capsule-specific block collision logic
|
//capsule-specific block collision logic
|
||||||
if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){
|
// if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){
|
||||||
//get capsule params
|
// //get capsule params
|
||||||
DCapsule capsuleGeom = (DCapsule)body.getFirstGeom();
|
// DCapsule capsuleGeom = (DCapsule)body.getFirstGeom();
|
||||||
double length = capsuleGeom.getLength();
|
// double length = capsuleGeom.getLength();
|
||||||
double halfLength = length / 2.0;
|
// double halfLength = length / 2.0;
|
||||||
double radius = capsuleGeom.getRadius();
|
// double radius = capsuleGeom.getRadius();
|
||||||
Vector3d bodyOffset = PhysicsUtils.odeVecToJomlVec(body.getFirstGeom().getOffsetPosition());
|
// Vector3d bodyOffset = PhysicsUtils.odeVecToJomlVec(body.getFirstGeom().getOffsetPosition());
|
||||||
|
|
||||||
//entity spatial transforms
|
// //entity spatial transforms
|
||||||
Vector3d entRealPos = EntityUtils.getPosition(parent);
|
// Vector3d entRealPos = EntityUtils.getPosition(parent);
|
||||||
Quaterniond entRot = EntityUtils.getRotation(parent);
|
// Quaterniond entRot = EntityUtils.getRotation(parent);
|
||||||
|
|
||||||
//start and end of capsule
|
// //start and end of capsule
|
||||||
Vector3d realStart = new Vector3d(0,-halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset);
|
// 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);
|
// Vector3d realEnd = new Vector3d(0,halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset);
|
||||||
|
|
||||||
|
|
||||||
//block position of body
|
// //block position of body
|
||||||
Vector3d blockPos = ClientWorldData.clampRealToBlock(entRealPos);
|
// Vector3d blockPos = ClientWorldData.clampRealToBlock(entRealPos);
|
||||||
Vector3d currBlockPos = new Vector3d();
|
// Vector3d currBlockPos = new Vector3d();
|
||||||
|
|
||||||
//get dims to scan along (ceil to overcompensate -- better to over scan than underscan)
|
// //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 halfRadBlockLen = (int)Math.ceil(halfLength / BlockChunkData.BLOCK_SIZE_MULTIPLIER);
|
||||||
int radBlockLen = (int)Math.ceil(radius / BlockChunkData.BLOCK_SIZE_MULTIPLIER);
|
// int radBlockLen = (int)Math.ceil(radius / BlockChunkData.BLOCK_SIZE_MULTIPLIER);
|
||||||
|
|
||||||
//final corrected position
|
// //final corrected position
|
||||||
Vector3d corrected = new Vector3d(entRealPos);
|
// Vector3d corrected = new Vector3d(entRealPos);
|
||||||
|
|
||||||
//scan for all potential blocks
|
// //scan for all potential blocks
|
||||||
for(int x = -radBlockLen; x <= radBlockLen; x++){
|
// for(int x = -radBlockLen; x <= radBlockLen; x++){
|
||||||
for(int z = -radBlockLen; z <= radBlockLen; z++){
|
// for(int z = -radBlockLen; z <= radBlockLen; z++){
|
||||||
for(int y = -halfRadBlockLen; y <= halfRadBlockLen; y++){
|
// for(int y = -halfRadBlockLen; y <= halfRadBlockLen; y++){
|
||||||
currBlockPos.set(blockPos).add(
|
// currBlockPos.set(blockPos).add(
|
||||||
x * BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
// x * BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
||||||
y * BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
// y * BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
||||||
z * BlockChunkData.BLOCK_SIZE_MULTIPLIER
|
// z * BlockChunkData.BLOCK_SIZE_MULTIPLIER
|
||||||
);
|
// );
|
||||||
Vector3i chunkPos = ClientWorldData.convertRealToChunkSpace(currBlockPos);
|
// Vector3i chunkPos = ClientWorldData.convertRealToChunkSpace(currBlockPos);
|
||||||
Vector3i entBlockPos = ClientWorldData.convertRealToLocalBlockSpace(currBlockPos);
|
// Vector3i entBlockPos = ClientWorldData.convertRealToLocalBlockSpace(currBlockPos);
|
||||||
|
|
||||||
//error check bounds
|
// //error check bounds
|
||||||
if(chunkPos.x < 0 || chunkPos.y < 0 || chunkPos.z < 0){
|
// if(chunkPos.x < 0 || chunkPos.y < 0 || chunkPos.z < 0){
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
//get block data for block to check
|
// //get block data for block to check
|
||||||
BlockChunkData data = Globals.clientState.clientBlockManager.getChunkDataAtWorldPoint(chunkPos, BlockChunkData.LOD_FULL_RES);
|
// BlockChunkData data = Globals.clientState.clientBlockManager.getChunkDataAtWorldPoint(chunkPos, BlockChunkData.LOD_FULL_RES);
|
||||||
if(data != null){
|
// if(data != null){
|
||||||
//check type of voxel to skip math
|
// //check type of voxel to skip math
|
||||||
short type = data.getType(entBlockPos.x, entBlockPos.y, entBlockPos.z);
|
// 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
|
// //AABB for the voxel
|
||||||
AABBd voxelBox = new AABBd(
|
// AABBd voxelBox = new AABBd(
|
||||||
currBlockPos.x,
|
// currBlockPos.x,
|
||||||
currBlockPos.y,
|
// currBlockPos.y,
|
||||||
currBlockPos.z,
|
// currBlockPos.z,
|
||||||
currBlockPos.x + BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
// currBlockPos.x + BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
||||||
currBlockPos.y + BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
// currBlockPos.y + BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
||||||
currBlockPos.z + BlockChunkData.BLOCK_SIZE_MULTIPLIER
|
// currBlockPos.z + BlockChunkData.BLOCK_SIZE_MULTIPLIER
|
||||||
);
|
// );
|
||||||
|
|
||||||
//actually collision check
|
// //actually collision check
|
||||||
CollisionResult collisionResult = CollisionUtils.collideCapsuleAABB(realStart, realEnd, radius, voxelBox);
|
// CollisionResult collisionResult = CollisionUtils.collideCapsuleAABB(realStart, realEnd, radius, voxelBox);
|
||||||
if(collisionResult != null){
|
// if(collisionResult != null){
|
||||||
double pen = collisionResult.getPenetration();
|
// double pen = collisionResult.getPenetration();
|
||||||
double forceMul = pen * 0.3;
|
// double forceMul = pen * 0.3;
|
||||||
Vector3d normal = collisionResult.getNormal().mul(forceMul);
|
// Vector3d normal = collisionResult.getNormal().mul(forceMul);
|
||||||
if(normal != null){
|
// if(normal != null){
|
||||||
// body.addForce(normal.x, normal.y, normal.z);
|
// // body.addForce(normal.x, normal.y, normal.z);
|
||||||
//correct the position of the capsule
|
// //correct the position of the capsule
|
||||||
corrected.add(normal);
|
// corrected.add(normal);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
//apply correction
|
// //apply correction
|
||||||
CollisionObjUtils.clientPositionCharacter(parent, newPosition, entRot);
|
// CollisionObjUtils.clientPositionCharacter(parent, newPosition, entRot);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,28 +1,13 @@
|
|||||||
package electrosphere.entity.state.collidable;
|
package electrosphere.entity.state.collidable;
|
||||||
|
|
||||||
import electrosphere.client.block.BlockChunkData;
|
|
||||||
import electrosphere.collision.PhysicsUtils;
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.collision.physics.CollisionResult;
|
|
||||||
import electrosphere.engine.Globals;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.entity.state.gravity.ServerGravityTree;
|
import electrosphere.entity.state.gravity.ServerGravityTree;
|
||||||
import electrosphere.entity.state.movement.fall.ServerFallTree;
|
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.DBody;
|
||||||
import org.ode4j.ode.DCapsule;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server collidable tree
|
* Server collidable tree
|
||||||
@ -32,17 +17,17 @@ public class ServerCollidableTree implements BehaviorTree {
|
|||||||
/**
|
/**
|
||||||
* The parent of the collidable
|
* The parent of the collidable
|
||||||
*/
|
*/
|
||||||
Entity parent;
|
private Entity parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The body
|
* The body
|
||||||
*/
|
*/
|
||||||
DBody body;
|
protected DBody body;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The collidable
|
* The collidable
|
||||||
*/
|
*/
|
||||||
Collidable collidable;
|
private Collidable collidable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,92 +61,92 @@ public class ServerCollidableTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//capsule-specific block collision logic
|
//capsule-specific block collision logic
|
||||||
if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){
|
// if(body.isEnabled() && body.getFirstGeom() != null && (body.getFirstGeom() instanceof DCapsule)){
|
||||||
Realm realm = Globals.serverState.realmManager.getEntityRealm(parent);
|
// Realm realm = Globals.serverState.realmManager.getEntityRealm(parent);
|
||||||
if(realm.getDataCellManager() instanceof VoxelCellManager){
|
// if(realm.getDataCellManager() instanceof VoxelCellManager){
|
||||||
VoxelCellManager voxelCellManager = (VoxelCellManager)realm.getDataCellManager();
|
// VoxelCellManager voxelCellManager = (VoxelCellManager)realm.getDataCellManager();
|
||||||
|
|
||||||
//get capsule params
|
// //get capsule params
|
||||||
DCapsule capsuleGeom = (DCapsule)body.getFirstGeom();
|
// DCapsule capsuleGeom = (DCapsule)body.getFirstGeom();
|
||||||
double length = capsuleGeom.getLength();
|
// double length = capsuleGeom.getLength();
|
||||||
double halfLength = length / 2.0;
|
// double halfLength = length / 2.0;
|
||||||
double radius = capsuleGeom.getRadius();
|
// double radius = capsuleGeom.getRadius();
|
||||||
Vector3d bodyOffset = PhysicsUtils.odeVecToJomlVec(body.getFirstGeom().getOffsetPosition());
|
// Vector3d bodyOffset = PhysicsUtils.odeVecToJomlVec(body.getFirstGeom().getOffsetPosition());
|
||||||
|
|
||||||
//entity spatial transforms
|
// //entity spatial transforms
|
||||||
Vector3d entRealPos = EntityUtils.getPosition(parent);
|
// Vector3d entRealPos = EntityUtils.getPosition(parent);
|
||||||
Quaterniond entRot = EntityUtils.getRotation(parent);
|
// Quaterniond entRot = EntityUtils.getRotation(parent);
|
||||||
|
|
||||||
//start and end of capsule
|
// //start and end of capsule
|
||||||
Vector3d realStart = new Vector3d(0,-halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset);
|
// 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);
|
// Vector3d realEnd = new Vector3d(0,halfLength,0).rotate(entRot).add(entRealPos).add(bodyOffset);
|
||||||
|
|
||||||
|
|
||||||
//block position of body
|
// //block position of body
|
||||||
Vector3d blockPos = ServerWorldData.clampRealToBlock(entRealPos);
|
// Vector3d blockPos = ServerWorldData.clampRealToBlock(entRealPos);
|
||||||
Vector3d currBlockPos = new Vector3d();
|
// Vector3d currBlockPos = new Vector3d();
|
||||||
|
|
||||||
//get dims to scan along (ceil to overcompensate -- better to over scan than underscan)
|
// //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 halfRadBlockLen = (int)Math.ceil(halfLength / BlockChunkData.BLOCK_SIZE_MULTIPLIER);
|
||||||
int radBlockLen = (int)Math.ceil(radius / BlockChunkData.BLOCK_SIZE_MULTIPLIER);
|
// int radBlockLen = (int)Math.ceil(radius / BlockChunkData.BLOCK_SIZE_MULTIPLIER);
|
||||||
|
|
||||||
//final corrected position
|
// //final corrected position
|
||||||
Vector3d corrected = new Vector3d(entRealPos);
|
// Vector3d corrected = new Vector3d(entRealPos);
|
||||||
|
|
||||||
//scan for all potential blocks
|
// //scan for all potential blocks
|
||||||
for(int x = -radBlockLen; x <= radBlockLen; x++){
|
// for(int x = -radBlockLen; x <= radBlockLen; x++){
|
||||||
for(int z = -radBlockLen; z <= radBlockLen; z++){
|
// for(int z = -radBlockLen; z <= radBlockLen; z++){
|
||||||
for(int y = -halfRadBlockLen; y <= halfRadBlockLen; y++){
|
// for(int y = -halfRadBlockLen; y <= halfRadBlockLen; y++){
|
||||||
currBlockPos.set(blockPos).add(
|
// currBlockPos.set(blockPos).add(
|
||||||
x * BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
// x * BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
||||||
y * BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
// y * BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
||||||
z * BlockChunkData.BLOCK_SIZE_MULTIPLIER
|
// z * BlockChunkData.BLOCK_SIZE_MULTIPLIER
|
||||||
);
|
// );
|
||||||
Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(currBlockPos);
|
// Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(currBlockPos);
|
||||||
Vector3i entBlockPos = ServerWorldData.convertRealToLocalBlockSpace(currBlockPos);
|
// Vector3i entBlockPos = ServerWorldData.convertRealToLocalBlockSpace(currBlockPos);
|
||||||
|
|
||||||
//error check bounds
|
// //error check bounds
|
||||||
if(chunkPos.x < 0 || chunkPos.y < 0 || chunkPos.z < 0){
|
// if(chunkPos.x < 0 || chunkPos.y < 0 || chunkPos.z < 0){
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
//get block data for block to check
|
// //get block data for block to check
|
||||||
BlockChunkData data = voxelCellManager.getBlocksAtPosition(chunkPos);
|
// BlockChunkData data = voxelCellManager.getBlocksAtPosition(chunkPos);
|
||||||
short type = data.getType(entBlockPos.x, entBlockPos.y, entBlockPos.z);
|
// 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
|
// //AABB for the voxel
|
||||||
AABBd voxelBox = new AABBd(
|
// AABBd voxelBox = new AABBd(
|
||||||
currBlockPos.x,
|
// currBlockPos.x,
|
||||||
currBlockPos.y,
|
// currBlockPos.y,
|
||||||
currBlockPos.z,
|
// currBlockPos.z,
|
||||||
currBlockPos.x + BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
// currBlockPos.x + BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
||||||
currBlockPos.y + BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
// currBlockPos.y + BlockChunkData.BLOCK_SIZE_MULTIPLIER,
|
||||||
currBlockPos.z + BlockChunkData.BLOCK_SIZE_MULTIPLIER
|
// currBlockPos.z + BlockChunkData.BLOCK_SIZE_MULTIPLIER
|
||||||
);
|
// );
|
||||||
|
|
||||||
//actually collision check
|
// //actually collision check
|
||||||
CollisionResult collisionResult = CollisionUtils.collideCapsuleAABB(realStart, realEnd, radius, voxelBox);
|
// CollisionResult collisionResult = CollisionUtils.collideCapsuleAABB(realStart, realEnd, radius, voxelBox);
|
||||||
if(collisionResult != null){
|
// if(collisionResult != null){
|
||||||
double pen = collisionResult.getPenetration();
|
// double pen = collisionResult.getPenetration();
|
||||||
double forceMul = pen * 0.3;
|
// double forceMul = pen * 0.3;
|
||||||
Vector3d normal = collisionResult.getNormal().mul(forceMul);
|
// Vector3d normal = collisionResult.getNormal().mul(forceMul);
|
||||||
if(normal != null){
|
// if(normal != null){
|
||||||
// body.addForce(normal.x, normal.y, normal.z);
|
// // body.addForce(normal.x, normal.y, normal.z);
|
||||||
//correct the position of the capsule
|
// //correct the position of the capsule
|
||||||
corrected.add(normal);
|
// corrected.add(normal);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
//apply correction
|
// //apply correction
|
||||||
CollisionObjUtils.serverPositionCharacter(parent, corrected);
|
// CollisionObjUtils.serverPositionCharacter(parent, corrected);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -83,12 +83,21 @@ public class CollisionObjUtils {
|
|||||||
}
|
}
|
||||||
if(geom != null){
|
if(geom != null){
|
||||||
CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(e);
|
CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(e);
|
||||||
PhysicsUtils.setGeomTransform(
|
if(template == null){
|
||||||
collisionEngine,
|
PhysicsUtils.setGeomTransform(
|
||||||
new Vector3d(position).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()),
|
collisionEngine,
|
||||||
rotation,
|
position,
|
||||||
geom
|
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);
|
DGeom geom = PhysicsEntityUtils.getDGeom(e);
|
||||||
if(geom != null){
|
if(geom != null){
|
||||||
CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(e);
|
CollidableTemplate template = PhysicsEntityUtils.getPhysicsTemplate(e);
|
||||||
PhysicsUtils.setGeomTransform(
|
if(template == null){
|
||||||
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
|
PhysicsUtils.setGeomTransform(
|
||||||
new Vector3d(position).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()),
|
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
|
||||||
rotation,
|
new Vector3d(position),
|
||||||
geom
|
rotation,
|
||||||
);
|
geom
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
PhysicsUtils.setGeomTransform(
|
||||||
|
Globals.clientState.clientSceneWrapper.getCollisionEngine(),
|
||||||
|
new Vector3d(position).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()),
|
||||||
|
rotation,
|
||||||
|
geom
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import java.util.concurrent.Executors;
|
|||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DGeom;
|
||||||
|
|
||||||
import electrosphere.client.block.BlockChunkData;
|
import electrosphere.client.block.BlockChunkData;
|
||||||
import electrosphere.client.block.cells.BlockDrawCell;
|
import electrosphere.client.block.cells.BlockDrawCell;
|
||||||
@ -78,7 +78,7 @@ public class BlockChunkEntity {
|
|||||||
}));
|
}));
|
||||||
EntityCreationUtils.makeEntityDrawablePreexistingModel(solidsEnt, modelPath);
|
EntityCreationUtils.makeEntityDrawablePreexistingModel(solidsEnt, modelPath);
|
||||||
if(levelOfDetail == BlockChunkData.LOD_FULL_RES){
|
if(levelOfDetail == BlockChunkData.LOD_FULL_RES){
|
||||||
PhysicsEntityUtils.clientAttachMultiShapeTriGeomRigidBody(solidsEnt, data);
|
PhysicsEntityUtils.clientAttachMultiShapeTriGeomCollider(solidsEnt, data);
|
||||||
CollisionObjUtils.clientPositionCharacter(solidsEnt, new Vector3d(EntityUtils.getPosition(solidsEnt)), new Quaterniond());
|
CollisionObjUtils.clientPositionCharacter(solidsEnt, new Vector3d(EntityUtils.getPosition(solidsEnt)), new Quaterniond());
|
||||||
} else {
|
} else {
|
||||||
EntityCreationUtils.bypassShadowPass(solidsEnt);
|
EntityCreationUtils.bypassShadowPass(solidsEnt);
|
||||||
@ -129,7 +129,7 @@ public class BlockChunkEntity {
|
|||||||
}));
|
}));
|
||||||
EntityCreationUtils.makeEntityDrawablePreexistingModel(transparentEnt, modelPath);
|
EntityCreationUtils.makeEntityDrawablePreexistingModel(transparentEnt, modelPath);
|
||||||
if(levelOfDetail == BlockChunkData.LOD_FULL_RES){
|
if(levelOfDetail == BlockChunkData.LOD_FULL_RES){
|
||||||
PhysicsEntityUtils.clientAttachMultiShapeTriGeomRigidBody(transparentEnt, data);
|
PhysicsEntityUtils.clientAttachMultiShapeTriGeomCollider(transparentEnt, data);
|
||||||
CollisionObjUtils.clientPositionCharacter(transparentEnt, new Vector3d(EntityUtils.getPosition(transparentEnt)), new Quaterniond());
|
CollisionObjUtils.clientPositionCharacter(transparentEnt, new Vector3d(EntityUtils.getPosition(transparentEnt)), new Quaterniond());
|
||||||
} else {
|
} else {
|
||||||
EntityCreationUtils.bypassShadowPass(transparentEnt);
|
EntityCreationUtils.bypassShadowPass(transparentEnt);
|
||||||
@ -182,12 +182,12 @@ public class BlockChunkEntity {
|
|||||||
*/
|
*/
|
||||||
public static void serverCreateBlockChunkEntity(Entity entity, BlockMeshData blockChunkData){
|
public static void serverCreateBlockChunkEntity(Entity entity, BlockMeshData blockChunkData){
|
||||||
if(blockChunkData.getVertices().length > 0){
|
if(blockChunkData.getVertices().length > 0){
|
||||||
PhysicsEntityUtils.serverAttachMultiShapeTriGeomRigidBody(entity, blockChunkData);
|
PhysicsEntityUtils.serverAttachMultiShapeTriGeomCollider(entity, blockChunkData);
|
||||||
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
|
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
|
||||||
DBody terrainBody = PhysicsEntityUtils.getDBody(entity);
|
DGeom terrainCollider = PhysicsEntityUtils.getDGeom(entity);
|
||||||
Vector3d entityPos = EntityUtils.getPosition(entity);
|
Vector3d entityPos = EntityUtils.getPosition(entity);
|
||||||
Quaterniond entityRot = EntityUtils.getRotation(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);
|
entity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||||
CommonEntityUtils.setEntityType(entity, EntityType.ENGINE);
|
CommonEntityUtils.setEntityType(entity, EntityType.ENGINE);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import java.util.concurrent.Executors;
|
|||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DGeom;
|
||||||
|
|
||||||
import electrosphere.client.block.BlockChunkData;
|
import electrosphere.client.block.BlockChunkData;
|
||||||
import electrosphere.client.terrain.cells.ClientDrawCellManager;
|
import electrosphere.client.terrain.cells.ClientDrawCellManager;
|
||||||
@ -73,7 +73,7 @@ public class TerrainChunk {
|
|||||||
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas, notifyTarget, toDelete);
|
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas, notifyTarget, toDelete);
|
||||||
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
|
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
|
||||||
if(levelOfDetail == BlockChunkData.LOD_FULL_RES && data.getFaceElements().length > 0){
|
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));
|
Vector3d finalPos = new Vector3d(EntityUtils.getPosition(rVal));
|
||||||
CollisionObjUtils.clientPositionCharacter(rVal, finalPos, new Quaterniond());
|
CollisionObjUtils.clientPositionCharacter(rVal, finalPos, new Quaterniond());
|
||||||
} else {
|
} else {
|
||||||
@ -131,11 +131,11 @@ public class TerrainChunk {
|
|||||||
if(data.getVertices().length > 0){
|
if(data.getVertices().length > 0){
|
||||||
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
|
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
|
||||||
if(realm != null){
|
if(realm != null){
|
||||||
PhysicsEntityUtils.serverAttachTriGeomRigidBody(entity, data);
|
PhysicsEntityUtils.serverAttachTriGeomCollider(entity, data);
|
||||||
DBody terrainBody = PhysicsEntityUtils.getDBody(entity);
|
DGeom terrainGeom = PhysicsEntityUtils.getDGeom(entity);
|
||||||
Vector3d entityPos = EntityUtils.getPosition(entity);
|
Vector3d entityPos = EntityUtils.getPosition(entity);
|
||||||
Quaterniond entityRot = EntityUtils.getRotation(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);
|
entity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||||
CommonEntityUtils.setEntityType(entity, EntityType.ENGINE);
|
CommonEntityUtils.setEntityType(entity, EntityType.ENGINE);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,10 +94,12 @@ public class PhysicsDataCell {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//generate
|
//generate terrain
|
||||||
this.terrainChunkData = TerrainChunk.serverGenerateTerrainChunkData(weights, types);
|
this.terrainChunkData = TerrainChunk.serverGenerateTerrainChunkData(weights, types);
|
||||||
TerrainChunk.serverCreateTerrainChunkEntity(localPhysicsEnt, this.terrainChunkData);
|
TerrainChunk.serverCreateTerrainChunkEntity(localPhysicsEnt, this.terrainChunkData);
|
||||||
localPhysicsEnt.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
localPhysicsEnt.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||||
|
|
||||||
|
//generate blocks
|
||||||
this.blockData = BlockMeshgen.rasterize(this.blockChunk);
|
this.blockData = BlockMeshgen.rasterize(this.blockChunk);
|
||||||
BlockChunkEntity.serverCreateBlockChunkEntity(localBlockPhysicsEntity, this.blockData);
|
BlockChunkEntity.serverCreateBlockChunkEntity(localBlockPhysicsEntity, this.blockData);
|
||||||
localBlockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
localBlockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user