Fix falsely considering regions outside of the defined render-boundaries

This commit is contained in:
Lukas Rieger (Blue) 2022-04-24 18:53:06 +02:00
parent a21725ce57
commit 92ac2177cd
No known key found for this signature in database
GPG Key ID: 2D09EC5ED2687FF2
4 changed files with 55 additions and 13 deletions

View File

@ -39,6 +39,9 @@ public class MapConfig implements MapSettings {
private int minY = Integer.MIN_VALUE; private int minY = Integer.MIN_VALUE;
private int maxY = Integer.MAX_VALUE; private int maxY = Integer.MAX_VALUE;
private transient Vector3i min = null;
private transient Vector3i max = null;
private boolean renderEdges = true; private boolean renderEdges = true;
private String storage = "file"; private String storage = "file";
@ -83,11 +86,13 @@ public boolean isCaveDetectionUsesBlockLight() {
} }
public Vector3i getMinPos() { public Vector3i getMinPos() {
return new Vector3i(minX, minY, minZ); if (min == null) min = new Vector3i(minX, minY, minZ);
return min;
} }
public Vector3i getMaxPos() { public Vector3i getMaxPos() {
return new Vector3i(maxX, maxY, maxZ); if (max == null) max = new Vector3i(maxX, maxY, maxZ);
return max;
} }
public boolean isRenderEdges() { public boolean isRenderEdges() {

View File

@ -34,6 +34,8 @@
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@DebugDump @DebugDump
public class MapUpdateTask extends CombinedRenderTask<WorldRegionRenderTask> { public class MapUpdateTask extends CombinedRenderTask<WorldRegionRenderTask> {
@ -42,19 +44,19 @@ public class MapUpdateTask extends CombinedRenderTask<WorldRegionRenderTask> {
private final Collection<Vector2i> regions; private final Collection<Vector2i> regions;
public MapUpdateTask(BmMap map) { public MapUpdateTask(BmMap map) {
this(map, getRegions(map.getWorld())); this(map, getRegions(map));
} }
public MapUpdateTask(BmMap map, boolean force) { public MapUpdateTask(BmMap map, boolean force) {
this(map, getRegions(map.getWorld()), force); this(map, getRegions(map), force);
} }
public MapUpdateTask(BmMap map, Vector2i center, int radius) { public MapUpdateTask(BmMap map, Vector2i center, int radius) {
this(map, getRegions(map.getWorld(), center, radius)); this(map, getRegions(map, center, radius));
} }
public MapUpdateTask(BmMap map, Vector2i center, int radius, boolean force) { public MapUpdateTask(BmMap map, Vector2i center, int radius, boolean force) {
this(map, getRegions(map.getWorld(), center, radius), force); this(map, getRegions(map, center, radius), force);
} }
public MapUpdateTask(BmMap map, Collection<Vector2i> regions) { public MapUpdateTask(BmMap map, Collection<Vector2i> regions) {
@ -89,20 +91,37 @@ private static Collection<WorldRegionRenderTask> createTasks(BmMap map, Collecti
return tasks; return tasks;
} }
private static List<Vector2i> getRegions(World world) { private static List<Vector2i> getRegions(BmMap map) {
return getRegions(world, null, -1); return getRegions(map, null, -1);
} }
private static List<Vector2i> getRegions(World world, Vector2i center, int radius) { private static List<Vector2i> getRegions(BmMap map, Vector2i center, int radius) {
if (center == null || radius < 0) return new ArrayList<>(world.listRegions()); //TODO: remove regions outside render-boundaries World world = map.getWorld();
Grid regionGrid = world.getRegionGrid();
Predicate<Vector2i> regionFilter = r -> {
Vector2i cellMin = regionGrid.getCellMin(r);
if (cellMin.getX() > map.getMapSettings().getMaxPos().getX()) return false;
if (cellMin.getY() > map.getMapSettings().getMaxPos().getY()) return false;
Vector2i cellMax = regionGrid.getCellMax(r);
if (cellMax.getX() < map.getMapSettings().getMinPos().getX()) return false;
return cellMax.getY() >= map.getMapSettings().getMinPos().getY();
};
if (center == null || radius < 0) {
return world.listRegions().stream()
.filter(regionFilter)
.collect(Collectors.toList());
}
List<Vector2i> regions = new ArrayList<>(); List<Vector2i> regions = new ArrayList<>();
Grid regionGrid = world.getRegionGrid();
Vector2i halfCell = regionGrid.getGridSize().div(2); Vector2i halfCell = regionGrid.getGridSize().div(2);
int increasedRadiusSquared = (int) Math.pow(radius + Math.ceil(halfCell.length()), 2); int increasedRadiusSquared = (int) Math.pow(radius + Math.ceil(halfCell.length()), 2);
for (Vector2i region : world.listRegions()) { for (Vector2i region : world.listRegions()) {
if (!regionFilter.test(region)) continue;
Vector2i min = regionGrid.getCellMin(region); Vector2i min = regionGrid.getCellMin(region);
Vector2i regionCenter = min.add(halfCell); Vector2i regionCenter = min.add(halfCell);

View File

@ -32,6 +32,7 @@
import de.bluecolored.bluemap.core.world.Region; import de.bluecolored.bluemap.core.world.Region;
import java.util.*; import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@DebugDump @DebugDump
@ -91,10 +92,22 @@ private synchronized void init() {
} }
} }
Predicate<Vector2i> boundsTileFilter = t -> {
Vector2i cellMin = tileGrid.getCellMin(t);
if (cellMin.getX() > map.getMapSettings().getMaxPos().getX()) return false;
if (cellMin.getY() > map.getMapSettings().getMaxPos().getY()) return false;
Vector2i cellMax = tileGrid.getCellMax(t);
if (cellMax.getX() < map.getMapSettings().getMinPos().getX()) return false;
return cellMax.getY() >= map.getMapSettings().getMinPos().getY();
};
this.tileCount = tileSet.size(); this.tileCount = tileSet.size();
this.tiles = tileSet.stream() this.tiles = tileSet.stream()
.sorted(WorldRegionRenderTask::compareVec2L) //sort with longs to avoid overflow (comparison uses distanceSquared) .sorted(WorldRegionRenderTask::compareVec2L) //sort with longs to avoid overflow (comparison uses distanceSquared)
.map(Vector2l::toInt) // back to ints .map(Vector2l::toInt) // back to ints
.filter(boundsTileFilter)
.filter(map.getTileFilter())
.collect(Collectors.toCollection(ArrayDeque::new)); .collect(Collectors.toCollection(ArrayDeque::new));
if (tiles.isEmpty()) complete(); if (tiles.isEmpty()) complete();

View File

@ -53,6 +53,7 @@ public class BmMap {
private final String worldId; private final String worldId;
private final World world; private final World world;
private final Storage storage; private final Storage storage;
private final MapSettings mapSettings;
private final MapRenderState renderState; private final MapRenderState renderState;
@ -70,9 +71,9 @@ public BmMap(String id, String name, String worldId, World world, Storage storag
this.worldId = Objects.requireNonNull(worldId); this.worldId = Objects.requireNonNull(worldId);
this.world = Objects.requireNonNull(world); this.world = Objects.requireNonNull(world);
this.storage = Objects.requireNonNull(storage); this.storage = Objects.requireNonNull(storage);
this.mapSettings = Objects.requireNonNull(settings);
Objects.requireNonNull(resourcePack); Objects.requireNonNull(resourcePack);
Objects.requireNonNull(settings);
this.renderState = new MapRenderState(); this.renderState = new MapRenderState();
@ -149,6 +150,10 @@ public Storage getStorage() {
return storage; return storage;
} }
public MapSettings getMapSettings() {
return mapSettings;
}
public MapRenderState getRenderState() { public MapRenderState getRenderState() {
return renderState; return renderState;
} }