macro pathfinding work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
0d01a4c214
commit
57de3d5d81
@ -2085,6 +2085,7 @@ Synchronized time-of-day between server and client
|
|||||||
Skybox reflects time of day
|
Skybox reflects time of day
|
||||||
Standardize data sourcing in MacroTemporalData
|
Standardize data sourcing in MacroTemporalData
|
||||||
Macro pathfinding scaffolding
|
Macro pathfinding scaffolding
|
||||||
|
Macro pathfinding work
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,11 @@ public class ThreadCounts {
|
|||||||
*/
|
*/
|
||||||
public static final int PATHFINDING_THREADS = 1;
|
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
|
* Number of threads for gridded datacell manager chunk loading/unloading
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import electrosphere.server.db.DatabaseController;
|
|||||||
import electrosphere.server.saves.Save;
|
import electrosphere.server.saves.Save;
|
||||||
import electrosphere.server.service.CharacterService;
|
import electrosphere.server.service.CharacterService;
|
||||||
import electrosphere.server.service.LODEmitterService;
|
import electrosphere.server.service.LODEmitterService;
|
||||||
|
import electrosphere.server.service.MacroPathingService;
|
||||||
import electrosphere.server.service.StructureScanningService;
|
import electrosphere.server.service.StructureScanningService;
|
||||||
import electrosphere.server.simulation.MicroSimulation;
|
import electrosphere.server.simulation.MicroSimulation;
|
||||||
|
|
||||||
@ -65,6 +66,11 @@ public class ServerState {
|
|||||||
*/
|
*/
|
||||||
public final LODEmitterService lodEmitterService;
|
public final LODEmitterService lodEmitterService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The macro pathing service
|
||||||
|
*/
|
||||||
|
public final MacroPathingService macroPathingService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* behavior tree tracking service
|
* behavior tree tracking service
|
||||||
*/
|
*/
|
||||||
@ -92,6 +98,7 @@ public class ServerState {
|
|||||||
this.characterService = (CharacterService)Globals.engineState.serviceManager.registerService(new CharacterService());
|
this.characterService = (CharacterService)Globals.engineState.serviceManager.registerService(new CharacterService());
|
||||||
this.structureScanningService = (StructureScanningService)Globals.engineState.serviceManager.registerService(new StructureScanningService());
|
this.structureScanningService = (StructureScanningService)Globals.engineState.serviceManager.registerService(new StructureScanningService());
|
||||||
this.lodEmitterService = (LODEmitterService)Globals.engineState.serviceManager.registerService(new LODEmitterService());
|
this.lodEmitterService = (LODEmitterService)Globals.engineState.serviceManager.registerService(new LODEmitterService());
|
||||||
|
this.macroPathingService = (MacroPathingService)Globals.engineState.serviceManager.registerService(new MacroPathingService());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,8 @@ import electrosphere.server.ai.AI;
|
|||||||
import electrosphere.server.ai.blackboard.Blackboard;
|
import electrosphere.server.ai.blackboard.Blackboard;
|
||||||
import electrosphere.server.ai.nodes.AITreeNode;
|
import electrosphere.server.ai.nodes.AITreeNode;
|
||||||
import electrosphere.server.datacell.Realm;
|
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.spatial.path.MacroPathNode;
|
||||||
import electrosphere.server.macro.structure.VirtualStructure;
|
import electrosphere.server.macro.structure.VirtualStructure;
|
||||||
import electrosphere.server.pathfinding.recast.PathingProgressiveData;
|
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
|
//create a path if we don't already have one
|
||||||
if(!PathfindingNode.hasPathfindingData(blackboard)){
|
if(!PathfindingNode.hasPathfindingData(blackboard)){
|
||||||
|
|
||||||
|
//
|
||||||
|
//figure out what we're targeting
|
||||||
Object targetRaw = blackboard.get(this.targetEntityKey);
|
Object targetRaw = blackboard.get(this.targetEntityKey);
|
||||||
Vector3d targetPos = null;
|
|
||||||
if(targetRaw == null){
|
if(targetRaw == null){
|
||||||
throw new Error("Target undefined!");
|
throw new Error("Target undefined!");
|
||||||
}
|
}
|
||||||
if(targetRaw instanceof Vector3d){
|
if(targetRaw instanceof MacroAreaObject){
|
||||||
targetPos = (Vector3d)targetRaw;
|
|
||||||
} else if(targetRaw instanceof Entity){
|
|
||||||
targetPos = EntityUtils.getPosition((Entity)targetRaw);
|
|
||||||
} else if(targetRaw instanceof VirtualStructure){
|
|
||||||
targetPos = ((VirtualStructure)targetRaw).getPos();
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Unsupported target type " + targetRaw);
|
throw new Error("Unsupported target type " + targetRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
|
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);
|
PathfindingNode.setPathfindingData(blackboard, pathingProgressiveData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//make sure we found a path
|
||||||
if(!PathfindingNode.hasPathfindingData(blackboard)){
|
if(!PathfindingNode.hasPathfindingData(blackboard)){
|
||||||
throw new Error("Failed to find path! Unhandled");
|
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 entityPos = EntityUtils.getPosition(entity);
|
||||||
|
|
||||||
Vector3d currentPathPos = null;
|
Vector3d currentPathPos = null;
|
||||||
if(pathingProgressiveData.getCurrentPoint() < pathingProgressiveData.getPoints().size()){
|
if(pathingProgressiveData.getCurrentPoint() < pathingProgressiveData.getPoints().size()){
|
||||||
currentPathPos = pathingProgressiveData.getPoints().get(pathingProgressiveData.getCurrentPoint());
|
currentPathPos = pathingProgressiveData.getPoints().get(pathingProgressiveData.getCurrentPoint());
|
||||||
@ -152,4 +156,22 @@ public class MacroPathfindingNode implements AITreeNode {
|
|||||||
return AITreeNodeResult.SUCCESS;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
import electrosphere.util.annotation.Exclude;
|
import electrosphere.util.annotation.Exclude;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,4 +62,22 @@ public class MacroPathCache {
|
|||||||
idNodeMap.put(node.getId(),node);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,22 +12,22 @@ public class PathingProgressiveData {
|
|||||||
/**
|
/**
|
||||||
* The list of points that represent the path
|
* 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)
|
* The current point to move towards (ie all previous points have already been pathed to)
|
||||||
*/
|
*/
|
||||||
int currentPoint;
|
private int currentPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The goal position
|
* The goal position
|
||||||
*/
|
*/
|
||||||
Vector3d goal;
|
private Vector3d goal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks whether this data is ready to be used or not
|
* Tracks whether this data is ready to be used or not
|
||||||
*/
|
*/
|
||||||
boolean ready = false;
|
private boolean ready = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user