Call gridless pathfinder from rust code

This commit is contained in:
Manuel Vögele
2022-01-31 22:33:02 +01:00
parent 1ee406a047
commit 673fa42a20
3 changed files with 81 additions and 22 deletions
+28 -4
View File
@@ -4,22 +4,32 @@ import {debugGraphics} from "./main.js";
import {settingsKey} from "./settings.js"; import {settingsKey} from "./settings.js";
import {getSnapPointForTokenObj, iterPairs} from "./util.js"; import {getSnapPointForTokenObj, iterPairs} from "./util.js";
import * as GridlessPathfinding from "../wasm/gridless_pathfinding.js"
let cachedNodes = undefined; let cachedNodes = undefined;
let use5105 = false; let use5105 = false;
let gridlessPathfinder = undefined;
export function isPathfindingEnabled() { export function isPathfindingEnabled() {
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS)
return false;
if (!game.settings.get(settingsKey, "allowPathfinding")) if (!game.settings.get(settingsKey, "allowPathfinding"))
return false; return false;
return game.settings.get(settingsKey, "autoPathfinding") != togglePathfinding; return game.settings.get(settingsKey, "autoPathfinding") != togglePathfinding;
} }
export function findPath(from, to, token, previousWaypoints) { export function findPath(from, to, token, previousWaypoints) {
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) {
if (!gridlessPathfinder)
gridlessPathfinder = GridlessPathfinding.initialize(canvas.walls.placeables);
paintGridlessPathfindingDebug(gridlessPathfinder);
const path = GridlessPathfinding.findPath(gridlessPathfinder, from, to);
console.warn(path);
return path;
}
else {
const lastNode = calculatePath(from, to, token, previousWaypoints); const lastNode = calculatePath(from, to, token, previousWaypoints);
if (!lastNode) if (!lastNode)
return null; return null;
paintPathfindingDebug(lastNode, token); paintGriddedPathfindingDebug(lastNode, token);
const path = []; const path = [];
let currentNode = lastNode; let currentNode = lastNode;
while (currentNode) { while (currentNode) {
@@ -32,6 +42,7 @@ export function findPath(from, to, token, previousWaypoints) {
currentNode = currentNode.previous; currentNode = currentNode.previous;
} }
return path; return path;
}
} }
export function wipePathfindingCache() { export function wipePathfindingCache() {
@@ -135,7 +146,7 @@ function stepCollidesWithWall(from, to, token) {
return canvas.walls.checkCollision(new Ray(stepStart, stepEnd)); return canvas.walls.checkCollision(new Ray(stepStart, stepEnd));
} }
function paintPathfindingDebug(lastNode, token) { function paintGriddedPathfindingDebug(lastNode, token) {
if (!CONFIG.debug.dragRuler) if (!CONFIG.debug.dragRuler)
return; return;
@@ -151,3 +162,16 @@ function paintPathfindingDebug(lastNode, token) {
currentNode = currentNode.previous; currentNode = currentNode.previous;
} }
} }
function paintGridlessPathfindingDebug(pathfinder) {
if (!CONFIG.debug.dragRuler)
return;
debugGraphics.removeChildren();
let graphic = new PIXI.Graphics();
graphic.lineStyle(2, 0x440000);
for (const point of GridlessPathfinding.debugGetPathfindingPoints(pathfinder)) {
graphic.drawCircle(point.x, point.y, 5);
}
debugGraphics.addChild(graphic);
}
+35 -4
View File
@@ -20,7 +20,7 @@ extern "C" {
} }
#[wasm_bindgen( #[wasm_bindgen(
inline_js = "export function collidesWithWall(p1, p2) { return canvas.walls.checkCollision(new Ray(p1, p2)); }" inline_js = "export function collidesWithWall(p1, p2) { return canvas.walls.checkCollision(new Ray(p1, p2));}"
)] )]
extern "C" { extern "C" {
#[wasm_bindgen(js_name=collidesWithWall)] #[wasm_bindgen(js_name=collidesWithWall)]
@@ -39,6 +39,26 @@ extern "C" {
fn c(this: &JsWallData) -> Vec<f64>; fn c(this: &JsWallData) -> Vec<f64>;
} }
#[wasm_bindgen]
extern "C" {
pub type JsPoint;
#[wasm_bindgen(method, getter)]
fn x(this: &JsPoint) -> f64;
#[wasm_bindgen(method, getter)]
fn y(this: &JsPoint) -> f64;
}
impl From<JsPoint> for Point {
fn from(point: JsPoint) -> Self {
Point {
x: point.x(),
y: point.y(),
}
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Wall { pub struct Wall {
pub p1: Point, pub p1: Point,
@@ -61,7 +81,7 @@ impl Wall {
} }
#[allow(dead_code)] #[allow(dead_code)]
#[wasm_bindgen(js_name=buildCache)] #[wasm_bindgen]
pub fn initialize(js_walls: Vec<JsValue>) -> Pathfinder { pub fn initialize(js_walls: Vec<JsValue>) -> Pathfinder {
let mut walls = Vec::with_capacity(js_walls.len()); let mut walls = Vec::with_capacity(js_walls.len());
for wall in js_walls { for wall in js_walls {
@@ -79,14 +99,25 @@ pub fn free(pathfinder: Pathfinder) {
#[allow(dead_code)] #[allow(dead_code)]
#[wasm_bindgen(js_name=findPath)] #[wasm_bindgen(js_name=findPath)]
pub fn find_path(pathfinder: &mut Pathfinder, from: Point, to: Point) -> Option<Array> { pub fn find_path(pathfinder: &mut Pathfinder, from: JsPoint, to: JsPoint) -> Option<Array> {
if let Some(first_node) = pathfinder.find_path(from, to) { if let Some(first_node) = pathfinder.find_path(from.into(), to.into()) {
Some(first_node.iter_path().map(JsValue::from).collect()) Some(first_node.iter_path().map(JsValue::from).collect())
} else { } else {
None None
} }
} }
#[allow(dead_code)]
#[wasm_bindgen(js_name=debugGetPathfindingPoints)]
pub fn debug_get_pathfinding_points(pathfinder: &Pathfinder) -> Array {
pathfinder
.nodes
.iter()
.map(|node| node.borrow().point)
.map(JsValue::from)
.collect()
}
trait IteratePath { trait IteratePath {
fn iter_path(&self) -> PathIterator; fn iter_path(&self) -> PathIterator;
} }
+4
View File
@@ -83,6 +83,10 @@ impl NodeStorage {
node.borrow_mut().edges = Some(edges); node.borrow_mut().edges = Some(edges);
} }
pub fn iter(&self) -> std::slice::Iter<'_, NodePtr> {
self.0.iter()
}
} }
#[wasm_bindgen] #[wasm_bindgen]