From 576db2dc5a5e1eaa5b87ad9db341b7f5bc37220b Mon Sep 17 00:00:00 2001 From: Jonathan Calvert <38069151+JDCalvert@users.noreply.github.com> Date: Mon, 28 Feb 2022 08:52:12 +0000 Subject: [PATCH] Pathfinding Improvements: Bound Algorithm to Canvas (#168) --- .gitignore | 1 + js/main.js | 7 +++++-- js/pathfinding.js | 30 +++++++++++++++++++----------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 9255806..a87f000 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /foundry*.js artifact/ wasm/ +*.lock diff --git a/js/main.js b/js/main.js index bd963de..0cf1f4e 100644 --- a/js/main.js +++ b/js/main.js @@ -7,7 +7,7 @@ import {disableSnap, registerKeybindings} from "./keybindings.js"; import {libWrapper} from "./libwrapper_shim.js"; import {performMigrations} from "./migration.js" import {removeLastHistoryEntryIfAt, resetMovementHistory} from "./movement_tracking.js"; -import {wipePathfindingCache} from "./pathfinding.js"; +import {wipePathfindingCache, initializePathfinding} from "./pathfinding.js"; import {extendRuler} from "./ruler.js"; import {registerSettings, RightClickAction, settingsKey} from "./settings.js" import {recalculate} from "./socket.js"; @@ -21,7 +21,10 @@ export let debugGraphics = undefined; initGridlessPathfinding().then(() => { Hooks.on("canvasInit", wipePathfindingCache); - Hooks.on("canvasReady", wipePathfindingCache); + Hooks.on("canvasReady", () => { + wipePathfindingCache(); + initializePathfinding(); + }); Hooks.on("createWall", wipePathfindingCache); Hooks.on("updateWall", wipePathfindingCache); Hooks.on("deleteWall", wipePathfindingCache); diff --git a/js/pathfinding.js b/js/pathfinding.js index ed899c1..e80a291 100644 --- a/js/pathfinding.js +++ b/js/pathfinding.js @@ -9,6 +9,7 @@ import * as GridlessPathfinding from "../wasm/gridless_pathfinding.js" let cachedNodes = undefined; let use5105 = false; let gridlessPathfinders = new Map(); +let gridWidth, gridHeight; export function isPathfindingEnabled() { if (this.user !== game.user) @@ -51,16 +52,6 @@ export function findPath(from, to, token, previousWaypoints) { } } -export function wipePathfindingCache() { - cachedNodes = undefined; - for (const pathfinder of gridlessPathfinders.values()) { - GridlessPathfinding.free(pathfinder); - } - gridlessPathfinders.clear(); - if (debugGraphics) - debugGraphics.removeChildren().forEach(c => c.destroy()); -} - function getNode(pos, token, initialize=true) { pos = {layer: 0, ...pos}; // Copy pos and set pos.layer to the default value if it's unset if (!cachedNodes) @@ -77,8 +68,10 @@ function getNode(pos, token, initialize=true) { if (initialize && !node.edges) { node.edges = []; for (const neighborPos of canvas.grid.grid.getNeighbors(pos.y, pos.x).map(([y, x]) => {return {x, y};})) { - if (neighborPos.x < 0 || neighborPos.y < 0) + if (neighborPos.x < 0 || neighborPos.y < 0 || neighborPos.x > gridWidth || neighborPos.y > gridHeight) { continue; + } + // TODO Work with pixels instead of grid locations if (!stepCollidesWithWall(pos, neighborPos, token)) { const isDiagonal = node.x !== neighborPos.x && node.y !== neighborPos.y && canvas.grid.type === CONST.GRID_TYPES.SQUARE; @@ -158,6 +151,21 @@ function stepCollidesWithWall(from, to, token) { return canvas.walls.checkCollision(new Ray(stepStart, stepEnd)); } +export function wipePathfindingCache() { + cachedNodes = undefined; + for (const pathfinder of gridlessPathfinders.values()) { + GridlessPathfinding.free(pathfinder); + } + gridlessPathfinders.clear(); + if (debugGraphics) + debugGraphics.removeChildren().forEach(c => c.destroy()); +} + +export function initializePathfinding() { + gridWidth = Math.ceil(canvas.dimensions.width / canvas.grid.w); + gridHeight = Math.ceil(canvas.dimensions.height / canvas.grid.h); +} + function paintGriddedPathfindingDebug(lastNode, token) { if (!CONFIG.debug.dragRuler) return;