pathfinding tiling work
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-02 16:46:46 -04:00
parent 18023872b0
commit e489def162
4 changed files with 90 additions and 13 deletions

View File

@ -1649,6 +1649,7 @@ Fix blocks not saving to disk when being ejected from cache
Block chunk memory pooling
Rename MoveToTree
Major pathfinding work -- breaking MoteToTree
Pathfinding tiling work

View File

@ -84,7 +84,6 @@ import electrosphere.server.datacell.EntityDataCellMapper;
import electrosphere.server.datacell.RealmManager;
import electrosphere.server.db.DatabaseController;
import electrosphere.server.entity.poseactor.PoseModel;
import electrosphere.server.pathfinding.Pathfinder;
import electrosphere.server.saves.Save;
import electrosphere.server.simulation.MacroSimulation;
import electrosphere.server.simulation.MicroSimulation;
@ -430,9 +429,6 @@ public class Globals {
//drag item state
public static Entity draggedItem = null;
public static Object dragSourceInventory = null;
//pathfinder
public static Pathfinder pathfinder;
@ -522,9 +518,6 @@ public class Globals {
gameConfigCurrent = gameConfigDefault;
NetConfig.readNetConfig();
//pathfinder
Globals.pathfinder = new Pathfinder();
//
//Values that depend on the loaded config
Globals.clientSelectedVoxelType = (VoxelType)gameConfigCurrent.getVoxelData().getTypes().toArray()[1];

View File

@ -40,6 +40,7 @@ import electrosphere.server.datacell.physics.PhysicsDataCell;
import electrosphere.server.entity.ServerContentManager;
import electrosphere.server.entity.serialization.ContentSerialization;
import electrosphere.server.pathfinding.NavMeshConstructor;
import electrosphere.server.pathfinding.Pathfinder;
import electrosphere.server.physics.block.manager.ServerBlockManager;
import electrosphere.server.physics.fluid.manager.ServerFluidChunk;
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)
*/
Map<Long,Vector3i> physicsQueue = new HashMap<Long,Vector3i>();
/**
* The pathfinder for the manager
*/
Pathfinder pathfinder;
/**
* Constructor
@ -188,6 +194,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
this.serverContentManager + " "
);
}
this.pathfinder = new Pathfinder();
}
/**
@ -369,6 +376,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
if(pathingMeshData == null){
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);
}
@ -754,7 +770,8 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
Map<Long, PhysicsDataCell> posPhysicsMap,
Map<Long, ServerDataCell> groundDataCells,
Map<ServerDataCell,GriddedDataCellTrackingData> cellTrackingMap,
Realm realm
Realm realm,
Pathfinder pathfinder
){
//get data to generate with
Vector3d realPos = new Vector3d(
@ -811,6 +828,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
if(pathingMeshData == null){
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);
}
@ -861,7 +887,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
//generates physics for the cell in a dedicated thread then finally registers
loadedCellsLock.lock();
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();
@ -1123,7 +1149,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
if(trackingMeshData == 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;
}

View File

@ -1,8 +1,11 @@
package electrosphere.server.pathfinding;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -10,6 +13,7 @@ import org.recast4j.detour.DefaultQueryFilter;
import org.recast4j.detour.FindNearestPolyResult;
import org.recast4j.detour.MeshData;
import org.recast4j.detour.NavMesh;
import org.recast4j.detour.NavMeshParams;
import org.recast4j.detour.NavMeshQuery;
import org.recast4j.detour.QueryFilter;
import org.recast4j.detour.Result;
@ -27,6 +31,57 @@ public class Pathfinder {
* Maximum points in a straight path
*/
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
@ -36,6 +91,7 @@ public class Pathfinder {
* @return The set of points to path along
*/
public List<Vector3d> solve(MeshData mesh, Vector3d startPos, Vector3d endPos){
lock.lock();
List<Vector3d> rVal = new LinkedList<Vector3d>();
if(mesh == null){
@ -43,8 +99,7 @@ public class Pathfinder {
}
//construct objects
NavMesh navMesh = new NavMesh(mesh,6,0);
NavMeshQuery query = new NavMeshQuery(navMesh);
NavMeshQuery query = new NavMeshQuery(this.navMesh);
QueryFilter filter = new DefaultQueryFilter();
//convert points to correct datatypes
@ -91,7 +146,7 @@ public class Pathfinder {
message = "Failed to solve for path -- invalid param!\n" +
"Message: " + pathResult.message + "\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]));
}
lock.unlock();
return rVal;
}