mirror of https://codeberg.org/topola/topola.git
Add methods to add multivertices to navmesher
This commit is contained in:
parent
1b84eea06b
commit
f9e6c1bdda
|
|
@ -287,7 +287,9 @@ impl Display {
|
||||||
) {
|
) {
|
||||||
for layer in 0..*workspace.navmesher_board.board().layout().layer_count() {
|
for layer in 0..*workspace.navmesher_board.board().layout().layer_count() {
|
||||||
if workspace.appearance_panel.visible[layer] {
|
if workspace.appearance_panel.visible[layer] {
|
||||||
for navmesh in workspace.navmesher_board.navmesher().layers()[layer].navmeshes() {
|
for navmesh in
|
||||||
|
workspace.navmesher_board.navmesher().layer_navmeshers()[layer].navmeshes()
|
||||||
|
{
|
||||||
for edge_geom in navmesh
|
for edge_geom in navmesh
|
||||||
.triangulation()
|
.triangulation()
|
||||||
.rtreed_dcel()
|
.rtreed_dcel()
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bimap = "0.6"
|
bimap = "0.6"
|
||||||
dearcut = { version = "0.3", features = ["undoredo"] }
|
dearcut = { version = "0.3", features = ["serde", "undoredo"] }
|
||||||
derive-getters.workspace = true
|
derive-getters.workspace = true
|
||||||
derive_more.workspace = true
|
derive_more.workspace = true
|
||||||
rstar = "0.12"
|
rstar = "0.12"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
use dearcut::RecordingTriangulator;
|
use dearcut::{RecordingTriangulator, VertexId};
|
||||||
use derive_getters::Getters;
|
use derive_getters::Getters;
|
||||||
use derive_more::Constructor;
|
use derive_more::Constructor;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
@ -16,12 +16,12 @@ use crate::{
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
Clone, Constructor, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
|
||||||
)]
|
)]
|
||||||
pub struct ObstacleId {
|
pub struct MultiObstacleId {
|
||||||
layer: usize,
|
layer: usize,
|
||||||
index: usize,
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObstacleId {
|
impl MultiObstacleId {
|
||||||
/// Layer of the obstacle.
|
/// Layer of the obstacle.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn layer(self) -> usize {
|
pub fn layer(self) -> usize {
|
||||||
|
|
@ -35,6 +35,20 @@ impl ObstacleId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Constructor, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
|
pub struct MultiVertexId {
|
||||||
|
layer: usize,
|
||||||
|
indices: Vec<VertexId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MultiVertexId {
|
||||||
|
/// Layer of the obstacle.
|
||||||
|
#[inline]
|
||||||
|
pub fn layer(self) -> usize {
|
||||||
|
self.layer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Getters)]
|
#[derive(Clone, Debug, Getters)]
|
||||||
pub struct LayerNavmesher {
|
pub struct LayerNavmesher {
|
||||||
boundary: Vec<Vector2<i64>>,
|
boundary: Vec<Vector2<i64>>,
|
||||||
|
|
@ -51,12 +65,15 @@ impl LayerNavmesher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_obstacle(&mut self, polygon: impl IntoIterator<Item = Vector2<i64>>) -> usize {
|
pub fn insert_multiobstacle(
|
||||||
|
&mut self,
|
||||||
|
polygon: impl IntoIterator<Item = Vector2<i64>>,
|
||||||
|
) -> usize {
|
||||||
let polygon: Vec<Vector2<i64>> = polygon.into_iter().collect();
|
let polygon: Vec<Vector2<i64>> = polygon.into_iter().collect();
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
|
||||||
for i in 0..self.navmeshes.len() {
|
for i in 0..self.navmeshes.len() {
|
||||||
index = self.navmeshes[i].insert_polygon_and_rebuild(
|
index = self.navmeshes[i].insert_obstacle_and_rebuild(
|
||||||
Self::inflate_polygon(polygon.clone(), self.inflation_factors[i])
|
Self::inflate_polygon(polygon.clone(), self.inflation_factors[i])
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Into::into),
|
.map(Into::into),
|
||||||
|
|
@ -98,11 +115,28 @@ impl LayerNavmesher {
|
||||||
Vector2::new(rx as i64, ry as i64)
|
Vector2::new(rx as i64, ry as i64)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert_free_multivertex_in_multiobstacle(
|
||||||
|
&mut self,
|
||||||
|
multiobstacle_index: usize,
|
||||||
|
position: Vector2<i64>,
|
||||||
|
) -> Vec<VertexId> {
|
||||||
|
let mut vertices = Vec::new();
|
||||||
|
|
||||||
|
for navmesh in &mut self.navmeshes {
|
||||||
|
vertices.push(
|
||||||
|
navmesh
|
||||||
|
.insert_free_vertex_in_obstacle(multiobstacle_index, [position.x, position.y]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertices
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Getters)]
|
#[derive(Clone, Debug, Getters)]
|
||||||
pub struct Navmesher {
|
pub struct Navmesher {
|
||||||
layers: Vec<LayerNavmesher>,
|
layer_navmeshers: Vec<LayerNavmesher>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Navmesher {
|
impl Navmesher {
|
||||||
|
|
@ -110,18 +144,33 @@ impl Navmesher {
|
||||||
let boundary: Vec<Vector2<i64>> = boundary.into_iter().collect();
|
let boundary: Vec<Vector2<i64>> = boundary.into_iter().collect();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
layers: std::iter::repeat_with(|| LayerNavmesher::new(boundary.clone()))
|
layer_navmeshers: std::iter::repeat_with(|| LayerNavmesher::new(boundary.clone()))
|
||||||
.take(layer_count)
|
.take(layer_count)
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_obstacle(
|
pub fn insert_multiobstacle(
|
||||||
&mut self,
|
&mut self,
|
||||||
layer: usize,
|
layer: usize,
|
||||||
polygon: impl IntoIterator<Item = Vector2<i64>>,
|
multiobstacle: impl IntoIterator<Item = Vector2<i64>>,
|
||||||
) -> ObstacleId {
|
) -> MultiObstacleId {
|
||||||
ObstacleId::new(layer, self.layers[layer].insert_obstacle(polygon))
|
MultiObstacleId::new(
|
||||||
|
layer,
|
||||||
|
self.layer_navmeshers[layer].insert_multiobstacle(multiobstacle),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_free_multivertex_in_multiobstacle(
|
||||||
|
&mut self,
|
||||||
|
multiobstacle_id: MultiObstacleId,
|
||||||
|
position: Vector2<i64>,
|
||||||
|
) -> MultiVertexId {
|
||||||
|
MultiVertexId {
|
||||||
|
layer: multiobstacle_id.layer,
|
||||||
|
indices: self.layer_navmeshers[multiobstacle_id.layer]
|
||||||
|
.insert_free_multivertex_in_multiobstacle(multiobstacle_id.index, position),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,9 +179,9 @@ pub struct NavmesherBoard {
|
||||||
navmesher: Navmesher,
|
navmesher: Navmesher,
|
||||||
board: Board,
|
board: Board,
|
||||||
|
|
||||||
joint_obstacles: Recorder<Vec<ObstacleId>>,
|
joint_multiobstacles: Recorder<Vec<MultiObstacleId>>,
|
||||||
segment_obstacles: Recorder<Vec<ObstacleId>>,
|
segment_multiobstacles: Recorder<Vec<MultiObstacleId>>,
|
||||||
polygon_obstacles: Recorder<Vec<ObstacleId>>,
|
polygon_multiobstacles: Recorder<Vec<MultiObstacleId>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NavmesherBoard {
|
impl NavmesherBoard {
|
||||||
|
|
@ -148,23 +197,23 @@ impl NavmesherBoard {
|
||||||
),
|
),
|
||||||
board,
|
board,
|
||||||
|
|
||||||
joint_obstacles: Recorder::new(Vec::new()),
|
joint_multiobstacles: Recorder::new(Vec::new()),
|
||||||
segment_obstacles: Recorder::new(Vec::new()),
|
segment_multiobstacles: Recorder::new(Vec::new()),
|
||||||
polygon_obstacles: Recorder::new(Vec::new()),
|
polygon_multiobstacles: Recorder::new(Vec::new()),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i, joint) in this.board.layout().joints().collection() {
|
for (i, joint) in this.board.layout().joints().collection() {
|
||||||
this.joint_obstacles.insert(
|
this.joint_multiobstacles.insert(
|
||||||
i,
|
i,
|
||||||
this.navmesher
|
this.navmesher
|
||||||
.insert_obstacle(joint.layer, Self::joint_bounding_octagon(*joint)),
|
.insert_multiobstacle(joint.layer, Self::joint_bounding_octagon(*joint)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, segment) in this.board.layout().segments().collection() {
|
for (i, segment) in this.board.layout().segments().collection() {
|
||||||
this.segment_obstacles.insert(
|
this.segment_multiobstacles.insert(
|
||||||
i,
|
i,
|
||||||
this.navmesher.insert_obstacle(
|
this.navmesher.insert_multiobstacle(
|
||||||
segment.layer,
|
segment.layer,
|
||||||
this.segment_bounding_rectangle(SegmentId::new(i), *segment),
|
this.segment_bounding_rectangle(SegmentId::new(i), *segment),
|
||||||
),
|
),
|
||||||
|
|
@ -172,10 +221,10 @@ impl NavmesherBoard {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, polygon) in this.board.layout().polygons().collection() {
|
for (i, polygon) in this.board.layout().polygons().collection() {
|
||||||
this.polygon_obstacles.insert(
|
this.polygon_multiobstacles.insert(
|
||||||
i,
|
i,
|
||||||
this.navmesher
|
this.navmesher
|
||||||
.insert_obstacle(polygon.layer, polygon.vertices.clone()),
|
.insert_multiobstacle(polygon.layer, polygon.vertices.clone()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,10 +233,10 @@ impl NavmesherBoard {
|
||||||
|
|
||||||
pub fn insert_joint(&mut self, joint: Joint) -> JointId {
|
pub fn insert_joint(&mut self, joint: Joint) -> JointId {
|
||||||
let joint_id = self.board.add_joint(joint);
|
let joint_id = self.board.add_joint(joint);
|
||||||
self.joint_obstacles.insert(
|
self.joint_multiobstacles.insert(
|
||||||
joint_id.id(),
|
joint_id.id(),
|
||||||
self.navmesher
|
self.navmesher
|
||||||
.insert_obstacle(joint.layer, Self::joint_bounding_octagon(joint)),
|
.insert_multiobstacle(joint.layer, Self::joint_bounding_octagon(joint)),
|
||||||
);
|
);
|
||||||
|
|
||||||
joint_id
|
joint_id
|
||||||
|
|
@ -212,9 +261,9 @@ impl NavmesherBoard {
|
||||||
|
|
||||||
pub fn insert_segment(&mut self, segment: Segment) -> SegmentId {
|
pub fn insert_segment(&mut self, segment: Segment) -> SegmentId {
|
||||||
let segment_id = self.board.add_segment(segment);
|
let segment_id = self.board.add_segment(segment);
|
||||||
self.segment_obstacles.insert(
|
self.segment_multiobstacles.insert(
|
||||||
segment_id.id(),
|
segment_id.id(),
|
||||||
self.navmesher.insert_obstacle(
|
self.navmesher.insert_multiobstacle(
|
||||||
segment.layer,
|
segment.layer,
|
||||||
self.segment_bounding_rectangle(segment_id, segment),
|
self.segment_bounding_rectangle(segment_id, segment),
|
||||||
),
|
),
|
||||||
|
|
@ -245,10 +294,10 @@ impl NavmesherBoard {
|
||||||
|
|
||||||
pub fn insert_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
pub fn insert_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||||
let polygon_id = self.board.add_polygon(polygon.clone());
|
let polygon_id = self.board.add_polygon(polygon.clone());
|
||||||
self.polygon_obstacles.insert(
|
self.polygon_multiobstacles.insert(
|
||||||
polygon_id.id(),
|
polygon_id.id(),
|
||||||
self.navmesher
|
self.navmesher
|
||||||
.insert_obstacle(polygon.layer, polygon.vertices),
|
.insert_multiobstacle(polygon.layer, polygon.vertices),
|
||||||
);
|
);
|
||||||
|
|
||||||
polygon_id
|
polygon_id
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue