Display navmeshes

This commit is contained in:
Mikolaj Wielgus 2026-03-11 18:58:19 +01:00
parent 09e1e35151
commit f3112dd886
4 changed files with 82 additions and 41 deletions

View File

@ -21,6 +21,7 @@ impl Displayer {
workspace: &Workspace,
) {
self.display_layout(ctx, ui, /*menu_bar,*/ viewport, workspace);
self.display_navmeshes(ctx, ui, viewport, workspace);
}
pub fn display_layout(
@ -174,4 +175,59 @@ impl Displayer {
egui::Stroke::new(5.0 / viewport.scale_factor(), color),
));
}
fn display_navmeshes(
&mut self,
ctx: &egui::Context,
ui: &egui::Ui,
viewport: &Viewport,
workspace: &Workspace,
) {
for layer in 0..*workspace.navmesher_board.board().layout().layer_count() {
if workspace.appearance_panel.visible[layer] {
for navmesh in workspace.navmesher_board.navmesher().layers()[layer].navmeshes() {
for edge_geom in navmesh
.triangulation()
.rtreed_dcel()
.edges_rtree()
.as_ref()
.iter()
{
let (from_vertex, to_vertex) = navmesh
.triangulation()
.rtreed_dcel()
.dcel()
.edge_endpoints(edge_geom.data);
let from = navmesh
.triangulation()
.rtreed_dcel()
.dcel()
.vertex_weight(from_vertex)
.position();
let to = navmesh
.triangulation()
.rtreed_dcel()
.dcel()
.vertex_weight(to_vertex)
.position();
ui.painter().line_segment(
[
egui::pos2(*from.x() as f32, *from.y() as f32),
egui::pos2(*to.x() as f32, *to.y() as f32),
],
egui::Stroke::new(
10.0,
workspace
.appearance_panel
.colors(ctx)
.layers
.color(workspace.navmesher_board.board().layer_name(layer))
.normal,
),
);
}
}
}
}
}
}

View File

@ -7,8 +7,7 @@ use derive_getters::{Dissolve, Getters};
use undoredo::{ApplyDelta, Delta, FlushDelta};
use crate::layout::{
Arc, ArcId, Joint, JointId, Layout, LayoutHalfDelta, Polygon, PolygonId, Segment, SegmentId,
Via, ViaId,
Joint, JointId, Layout, LayoutHalfDelta, Polygon, PolygonId, Segment, SegmentId, Via, ViaId,
};
struct Layer {

View File

@ -56,31 +56,6 @@ pub struct Segment {
pub half_width: u64,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct ArcId(usize);
impl ArcId {
/// Wrap an arc index in a newtype struct.
#[inline]
pub fn new(id: usize) -> Self {
Self(id)
}
/// Returns the underlying index.
#[inline]
pub fn id(self) -> usize {
self.0
}
}
#[derive(Clone, Copy, Debug)]
pub struct Arc {
pub endpoints: [JointId; 2],
pub focus: [i64; 2],
pub layer: usize,
pub half_width: u64,
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct ViaId(usize);

View File

@ -7,7 +7,7 @@ use derive_getters::Getters;
use crate::{
Board,
layout::{Arc, ArcId, Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Via, ViaId},
layout::{Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Via, ViaId},
};
#[derive(Clone, Debug, Getters)]
@ -19,8 +19,8 @@ pub struct LayerNavmesher {
impl LayerNavmesher {
pub fn new() -> Self {
Self {
navmeshes: Vec::new(),
inflation_factors: Vec::new(),
navmeshes: vec![RecordingTriangulator::new()],
inflation_factors: vec![0.0],
}
}
@ -28,7 +28,7 @@ impl LayerNavmesher {
let polygon: Vec<[i64; 2]> = polygon.into_iter().collect();
for i in 0..self.navmeshes.len() {
self.navmeshes[i].insert_polygon(Self::inflate_polygon(
self.navmeshes[i].insert_polygon_and_rebuild(Self::inflate_polygon(
polygon.clone(),
self.inflation_factors[i],
));
@ -118,23 +118,34 @@ impl NavmesherBoard {
let cy = joint.position[1];
let r = joint.radius as i64;
[
[cx + r, cy + r / 2],
[cx + r / 2, cy + r],
[cx - r / 2, cy + r],
[cx - r, cy + r / 2],
[cx - r, cy - r / 2],
[cx - r / 2, cy - r],
[cx + r / 2, cy - r],
[cx + r, cy - r / 2],
]
// 1.082392... = 1 / cos(π/8)
// 0.414213... = tan(π/8)
// Approximate multipliers as fractions.
let r1 = (r * 277 + 128) / 256; // round(r * 1.0823922)
/*let r1 = (r * 277 + 128) / 256; // round(r * 1.0823922)
let r2 = (r * 106 + 128) / 256; // round(r * 0.41421356)
[
[cx + r1, cy], // right
[cx + r2, cy + r2], // top-right
[cx, cy + r1], // top
[cx - r2, cy + r2], // top-left
[cx - r1, cy], // left
[cx - r2, cy - r2], // bottom-left
[cx, cy - r1], // bottom
[cx + r2, cy - r2], // bottom-right
]
[cx + r1, cy],
[cx + r2, cy + r2],
[cx, cy + r1],
[cx - r2, cy + r2],
[cx - r1, cy],
[cx - r2, cy - r2],
[cx, cy - r1],
[cx + r2, cy - r2],
]*/
}
pub fn insert_segment(&mut self, segment: Segment) -> SegmentId {