macro pathfinding work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-05-30 21:27:53 -04:00
parent 0d01a4c214
commit 57de3d5d81
7 changed files with 153 additions and 17 deletions

View File

@ -2085,6 +2085,7 @@ Synchronized time-of-day between server and client
Skybox reflects time of day
Standardize data sourcing in MacroTemporalData
Macro pathfinding scaffolding
Macro pathfinding work

View File

@ -25,6 +25,11 @@ public class ThreadCounts {
*/
public static final int PATHFINDING_THREADS = 1;
/**
* Number of threads for solving macro pathfinding
*/
public static final int MACRO_PATHING_THREADS = 1;
/**
* Number of threads for gridded datacell manager chunk loading/unloading
*/

View File

@ -12,6 +12,7 @@ import electrosphere.server.db.DatabaseController;
import electrosphere.server.saves.Save;
import electrosphere.server.service.CharacterService;
import electrosphere.server.service.LODEmitterService;
import electrosphere.server.service.MacroPathingService;
import electrosphere.server.service.StructureScanningService;
import electrosphere.server.simulation.MicroSimulation;
@ -65,6 +66,11 @@ public class ServerState {
*/
public final LODEmitterService lodEmitterService;
/**
* The macro pathing service
*/
public final MacroPathingService macroPathingService;
/**
* behavior tree tracking service
*/
@ -92,6 +98,7 @@ public class ServerState {
this.characterService = (CharacterService)Globals.engineState.serviceManager.registerService(new CharacterService());
this.structureScanningService = (StructureScanningService)Globals.engineState.serviceManager.registerService(new StructureScanningService());
this.lodEmitterService = (LODEmitterService)Globals.engineState.serviceManager.registerService(new LODEmitterService());
this.macroPathingService = (MacroPathingService)Globals.engineState.serviceManager.registerService(new MacroPathingService());
}
}

View File

@ -9,7 +9,8 @@ import electrosphere.server.ai.AI;
import electrosphere.server.ai.blackboard.Blackboard;
import electrosphere.server.ai.nodes.AITreeNode;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.interfaces.PathfindingManager;
import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.spatial.MacroAreaObject;
import electrosphere.server.macro.spatial.path.MacroPathNode;
import electrosphere.server.macro.structure.VirtualStructure;
import electrosphere.server.pathfinding.recast.PathingProgressiveData;
@ -70,30 +71,32 @@ public class MacroPathfindingNode implements AITreeNode {
//create a path if we don't already have one
if(!PathfindingNode.hasPathfindingData(blackboard)){
//
//figure out what we're targeting
Object targetRaw = blackboard.get(this.targetEntityKey);
Vector3d targetPos = null;
if(targetRaw == null){
throw new Error("Target undefined!");
}
if(targetRaw instanceof Vector3d){
targetPos = (Vector3d)targetRaw;
} else if(targetRaw instanceof Entity){
targetPos = EntityUtils.getPosition((Entity)targetRaw);
} else if(targetRaw instanceof VirtualStructure){
targetPos = ((VirtualStructure)targetRaw).getPos();
if(targetRaw instanceof MacroAreaObject){
} else {
throw new Error("Unsupported target type " + targetRaw);
}
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
PathfindingManager pathfindingManager = realm.getPathfindingManager();
MacroPathNode targetMacro = realm.getMacroData().getPathCache().getPathingNode(((MacroAreaObject)targetRaw).getPos());
Vector3d entityPos = EntityUtils.getPosition(entity);
PathingProgressiveData pathingProgressiveData = pathfindingManager.findPathAsync(entityPos, targetPos);
//
//Find where the entity is currently
MacroPathNode currentPos = this.solveCurrentNode(entity);
//
//Queue the pathfinding operation
PathingProgressiveData pathingProgressiveData = Globals.serverState.macroPathingService.queuePathfinding(realm, currentPos, targetMacro);
PathfindingNode.setPathfindingData(blackboard, pathingProgressiveData);
}
//make sure we found a path
if(!PathfindingNode.hasPathfindingData(blackboard)){
throw new Error("Failed to find path! Unhandled");
}
@ -106,8 +109,9 @@ public class MacroPathfindingNode implements AITreeNode {
}
//
//walk along the path if it exists
Vector3d entityPos = EntityUtils.getPosition(entity);
Vector3d currentPathPos = null;
if(pathingProgressiveData.getCurrentPoint() < pathingProgressiveData.getPoints().size()){
currentPathPos = pathingProgressiveData.getPoints().get(pathingProgressiveData.getCurrentPoint());
@ -152,4 +156,22 @@ public class MacroPathfindingNode implements AITreeNode {
return AITreeNodeResult.SUCCESS;
}
/**
* Gets the pathing node of this entity
* @param entity The entity
* @return The pathing node
*/
private MacroPathNode solveCurrentNode(Entity entity){
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
if(realm == null){
throw new Error("Entity is not attached to a realm!");
}
MacroData macroData = realm.getMacroData();
if(macroData == null){
throw new Error("Macro data undefined!");
}
Vector3d entityPos = EntityUtils.getPosition(entity);
return macroData.getPathCache().getPathingNode(entityPos);
}
}

View File

@ -5,6 +5,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.joml.Vector3d;
import electrosphere.util.annotation.Exclude;
/**
@ -60,4 +62,22 @@ public class MacroPathCache {
idNodeMap.put(node.getId(),node);
}
/**
* Gets the pathing node at a given point
* @param point The point
* @return The corresponding pathing node
*/
public MacroPathNode getPathingNode(Vector3d point){
double minDist = 100;
MacroPathNode rVal = null;
for(MacroPathNode node : this.nodes){
double dist = point.distance(node.getPosition());
if(dist < minDist){
minDist = dist;
rVal = node;
}
}
return rVal;
}
}

View File

@ -12,22 +12,22 @@ public class PathingProgressiveData {
/**
* The list of points that represent the path
*/
List<Vector3d> points;
private List<Vector3d> points;
/**
* The current point to move towards (ie all previous points have already been pathed to)
*/
int currentPoint;
private int currentPoint;
/**
* The goal position
*/
Vector3d goal;
private Vector3d goal;
/**
* Tracks whether this data is ready to be used or not
*/
boolean ready = false;
private boolean ready = false;
/**

View File

@ -0,0 +1,81 @@
package electrosphere.server.service;
import java.util.List;
import java.util.concurrent.ExecutorService;
import org.joml.Vector3d;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.engine.Globals;
import electrosphere.engine.signal.SignalServiceImpl;
import electrosphere.engine.threads.ThreadCounts;
import electrosphere.server.datacell.Realm;
import electrosphere.server.macro.MacroData;
import electrosphere.server.macro.spatial.path.MacroPathNode;
import electrosphere.server.pathfinding.recast.PathingProgressiveData;
/**
* Service for solving pathing between macro area objects
*/
public class MacroPathingService extends SignalServiceImpl {
/**
* The executor service
*/
final ExecutorService executorService;
/**
* Constructor
*/
public MacroPathingService() {
super("MacroPathingService", new SignalType[]{
});
this.executorService = Globals.engineState.threadManager.requestFixedThreadPool(ThreadCounts.MACRO_PATHING_THREADS);
}
/**
* Simulates the macro pathing service
*/
public void simulate(){
}
/**
* Queues a pathfinding job
* @param realm The realm
* @param start The start point
* @param end The end point
* @return The object that will eventually hold the pathfinding data
*/
public PathingProgressiveData queuePathfinding(Realm realm, MacroPathNode start, MacroPathNode end){
PathingProgressiveData rVal = new PathingProgressiveData(end.getPosition());
executorService.submit(() -> {
try {
List<Vector3d> points = this.findPath(realm.getMacroData(), start, end);
rVal.setPoints(points);
rVal.setReady(true);
} catch(Throwable e){
e.printStackTrace();
}
});
return rVal;
}
/**
* Halts all threads in the pathfinding service
*/
public void haltThreads(){
executorService.shutdownNow();
}
/**
* Finds a path between macro area objects
* @param macroData The macro data
* @param start The start area
* @param end The end area
* @return The path
*/
private List<Vector3d> findPath(MacroData macroData, MacroPathNode start, MacroPathNode end){
throw new Error("Not implemented yet!");
}
}