Remove dynamic neighbor caching (more work is needed to adjust walls generated for keeping distance to the walls when opening and closing doors)
This partially reverts commit db7dd1c1c9.
This commit is contained in:
+1
-8
@@ -24,9 +24,6 @@ extern "C" {
|
|||||||
pub type JsWall;
|
pub type JsWall;
|
||||||
pub type JsWallData;
|
pub type JsWallData;
|
||||||
|
|
||||||
#[wasm_bindgen(method, getter)]
|
|
||||||
fn id(this: &JsWall) -> String;
|
|
||||||
|
|
||||||
#[wasm_bindgen(method, getter)]
|
#[wasm_bindgen(method, getter)]
|
||||||
fn data(this: &JsWall) -> JsWallData;
|
fn data(this: &JsWall) -> JsWallData;
|
||||||
|
|
||||||
@@ -100,9 +97,8 @@ impl TryFrom<usize> for DoorType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Wall {
|
pub struct Wall {
|
||||||
pub id: String,
|
|
||||||
pub p1: Point,
|
pub p1: Point,
|
||||||
pub p2: Point,
|
pub p2: Point,
|
||||||
pub door_type: DoorType,
|
pub door_type: DoorType,
|
||||||
@@ -111,14 +107,12 @@ pub struct Wall {
|
|||||||
|
|
||||||
impl Wall {
|
impl Wall {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id: String,
|
|
||||||
p1: Point,
|
p1: Point,
|
||||||
p2: Point,
|
p2: Point,
|
||||||
door_type: DoorType,
|
door_type: DoorType,
|
||||||
door_state: DoorState,
|
door_state: DoorState,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id,
|
|
||||||
p1,
|
p1,
|
||||||
p2,
|
p2,
|
||||||
door_type,
|
door_type,
|
||||||
@@ -141,7 +135,6 @@ impl Wall {
|
|||||||
let mut c = data.c();
|
let mut c = data.c();
|
||||||
c.iter_mut().for_each(|val| *val = val.round());
|
c.iter_mut().for_each(|val| *val = val.round());
|
||||||
Self::new(
|
Self::new(
|
||||||
wall.id(),
|
|
||||||
Point::new(c[0], c[1]),
|
Point::new(c[0], c[1]),
|
||||||
Point::new(c[2], c[3]),
|
Point::new(c[2], c[3]),
|
||||||
data.door_type(),
|
data.door_type(),
|
||||||
|
|||||||
+35
-116
@@ -18,8 +18,6 @@ pub struct Edge {
|
|||||||
pub struct Node {
|
pub struct Node {
|
||||||
pub point: Point,
|
pub point: Point,
|
||||||
edges: Option<Vec<Edge>>,
|
edges: Option<Vec<Edge>>,
|
||||||
dynamic_neighbors: Option<Vec<NodePtr>>,
|
|
||||||
dynamic_edges: Option<Vec<Edge>>,
|
|
||||||
final_edge: Option<Option<Edge>>,
|
final_edge: Option<Option<Edge>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,17 +26,18 @@ impl Node {
|
|||||||
Self {
|
Self {
|
||||||
point,
|
point,
|
||||||
edges: None,
|
edges: None,
|
||||||
dynamic_neighbors: None,
|
|
||||||
dynamic_edges: None,
|
|
||||||
final_edge: None,
|
final_edge: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_edges(&self) -> impl Iterator<Item = &Edge> {
|
fn iter_edges(
|
||||||
let edge_iter = self.edges.as_ref().unwrap().iter();
|
&self,
|
||||||
let dynamic_edges_iter = self.dynamic_edges.as_ref().unwrap().iter();
|
) -> std::iter::Chain<std::slice::Iter<'_, Edge>, std::option::Iter<'_, Edge>> {
|
||||||
let final_edge_iter = self.final_edge.as_ref().unwrap().iter();
|
self.edges
|
||||||
edge_iter.chain(dynamic_edges_iter).chain(final_edge_iter)
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.chain(self.final_edge.as_ref().unwrap().iter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ impl NodeStorage {
|
|||||||
self.regular_nodes.push(node);
|
self.regular_nodes.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_edges(&mut self, node: &NodePtr, walls: &WallStorage) {
|
fn initialize_edges(&mut self, node: &NodePtr, walls: &[LineSegment]) {
|
||||||
if node.borrow().final_edge.is_none() {
|
if node.borrow().final_edge.is_none() {
|
||||||
let final_edge = self
|
let final_edge = self
|
||||||
.final_node
|
.final_node
|
||||||
@@ -93,7 +92,7 @@ impl NodeStorage {
|
|||||||
.filter(|neighbor| {
|
.filter(|neighbor| {
|
||||||
!self.collides_with_wall(
|
!self.collides_with_wall(
|
||||||
&LineSegment::new(node.borrow().point, neighbor.borrow().point),
|
&LineSegment::new(node.borrow().point, neighbor.borrow().point),
|
||||||
walls.iter_all(),
|
walls,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|neighbor| Edge {
|
.map(|neighbor| Edge {
|
||||||
@@ -103,63 +102,30 @@ impl NodeStorage {
|
|||||||
node.borrow_mut().final_edge = Some(final_edge);
|
node.borrow_mut().final_edge = Some(final_edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
let persistent_initialized = node.borrow().edges.is_some();
|
if node.borrow().edges.is_some() {
|
||||||
if persistent_initialized && node.borrow().dynamic_edges.is_some() {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let point = node.borrow().point;
|
let point = node.borrow().point;
|
||||||
let mut dynamic_edges = Vec::new();
|
let mut edges = Vec::new();
|
||||||
if persistent_initialized {
|
for neighbor in &self.regular_nodes {
|
||||||
for neighbor in node.borrow().dynamic_neighbors.as_ref().unwrap() {
|
if Rc::ptr_eq(neighbor, node) {
|
||||||
let neighbor_point = neighbor.borrow().point;
|
continue;
|
||||||
let line = LineSegment::new(point, neighbor_point);
|
|
||||||
if !self.collides_with_wall(&line, walls.iter_dynamic_active()) {
|
|
||||||
let cost = point.distance_to(neighbor_point);
|
|
||||||
let edge = Edge {
|
|
||||||
target: neighbor.clone(),
|
|
||||||
cost,
|
|
||||||
};
|
|
||||||
dynamic_edges.push(edge);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
let neighbor_point = neighbor.borrow().point;
|
||||||
let mut edges = Vec::new();
|
if !self.collides_with_wall(&LineSegment::new(point, neighbor_point), walls) {
|
||||||
let mut dynamic_neighbors = Vec::new();
|
let cost = point.distance_to(neighbor_point);
|
||||||
for neighbor in &self.regular_nodes {
|
edges.push(Edge {
|
||||||
if Rc::ptr_eq(neighbor, node) {
|
target: neighbor.clone(),
|
||||||
continue;
|
cost,
|
||||||
}
|
});
|
||||||
let neighbor_point = neighbor.borrow().point;
|
|
||||||
let line = LineSegment::new(point, neighbor_point);
|
|
||||||
if !self.collides_with_wall(&line, &walls.persistent) {
|
|
||||||
let cost = point.distance_to(neighbor_point);
|
|
||||||
let edge = Edge {
|
|
||||||
target: neighbor.clone(),
|
|
||||||
cost,
|
|
||||||
};
|
|
||||||
if self.collides_with_wall(&line, walls.iter_dynamic_active()) {
|
|
||||||
dynamic_neighbors.push(neighbor.clone());
|
|
||||||
} else if self.collides_with_wall(&line, walls.iter_dynamic_inactive()) {
|
|
||||||
dynamic_neighbors.push(neighbor.clone());
|
|
||||||
dynamic_edges.push(edge);
|
|
||||||
} else {
|
|
||||||
edges.push(edge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
node.borrow_mut().edges = Some(edges);
|
|
||||||
}
|
}
|
||||||
node.borrow_mut().dynamic_edges = Some(dynamic_edges);
|
node.borrow_mut().edges = Some(edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collides_with_wall<'a, I>(&self, line: &LineSegment, walls: I) -> bool
|
fn collides_with_wall(&self, line: &LineSegment, walls: &[LineSegment]) -> bool {
|
||||||
where
|
walls.iter().any(|wall| line.intersection(wall).is_some())
|
||||||
I: IntoIterator<Item = &'a LineSegment>,
|
|
||||||
{
|
|
||||||
walls
|
|
||||||
.into_iter()
|
|
||||||
.any(|wall| line.intersection(wall).is_some())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cleanup_final_edges(&mut self) {
|
pub fn cleanup_final_edges(&mut self) {
|
||||||
@@ -173,50 +139,12 @@ impl NodeStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct DynamicWall {
|
|
||||||
pub line: LineSegment,
|
|
||||||
pub active: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DynamicWall {
|
|
||||||
fn new(line: LineSegment, active: bool) -> Self {
|
|
||||||
Self { line, active }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct WallStorage {
|
|
||||||
pub persistent: Vec<LineSegment>,
|
|
||||||
pub dynamic: FxHashMap<String, DynamicWall>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WallStorage {
|
|
||||||
pub fn iter_dynamic_inactive(&self) -> impl Iterator<Item = &LineSegment> {
|
|
||||||
self.dynamic
|
|
||||||
.values()
|
|
||||||
.filter(|wall| !wall.active)
|
|
||||||
.map(|wall| &wall.line)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter_dynamic_active(&self) -> impl Iterator<Item = &LineSegment> {
|
|
||||||
self.dynamic
|
|
||||||
.values()
|
|
||||||
.filter(|wall| wall.active)
|
|
||||||
.map(|wall| &wall.line)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter_all(&self) -> impl Iterator<Item = &LineSegment> {
|
|
||||||
self.persistent.iter().chain(self.iter_dynamic_active())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct Pathfinder {
|
pub struct Pathfinder {
|
||||||
#[wasm_bindgen(skip)]
|
#[wasm_bindgen(skip)]
|
||||||
pub nodes: NodeStorage,
|
pub nodes: NodeStorage,
|
||||||
#[wasm_bindgen(skip)]
|
#[wasm_bindgen(skip)]
|
||||||
pub walls: WallStorage,
|
pub walls: Vec<LineSegment>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pathfinder {
|
impl Pathfinder {
|
||||||
@@ -226,8 +154,7 @@ impl Pathfinder {
|
|||||||
{
|
{
|
||||||
let distance_from_walls = token_size / 2.0;
|
let distance_from_walls = token_size / 2.0;
|
||||||
let mut endpoints = FxHashMap::<Point, Vec<f64>>::default();
|
let mut endpoints = FxHashMap::<Point, Vec<f64>>::default();
|
||||||
let mut wall_storage = WallStorage::default();
|
let mut line_segments = Vec::new();
|
||||||
|
|
||||||
for wall in walls {
|
for wall in walls {
|
||||||
let x_diff = wall.p2.x - wall.p1.x;
|
let x_diff = wall.p2.x - wall.p1.x;
|
||||||
let y_diff = wall.p2.y - wall.p1.y;
|
let y_diff = wall.p2.y - wall.p1.y;
|
||||||
@@ -237,15 +164,7 @@ impl Pathfinder {
|
|||||||
let angles = endpoints.entry(point).or_insert_with(Vec::new);
|
let angles = endpoints.entry(point).or_insert_with(Vec::new);
|
||||||
angles.push(angle);
|
angles.push(angle);
|
||||||
}
|
}
|
||||||
let line = LineSegment::new(wall.p1, wall.p2);
|
line_segments.push(LineSegment::new(wall.p1, wall.p2));
|
||||||
if !wall.is_door() {
|
|
||||||
wall_storage.persistent.push(line);
|
|
||||||
} else {
|
|
||||||
let is_open = wall.is_open();
|
|
||||||
wall_storage
|
|
||||||
.dynamic
|
|
||||||
.insert(wall.id, DynamicWall::new(line, !is_open));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
endpoints
|
endpoints
|
||||||
.values_mut()
|
.values_mut()
|
||||||
@@ -269,20 +188,20 @@ impl Pathfinder {
|
|||||||
point,
|
point,
|
||||||
angle_between,
|
angle_between,
|
||||||
distance_from_walls,
|
distance_from_walls,
|
||||||
&mut wall_storage.persistent,
|
&mut line_segments,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
nodes.push(calc_pathfinding_node(
|
nodes.push(calc_pathfinding_node(
|
||||||
point,
|
point,
|
||||||
angle1 + 0.5 * PI,
|
angle1 + 0.5 * PI,
|
||||||
distance_from_walls,
|
distance_from_walls,
|
||||||
&mut wall_storage.persistent,
|
&mut line_segments,
|
||||||
));
|
));
|
||||||
nodes.push(calc_pathfinding_node(
|
nodes.push(calc_pathfinding_node(
|
||||||
point,
|
point,
|
||||||
angle2 - 0.5 * PI,
|
angle2 - 0.5 * PI,
|
||||||
distance_from_walls,
|
distance_from_walls,
|
||||||
&mut wall_storage.persistent,
|
&mut line_segments,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let angle1 = angles.last().unwrap();
|
let angle1 = angles.last().unwrap();
|
||||||
@@ -297,26 +216,26 @@ impl Pathfinder {
|
|||||||
point,
|
point,
|
||||||
angle_between,
|
angle_between,
|
||||||
distance_from_walls,
|
distance_from_walls,
|
||||||
&mut wall_storage.persistent,
|
&mut line_segments,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
nodes.push(calc_pathfinding_node(
|
nodes.push(calc_pathfinding_node(
|
||||||
point,
|
point,
|
||||||
angle1 + 0.5 * PI,
|
angle1 + 0.5 * PI,
|
||||||
distance_from_walls,
|
distance_from_walls,
|
||||||
&mut wall_storage.persistent,
|
&mut line_segments,
|
||||||
));
|
));
|
||||||
nodes.push(calc_pathfinding_node(
|
nodes.push(calc_pathfinding_node(
|
||||||
point,
|
point,
|
||||||
angle2 - 0.5 * PI,
|
angle2 - 0.5 * PI,
|
||||||
distance_from_walls,
|
distance_from_walls,
|
||||||
&mut wall_storage.persistent,
|
&mut line_segments,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
// TODO Eliminating nodes close to each other may improve performance
|
// TODO Eliminating nodes close to each other may improve performance
|
||||||
Self {
|
Self {
|
||||||
nodes,
|
nodes,
|
||||||
walls: wall_storage,
|
walls: line_segments,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user