From 10e016c850d72f7314d5cf6a728f8fdd4e701ff4 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 21 Dec 2024 10:52:41 +0100 Subject: [PATCH] Partial diagonal HullHider uncovering, performance improvement --- .../de/steamwar/fightsystem/utils/Hull.java | 71 +++++++------------ 1 file changed, 25 insertions(+), 46 deletions(-) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java index 531b133e..5c4bd32c 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/Hull.java @@ -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 visibilityDirections = new HashMap<>(); // Contains the visible directions of each occluding visible block - private final Set uncoveredSurface = new HashSet<>(); + private final HashSet uncoveredSurface = new HashSet<>(); private final HashSet players = new HashSet<>(); - private final Set entities = new HashSet<>(); - private final Set rentities = new HashSet<>(); + private final HashSet entities = new HashSet<>(); + private final HashSet 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 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 uncoveredSet = new HashSet<>(uncovered); - Iterator 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 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 uncovered, IntVector block, IntVector direction, BitSet directionalVisibility) { + private void uncoverBlocks(List 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 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); }