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 {
|
||||
|
||||
private static final IntVector[] NO_BRANCHES = new IntVector[0];
|
||||
|
||||
private static boolean isOccluding(Material material) {
|
||||
return material.isOccluding() || Config.HiddenBlocks.contains(material);
|
||||
}
|
||||
|
||||
private final Region region;
|
||||
private final boolean groundVisible;
|
||||
private final IntVector primaryDirection;
|
||||
private final IntVector[] directions;
|
||||
private final IntVector[] branchDirections;
|
||||
|
||||
private final BitSet occluding;
|
||||
private final BitSet visibility;
|
||||
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 Set<Entity> entities = new HashSet<>();
|
||||
private final Set<REntity> rentities = new HashSet<>();
|
||||
private final HashSet<Entity> entities = new HashSet<>();
|
||||
private final HashSet<REntity> rentities = new HashSet<>();
|
||||
|
||||
public Hull(FightTeam team) {
|
||||
this.region = team.getSchemRegion();
|
||||
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.visibility = new BitSet(region.volume());
|
||||
|
||||
IntVector primaryDirection = new IntVector(0, 0, team.isBlue() == (Config.BlueToRedZ > 0) ? -1 : 1);
|
||||
directions = IntStream.range(0, 27)
|
||||
.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
|
||||
.toArray(IntVector[]::new);
|
||||
branchDirections = Arrays.stream(directions)
|
||||
.filter(v -> v.sqLength() >= 2) // Diagonal
|
||||
.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);
|
||||
|
||||
for(IntVector direction : directions)
|
||||
@@ -141,6 +138,7 @@ public class Hull {
|
||||
public void initialize() {
|
||||
visibility.clear();
|
||||
occluding.clear();
|
||||
uncoveredSurface.clear();
|
||||
for(BitSet directionalVisibility : visibilityDirections.values())
|
||||
directionalVisibility.clear();
|
||||
|
||||
@@ -150,7 +148,7 @@ public class Hull {
|
||||
if (isOccluding(Config.world.getBlockAt(x, y, z).getType()))
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -171,34 +169,11 @@ public class Hull {
|
||||
for(Map.Entry<IntVector, BitSet> directionalVisibility : visibilityDirections.entrySet()) {
|
||||
if(directionalVisibility.getValue().get(id)) {
|
||||
directionalVisibility.getValue().clear(id);
|
||||
updateBlocks(uncovered, root, directionalVisibility.getKey(), directionalVisibility.getValue());
|
||||
uncoverBlocks(uncovered, root, directionalVisibility.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
if(uncovered.isEmpty())
|
||||
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.addAll(new HashSet<>(uncovered));
|
||||
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))
|
||||
return;
|
||||
|
||||
@@ -260,16 +246,9 @@ public class Hull {
|
||||
if (occluding.get(id))
|
||||
return;
|
||||
|
||||
updateBlocks(uncovered, block.add(direction), direction, directionalVisibility);
|
||||
if(!direction.equals(primaryDirection))
|
||||
return;
|
||||
|
||||
uncoverBlocks(uncovered, block.add(direction), direction, directionalVisibility, branchDirections);
|
||||
for(IntVector branchDirection : branchDirections)
|
||||
updateBlocks(uncovered, block.add(branchDirection), branchDirection, visibilityDirections.get(branchDirection));
|
||||
}
|
||||
|
||||
private int directionId(IntVector v) {
|
||||
return 1 << (9*(v.z+1) + 3*(v.y+1) + (v.x+1));
|
||||
uncoverBlocks(uncovered, block.add(branchDirection), branchDirection, visibilityDirections.get(branchDirection), NO_BRANCHES);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user