From f9d5b4d839b7a535a1a7270bceb104decacea9fe Mon Sep 17 00:00:00 2001 From: Kenneth VanderLinde Date: Tue, 16 Jan 2024 23:41:59 -0800 Subject: [PATCH] Fix issue with vision bounds not including the vision origin The vision sweep is only well-behaved if it has bounds surrounding the origin. It is not enough that we use the vision bounds since certain cases may not guarantee that the vision shape include the vision origin. So we now make sure to explicitly expands the sweep bounds to include the origin. Also some separation of concerns: `EndpointSet` has no reason to know anything about vision, not even just to provide initial bounds. So now it only tracks the bounding box of its contents and nothing else. --- .../maptool/client/ui/zone/vbl/EndpointSet.java | 4 ++-- .../client/ui/zone/vbl/VisibilityProblem.java | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/vbl/EndpointSet.java b/src/main/java/net/rptools/maptool/client/ui/zone/vbl/EndpointSet.java index b9816d96d8..11877d73ee 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/vbl/EndpointSet.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/vbl/EndpointSet.java @@ -53,9 +53,9 @@ public class EndpointSet { private final int[] bucketSizes; - public EndpointSet(Coordinate origin, Envelope bounds) { + public EndpointSet(Coordinate origin) { this.origin = origin; - this.envelope = new Envelope(bounds); + this.envelope = new Envelope(); this.buckets = new VisibilitySweepEndpoint[BUCKET_COUNT][]; Arrays.setAll(this.buckets, i -> new VisibilitySweepEndpoint[32]); diff --git a/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisibilityProblem.java b/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisibilityProblem.java index 2bdc559dfd..dfa00cf2c0 100644 --- a/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisibilityProblem.java +++ b/src/main/java/net/rptools/maptool/client/ui/zone/vbl/VisibilityProblem.java @@ -47,6 +47,14 @@ public class VisibilityProblem { */ private final EndpointSet endpointSet; + /** + * Bounds on the vision and origin. + * + *

This will be used to guarantee that we have endpoints in every direction around the origin, + * and that we avoid infinite results. + */ + private final Envelope bounds; + /** * The set of walls that are intersected by the current event line. * @@ -66,7 +74,9 @@ public class VisibilityProblem { */ public VisibilityProblem(Coordinate origin, Envelope visionBounds) { this.origin = origin; - this.endpointSet = new EndpointSet(origin, visionBounds); + this.endpointSet = new EndpointSet(origin); + this.bounds = new Envelope(visionBounds); + this.bounds.expandToInclude(origin); this.openWalls = new TreeSet<>(this::compareOpenWalls); } @@ -145,6 +155,7 @@ public void add(List string) { timer.start("add bounds"); final var envelope = endpointSet.getBounds(); + envelope.expandToInclude(this.bounds); // Exact expansion distance doesn't matter, we just don't want the boundary walls to overlap // endpoints from real walls. envelope.expandBy(1.0);