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 maxY = Integer.MAX_VALUE;
private transient Vector3i min = null;
private transient Vector3i max = null;
private boolean renderEdges = true;
private String storage = "file";
@ -83,11 +86,13 @@ public class MapConfig implements MapSettings {
}
public Vector3i getMinPos() {
return new Vector3i(minX, minY, minZ);
if (min == null) min = new Vector3i(minX, minY, minZ);
return min;
}
public Vector3i getMaxPos() {
return new Vector3i(maxX, maxY, maxZ);
if (max == null) max = new Vector3i(maxX, maxY, maxZ);
return max;
}
public boolean isRenderEdges() {

View File

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

View File

@ -32,6 +32,7 @@ import de.bluecolored.bluemap.core.world.Grid;
import de.bluecolored.bluemap.core.world.Region;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@DebugDump
@ -91,10 +92,22 @@ public class WorldRegionRenderTask implements RenderTask {
}
}
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.tiles = tileSet.stream()
.sorted(WorldRegionRenderTask::compareVec2L) //sort with longs to avoid overflow (comparison uses distanceSquared)
.map(Vector2l::toInt) // back to ints
.filter(boundsTileFilter)
.filter(map.getTileFilter())
.collect(Collectors.toCollection(ArrayDeque::new));
if (tiles.isEmpty()) complete();

View File

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