mirror of https://codeberg.org/topola/topola.git
Exclude mesh neighbors from collision detection
This commit is contained in:
parent
1a599951cd
commit
4f473bacec
|
|
@ -63,7 +63,7 @@ impl<T> Index<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn retag(&self, weight: TaggedWeight) -> TaggedIndex {
|
||||
pub fn retag(&self, weight: &TaggedWeight) -> TaggedIndex {
|
||||
match weight {
|
||||
TaggedWeight::Dot(..) => TaggedIndex::Dot(DotIndex {
|
||||
index: self.index,
|
||||
|
|
|
|||
56
src/main.rs
56
src/main.rs
|
|
@ -177,11 +177,41 @@ fn main() {
|
|||
})
|
||||
.unwrap();
|
||||
|
||||
let dot5 = layout
|
||||
.add_dot(DotWeight {
|
||||
net: 0,
|
||||
circle: Circle {
|
||||
pos: (150.5, 100.5).into(),
|
||||
r: 8.0,
|
||||
},
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let dot6 = layout
|
||||
.add_dot(DotWeight {
|
||||
net: 0,
|
||||
circle: Circle {
|
||||
pos: (190.5, 100.5).into(),
|
||||
r: 8.0,
|
||||
},
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let dot7 = layout
|
||||
.add_dot(DotWeight {
|
||||
net: 0,
|
||||
circle: Circle {
|
||||
pos: (230.5, 70.5).into(),
|
||||
r: 8.0,
|
||||
},
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let barrier1_dot1 = layout
|
||||
.add_dot(DotWeight {
|
||||
net: 0,
|
||||
circle: Circle {
|
||||
pos: (250.5, 150.5).into(),
|
||||
pos: (250.5, 250.5).into(),
|
||||
r: 8.0,
|
||||
},
|
||||
})
|
||||
|
|
@ -217,16 +247,20 @@ fn main() {
|
|||
.unwrap();
|
||||
let _ = layout.add_seg(barrier2_dot1, barrier2_dot2, 16.0);
|
||||
|
||||
let head = layout.route_start(dot5);
|
||||
let head = layout.route_around_dot(head, dot6, true, 5.0).unwrap();
|
||||
let _ = layout.route_finish(head, dot7, 5.0);
|
||||
|
||||
/*render_times(&mut event_pump, &mut canvas, &mut layout, None, -1);
|
||||
|
||||
let head = layout.route_start(dot1_1);
|
||||
let head = layout
|
||||
.route_around_dot(head, barrier1_dot1, true, 5.)
|
||||
.route_around_dot(head, barrier1_dot1, true, 5.0)
|
||||
.unwrap();
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
let head = layout
|
||||
.route_around_dot(head, barrier2_dot1, true, 5.)
|
||||
.route_around_dot(head, barrier2_dot1, true, 5.0)
|
||||
.unwrap();
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
|
|
@ -236,12 +270,12 @@ fn main() {
|
|||
|
||||
let head = layout.route_start(dot2_1);
|
||||
let head = layout
|
||||
.shove_around_dot(head, barrier1_dot1, true, 5.)
|
||||
.shove_around_dot(head, barrier1_dot1, true, 5.0)
|
||||
.unwrap();
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
let head = layout
|
||||
.shove_around_dot(head, barrier2_dot1, true, 5.)
|
||||
.shove_around_dot(head, barrier2_dot1, true, 5.0)
|
||||
.unwrap();
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
|
|
@ -253,16 +287,16 @@ fn main() {
|
|||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
let head = layout
|
||||
.shove_around_dot(head, barrier1_dot1, true, 5.)
|
||||
.shove_around_dot(head, barrier1_dot1, true, 5.0)
|
||||
.unwrap();
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
let head = layout
|
||||
.shove_around_dot(head, barrier2_dot1, true, 5.)
|
||||
.shove_around_dot(head, barrier2_dot1, true, 5.0)
|
||||
.unwrap();
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
let _ = layout.route_finish(head, dot3_2, 5.);
|
||||
let _ = layout.route_finish(head, dot3_2, 5.0);
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
|
||||
|
|
@ -270,16 +304,16 @@ fn main() {
|
|||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
let head = layout
|
||||
.shove_around_dot(head, barrier1_dot1, true, 5.)
|
||||
.shove_around_dot(head, barrier1_dot1, true, 5.0)
|
||||
.unwrap();
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
let head = layout
|
||||
.shove_around_dot(head, barrier2_dot1, true, 5.)
|
||||
.shove_around_dot(head, barrier2_dot1, true, 5.0)
|
||||
.unwrap();
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, 50);
|
||||
let _ = layout.route_finish(head, dot4_2, 5.);*/
|
||||
let _ = layout.route_finish(head, dot4_2, 5.0);*/
|
||||
|
||||
render_times(&mut event_pump, &mut canvas, &mut layout, None, -1);
|
||||
render_times(
|
||||
|
|
|
|||
32
src/mesh.rs
32
src/mesh.rs
|
|
@ -45,14 +45,14 @@ impl Mesh {
|
|||
// Unnecessary retag. It should be possible to elide it.
|
||||
let weight = *self.graph.node_weight(index.index).unwrap();
|
||||
|
||||
let wrapper = RTreeWrapper::new(self.primitive(index).shape(), index.retag(weight));
|
||||
let wrapper = RTreeWrapper::new(self.primitive(index).shape(), index.retag(&weight));
|
||||
assert!(self.rtree.remove(&wrapper).is_some());
|
||||
self.graph.remove_node(index.index);
|
||||
}
|
||||
|
||||
pub fn add_dot(&mut self, weight: DotWeight) -> Result<DotIndex, ()> {
|
||||
let dot = DotIndex::new(self.graph.add_node(TaggedWeight::Dot(weight)));
|
||||
self.fail_and_remove_if_collides(dot)?;
|
||||
//self.fail_and_remove_if_collides_except(dot, &[])?;
|
||||
|
||||
self.rtree.insert(RTreeWrapper::new(
|
||||
self.primitive(dot).shape(),
|
||||
|
|
@ -68,11 +68,11 @@ impl Mesh {
|
|||
weight: SegWeight,
|
||||
) -> Result<SegIndex, ()> {
|
||||
let seg = SegIndex::new(self.graph.add_node(TaggedWeight::Seg(weight)));
|
||||
self.fail_and_remove_if_collides(seg)?;
|
||||
|
||||
self.graph.add_edge(from.index, seg.index, Label::End);
|
||||
self.graph.add_edge(seg.index, to.index, Label::End);
|
||||
|
||||
//self.fail_and_remove_if_collides_except(seg, &[from.tag(), to.tag()])?;
|
||||
self.insert_into_rtree(seg.tag());
|
||||
Ok(seg)
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ impl Mesh {
|
|||
weight: BendWeight,
|
||||
) -> Result<BendIndex, ()> {
|
||||
let bend = BendIndex::new(self.graph.add_node(TaggedWeight::Bend(weight)));
|
||||
self.fail_and_remove_if_collides(bend)?;
|
||||
//self.fail_and_remove_if_collides_except(bend, &[from.tag(), to.tag(), core.tag()])?;
|
||||
|
||||
self.graph.add_edge(from.index, bend.index, Label::End);
|
||||
self.graph.add_edge(bend.index, to.index, Label::End);
|
||||
|
|
@ -173,7 +173,7 @@ impl Mesh {
|
|||
dot_weight.circle.pos = to;
|
||||
*self.graph.node_weight_mut(dot.index).unwrap() = TaggedWeight::Dot(dot_weight);
|
||||
|
||||
if let Some(..) = self.detect_collision(&self.primitive(dot).shape()) {
|
||||
if let Some(..) = self.detect_collision_except(dot, &[]) {
|
||||
// Restore original state.
|
||||
*self.graph.node_weight_mut(dot.index).unwrap() = TaggedWeight::Dot(old_weight);
|
||||
self.insert_into_rtree(dot.tag());
|
||||
|
|
@ -209,20 +209,34 @@ impl Mesh {
|
|||
Bow::new(bend, &self.graph)
|
||||
}
|
||||
|
||||
fn fail_and_remove_if_collides<Weight: std::marker::Copy>(
|
||||
fn fail_and_remove_if_collides_except<Weight: std::marker::Copy>(
|
||||
&mut self,
|
||||
index: Index<Weight>,
|
||||
except: &[TaggedIndex],
|
||||
) -> Result<(), ()> {
|
||||
/*if self.detect_collision(&self.primitive(index).shape()) {
|
||||
if let Some(..) = self.detect_collision_except(index, except) {
|
||||
self.remove(index);
|
||||
return Err(());
|
||||
}*/
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn detect_collision(&self, shape: &Shape) -> Option<TaggedIndex> {
|
||||
fn detect_collision_except<Weight: std::marker::Copy>(
|
||||
&self,
|
||||
index: Index<Weight>,
|
||||
except: &[TaggedIndex],
|
||||
) -> Option<TaggedIndex> {
|
||||
let primitive = self.primitive(index);
|
||||
let shape = primitive.shape();
|
||||
|
||||
self.rtree
|
||||
.locate_in_envelope_intersecting(&shape.envelope())
|
||||
.filter(|wrapper| {
|
||||
!primitive
|
||||
.neighbors()
|
||||
.any(|neighbor| neighbor == wrapper.data)
|
||||
})
|
||||
.filter(|wrapper| !except.contains(&wrapper.data))
|
||||
.filter(|wrapper| shape.intersects(wrapper.geom()))
|
||||
.map(|wrapper| wrapper.data)
|
||||
.next()
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn neighbors(&self) -> impl Iterator<Item = TaggedIndex> + '_ {
|
||||
self.graph
|
||||
.neighbors_undirected(self.index.index)
|
||||
.map(|index| Index::<Label>::new(index).retag(self.graph.node_weight(index).unwrap()))
|
||||
}
|
||||
|
||||
pub fn next(&self) -> Option<TaggedIndex> {
|
||||
self.graph
|
||||
.neighbors_directed(self.index.index, Outgoing)
|
||||
|
|
@ -58,7 +64,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
.unwrap()
|
||||
.is_end()
|
||||
})
|
||||
.map(|ni| Index::<Label>::new(ni).retag(*self.graph.node_weight(ni).unwrap()))
|
||||
.map(|ni| Index::<Label>::new(ni).retag(self.graph.node_weight(ni).unwrap()))
|
||||
.next()
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +104,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
.unwrap()
|
||||
.is_end()
|
||||
})
|
||||
.map(|ni| Index::<Label>::new(ni).retag(*self.graph.node_weight(ni).unwrap()))
|
||||
.map(|ni| Index::<Label>::new(ni).retag(self.graph.node_weight(ni).unwrap()))
|
||||
.next()
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +150,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
|||
|
||||
pub fn tagged_index(&self) -> TaggedIndex {
|
||||
self.index
|
||||
.retag(*self.graph.node_weight(self.index.index).unwrap())
|
||||
.retag(self.graph.node_weight(self.index.index).unwrap())
|
||||
}
|
||||
|
||||
pub fn tagged_weight(&self) -> TaggedWeight {
|
||||
|
|
|
|||
Loading…
Reference in New Issue