mirror of
https://github.com/Retera/WarsmashModEngine.git
synced 2022-07-31 17:38:59 +02:00
Attempt to improve pathfinding performance
This commit is contained in:
parent
28a24471fc
commit
12ef127d0e
@ -1,6 +1,7 @@
|
|||||||
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest;
|
package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest;
|
||||||
|
|
||||||
import com.etheller.warsmash.util.War3ID;
|
import com.etheller.warsmash.util.War3ID;
|
||||||
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit;
|
||||||
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget;
|
||||||
@ -102,6 +103,9 @@ public class CAbilityHarvest extends AbstractGenericSingleIconActiveAbility {
|
|||||||
}
|
}
|
||||||
receiver.mustTargetResources();
|
receiver.mustTargetResources();
|
||||||
}
|
}
|
||||||
|
else if (target instanceof CDestructable) {
|
||||||
|
receiver.mustTargetResources();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
receiver.mustTargetResources();
|
receiver.mustTargetResources();
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,9 @@ public class CPathfindingProcessor {
|
|||||||
private final Node[][] cornerNodes;
|
private final Node[][] cornerNodes;
|
||||||
private final Node[] goalSet = new Node[4];
|
private final Node[] goalSet = new Node[4];
|
||||||
private int goals = 0;
|
private int goals = 0;
|
||||||
|
private int pathfindJobId = 0;
|
||||||
|
private int totalIterations = 0;
|
||||||
|
private int totalJobLoops = 0;
|
||||||
|
|
||||||
public CPathfindingProcessor(final PathingGrid pathingGrid, final CWorldCollision worldCollision) {
|
public CPathfindingProcessor(final PathingGrid pathingGrid, final CWorldCollision worldCollision) {
|
||||||
this.pathingGrid = pathingGrid;
|
this.pathingGrid = pathingGrid;
|
||||||
@ -140,10 +143,21 @@ public class CPathfindingProcessor {
|
|||||||
private double f;
|
private double f;
|
||||||
private double g;
|
private double g;
|
||||||
private Node cameFrom;
|
private Node cameFrom;
|
||||||
|
private int pathfindJobId;
|
||||||
|
|
||||||
private Node(final Point2D.Float point) {
|
private Node(final Point2D.Float point) {
|
||||||
this.point = point;
|
this.point = point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void touch(final int pathfindJobId) {
|
||||||
|
if (pathfindJobId != this.pathfindJobId) {
|
||||||
|
this.g = Float.POSITIVE_INFINITY;
|
||||||
|
this.f = Float.POSITIVE_INFINITY;
|
||||||
|
this.cameFrom = null;
|
||||||
|
this.cameFromDirection = null;
|
||||||
|
this.pathfindJobId = pathfindJobId;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static enum Direction {
|
private static enum Direction {
|
||||||
@ -205,8 +219,12 @@ public class CPathfindingProcessor {
|
|||||||
public void update(final CSimulation simulation) {
|
public void update(final CSimulation simulation) {
|
||||||
int workIterations = 0;
|
int workIterations = 0;
|
||||||
JobsLoop: while (!this.moveQueue.isEmpty()) {
|
JobsLoop: while (!this.moveQueue.isEmpty()) {
|
||||||
|
this.totalJobLoops++;
|
||||||
final PathfindingJob job = this.moveQueue.peek();
|
final PathfindingJob job = this.moveQueue.peek();
|
||||||
if (!job.jobStarted) {
|
if (!job.jobStarted) {
|
||||||
|
this.pathfindJobId++;
|
||||||
|
this.totalIterations = 0;
|
||||||
|
this.totalJobLoops = 0;
|
||||||
job.jobStarted = true;
|
job.jobStarted = true;
|
||||||
System.out.println("starting job with smoothing=" + job.allowSmoothing);
|
System.out.println("starting job with smoothing=" + job.allowSmoothing);
|
||||||
workIterations += 5; // setup of job predicted cost
|
workIterations += 5; // setup of job predicted cost
|
||||||
@ -239,12 +257,14 @@ public class CPathfindingProcessor {
|
|||||||
final int goalCellY = job.gridMapping.getY(this.pathingGrid, job.goalY);
|
final int goalCellY = job.gridMapping.getY(this.pathingGrid, job.goalY);
|
||||||
final int goalCellX = job.gridMapping.getX(this.pathingGrid, job.goalX);
|
final int goalCellX = job.gridMapping.getX(this.pathingGrid, job.goalX);
|
||||||
final Node mostLikelyGoal = job.searchGraph[goalCellY][goalCellX];
|
final Node mostLikelyGoal = job.searchGraph[goalCellY][goalCellX];
|
||||||
|
mostLikelyGoal.touch(this.pathfindJobId);
|
||||||
final double bestGoalDistance = mostLikelyGoal.point.distance(job.goalX, job.goalY);
|
final double bestGoalDistance = mostLikelyGoal.point.distance(job.goalX, job.goalY);
|
||||||
Arrays.fill(this.goalSet, null);
|
Arrays.fill(this.goalSet, null);
|
||||||
this.goals = 0;
|
this.goals = 0;
|
||||||
for (int i = goalCellX - 1; i <= (goalCellX + 1); i++) {
|
for (int i = goalCellX - 1; i <= (goalCellX + 1); i++) {
|
||||||
for (int j = goalCellY - 1; j <= (goalCellY + 1); j++) {
|
for (int j = goalCellY - 1; j <= (goalCellY + 1); j++) {
|
||||||
final Node possibleGoal = job.searchGraph[j][i];
|
final Node possibleGoal = job.searchGraph[j][i];
|
||||||
|
possibleGoal.touch(this.pathfindJobId);
|
||||||
if (possibleGoal.point.distance(job.goalX, job.goalY) <= bestGoalDistance) {
|
if (possibleGoal.point.distance(job.goalX, job.goalY) <= bestGoalDistance) {
|
||||||
this.goalSet[this.goals++] = possibleGoal;
|
this.goalSet[this.goals++] = possibleGoal;
|
||||||
}
|
}
|
||||||
@ -252,16 +272,6 @@ public class CPathfindingProcessor {
|
|||||||
}
|
}
|
||||||
final int startGridY = job.gridMapping.getY(this.pathingGrid, job.startY);
|
final int startGridY = job.gridMapping.getY(this.pathingGrid, job.startY);
|
||||||
final int startGridX = job.gridMapping.getX(this.pathingGrid, job.startX);
|
final int startGridX = job.gridMapping.getX(this.pathingGrid, job.startX);
|
||||||
for (int i = 0; i < job.searchGraph.length; i++) {
|
|
||||||
for (int j = 0; j < job.searchGraph[i].length; j++) {
|
|
||||||
final Node node = job.searchGraph[i][j];
|
|
||||||
node.g = Float.POSITIVE_INFINITY;
|
|
||||||
node.f = Float.POSITIVE_INFINITY;
|
|
||||||
node.cameFrom = null;
|
|
||||||
node.cameFromDirection = null;
|
|
||||||
workIterations++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
job.openSet = new PriorityQueue<>(new Comparator<Node>() {
|
job.openSet = new PriorityQueue<>(new Comparator<Node>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(final Node a, final Node b) {
|
public int compare(final Node a, final Node b) {
|
||||||
@ -270,6 +280,7 @@ public class CPathfindingProcessor {
|
|||||||
});
|
});
|
||||||
|
|
||||||
job.start = job.searchGraph[startGridY][startGridX];
|
job.start = job.searchGraph[startGridY][startGridX];
|
||||||
|
job.start.touch(this.pathfindJobId);
|
||||||
if (job.startX > job.start.point.x) {
|
if (job.startX > job.start.point.x) {
|
||||||
job.startGridMinX = startGridX;
|
job.startGridMinX = startGridX;
|
||||||
job.startGridMaxX = startGridX + 1;
|
job.startGridMaxX = startGridX + 1;
|
||||||
@ -299,6 +310,7 @@ public class CPathfindingProcessor {
|
|||||||
if ((cellX >= 0) && (cellX < this.pathingGrid.getWidth()) && (cellY >= 0)
|
if ((cellX >= 0) && (cellX < this.pathingGrid.getWidth()) && (cellY >= 0)
|
||||||
&& (cellY < this.pathingGrid.getHeight())) {
|
&& (cellY < this.pathingGrid.getHeight())) {
|
||||||
final Node possibleNode = job.searchGraph[cellY][cellX];
|
final Node possibleNode = job.searchGraph[cellY][cellX];
|
||||||
|
possibleNode.touch(this.pathfindJobId);
|
||||||
final float x = possibleNode.point.x;
|
final float x = possibleNode.point.x;
|
||||||
final float y = possibleNode.point.y;
|
final float y = possibleNode.point.y;
|
||||||
if (pathableBetween(job.ignoreIntersectionsWithThisUnit,
|
if (pathableBetween(job.ignoreIntersectionsWithThisUnit,
|
||||||
@ -325,6 +337,7 @@ public class CPathfindingProcessor {
|
|||||||
|
|
||||||
while (!job.openSet.isEmpty()) {
|
while (!job.openSet.isEmpty()) {
|
||||||
Node current = job.openSet.poll();
|
Node current = job.openSet.poll();
|
||||||
|
current.touch(this.pathfindJobId);
|
||||||
if (isGoal(current)) {
|
if (isGoal(current)) {
|
||||||
final LinkedList<Point2D.Float> totalPath = new LinkedList<>();
|
final LinkedList<Point2D.Float> totalPath = new LinkedList<>();
|
||||||
Direction lastCameFromDirection = null;
|
Direction lastCameFromDirection = null;
|
||||||
@ -377,6 +390,8 @@ public class CPathfindingProcessor {
|
|||||||
}
|
}
|
||||||
job.queueItem.pathFound(totalPath, simulation);
|
job.queueItem.pathFound(totalPath, simulation);
|
||||||
this.moveQueue.poll();
|
this.moveQueue.poll();
|
||||||
|
System.out.println("Task " + this.pathfindJobId + " took " + this.totalIterations
|
||||||
|
+ " iterations and " + this.totalJobLoops + " job loops!");
|
||||||
continue JobsLoop;
|
continue JobsLoop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,6 +414,7 @@ public class CPathfindingProcessor {
|
|||||||
}
|
}
|
||||||
final Node neighbor = job.searchGraph[job.gridMapping.getY(this.pathingGrid, y)][job.gridMapping
|
final Node neighbor = job.searchGraph[job.gridMapping.getY(this.pathingGrid, y)][job.gridMapping
|
||||||
.getX(this.pathingGrid, x)];
|
.getX(this.pathingGrid, x)];
|
||||||
|
neighbor.touch(this.pathfindJobId);
|
||||||
if (tentativeScore < neighbor.g) {
|
if (tentativeScore < neighbor.g) {
|
||||||
neighbor.cameFrom = current;
|
neighbor.cameFrom = current;
|
||||||
neighbor.cameFromDirection = direction;
|
neighbor.cameFromDirection = direction;
|
||||||
@ -411,13 +427,16 @@ public class CPathfindingProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
workIterations++;
|
workIterations++;
|
||||||
if (workIterations >= 15000) {
|
this.totalIterations++;
|
||||||
|
if (workIterations >= 7500) {
|
||||||
// breaking jobs loop will implicitly exit without calling pathFound() below
|
// breaking jobs loop will implicitly exit without calling pathFound() below
|
||||||
break JobsLoop;
|
break JobsLoop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
job.queueItem.pathFound(Collections.emptyList(), simulation);
|
job.queueItem.pathFound(Collections.emptyList(), simulation);
|
||||||
this.moveQueue.poll();
|
this.moveQueue.poll();
|
||||||
|
System.out.println("Task " + this.pathfindJobId + " took " + this.totalIterations + " iterations and "
|
||||||
|
+ this.totalJobLoops + " job loops!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user