mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-01-28 08:30:08 +07:00
Reduced static memory usage of MapGraph
Changed rounding method of Map#flags(float,float) to use Map#round(float) instead of casting down to int Removed indexing and connection links from Point2 Point2 are now indexed using MapGraph#getOrCreate and mapped using an ObjectSet -- using int hash did not seem sufficient Connections to a given Point2 are lazily generated using a static Array -- it did not make sense to cache this for every node Cleaned up API and method references (all pathing methods now use MapGraph#searchNodePath as their base method) Most of these changed are geared to hopefully use the underlying map collision flags array as the graph instead of building a new one
This commit is contained in:
parent
222fe7077a
commit
2298d80cab
@ -619,8 +619,12 @@ public class Map implements Disposable {
|
||||
return zone;
|
||||
}
|
||||
|
||||
public int flags(Vector2 pos) {
|
||||
return flags(pos.x, pos.y);
|
||||
}
|
||||
|
||||
public int flags(float x, float y) {
|
||||
return flags((int) x, (int) y);
|
||||
return flags(round(x), round(y));
|
||||
}
|
||||
|
||||
public int flags(int x, int y) {
|
||||
|
@ -16,7 +16,8 @@ import com.badlogic.gdx.ai.utils.Ray;
|
||||
import com.badlogic.gdx.ai.utils.RaycastCollisionDetector;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.ObjectIntMap;
|
||||
import com.badlogic.gdx.utils.ObjectSet;
|
||||
import com.badlogic.gdx.utils.Pool;
|
||||
|
||||
public class MapGraph implements IndexedGraph<MapGraph.Point2> {
|
||||
@ -27,67 +28,52 @@ public class MapGraph implements IndexedGraph<MapGraph.Point2> {
|
||||
Heuristic<Point2> heuristic = new EuclideanDistanceHeuristic();
|
||||
|
||||
Map map;
|
||||
IntMap<Point2> points = new IntMap<>();
|
||||
MapRaycastCollisionDetector rayCaster;
|
||||
PathSmoother<Point2, Vector2> pathSmoother;
|
||||
|
||||
|
||||
final Point2 tmpPoint = new Point2();
|
||||
final Vector2 tmpVec = new Vector2();
|
||||
|
||||
int index = 0;
|
||||
final ObjectIntMap<Point2> indexes = new ObjectIntMap<>();
|
||||
|
||||
final ObjectSet<Point2> identity = new ObjectSet<>();
|
||||
final Array<Connection<Point2>> connections = new Array<>(false, 8);
|
||||
|
||||
public MapGraph(Map map) {
|
||||
this.map = map;
|
||||
rayCaster = new MapRaycastCollisionDetector(this);
|
||||
pathSmoother = new PathSmoother<>(rayCaster);
|
||||
}
|
||||
|
||||
public GraphPath<Point2> path(Vector2 src, Vector2 dst, GraphPath<Point2> path) {
|
||||
Map.Zone zone = map.getZone((int) dst.x, (int) dst.y);
|
||||
if (zone != null && zone.flags((int) dst.x, (int) dst.y) != 0) {
|
||||
return path;
|
||||
private Point2 getOrCreate(Vector2 src) {
|
||||
Point2 existing = identity.get(tmpPoint.set(src));
|
||||
if (existing == null) {
|
||||
existing = new Point2(src);
|
||||
identity.add(existing);
|
||||
indexes.put(existing, index++);
|
||||
}
|
||||
|
||||
int hash = Point2.hash(src);
|
||||
Point2 srcP = points.get(hash);
|
||||
if (srcP == null) {
|
||||
srcP = new Point2(src);
|
||||
points.put(hash, srcP);
|
||||
}
|
||||
hash = Point2.hash(dst);
|
||||
Point2 dstP = points.get(hash);
|
||||
if (dstP == null) {
|
||||
dstP = new Point2(dst);
|
||||
points.put(hash, dstP);
|
||||
}
|
||||
return path(srcP, dstP, path);
|
||||
return existing;
|
||||
}
|
||||
|
||||
public GraphPath<Point2> path(Vector2 src, Vector2 dst, GraphPath<Point2> path) {
|
||||
searchNodePath(new IndexedAStarPathFinder<>(this), src, dst, path);
|
||||
return path;
|
||||
}
|
||||
|
||||
public GraphPath<Point2> path(Point2 src, Point2 dst, GraphPath<Point2> path) {
|
||||
path.clear();
|
||||
new IndexedAStarPathFinder<>(this).searchNodePath(src, dst, heuristic, path);
|
||||
searchNodePath(new IndexedAStarPathFinder<>(this), src, dst, path);
|
||||
return path;
|
||||
}
|
||||
|
||||
public boolean searchNodePath(PathFinder<Point2> pathFinder, Vector2 src, Vector2 dst, GraphPath<Point2> path) {
|
||||
path.clear();
|
||||
if (dst == null) return false;
|
||||
//Map.Zone zone = map.getZone((int) dst.x, (int) dst.y);
|
||||
//if (zone != null && zone.flags((int) dst.x, (int) dst.y) != 0) {
|
||||
int x = Map.round(dst.x);
|
||||
int y = Map.round(dst.y);
|
||||
Map.Zone zone = map.getZone(x, y);
|
||||
if (zone != null && zone.flags(x, y) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int hash = Point2.hash(src);
|
||||
Point2 srcP = points.get(hash);
|
||||
if (srcP == null) {
|
||||
srcP = new Point2(src);
|
||||
points.put(hash, srcP);
|
||||
}
|
||||
hash = Point2.hash(dst);
|
||||
Point2 dstP = points.get(hash);
|
||||
if (dstP == null) {
|
||||
dstP = new Point2(dst);
|
||||
points.put(hash, dstP);
|
||||
}
|
||||
if (map.flags(dst) != 0) return false;
|
||||
Point2 srcP = getOrCreate(src);
|
||||
Point2 dstP = getOrCreate(dst);
|
||||
return searchNodePath(pathFinder, srcP, dstP, path);
|
||||
}
|
||||
|
||||
@ -108,7 +94,7 @@ public class MapGraph implements IndexedGraph<MapGraph.Point2> {
|
||||
|
||||
@Override
|
||||
public int getIndex(Point2 node) {
|
||||
return node.index;
|
||||
return indexes.get(node, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -118,68 +104,54 @@ public class MapGraph implements IndexedGraph<MapGraph.Point2> {
|
||||
|
||||
@Override
|
||||
public Array<Connection<Point2>> getConnections(Point2 src) {
|
||||
Array<Connection<Point2>> connections = src.connections;
|
||||
if (connections == null) {
|
||||
connections = src.connections = new Array<>(8);
|
||||
tryConnect(src, src.x - 1, src.y - 1);
|
||||
tryConnect(src, src.x - 1, src.y );
|
||||
tryConnect(src, src.x - 1, src.y + 1);
|
||||
tryConnect(src, src.x , src.y - 1);
|
||||
tryConnect(src, src.x , src.y + 1);
|
||||
tryConnect(src, src.x + 1, src.y - 1);
|
||||
tryConnect(src, src.x + 1, src.y );
|
||||
tryConnect(src, src.x + 1, src.y + 1);
|
||||
}
|
||||
|
||||
connections.clear();
|
||||
tryConnect(connections, src, src.x - 1, src.y - 1);
|
||||
tryConnect(connections, src, src.x - 1, src.y );
|
||||
tryConnect(connections, src, src.x - 1, src.y + 1);
|
||||
tryConnect(connections, src, src.x , src.y - 1);
|
||||
tryConnect(connections, src, src.x , src.y + 1);
|
||||
tryConnect(connections, src, src.x + 1, src.y - 1);
|
||||
tryConnect(connections, src, src.x + 1, src.y );
|
||||
tryConnect(connections, src, src.x + 1, src.y + 1);
|
||||
return connections;
|
||||
}
|
||||
|
||||
private void tryConnect(Point2 src, int x, int y) {
|
||||
Map.Zone zone = map.getZone(x, y);
|
||||
if (zone != null && zone.flags(x, y) == 0) {
|
||||
final int hash = Point2.hash(x, y);
|
||||
Point2 dst = points.get(hash);
|
||||
if (dst == null) {
|
||||
dst = new Point2(x, y);
|
||||
points.put(hash, dst);
|
||||
}
|
||||
src.connections.add(new Path(src, dst));
|
||||
}
|
||||
private void tryConnect(Array<Connection<Point2>> connections, Point2 src, int x, int y) {
|
||||
if (map.flags(tmpVec.set(x, y)) != 0) return;
|
||||
Point2 dst = getOrCreate(tmpVec);
|
||||
connections.add(new Path(src, dst));
|
||||
}
|
||||
|
||||
public static class Point2 {
|
||||
public int x;
|
||||
public int y;
|
||||
int index;
|
||||
Array<Connection<Point2>> connections;
|
||||
|
||||
static int indexes = 0;
|
||||
|
||||
Point2(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
index = indexes++;
|
||||
}
|
||||
Point2() {}
|
||||
|
||||
Point2(Vector2 src) {
|
||||
//this((int) src.x, (int) src.y);
|
||||
this(Map.round(src.x), Map.round(src.y));
|
||||
set(src);
|
||||
}
|
||||
|
||||
Point2 set(Vector2 src) {
|
||||
x = Map.round(src.x);
|
||||
y = Map.round(src.y);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hash(x, y);
|
||||
}
|
||||
|
||||
static int hash(Vector2 src) {
|
||||
//return hash((int) src.x, (int) src.y);
|
||||
return hash(Map.round(src.x), Map.round(src.y));
|
||||
}
|
||||
|
||||
static int hash(int x, int y) {
|
||||
return (x * 73856093) ^ (y * 83492791);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof Point2)) return false;
|
||||
Point2 other = (Point2) obj;
|
||||
return x == other.x && y == other.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + x + "," + y + ")";
|
||||
|
Loading…
Reference in New Issue
Block a user