egui: add widget to control showing bboxes

This commit is contained in:
Mikolaj Wielgus 2024-07-19 14:44:03 +02:00
parent 4f8bf8f686
commit a644ac276b
4 changed files with 34 additions and 20 deletions

View File

@ -7,11 +7,20 @@ use topola::{
pub struct Painter<'a> { pub struct Painter<'a> {
ui: &'a mut egui::Ui, ui: &'a mut egui::Ui,
transform: egui::emath::RectTransform, transform: egui::emath::RectTransform,
paint_bboxes: bool,
} }
impl<'a> Painter<'a> { impl<'a> Painter<'a> {
pub fn new(ui: &'a mut egui::Ui, transform: egui::emath::RectTransform) -> Self { pub fn new(
Self { ui, transform } ui: &'a mut egui::Ui,
transform: egui::emath::RectTransform,
paint_bboxes: bool,
) -> Self {
Self {
ui,
transform,
paint_bboxes,
}
} }
pub fn paint_primitive(&mut self, shape: &PrimitiveShape, color: egui::epaint::Color32) { pub fn paint_primitive(&mut self, shape: &PrimitiveShape, color: egui::epaint::Color32) {
@ -49,16 +58,18 @@ impl<'a> Painter<'a> {
self.ui.painter().add(epaint_shape); self.ui.painter().add(epaint_shape);
let envelope = AccessPrimitiveShape::envelope(shape, 0.0); if self.paint_bboxes {
let rect = egui::epaint::Rect { let bbox = AccessPrimitiveShape::bbox(shape, 0.0);
min: [envelope.lower()[0] as f32, -envelope.upper()[1] as f32].into(), let rect = egui::epaint::Rect {
max: [envelope.upper()[0] as f32, -envelope.lower()[1] as f32].into(), min: [bbox.lower()[0] as f32, -bbox.upper()[1] as f32].into(),
}; max: [bbox.upper()[0] as f32, -bbox.lower()[1] as f32].into(),
self.ui.painter().add(egui::Shape::rect_stroke( };
self.transform.transform_rect(rect), self.ui.painter().add(egui::Shape::rect_stroke(
egui::Rounding::ZERO, self.transform.transform_rect(rect),
egui::Stroke::new(1.0, egui::Color32::GRAY), egui::Rounding::ZERO,
)); egui::Stroke::new(1.0, egui::Color32::GRAY),
));
}
} }
pub fn paint_dot(&mut self, circle: Circle, color: egui::epaint::Color32) { pub fn paint_dot(&mut self, circle: Circle, color: egui::epaint::Color32) {

View File

@ -22,6 +22,7 @@ pub struct Top {
pub is_placing_via: bool, pub is_placing_via: bool,
pub show_ratsnest: bool, pub show_ratsnest: bool,
pub show_navmesh: bool, pub show_navmesh: bool,
pub show_bboxes: bool,
} }
impl Top { impl Top {
@ -30,6 +31,7 @@ impl Top {
is_placing_via: false, is_placing_via: false,
show_ratsnest: false, show_ratsnest: false,
show_navmesh: false, show_navmesh: false,
show_bboxes: false,
} }
} }
@ -109,6 +111,7 @@ impl Top {
ui.toggle_value(&mut self.show_ratsnest, "Show Ratsnest"); ui.toggle_value(&mut self.show_ratsnest, "Show Ratsnest");
ui.toggle_value(&mut self.show_navmesh, "Show Navmesh"); ui.toggle_value(&mut self.show_navmesh, "Show Navmesh");
ui.toggle_value(&mut self.show_bboxes, "Show Bboxes");
ui.separator(); ui.separator();

View File

@ -70,7 +70,7 @@ impl Viewport {
.translate(ctx.input(|i| -i.raw_scroll_delta / new_scale)); .translate(ctx.input(|i| -i.raw_scroll_delta / new_scale));
let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect); let transform = egui::emath::RectTransform::from_to(self.from_rect, viewport_rect);
let mut painter = Painter::new(ui, transform); let mut painter = Painter::new(ui, transform, top.show_bboxes);
if let Some(ref mut invoker) = maybe_invoker { if let Some(ref mut invoker) = maybe_invoker {
if ctx.input(|i| i.pointer.any_click()) { if ctx.input(|i| i.pointer.any_click()) {

View File

@ -14,11 +14,11 @@ pub trait AccessPrimitiveShape: AccessShape {
fn priority(&self) -> usize; fn priority(&self) -> usize;
fn inflate(&self, margin: f64) -> PrimitiveShape; fn inflate(&self, margin: f64) -> PrimitiveShape;
fn intersects(&self, other: &PrimitiveShape) -> bool; fn intersects(&self, other: &PrimitiveShape) -> bool;
fn envelope(&self, margin: f64) -> AABB<[f64; 2]>; fn bbox(&self, margin: f64) -> AABB<[f64; 2]>;
fn width(&self) -> f64; fn width(&self) -> f64;
fn envelope_3d(&self, margin: f64, layer: usize) -> AABB<[f64; 3]> { fn envelope_3d(&self, margin: f64, layer: usize) -> AABB<[f64; 3]> {
let envelope = self.envelope(margin); let envelope = self.bbox(margin);
AABB::from_corners( AABB::from_corners(
[envelope.lower()[0], envelope.lower()[1], layer as f64], [envelope.lower()[0], envelope.lower()[1], layer as f64],
[envelope.upper()[0], envelope.upper()[1], layer as f64], [envelope.upper()[0], envelope.upper()[1], layer as f64],
@ -26,7 +26,7 @@ pub trait AccessPrimitiveShape: AccessShape {
} }
fn full_height_envelope_3d(&self, margin: f64, layer_count: usize) -> AABB<[f64; 3]> { fn full_height_envelope_3d(&self, margin: f64, layer_count: usize) -> AABB<[f64; 3]> {
let envelope = self.envelope(margin); let envelope = self.bbox(margin);
AABB::from_corners( AABB::from_corners(
[envelope.lower()[0], envelope.lower()[1], 0.0], [envelope.lower()[0], envelope.lower()[1], 0.0],
[ [
@ -113,7 +113,7 @@ impl AccessPrimitiveShape for DotShape {
} }
} }
fn envelope(&self, margin: f64) -> AABB<[f64; 2]> { fn bbox(&self, margin: f64) -> AABB<[f64; 2]> {
AABB::from_corners( AABB::from_corners(
[ [
self.circle.pos.x() - self.circle.r - margin, self.circle.pos.x() - self.circle.r - margin,
@ -215,7 +215,7 @@ impl AccessPrimitiveShape for SegShape {
} }
} }
fn envelope(&self, margin: f64) -> AABB<[f64; 2]> { fn bbox(&self, margin: f64) -> AABB<[f64; 2]> {
let points: Vec<[f64; 2]> = self let points: Vec<[f64; 2]> = self
.polygon() .polygon()
.exterior() .exterior()
@ -371,7 +371,7 @@ impl AccessPrimitiveShape for BendShape {
} }
} }
fn envelope(&self, _margin: f64) -> AABB<[f64; 2]> { fn bbox(&self, _margin: f64) -> AABB<[f64; 2]> {
let halfwidth = self.inner_circle.r + self.width; let halfwidth = self.inner_circle.r + self.width;
AABB::from_corners( AABB::from_corners(
[ [
@ -393,6 +393,6 @@ impl AccessPrimitiveShape for BendShape {
impl RTreeObject for PrimitiveShape { impl RTreeObject for PrimitiveShape {
type Envelope = AABB<[f64; 2]>; type Envelope = AABB<[f64; 2]>;
fn envelope(&self) -> Self::Envelope { fn envelope(&self) -> Self::Envelope {
AccessPrimitiveShape::envelope(self, 0.0) AccessPrimitiveShape::bbox(self, 0.0)
} }
} }