Allocate path with object pool for pathfinding
This commit is contained in:
@@ -17,6 +17,8 @@ static i32 dst(TilePosition a, TilePosition b) {
|
||||
bool findPath(const PathfindingDesc *desc) {
|
||||
BZ_ASSERT(desc->map);
|
||||
BzTileMap *map = desc->map;
|
||||
BZ_ASSERT(desc->start.x >= 0 && desc->start.x < map->width);
|
||||
BZ_ASSERT(desc->start.y >= 0 && desc->start.y < map->height);
|
||||
typedef struct Visited {
|
||||
bool visited : 1;
|
||||
i8 x : 3;
|
||||
@@ -81,37 +83,50 @@ bool findPath(const PathfindingDesc *desc) {
|
||||
i32 pathLen = 0;
|
||||
if (foundPath && desc->outPath) {
|
||||
TilePosition pos = desc->target;
|
||||
while (pos.x != desc->start.x || pos.y != desc->start.y) {
|
||||
Visited *visit = &visited[pos.y * map->width + pos.x];
|
||||
BZ_ASSERT(visit->x != 0 && visit->y != 0);
|
||||
pos.x -= visit->x;
|
||||
pos.y -= visit->y;
|
||||
pathLen++;
|
||||
}
|
||||
Path *out = desc->outPath;
|
||||
out->curWaypoint = 0;
|
||||
pos = desc->target;
|
||||
i32 len = pathLen;
|
||||
// Skip positions
|
||||
while (len >= out->maxWaypoints) {
|
||||
Visited visit = visited[pos.y * map->width + pos.x];
|
||||
pos.x -= visit.x;
|
||||
pos.y -= visit.y;
|
||||
len--;
|
||||
}
|
||||
BZ_ASSERT(desc->pool);
|
||||
PathData *pathData = bzObjectPool(desc->pool);
|
||||
pathData->numWaypoints = 0;
|
||||
pathData->next = NULL;
|
||||
i32 numWaypoints = 0;
|
||||
// Write path
|
||||
for (i32 i = 0; i < len; i++) {
|
||||
out->waypoints[len - i - 1] = (Position){
|
||||
pos.x * map->tileWidth + map->tileWidth * 0.5f,
|
||||
pos.y * map->tileHeight + map->tileHeight * 0.5f
|
||||
while (pos.x != desc->start.x || pos.y != desc->start.y) {
|
||||
Position waypoint = {
|
||||
pos.x * map->tileWidth + map->tileWidth * 0.5f,
|
||||
pos.y * map->tileHeight + map->tileHeight * 0.5f
|
||||
};
|
||||
out->numWaypoints++;
|
||||
|
||||
if (pathData->numWaypoints + 1 > PATH_DATA_SIZE) {
|
||||
PathData *newPathData = bzObjectPool(desc->pool);
|
||||
newPathData->numWaypoints = 0;
|
||||
newPathData->next = pathData;
|
||||
pathData = newPathData;
|
||||
numWaypoints = 0;
|
||||
}
|
||||
pathData->waypoints[numWaypoints++] = waypoint;
|
||||
pathData->numWaypoints = numWaypoints;
|
||||
|
||||
Visited visit = visited[pos.y * map->width + pos.x];
|
||||
BZ_ASSERT(visit.x != 0 || visit.y != 0);
|
||||
pos.x -= visit.x;
|
||||
pos.y -= visit.y;
|
||||
pathLen++;
|
||||
}
|
||||
out->paths = pathData;
|
||||
|
||||
// Reverse paths
|
||||
while (pathData) {
|
||||
for (i32 i = 0; i < pathData->numWaypoints / 2; i++) {
|
||||
i32 left = i;
|
||||
i32 right = (i32) (pathData->numWaypoints - 1 - i);
|
||||
|
||||
Position tmp = pathData->waypoints[left];
|
||||
pathData->waypoints[left] = pathData->waypoints[right];
|
||||
pathData->waypoints[right] = tmp;
|
||||
}
|
||||
pathData = pathData->next;
|
||||
}
|
||||
BZ_ASSERT(len == out->maxWaypoints);
|
||||
out->numWaypoints = len;
|
||||
}
|
||||
|
||||
if (!desc->heap) {
|
||||
|
||||
Reference in New Issue
Block a user