Always keep tokenSize/2 distance from walls
This commit is contained in:
+3
-1
@@ -18,8 +18,10 @@ export function isPathfindingEnabled() {
|
||||
|
||||
export function findPath(from, to, token, previousWaypoints) {
|
||||
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) {
|
||||
// TODO Store multiple pathfinders for different token sizes
|
||||
let tokenSize = Math.max(token.data.width, token.data.height) * canvas.dimensions.size;
|
||||
if (!gridlessPathfinder)
|
||||
gridlessPathfinder = GridlessPathfinding.initialize(canvas.walls.placeables);
|
||||
gridlessPathfinder = GridlessPathfinding.initialize(canvas.walls.placeables, tokenSize);
|
||||
paintGridlessPathfindingDebug(gridlessPathfinder);
|
||||
return GridlessPathfinding.findPath(gridlessPathfinder, from, to);
|
||||
}
|
||||
|
||||
+2
-2
@@ -74,13 +74,13 @@ impl Wall {
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[wasm_bindgen]
|
||||
pub fn initialize(js_walls: Vec<JsValue>) -> Pathfinder {
|
||||
pub fn initialize(js_walls: Vec<JsValue>, token_size: f64) -> Pathfinder {
|
||||
let mut walls = Vec::with_capacity(js_walls.len());
|
||||
for wall in js_walls {
|
||||
let wall = JsWall::from(wall);
|
||||
walls.push(Wall::from_js(&wall));
|
||||
}
|
||||
Pathfinder::initialize(walls)
|
||||
Pathfinder::initialize(walls, token_size)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
||||
+63
-11
@@ -147,10 +147,11 @@ pub struct Pathfinder {
|
||||
}
|
||||
|
||||
impl Pathfinder {
|
||||
pub fn initialize<I>(walls: I) -> Self
|
||||
pub fn initialize<I>(walls: I, token_size: f64) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = Wall>,
|
||||
{
|
||||
let distance_from_walls = token_size / 2.0;
|
||||
let mut endpoints = FxHashMap::<Point, Vec<f64>>::default();
|
||||
let mut line_segments = Vec::new();
|
||||
for wall in walls {
|
||||
@@ -180,8 +181,27 @@ impl Pathfinder {
|
||||
if angle_diff <= PI {
|
||||
continue;
|
||||
}
|
||||
let angle_between = angle_diff / 2.0 + angle1;
|
||||
nodes.push(calc_pathfinding_node(point, angle_between));
|
||||
if angle_diff > 1.5 * PI {
|
||||
let angle_between = angle_diff / 2.0 + angle1;
|
||||
nodes.push(calc_pathfinding_node(
|
||||
point,
|
||||
angle_between,
|
||||
distance_from_walls,
|
||||
&mut line_segments,
|
||||
));
|
||||
}
|
||||
nodes.push(calc_pathfinding_node(
|
||||
point,
|
||||
angle1 + 0.5 * PI,
|
||||
distance_from_walls,
|
||||
&mut line_segments,
|
||||
));
|
||||
nodes.push(calc_pathfinding_node(
|
||||
point,
|
||||
angle2 - 0.5 * PI,
|
||||
distance_from_walls,
|
||||
&mut line_segments,
|
||||
));
|
||||
}
|
||||
let angle1 = angles.last().unwrap();
|
||||
let angle2 = angles.first().unwrap() + 2.0 * PI;
|
||||
@@ -189,9 +209,27 @@ impl Pathfinder {
|
||||
if angle_diff <= PI {
|
||||
continue;
|
||||
}
|
||||
let angle_between = angle_diff / 2.0 + angle1;
|
||||
let angle_between = angle_between.rem_euclid(2.0 * PI);
|
||||
nodes.push(calc_pathfinding_node(point, angle_between));
|
||||
if angle_diff > 1.5 * PI {
|
||||
let angle_between = angle_diff / 2.0 + angle1;
|
||||
nodes.push(calc_pathfinding_node(
|
||||
point,
|
||||
angle_between,
|
||||
distance_from_walls,
|
||||
&mut line_segments,
|
||||
));
|
||||
}
|
||||
nodes.push(calc_pathfinding_node(
|
||||
point,
|
||||
angle1 + 0.5 * PI,
|
||||
distance_from_walls,
|
||||
&mut line_segments,
|
||||
));
|
||||
nodes.push(calc_pathfinding_node(
|
||||
point,
|
||||
angle2 - 0.5 * PI,
|
||||
distance_from_walls,
|
||||
&mut line_segments,
|
||||
));
|
||||
}
|
||||
// TODO Eliminating nodes close to each other may improve performance
|
||||
Self {
|
||||
@@ -263,9 +301,23 @@ impl Pathfinder {
|
||||
}
|
||||
}
|
||||
|
||||
fn calc_pathfinding_node(p: Point, angle: f64) -> NodePtr {
|
||||
let diatance_from_walls = 10.0;
|
||||
let x = p.x + angle.cos() * diatance_from_walls;
|
||||
let y = p.y + angle.sin() * diatance_from_walls;
|
||||
NodePtr::from(Node::new(Point { x, y }))
|
||||
fn calc_pathfinding_node(
|
||||
p: Point,
|
||||
angle: f64,
|
||||
distance_from_walls: f64,
|
||||
line_segments: &mut Vec<LineSegment>,
|
||||
) -> NodePtr {
|
||||
let offset_x = angle.cos() * distance_from_walls;
|
||||
let offset_y = angle.sin() * distance_from_walls;
|
||||
line_segments.push(LineSegment::new(
|
||||
p,
|
||||
Point {
|
||||
x: p.x + offset_x * 0.99,
|
||||
y: p.y + offset_y * 0.99,
|
||||
},
|
||||
));
|
||||
NodePtr::from(Node::new(Point {
|
||||
x: p.x + offset_x,
|
||||
y: p.y + offset_y,
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user