pathfinding tiling work
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
18023872b0
commit
e489def162
@ -1649,6 +1649,7 @@ Fix blocks not saving to disk when being ejected from cache
|
|||||||
Block chunk memory pooling
|
Block chunk memory pooling
|
||||||
Rename MoveToTree
|
Rename MoveToTree
|
||||||
Major pathfinding work -- breaking MoteToTree
|
Major pathfinding work -- breaking MoteToTree
|
||||||
|
Pathfinding tiling work
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,6 @@ import electrosphere.server.datacell.EntityDataCellMapper;
|
|||||||
import electrosphere.server.datacell.RealmManager;
|
import electrosphere.server.datacell.RealmManager;
|
||||||
import electrosphere.server.db.DatabaseController;
|
import electrosphere.server.db.DatabaseController;
|
||||||
import electrosphere.server.entity.poseactor.PoseModel;
|
import electrosphere.server.entity.poseactor.PoseModel;
|
||||||
import electrosphere.server.pathfinding.Pathfinder;
|
|
||||||
import electrosphere.server.saves.Save;
|
import electrosphere.server.saves.Save;
|
||||||
import electrosphere.server.simulation.MacroSimulation;
|
import electrosphere.server.simulation.MacroSimulation;
|
||||||
import electrosphere.server.simulation.MicroSimulation;
|
import electrosphere.server.simulation.MicroSimulation;
|
||||||
@ -430,9 +429,6 @@ public class Globals {
|
|||||||
//drag item state
|
//drag item state
|
||||||
public static Entity draggedItem = null;
|
public static Entity draggedItem = null;
|
||||||
public static Object dragSourceInventory = null;
|
public static Object dragSourceInventory = null;
|
||||||
|
|
||||||
//pathfinder
|
|
||||||
public static Pathfinder pathfinder;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -522,9 +518,6 @@ public class Globals {
|
|||||||
gameConfigCurrent = gameConfigDefault;
|
gameConfigCurrent = gameConfigDefault;
|
||||||
NetConfig.readNetConfig();
|
NetConfig.readNetConfig();
|
||||||
|
|
||||||
//pathfinder
|
|
||||||
Globals.pathfinder = new Pathfinder();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//Values that depend on the loaded config
|
//Values that depend on the loaded config
|
||||||
Globals.clientSelectedVoxelType = (VoxelType)gameConfigCurrent.getVoxelData().getTypes().toArray()[1];
|
Globals.clientSelectedVoxelType = (VoxelType)gameConfigCurrent.getVoxelData().getTypes().toArray()[1];
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import electrosphere.server.datacell.physics.PhysicsDataCell;
|
|||||||
import electrosphere.server.entity.ServerContentManager;
|
import electrosphere.server.entity.ServerContentManager;
|
||||||
import electrosphere.server.entity.serialization.ContentSerialization;
|
import electrosphere.server.entity.serialization.ContentSerialization;
|
||||||
import electrosphere.server.pathfinding.NavMeshConstructor;
|
import electrosphere.server.pathfinding.NavMeshConstructor;
|
||||||
|
import electrosphere.server.pathfinding.Pathfinder;
|
||||||
import electrosphere.server.physics.block.manager.ServerBlockManager;
|
import electrosphere.server.physics.block.manager.ServerBlockManager;
|
||||||
import electrosphere.server.physics.fluid.manager.ServerFluidChunk;
|
import electrosphere.server.physics.fluid.manager.ServerFluidChunk;
|
||||||
import electrosphere.server.physics.fluid.manager.ServerFluidManager;
|
import electrosphere.server.physics.fluid.manager.ServerFluidManager;
|
||||||
@ -158,6 +159,11 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
* Queue of cells that need to have their physics regenerated (ie on block edits)
|
* Queue of cells that need to have their physics regenerated (ie on block edits)
|
||||||
*/
|
*/
|
||||||
Map<Long,Vector3i> physicsQueue = new HashMap<Long,Vector3i>();
|
Map<Long,Vector3i> physicsQueue = new HashMap<Long,Vector3i>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pathfinder for the manager
|
||||||
|
*/
|
||||||
|
Pathfinder pathfinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@ -188,6 +194,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
this.serverContentManager + " "
|
this.serverContentManager + " "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
this.pathfinder = new Pathfinder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -369,6 +376,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
if(pathingMeshData == null){
|
if(pathingMeshData == null){
|
||||||
throw new Error("Failed to build pathing data from existing vertices!");
|
throw new Error("Failed to build pathing data from existing vertices!");
|
||||||
}
|
}
|
||||||
|
pathingMeshData.header.x = worldPos.x;
|
||||||
|
pathingMeshData.header.y = worldPos.z;
|
||||||
|
pathingMeshData.header.bmin[0] = worldPos.x;
|
||||||
|
pathingMeshData.header.bmin[1] = worldPos.y;
|
||||||
|
pathingMeshData.header.bmin[2] = worldPos.z;
|
||||||
|
pathingMeshData.header.bmax[0] = worldPos.x + ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET;
|
||||||
|
pathingMeshData.header.bmax[1] = worldPos.y + ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET;
|
||||||
|
pathingMeshData.header.bmax[2] = worldPos.z + ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET;
|
||||||
|
pathfinder.addTile(pathingMeshData);
|
||||||
trackingData.setNavMeshData(pathingMeshData);
|
trackingData.setNavMeshData(pathingMeshData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,7 +770,8 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
Map<Long, PhysicsDataCell> posPhysicsMap,
|
Map<Long, PhysicsDataCell> posPhysicsMap,
|
||||||
Map<Long, ServerDataCell> groundDataCells,
|
Map<Long, ServerDataCell> groundDataCells,
|
||||||
Map<ServerDataCell,GriddedDataCellTrackingData> cellTrackingMap,
|
Map<ServerDataCell,GriddedDataCellTrackingData> cellTrackingMap,
|
||||||
Realm realm
|
Realm realm,
|
||||||
|
Pathfinder pathfinder
|
||||||
){
|
){
|
||||||
//get data to generate with
|
//get data to generate with
|
||||||
Vector3d realPos = new Vector3d(
|
Vector3d realPos = new Vector3d(
|
||||||
@ -811,6 +828,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
if(pathingMeshData == null){
|
if(pathingMeshData == null){
|
||||||
throw new Error("Failed to build pathing data from existing vertices!");
|
throw new Error("Failed to build pathing data from existing vertices!");
|
||||||
}
|
}
|
||||||
|
pathingMeshData.header.x = worldPos.x;
|
||||||
|
pathingMeshData.header.y = worldPos.z;
|
||||||
|
pathingMeshData.header.bmin[0] = worldPos.x;
|
||||||
|
pathingMeshData.header.bmin[1] = worldPos.y;
|
||||||
|
pathingMeshData.header.bmin[2] = worldPos.z;
|
||||||
|
pathingMeshData.header.bmax[0] = worldPos.x + ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET;
|
||||||
|
pathingMeshData.header.bmax[1] = worldPos.y + ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET;
|
||||||
|
pathingMeshData.header.bmax[2] = worldPos.z + ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET;
|
||||||
|
pathfinder.addTile(pathingMeshData);
|
||||||
trackingData.setNavMeshData(pathingMeshData);
|
trackingData.setNavMeshData(pathingMeshData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,7 +887,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
//generates physics for the cell in a dedicated thread then finally registers
|
//generates physics for the cell in a dedicated thread then finally registers
|
||||||
loadedCellsLock.lock();
|
loadedCellsLock.lock();
|
||||||
PhysicsDataCell cell = posPhysicsMap.get(key);
|
PhysicsDataCell cell = posPhysicsMap.get(key);
|
||||||
GriddedDataCellManager.runPhysicsGenerationThread(localWorldPos,key,cell,this.posPhysicsMap,this.groundDataCells,this.cellTrackingMap,this.parent);
|
GriddedDataCellManager.runPhysicsGenerationThread(localWorldPos,key,cell,this.posPhysicsMap,this.groundDataCells,this.cellTrackingMap,this.parent,this.pathfinder);
|
||||||
loadedCellsLock.unlock();
|
loadedCellsLock.unlock();
|
||||||
|
|
||||||
|
|
||||||
@ -1123,7 +1149,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
|||||||
if(trackingMeshData == null){
|
if(trackingMeshData == null){
|
||||||
throw new Error("Tracking mesh data is null!");
|
throw new Error("Tracking mesh data is null!");
|
||||||
}
|
}
|
||||||
List<Vector3d> points = Globals.pathfinder.solve(trackingMeshData, start, end);
|
List<Vector3d> points = this.pathfinder.solve(trackingMeshData, start, end);
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
package electrosphere.server.pathfinding;
|
package electrosphere.server.pathfinding;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
@ -10,6 +13,7 @@ import org.recast4j.detour.DefaultQueryFilter;
|
|||||||
import org.recast4j.detour.FindNearestPolyResult;
|
import org.recast4j.detour.FindNearestPolyResult;
|
||||||
import org.recast4j.detour.MeshData;
|
import org.recast4j.detour.MeshData;
|
||||||
import org.recast4j.detour.NavMesh;
|
import org.recast4j.detour.NavMesh;
|
||||||
|
import org.recast4j.detour.NavMeshParams;
|
||||||
import org.recast4j.detour.NavMeshQuery;
|
import org.recast4j.detour.NavMeshQuery;
|
||||||
import org.recast4j.detour.QueryFilter;
|
import org.recast4j.detour.QueryFilter;
|
||||||
import org.recast4j.detour.Result;
|
import org.recast4j.detour.Result;
|
||||||
@ -27,6 +31,57 @@ public class Pathfinder {
|
|||||||
* Maximum points in a straight path
|
* Maximum points in a straight path
|
||||||
*/
|
*/
|
||||||
static final int MAX_STRAIGHT_PATH_POINTS = 100;
|
static final int MAX_STRAIGHT_PATH_POINTS = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The root navmesh
|
||||||
|
*/
|
||||||
|
NavMesh navMesh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The map of ref -> nav tile
|
||||||
|
*/
|
||||||
|
Map<MeshData,Long> meshRefMap = new HashMap<MeshData,Long>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The lock for thread safety
|
||||||
|
*/
|
||||||
|
ReentrantLock lock = new ReentrantLock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the pathfinder
|
||||||
|
*/
|
||||||
|
public Pathfinder(){
|
||||||
|
NavMeshParams params = new NavMeshParams();
|
||||||
|
params.tileHeight = ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET;
|
||||||
|
params.tileWidth = ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET;
|
||||||
|
params.orig[0] = 0;
|
||||||
|
params.orig[1] = 0;
|
||||||
|
params.orig[2] = 0;
|
||||||
|
params.maxTiles = 1000;
|
||||||
|
params.maxPolys = 100000;
|
||||||
|
this.navMesh = new NavMesh(params, NavMeshConstructor.RECAST_VERTS_PER_POLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a tile to the pathfinder
|
||||||
|
* @param tile The file
|
||||||
|
*/
|
||||||
|
public void addTile(MeshData tile){
|
||||||
|
lock.lock();
|
||||||
|
long ref = this.navMesh.addTile(tile, 0, 0);
|
||||||
|
meshRefMap.put(tile,ref);
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a tile from the navmesh
|
||||||
|
* @param tile The tile
|
||||||
|
*/
|
||||||
|
public void removeTile(MeshData tile){
|
||||||
|
lock.lock();
|
||||||
|
this.navMesh.removeTile(MAX_STRAIGHT_PATH_POINTS);
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Solves for a path
|
* Solves for a path
|
||||||
@ -36,6 +91,7 @@ public class Pathfinder {
|
|||||||
* @return The set of points to path along
|
* @return The set of points to path along
|
||||||
*/
|
*/
|
||||||
public List<Vector3d> solve(MeshData mesh, Vector3d startPos, Vector3d endPos){
|
public List<Vector3d> solve(MeshData mesh, Vector3d startPos, Vector3d endPos){
|
||||||
|
lock.lock();
|
||||||
List<Vector3d> rVal = new LinkedList<Vector3d>();
|
List<Vector3d> rVal = new LinkedList<Vector3d>();
|
||||||
|
|
||||||
if(mesh == null){
|
if(mesh == null){
|
||||||
@ -43,8 +99,7 @@ public class Pathfinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//construct objects
|
//construct objects
|
||||||
NavMesh navMesh = new NavMesh(mesh,6,0);
|
NavMeshQuery query = new NavMeshQuery(this.navMesh);
|
||||||
NavMeshQuery query = new NavMeshQuery(navMesh);
|
|
||||||
QueryFilter filter = new DefaultQueryFilter();
|
QueryFilter filter = new DefaultQueryFilter();
|
||||||
|
|
||||||
//convert points to correct datatypes
|
//convert points to correct datatypes
|
||||||
@ -91,7 +146,7 @@ public class Pathfinder {
|
|||||||
message = "Failed to solve for path -- invalid param!\n" +
|
message = "Failed to solve for path -- invalid param!\n" +
|
||||||
"Message: " + pathResult.message + "\n" +
|
"Message: " + pathResult.message + "\n" +
|
||||||
"Status: " + pathResult.status + "\n" +
|
"Status: " + pathResult.status + "\n" +
|
||||||
Pathfinder.checkInvalidParam(navMesh,startRef,endRef,startArr,endArr) + "\n" +
|
Pathfinder.checkInvalidParam(this.navMesh,startRef,endRef,startArr,endArr) + "\n" +
|
||||||
""
|
""
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -112,6 +167,8 @@ public class Pathfinder {
|
|||||||
rVal.add(new Vector3d(pathItem.getPos()[0],pathItem.getPos()[1],pathItem.getPos()[2]));
|
rVal.add(new Vector3d(pathItem.getPos()[0],pathItem.getPos()[1],pathItem.getPos()[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user