forked from SteamWar/SteamWar
Partial diagonal HullHider uncovering, performance improvement
This commit is contained in:
@@ -39,38 +39,35 @@ import java.util.stream.IntStream;
|
|||||||
|
|
||||||
public class Hull {
|
public class Hull {
|
||||||
|
|
||||||
|
private static final IntVector[] NO_BRANCHES = new IntVector[0];
|
||||||
|
|
||||||
private static boolean isOccluding(Material material) {
|
private static boolean isOccluding(Material material) {
|
||||||
return material.isOccluding() || Config.HiddenBlocks.contains(material);
|
return material.isOccluding() || Config.HiddenBlocks.contains(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Region region;
|
private final Region region;
|
||||||
private final boolean groundVisible;
|
private final boolean groundVisible;
|
||||||
private final IntVector primaryDirection;
|
|
||||||
private final IntVector[] directions;
|
private final IntVector[] directions;
|
||||||
private final IntVector[] branchDirections;
|
|
||||||
|
|
||||||
private final BitSet occluding;
|
private final BitSet occluding;
|
||||||
private final BitSet visibility;
|
private final BitSet visibility;
|
||||||
private final HashMap<IntVector, BitSet> visibilityDirections = new HashMap<>(); // Contains the visible directions of each occluding visible block
|
private final HashMap<IntVector, BitSet> visibilityDirections = new HashMap<>(); // Contains the visible directions of each occluding visible block
|
||||||
private final Set<IntVector> uncoveredSurface = new HashSet<>();
|
private final HashSet<IntVector> uncoveredSurface = new HashSet<>();
|
||||||
|
|
||||||
private final HashSet<Player> players = new HashSet<>();
|
private final HashSet<Player> players = new HashSet<>();
|
||||||
private final Set<Entity> entities = new HashSet<>();
|
private final HashSet<Entity> entities = new HashSet<>();
|
||||||
private final Set<REntity> rentities = new HashSet<>();
|
private final HashSet<REntity> rentities = new HashSet<>();
|
||||||
|
|
||||||
public Hull(FightTeam team) {
|
public Hull(FightTeam team) {
|
||||||
this.region = team.getSchemRegion();
|
this.region = team.getSchemRegion();
|
||||||
this.groundVisible = region.getMinY() != Config.PlayerRegion.getMinY();
|
this.groundVisible = region.getMinY() != Config.PlayerRegion.getMinY();
|
||||||
this.primaryDirection = new IntVector(0, 0, team.isBlue() == (Config.BlueToRedZ > 0) ? -1 : 1);
|
|
||||||
this.occluding = new BitSet(region.volume());
|
this.occluding = new BitSet(region.volume());
|
||||||
this.visibility = new BitSet(region.volume());
|
this.visibility = new BitSet(region.volume());
|
||||||
|
|
||||||
|
IntVector primaryDirection = new IntVector(0, 0, team.isBlue() == (Config.BlueToRedZ > 0) ? -1 : 1);
|
||||||
directions = IntStream.range(0, 27)
|
directions = IntStream.range(0, 27)
|
||||||
.mapToObj(v -> new IntVector(v%3 -1, (v/3)%3 -1, v/9 -1))
|
.mapToObj(v -> new IntVector(v%3 -1, (v/3)%3 -1, v/9 -1))
|
||||||
.filter(v -> v.sqLength() == 1 || v.x*primaryDirection.x + v.y*primaryDirection.y + v.z*primaryDirection.z >= 1) // Not pointing away from primary direction
|
.filter(v -> v.sqLength() == 1 || v.x*primaryDirection.x + v.y*primaryDirection.y + v.z*primaryDirection.z == 1) // Not pointing away from primary direction
|
||||||
.toArray(IntVector[]::new);
|
|
||||||
branchDirections = Arrays.stream(directions)
|
|
||||||
.filter(v -> v.sqLength() >= 2) // Diagonal
|
|
||||||
.toArray(IntVector[]::new);
|
.toArray(IntVector[]::new);
|
||||||
|
|
||||||
for(IntVector direction : directions)
|
for(IntVector direction : directions)
|
||||||
@@ -141,6 +138,7 @@ public class Hull {
|
|||||||
public void initialize() {
|
public void initialize() {
|
||||||
visibility.clear();
|
visibility.clear();
|
||||||
occluding.clear();
|
occluding.clear();
|
||||||
|
uncoveredSurface.clear();
|
||||||
for(BitSet directionalVisibility : visibilityDirections.values())
|
for(BitSet directionalVisibility : visibilityDirections.values())
|
||||||
directionalVisibility.clear();
|
directionalVisibility.clear();
|
||||||
|
|
||||||
@@ -150,7 +148,7 @@ public class Hull {
|
|||||||
if (isOccluding(Config.world.getBlockAt(x, y, z).getType()))
|
if (isOccluding(Config.world.getBlockAt(x, y, z).getType()))
|
||||||
occluding.set(block.toId(region));
|
occluding.set(block.toId(region));
|
||||||
});
|
});
|
||||||
forEachBorder((root, direction) -> updateBlocks(new NullList<>(), root, direction, visibilityDirections.get(direction)));
|
forEachBorder((root, direction) -> uncoverBlocks(new NullList<>(), root, direction));
|
||||||
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> "[HullHider] initialisation finished: " + (System.currentTimeMillis() - start) + " ms, visible blocks: " + visibility.cardinality());
|
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> "[HullHider] initialisation finished: " + (System.currentTimeMillis() - start) + " ms, visible blocks: " + visibility.cardinality());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,34 +169,11 @@ public class Hull {
|
|||||||
for(Map.Entry<IntVector, BitSet> directionalVisibility : visibilityDirections.entrySet()) {
|
for(Map.Entry<IntVector, BitSet> directionalVisibility : visibilityDirections.entrySet()) {
|
||||||
if(directionalVisibility.getValue().get(id)) {
|
if(directionalVisibility.getValue().get(id)) {
|
||||||
directionalVisibility.getValue().clear(id);
|
directionalVisibility.getValue().clear(id);
|
||||||
updateBlocks(uncovered, root, directionalVisibility.getKey(), directionalVisibility.getValue());
|
uncoverBlocks(uncovered, root, directionalVisibility.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uncovered.isEmpty())
|
uncoveredSurface.addAll(new HashSet<>(uncovered));
|
||||||
return;
|
|
||||||
|
|
||||||
Set<IntVector> uncoveredSet = new HashSet<>(uncovered);
|
|
||||||
Iterator<Entity> it = entities.iterator();
|
|
||||||
while(it.hasNext()) {
|
|
||||||
Entity entity = it.next();
|
|
||||||
if(uncoveredSet.contains(new IntVector(entity.getLocation()))) {
|
|
||||||
it.remove();
|
|
||||||
for(Player player : players)
|
|
||||||
BlockIdWrapper.impl.trackEntity(player, entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<REntity> rit = rentities.iterator();
|
|
||||||
while(rit.hasNext()) {
|
|
||||||
REntity entity = rit.next();
|
|
||||||
if(uncoveredSet.contains(new IntVector(new Location(Config.world, entity.getX(), entity.getY(), entity.getZ())))) {
|
|
||||||
rit.remove();
|
|
||||||
entity.hide(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uncoveredSurface.addAll(uncoveredSet);
|
|
||||||
uncoveredSurface.remove(root);
|
uncoveredSurface.remove(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +218,18 @@ public class Hull {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBlocks(List<IntVector> uncovered, IntVector block, IntVector direction, BitSet directionalVisibility) {
|
private void uncoverBlocks(List<IntVector> uncovered, IntVector block, IntVector direction) {
|
||||||
|
uncoverBlocks(
|
||||||
|
uncovered, block, direction, visibilityDirections.get(direction),
|
||||||
|
direction.sqLength() == 1
|
||||||
|
? Arrays.stream(directions)
|
||||||
|
.filter(v -> v.sqLength() >= 2 && v.x*direction.x + v.y*direction.y + v.z*direction.z == 1)
|
||||||
|
.toArray(IntVector[]::new)
|
||||||
|
: NO_BRANCHES
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uncoverBlocks(List<IntVector> uncovered, IntVector block, IntVector direction, BitSet directionalVisibility, IntVector[] branchDirections) {
|
||||||
if (block.notInRegion(region))
|
if (block.notInRegion(region))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -260,16 +246,9 @@ public class Hull {
|
|||||||
if (occluding.get(id))
|
if (occluding.get(id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
updateBlocks(uncovered, block.add(direction), direction, directionalVisibility);
|
uncoverBlocks(uncovered, block.add(direction), direction, directionalVisibility, branchDirections);
|
||||||
if(!direction.equals(primaryDirection))
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(IntVector branchDirection : branchDirections)
|
for(IntVector branchDirection : branchDirections)
|
||||||
updateBlocks(uncovered, block.add(branchDirection), branchDirection, visibilityDirections.get(branchDirection));
|
uncoverBlocks(uncovered, block.add(branchDirection), branchDirection, visibilityDirections.get(branchDirection), NO_BRANCHES);
|
||||||
}
|
|
||||||
|
|
||||||
private int directionId(IntVector v) {
|
|
||||||
return 1 << (9*(v.z+1) + 3*(v.y+1) + (v.x+1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user