Merge pull request 'Partial diagonal HullHider uncovering, performance improvement' (#79) from FIghtSystem/partialSides into main

Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/79
Reviewed-by: YoyoNow <jwsteam@nidido.de>
This commit is contained in:
Lixfel
2024-12-21 11:21:45 +01:00
@@ -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);
}