]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/commitdiff
General performance improvements and serverside fixes
authorishland <ishlandmc@yeah.net>
Wed, 4 Aug 2021 16:04:54 +0000 (00:04 +0800)
committerirtimaled <irtimaled@gmail.com>
Sun, 15 Aug 2021 18:36:02 +0000 (11:36 -0700)
Adds early frustum culling to reduce sorting overhead
Added biome caching for better performance of biome borders and flower forest

29 files changed:
src/main/java/com/irtimaled/bbor/client/ClientRenderer.java
src/main/java/com/irtimaled/bbor/client/RenderCulling.java
src/main/java/com/irtimaled/bbor/client/config/ConfigManager.java
src/main/java/com/irtimaled/bbor/client/gui/IntSettingSlider.java
src/main/java/com/irtimaled/bbor/client/gui/SettingsScreen.java
src/main/java/com/irtimaled/bbor/client/interop/BiomeBorderHelper.java
src/main/java/com/irtimaled/bbor/client/interop/ClientInterop.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxBeacon.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxBedrockCeiling.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxBiomeBorder.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxConduit.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxFlowerForest.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxLine.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxMobSpawner.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxSlimeChunk.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxSpawnableBlocks.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxSpawningSphere.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxSphere.java
src/main/java/com/irtimaled/bbor/client/models/BoundingBoxWorldSpawn.java
src/main/java/com/irtimaled/bbor/client/renderers/AbstractRenderer.java
src/main/java/com/irtimaled/bbor/client/renderers/BiomeBorderRenderer.java
src/main/java/com/irtimaled/bbor/client/renderers/LineRenderer.java
src/main/java/com/irtimaled/bbor/client/renderers/MobSpawnerRenderer.java
src/main/java/com/irtimaled/bbor/client/renderers/OffsetPoint.java
src/main/java/com/irtimaled/bbor/client/renderers/RenderBatch.java
src/main/java/com/irtimaled/bbor/client/renderers/RenderHelper.java
src/main/java/com/irtimaled/bbor/common/models/AbstractBoundingBox.java
src/main/java/com/irtimaled/bbor/common/models/BoundingBoxCuboid.java
src/main/java/com/irtimaled/bbor/mixin/client/network/play/MixinClientPlayNetHandler.java

index 76af6f2b1765fc26c039c0534feda02fc05d77c0..554dcdc064f97d3ed2739751cb1e58d4494d19f7 100644 (file)
@@ -25,7 +25,10 @@ import com.irtimaled.bbor.common.MathHelper;
 import com.irtimaled.bbor.common.TypeHelper;
 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
 import com.irtimaled.bbor.common.models.DimensionId;
+import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
 import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.client.util.math.MatrixStack;
 
 import java.util.ArrayList;
@@ -36,10 +39,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Supplier;
 
 public class ClientRenderer {
     private static final int CHUNK_SIZE = 16;
-    private static final Map<Class<? extends AbstractBoundingBox>, AbstractRenderer> boundingBoxRendererMap = new Object2ObjectOpenHashMap<>();
+    private static final Map<Class<? extends AbstractBoundingBox>, AbstractRenderer> boundingBoxRendererMap = Object2ObjectMaps.synchronize(new Object2ObjectOpenHashMap<>());
 
     private static boolean active;
     private static final Set<IBoundingBoxProvider> providers = new HashSet<>();
@@ -62,38 +66,33 @@ public class ClientRenderer {
     }
 
     static {
-
-
-
-
-
-
-
-
-
-        registerProvider(new SlimeChunkProvider());
-        registerProvider(new WorldSpawnProvider());
-        registerProvider(new SpawningSphereProvider());
-        registerProvider(new BeaconProvider());
-        registerProvider(new CustomBoxProvider());
-        registerProvider(new CustomBeaconProvider());
-        registerProvider(new BiomeBorderProvider());
-        registerProvider(new MobSpawnerProvider());
-        registerProvider(new ConduitProvider());
-        registerProvider(new SpawnableBlocksProvider());
-        registerProvider(new CustomLineProvider());
-        registerProvider(new CustomSphereProvider());
-        registerProvider(new FlowerForestProvider());
-        registerProvider(new BedrockCeilingProvider());
+        if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
+            registerProvider(new SlimeChunkProvider());
+            registerProvider(new WorldSpawnProvider());
+            registerProvider(new SpawningSphereProvider());
+            registerProvider(new BeaconProvider());
+            registerProvider(new CustomBoxProvider());
+            registerProvider(new CustomBeaconProvider());
+            registerProvider(new BiomeBorderProvider());
+            registerProvider(new MobSpawnerProvider());
+            registerProvider(new ConduitProvider());
+            registerProvider(new SpawnableBlocksProvider());
+            registerProvider(new CustomLineProvider());
+            registerProvider(new CustomSphereProvider());
+            registerProvider(new FlowerForestProvider());
+            registerProvider(new BedrockCeilingProvider());
+        }
     }
 
     public static <T extends AbstractBoundingBox> void registerProvider(IBoundingBoxProvider<T> provider) {
         providers.add(provider);
     }
 
-    public static <T extends AbstractBoundingBox> AbstractRenderer<T> registerRenderer(Class<? extends T> type, AbstractRenderer<T> renderer) {
-        boundingBoxRendererMap.put(type, renderer);
-        return renderer;
+    public static <T extends AbstractBoundingBox> AbstractRenderer<T> registerRenderer(Class<? extends T> type, Supplier<AbstractRenderer<T>> renderer) {
+        if (FabricLoader.getInstance().getEnvironmentType() != EnvType.CLIENT) return null;
+        final AbstractRenderer<T> renderer1 = renderer.get();
+        boundingBoxRendererMap.put(type, renderer1);
+        return renderer1;
     }
 
     public static AbstractRenderer getRenderer(Class<? extends AbstractBoundingBox> clazz) {
@@ -117,10 +116,10 @@ public class ClientRenderer {
         matrixStack.push();
         RenderHelper.beforeRender();
 
-        getBoundingBoxes(dimensionId).forEach(key -> {
+        for (AbstractBoundingBox key : getBoundingBoxes(dimensionId)) {
             AbstractRenderer renderer = key.getRenderer();
             if (renderer != null) renderer.render(matrixStack, key);
-        });
+        }
 
         RenderQueue.renderDeferred();
 
@@ -134,7 +133,7 @@ public class ClientRenderer {
         for (IBoundingBoxProvider<?> provider : providers) {
             if (provider.canProvide(dimensionId)) {
                 for (AbstractBoundingBox boundingBox : provider.get(dimensionId)) {
-                    if (isWithinRenderDistance(boundingBox)) {
+                    if (boundingBox.isVisibleCulling() && isWithinRenderDistance(boundingBox)) {
                         tmp.add(boundingBox);
                     }
                 }
index c76a9239cb11610fca87fd78612510c8d2afac71..4a31ecba5eb5d515a2689516a4d6250501951079 100644 (file)
@@ -50,8 +50,8 @@ public class RenderCulling {
         }
     }
 
-    public static boolean cullRayTrace(Box box) {
-        return true;
+    public static boolean isVisibleCulling(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
+        return isVisibleCulling(new Box(minX, minY, minZ, maxX, maxY, maxZ));
     }
 
     public static boolean isVisibleCulling(Box box) {
index a15959c9718b9cae17ad6f25b0969628f7232dba..ceeda1200de481a575b9e19ce920151d9d64065b 100644 (file)
@@ -9,7 +9,6 @@ public class ConfigManager {
     private static File configDir;
 
     public static Setting<Boolean> fill;
-    public static Setting<Integer> lineWidthModifier;
     public static Setting<Boolean> drawVillages;
     public static Setting<Boolean> drawDesertTemples;
     public static Setting<Boolean> drawJungleTemples;
@@ -118,7 +117,6 @@ public class ConfigManager {
         invertBoxColorPlayerInside = setup(config, "general", "invertBoxColorPlayerInside", false, "If set to true the color of any bounding box the player is inside will be inverted.");
         renderSphereAsDots = setup(config, "general", "renderSphereAsDots", false, "If set to true spheres will be rendered as dots.");
         buttonOnOverlay = setup(config, "general", "buttonEnabledOverlay", HexColor.from("#3000ff00"), "The color and alpha of the button overlay when a button is on.");
-        lineWidthModifier = setup(config, "general", "lineWidthModifier", 1, "");
 
         drawBeacons = setup(config, "beacons", "drawBeacons", true, "If set to true beacon bounding boxes will be drawn.");
 
index fb643d0d3ebaa323531b4215a794f643389ab1bf..a681e6d2e8cf1ac5bd9315751b2b77fdf4da6919 100644 (file)
@@ -1,7 +1,5 @@
 package com.irtimaled.bbor.client.gui;
 
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
 import com.irtimaled.bbor.client.config.Setting;
 import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
 import net.minecraft.client.resource.language.I18n;
@@ -9,7 +7,6 @@ import net.minecraft.text.LiteralText;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.stream.IntStream;
 
 class IntSettingSlider extends AbstractSlider {
     private final String format;
@@ -39,17 +36,6 @@ class IntSettingSlider extends AbstractSlider {
         return this;
     }
 
-    IntSettingSlider addDisplayValueRange(int start, int end) {
-        return addDisplayValueRange(start, end, String::valueOf);
-    }
-
-    IntSettingSlider addDisplayValueRange(int start, int end, Function<Integer, String> formatter) {
-        Preconditions.checkArgument(start <= end);
-        Preconditions.checkNotNull(formatter);
-        IntStream.range(start, end).forEach(value -> addDisplayValue(value, formatter.apply(value)));
-        return this;
-    }
-
     protected Integer getSettingValue() {
         return minValue + getPosition();
     }
index 73f28353de5732d45be4c2ef971e7b08300e431f..49e5e6828b228e00d9c2db2298113929bc1d851a 100644 (file)
@@ -53,9 +53,7 @@ public class SettingsScreen extends ListScreen {
                             }
                         },
                         width -> new BoolSettingButton(width, I18n.translate("bbor.options.outerBoxOnly"), ConfigManager.outerBoxesOnly),
-                        width -> new BoolSettingButton(width, I18n.translate("bbor.options.fill"), ConfigManager.fill),
-                        width -> new IntSettingSlider(width, 1, 25, I18n.translate("bbor.options.lineWidthModifier"), ConfigManager.lineWidthModifier)
-                                .addDisplayValueRange(1, 25))
+                        width -> new BoolSettingButton(width, I18n.translate("bbor.options.fill"), ConfigManager.fill))
                 .section(I18n.translate("bbor.features.spawnChunks"),
                         width -> new BoundingBoxTypeButton(width, I18n.translate("bbor.features.spawnChunks"), BoundingBoxType.WorldSpawn),
                         width -> new BoundingBoxTypeButton(width, I18n.translate("bbor.features.lazyChunks"), BoundingBoxType.LazySpawnChunks),
index 0da62167fa211ffd6d92174f7913fed22a3fc003..7cde22bbdc79702abb253550d9d21fa003cfd79f 100644 (file)
@@ -1,21 +1,47 @@
 package com.irtimaled.bbor.client.interop;
 
 import com.irtimaled.bbor.common.models.Coords;
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.world.ClientWorld;
 import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.ChunkPos;
 import net.minecraft.util.registry.Registry;
 import net.minecraft.world.biome.Biome;
+import net.minecraft.world.biome.source.BiomeArray;
+import net.minecraft.world.biome.source.BiomeCoords;
+import net.minecraft.world.chunk.WorldChunk;
 
 public class BiomeBorderHelper {
+
+    private static final Long2ObjectOpenHashMap<BiomeArray> biomeCache = new Long2ObjectOpenHashMap<>();
+
+    public static void onChunkLoaded(int chunkX, int chunkZ) {
+        assert MinecraftClient.getInstance().world != null;
+        final WorldChunk chunk = MinecraftClient.getInstance().world.getChunk(chunkX, chunkZ);
+        if (chunk == null) return;
+        biomeCache.put(ChunkPos.toLong(chunkX, chunkZ), chunk.getBiomeArray());
+    }
+
+    public static void onChunkUnload(int chunkX, int chunkZ) {
+        biomeCache.remove(ChunkPos.toLong(chunkX, chunkZ));
+    }
+
     public static int getBiomeId(Coords coords) {
         return getBiomeId(coords.getX(), coords.getY(), coords.getZ());
     }
 
     public static int getBiomeId(int x, int y, int z) {
         BlockPos pos = new BlockPos(x, y, z);
-        ClientWorld world = MinecraftClient.getInstance().world;
-        Biome biome = world.getBiome(pos);
+        final BiomeArray biomeArray = biomeCache.get(ChunkPos.toLong(pos));
+        final ClientWorld world = MinecraftClient.getInstance().world;
+        final Biome biome;
+        if (biomeArray != null) {
+            biome = biomeArray.getBiomeForNoiseGen(BiomeCoords.fromBlock(x & 15), y, BiomeCoords.fromBlock(z & 15));
+        } else {
+            assert world != null;
+            biome = world.getBiome(pos);
+        }
         return world.getRegistryManager().get(Registry.BIOME_KEY).getRawId(biome);
     }
 }
index 9d91ad8a7347ccaffb38a516415ae8bb8f1d07ab..e0cee81baaf1f87c087cad0f1b2b03ce2d692916 100644 (file)
@@ -107,6 +107,11 @@ public class ClientInterop {
 
     public static void receivedChunk(int chunkX, int chunkZ) {
         SaveGameStructureLoader.loadStructures(chunkX, chunkZ);
+        BiomeBorderHelper.onChunkLoaded(chunkX, chunkZ);
+    }
+
+    public static void unloadChunk(int chunkX, int chunkZ) {
+        BiomeBorderHelper.onChunkUnload(chunkX, chunkZ);
     }
 
     public static void saveLoaded(String fileName, long seed) {
index 7e4575f57a0f77b7948d96e1c5f4bd69e693ff96..14b4973c2ca49c02a58d2f46433e53eb06b7ae1d 100644 (file)
@@ -8,7 +8,7 @@ import com.irtimaled.bbor.common.models.BoundingBoxCuboid;
 import com.irtimaled.bbor.common.models.Coords;
 
 public class BoundingBoxBeacon extends BoundingBoxCuboid {
-    private static final AbstractRenderer<BoundingBoxBeacon> RENDERER = ClientRenderer.registerRenderer(BoundingBoxBeacon.class, new BeaconRenderer());
+    private static final AbstractRenderer<BoundingBoxBeacon> RENDERER = ClientRenderer.registerRenderer(BoundingBoxBeacon.class, () -> new BeaconRenderer());
 
     private final Coords coords;
     private final int level;
index 62e0ddd858d036cfc13d06f0fc74e201ae981c2a..354b0862aef736b9ca802a1a98e7e5c891b6c0b7 100644 (file)
@@ -8,7 +8,7 @@ import com.irtimaled.bbor.common.models.BoundingBoxCuboid;
 import com.irtimaled.bbor.common.models.Coords;
 
 public class BoundingBoxBedrockCeiling extends BoundingBoxCuboid {
-    private static final AbstractRenderer<BoundingBoxCuboid> RENDERER = ClientRenderer.registerRenderer(BoundingBoxBedrockCeiling.class, new CuboidRenderer());
+    private static final AbstractRenderer<BoundingBoxCuboid> RENDERER = ClientRenderer.registerRenderer(BoundingBoxBedrockCeiling.class, () -> new CuboidRenderer());
 
     public BoundingBoxBedrockCeiling(Coords coords) {
         super(coords, coords, BoundingBoxType.BedrockCeiling);
index e7b4481c9c9225a18f553d6d258915602c73f5f4..daf6b1ccf033ea776770ba29324ba50f8103b116 100644 (file)
@@ -1,6 +1,7 @@
 package com.irtimaled.bbor.client.models;
 
 import com.irtimaled.bbor.client.ClientRenderer;
+import com.irtimaled.bbor.client.RenderCulling;
 import com.irtimaled.bbor.client.renderers.AbstractRenderer;
 import com.irtimaled.bbor.client.renderers.BiomeBorderRenderer;
 import com.irtimaled.bbor.common.BoundingBoxType;
@@ -8,7 +9,7 @@ import com.irtimaled.bbor.common.models.AbstractBoundingBox;
 import com.irtimaled.bbor.common.models.Coords;
 
 public class BoundingBoxBiomeBorder extends AbstractBoundingBox {
-    private static final AbstractRenderer<BoundingBoxBiomeBorder> RENDERER = ClientRenderer.registerRenderer(BoundingBoxBiomeBorder.class, new BiomeBorderRenderer());
+    private static final AbstractRenderer<BoundingBoxBiomeBorder> RENDERER = ClientRenderer.registerRenderer(BoundingBoxBiomeBorder.class, () -> new BiomeBorderRenderer());
 
     private final Coords coords;
     private final boolean north;
@@ -72,4 +73,9 @@ public class BoundingBoxBiomeBorder extends AbstractBoundingBox {
     public AbstractRenderer<?> getRenderer() {
         return RENDERER;
     }
+
+    @Override
+    public boolean isVisibleCulling() {
+        return RenderCulling.isVisibleCulling(coords.getX(), coords.getY(), coords.getZ(), coords.getX() + 1, coords.getY() + 1, coords.getZ() + 1);
+    }
 }
index bdbf3c61b91dcdf1f50e2bf4937f6076bad88f26..3741808fcf5e51f68e1ffc569b4dcb01db1b930b 100644 (file)
@@ -8,7 +8,7 @@ import com.irtimaled.bbor.common.TypeHelper;
 import com.irtimaled.bbor.common.models.Coords;
 
 public class BoundingBoxConduit extends BoundingBoxSphere {
-    private static final AbstractRenderer<BoundingBoxConduit> RENDERER = ClientRenderer.registerRenderer(BoundingBoxConduit.class, new ConduitRenderer());
+    private static final AbstractRenderer<BoundingBoxConduit> RENDERER = ClientRenderer.registerRenderer(BoundingBoxConduit.class, () -> new ConduitRenderer());
 
     private final int level;
 
index e13e386b94b46fa6593ea8d63da8cb588da96ac1..23439b87156e9bbfceda604e626da52f5a7458c2 100644 (file)
@@ -1,6 +1,7 @@
 package com.irtimaled.bbor.client.models;
 
 import com.irtimaled.bbor.client.ClientRenderer;
+import com.irtimaled.bbor.client.RenderCulling;
 import com.irtimaled.bbor.client.config.ColorHelper;
 import com.irtimaled.bbor.client.config.HexColor;
 import com.irtimaled.bbor.client.config.Setting;
@@ -13,7 +14,7 @@ import com.irtimaled.bbor.common.models.Coords;
 import java.awt.*;
 
 public class BoundingBoxFlowerForest extends AbstractBoundingBox {
-    private static final AbstractRenderer<BoundingBoxFlowerForest> RENDERER = ClientRenderer.registerRenderer(BoundingBoxFlowerForest.class, new FlowerForestRenderer());
+    private static final AbstractRenderer<BoundingBoxFlowerForest> RENDERER = ClientRenderer.registerRenderer(BoundingBoxFlowerForest.class, () -> new FlowerForestRenderer());
 
     private final Coords coords;
     private final Setting<HexColor> colorSetting;
@@ -56,4 +57,9 @@ public class BoundingBoxFlowerForest extends AbstractBoundingBox {
     public AbstractRenderer<?> getRenderer() {
         return RENDERER;
     }
+
+    @Override
+    public boolean isVisibleCulling() {
+        return RenderCulling.isVisibleCulling(coords.getX(), coords.getY() + 0.01d, coords.getZ(), coords.getX() + 1, coords.getY(), coords.getZ());
+    }
 }
index 26ba5b77c197a33192a7af76b6fd07b69320a142..39e487ed0ad7f7370d6fd4a496f57a3755b44d5d 100644 (file)
@@ -1,6 +1,7 @@
 package com.irtimaled.bbor.client.models;
 
 import com.irtimaled.bbor.client.ClientRenderer;
+import com.irtimaled.bbor.client.RenderCulling;
 import com.irtimaled.bbor.client.renderers.AbstractRenderer;
 import com.irtimaled.bbor.client.renderers.LineRenderer;
 import com.irtimaled.bbor.common.BoundingBoxType;
@@ -9,7 +10,7 @@ import com.irtimaled.bbor.common.TypeHelper;
 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
 
 public class BoundingBoxLine extends AbstractBoundingBox {
-    private static final AbstractRenderer<BoundingBoxLine> RENDERER = ClientRenderer.registerRenderer(BoundingBoxLine.class, new LineRenderer());
+    private static final AbstractRenderer<BoundingBoxLine> RENDERER = ClientRenderer.registerRenderer(BoundingBoxLine.class, () -> new LineRenderer());
 
     private final Point minPoint;
     private final Point maxPoint;
@@ -118,4 +119,9 @@ public class BoundingBoxLine extends AbstractBoundingBox {
     public AbstractRenderer<?> getRenderer() {
         return RENDERER;
     }
+
+    @Override
+    public boolean isVisibleCulling() {
+        return RenderCulling.isVisibleCulling(minPoint.getX(), minPoint.getY(), minPoint.getZ(), maxPoint.getX(), maxPoint.getY(), maxPoint.getZ()); // TODO better culling
+    }
 }
index 71e919e93292f8ab30699a191e81677dd82b0c97..d7573f29bd94b91b14e3324aa833256117b41fab 100644 (file)
@@ -8,7 +8,7 @@ import com.irtimaled.bbor.common.models.BoundingBoxCuboid;
 import com.irtimaled.bbor.common.models.Coords;
 
 public class BoundingBoxMobSpawner extends BoundingBoxCuboid {
-    private static final AbstractRenderer<BoundingBoxMobSpawner> RENDERER = ClientRenderer.registerRenderer(BoundingBoxMobSpawner.class, new MobSpawnerRenderer());
+    private static final AbstractRenderer<BoundingBoxMobSpawner> RENDERER = ClientRenderer.registerRenderer(BoundingBoxMobSpawner.class, () -> new MobSpawnerRenderer());
 
     private final Coords coords;
 
index cd7470bf925a7fedefc627589652cc75ccfe7801..8c31514ee347105c0c0a89652b1411babc7f1e25 100644 (file)
@@ -11,7 +11,7 @@ import com.irtimaled.bbor.common.models.BoundingBoxCuboid;
 import com.irtimaled.bbor.common.models.Coords;
 
 public class BoundingBoxSlimeChunk extends BoundingBoxCuboid {
-    private static final AbstractRenderer<BoundingBoxSlimeChunk> RENDERER = ClientRenderer.registerRenderer(BoundingBoxSlimeChunk.class, new SlimeChunkRenderer());
+    private static final AbstractRenderer<BoundingBoxSlimeChunk> RENDERER = ClientRenderer.registerRenderer(BoundingBoxSlimeChunk.class, () -> new SlimeChunkRenderer());
 
     public BoundingBoxSlimeChunk(Coords minCoords, Coords maxCoords) {
         super(minCoords, maxCoords, BoundingBoxType.SlimeChunks);
index 797481fa77a29f1ef548c4dad12370d2ecd2d022..4976744fdc77dd76ab92c3da02a3b18ba349b609 100644 (file)
@@ -11,7 +11,7 @@ import java.util.HashSet;
 import java.util.Set;
 
 public class BoundingBoxSpawnableBlocks extends AbstractBoundingBox {
-    private static final AbstractRenderer<BoundingBoxSpawnableBlocks> RENDERER = ClientRenderer.registerRenderer(BoundingBoxSpawnableBlocks.class, new SpawnableBlocksRenderer());
+    private static final AbstractRenderer<BoundingBoxSpawnableBlocks> RENDERER = ClientRenderer.registerRenderer(BoundingBoxSpawnableBlocks.class, () -> new SpawnableBlocksRenderer());
 
     private final Set<BlockPos> blocks = new HashSet<>();
 
index 47a2e3aea4cd29140b920321731ca98ddb807a28..396a5c4d129382dc97587ee6e76a48737bcfe108 100644 (file)
@@ -10,7 +10,7 @@ import java.util.HashSet;
 import java.util.Set;
 
 public class BoundingBoxSpawningSphere extends BoundingBoxSphere {
-    private static final AbstractRenderer<BoundingBoxSpawningSphere> RENDERER = ClientRenderer.registerRenderer(BoundingBoxSpawningSphere.class, new SpawningSphereRenderer());
+    private static final AbstractRenderer<BoundingBoxSpawningSphere> RENDERER = ClientRenderer.registerRenderer(BoundingBoxSpawningSphere.class, () -> new SpawningSphereRenderer());
 
     public static final int SAFE_RADIUS = 24;
     public static final int SPAWN_RADIUS = 128;
index 8b4b9b5afbb3bd2818d398d00a15df7d97a59502..9198bacf0ea2f9cf523082a2b6053b56e04a03ed 100644 (file)
@@ -8,7 +8,7 @@ import com.irtimaled.bbor.common.models.AbstractBoundingBox;
 import com.irtimaled.bbor.common.models.Coords;
 
 public class BoundingBoxSphere extends AbstractBoundingBox {
-    private static final AbstractRenderer<BoundingBoxSphere> RENDERER = ClientRenderer.registerRenderer(BoundingBoxSphere.class, new SphereRenderer());
+    private static final AbstractRenderer<BoundingBoxSphere> RENDERER = ClientRenderer.registerRenderer(BoundingBoxSphere.class, () -> new SphereRenderer());
 
     private final double radius;
     private final double minX;
@@ -59,4 +59,9 @@ public class BoundingBoxSphere extends AbstractBoundingBox {
     public Point getPoint() {
         return point;
     }
+
+    @Override
+    public AbstractRenderer<?> getRenderer() {
+        return RENDERER;
+    }
 }
index 89de627a050e33112ee58ed34e0768b26c8aed80..22afcf5b2356800a26ddc183276e8e4382c4c6c6 100644 (file)
@@ -8,7 +8,7 @@ import com.irtimaled.bbor.common.models.BoundingBoxCuboid;
 import com.irtimaled.bbor.common.models.Coords;
 
 public class BoundingBoxWorldSpawn extends BoundingBoxCuboid {
-    private static final AbstractRenderer<BoundingBoxWorldSpawn> RENDERER = ClientRenderer.registerRenderer(BoundingBoxWorldSpawn.class, new WorldSpawnRenderer());
+    private static final AbstractRenderer<BoundingBoxWorldSpawn> RENDERER = ClientRenderer.registerRenderer(BoundingBoxWorldSpawn.class, () -> new WorldSpawnRenderer());
 
     public BoundingBoxWorldSpawn(Coords minCoords, Coords maxCoords, BoundingBoxType type) {
         super(minCoords, maxCoords, type);
index 7a7a46436131d940f6ba95b214d74ce1e4c45600..8074e493a89043bd01823d5a9564cd28742292af 100644 (file)
@@ -57,24 +57,24 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
                 (float) (maxZ - minZ));
 
         if (fillOnly || ConfigManager.fill.get()) {
-            RenderBatch.drawSolidBox(stack.peek(), ORIGIN_BOX, color, fillAlpha, mask);
+            RenderBatch.drawSolidBox(stack.peek(), ORIGIN_BOX, color, fillAlpha, mask, minX == maxX, minY == maxY, minZ == maxZ);
         }
         if (!fillOnly) {
             stack.push();
             stack.peek().getModel().load(lastStack.getModel());
             stack.peek().getNormal().load(lastStack.getNormal());
-            renderLine(stack, new OffsetPoint(minX, minY, minZ), new OffsetPoint(maxX, minY, minZ), color);
-            renderLine(stack, new OffsetPoint(maxX, minY, minZ), new OffsetPoint(maxX, minY, maxZ), color);
-            renderLine(stack, new OffsetPoint(maxX, minY, maxZ), new OffsetPoint(minX, minY, maxZ), color);
-            renderLine(stack, new OffsetPoint(minX, minY, maxZ), new OffsetPoint(minX, minY, minZ), color);
-            renderLine(stack, new OffsetPoint(minX, minY, minZ), new OffsetPoint(minX, maxY, minZ), color);
-            renderLine(stack, new OffsetPoint(maxX, minY, minZ), new OffsetPoint(maxX, maxY, minZ), color);
-            renderLine(stack, new OffsetPoint(maxX, minY, maxZ), new OffsetPoint(maxX, maxY, maxZ), color);
-            renderLine(stack, new OffsetPoint(minX, minY, maxZ), new OffsetPoint(minX, maxY, maxZ), color);
-            renderLine(stack, new OffsetPoint(minX, maxY, minZ), new OffsetPoint(maxX, maxY, minZ), color);
-            renderLine(stack, new OffsetPoint(maxX, maxY, minZ), new OffsetPoint(maxX, maxY, maxZ), color);
-            renderLine(stack, new OffsetPoint(maxX, maxY, maxZ), new OffsetPoint(minX, maxY, maxZ), color);
-            renderLine(stack, new OffsetPoint(minX, maxY, maxZ), new OffsetPoint(minX, maxY, minZ), color);
+            renderLine(stack, new OffsetPoint(minX, minY, minZ), new OffsetPoint(maxX, minY, minZ), color, true);
+            renderLine(stack, new OffsetPoint(maxX, minY, minZ), new OffsetPoint(maxX, minY, maxZ), color, true);
+            renderLine(stack, new OffsetPoint(maxX, minY, maxZ), new OffsetPoint(minX, minY, maxZ), color, true);
+            renderLine(stack, new OffsetPoint(minX, minY, maxZ), new OffsetPoint(minX, minY, minZ), color, true);
+            renderLine(stack, new OffsetPoint(minX, minY, minZ), new OffsetPoint(minX, maxY, minZ), color, true);
+            renderLine(stack, new OffsetPoint(maxX, minY, minZ), new OffsetPoint(maxX, maxY, minZ), color, true);
+            renderLine(stack, new OffsetPoint(maxX, minY, maxZ), new OffsetPoint(maxX, maxY, maxZ), color, true);
+            renderLine(stack, new OffsetPoint(minX, minY, maxZ), new OffsetPoint(minX, maxY, maxZ), color, true);
+            renderLine(stack, new OffsetPoint(minX, maxY, minZ), new OffsetPoint(maxX, maxY, minZ), color, true);
+            renderLine(stack, new OffsetPoint(maxX, maxY, minZ), new OffsetPoint(maxX, maxY, maxZ), color, true);
+            renderLine(stack, new OffsetPoint(maxX, maxY, maxZ), new OffsetPoint(minX, maxY, maxZ), color, true);
+            renderLine(stack, new OffsetPoint(minX, maxY, maxZ), new OffsetPoint(minX, maxY, minZ), color, true);
             stack.pop();
         }
 
@@ -88,7 +88,7 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
     }
 
 
-    void renderLine(MatrixStack matrixStack, OffsetPoint startPoint, OffsetPoint endPoint, Color color) {
+    void renderLine(MatrixStack matrixStack, OffsetPoint startPoint, OffsetPoint endPoint, Color color, boolean cullIfEmpty) {
 //        if ((startPoint.getY() == endPoint.getY() && startPoint.getZ() == endPoint.getZ()) ||
 //                (startPoint.getX() == endPoint.getX() && startPoint.getZ() == endPoint.getZ()) ||
 //                (startPoint.getX() == endPoint.getX() && startPoint.getY() == endPoint.getY())) {
@@ -96,6 +96,7 @@ public abstract class AbstractRenderer<T extends AbstractBoundingBox> {
 //            return;
 //        }
 
+        if (cullIfEmpty && startPoint.equals(endPoint)) return;
         if (!RenderCulling.isVisibleCulling(new OffsetBox(startPoint, endPoint).toBox())) return; // TODO better culling
 
         matrixStack.push();
index fc50eab8b58d3f61f160ee1319302c14ceda58ac..c82cd0952cdff651ac82d81e72536026a8eb9f8a 100644 (file)
@@ -46,11 +46,11 @@ public class BiomeBorderRenderer extends AbstractRenderer<BoundingBoxBiomeBorder
         topCorner1 = topCorner1.offset(xOffset, 0, zOffset);
         topCorner2 = topCorner2.offset(xOffset, 0, zOffset);
 
-        renderLine(matrixStack, topCorner1, topCorner2, color);
+        renderLine(matrixStack, topCorner1, topCorner2, color, false);
         OffsetPoint bottomCorner2 = topCorner2.offset(0, 1, 0);
         renderCuboid(matrixStack, new OffsetBox(topCorner1, bottomCorner2), color, true, 30);
         OffsetPoint bottomCorner1 = topCorner1.offset(0, 1, 0);
-        renderLine(matrixStack, bottomCorner1, bottomCorner2, color);
+        renderLine(matrixStack, bottomCorner1, bottomCorner2, color, false);
     }
 
     private double getOffset(double value) {
index 2e3cdd1f697da3db0d9428fcb2d580e6b93ef2a8..06c4270315542be098999c0f2b87e183fbe4726f 100644 (file)
@@ -16,7 +16,7 @@ public class LineRenderer extends AbstractRenderer<BoundingBoxLine> {
         if (boundingBox.getWidth() == 0) {
             OffsetPoint startPoint = new OffsetPoint(boundingBox.getMinPoint()).offset(0, 0.001f, 0);
             OffsetPoint endPoint = new OffsetPoint(boundingBox.getMaxPoint()).offset(0, 0.001f, 0);
-            renderLine(matrixStack, startPoint, endPoint, color);
+            renderLine(matrixStack, startPoint, endPoint, color, false);
             return;
         }
 
index 7d4784c36ce6cfd99276c4e27850a5c838afcf04..81e1df8ea1a75cd3bf0b506c74e91735b8abd0e9 100644 (file)
@@ -34,7 +34,7 @@ public class MobSpawnerRenderer extends AbstractRenderer<BoundingBoxMobSpawner>
         if (distance <= 20) {
 
             OffsetPoint playerPoint = playerPos.offset(0, 0.1, 0);
-            renderLine(matrixStack, centerPoint, playerPoint, getColor(distance));
+            renderLine(matrixStack, centerPoint, playerPoint, getColor(distance), false);
         }
     }
 
index 2b8675b42de5ab18c78a3c999a13a7855936876d..cb7ffda63c530d341513ffe40e639728c6a69013 100644 (file)
@@ -3,6 +3,8 @@ package com.irtimaled.bbor.client.renderers;
 import com.irtimaled.bbor.client.models.Point;
 import com.irtimaled.bbor.common.models.Coords;
 
+import java.util.Objects;
+
 class OffsetPoint {
     private final Point point;
 
@@ -41,4 +43,17 @@ class OffsetPoint {
     Point getPoint() {
         return point;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        OffsetPoint that = (OffsetPoint) o;
+        return point.equals(that.point);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(point);
+    }
 }
index c2dfa8cfc34c4f570e19ed7dcdb81a0129551669..016b45747277c812d6dc62bf8aa1da8f2c0f922f 100644 (file)
@@ -36,7 +36,7 @@ public class RenderBatch {
         lineBufferBuilder.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR);
     }
 
-    public static void drawSolidBox(MatrixStack.Entry matrixEntry, Box box, Color color, int alpha, boolean mask) {
+    public static void drawSolidBox(MatrixStack.Entry matrixEntry, Box box, Color color, int alpha, boolean mask, boolean sameX, boolean sameY, boolean sameZ) {
         final float minX = (float) box.minX;
         final float minY = (float) box.minY;
         final float minZ = (float) box.minZ;
@@ -49,58 +49,55 @@ public class RenderBatch {
 
         final BufferBuilder bufferBuilder = mask ? RenderBatch.quadBufferBuilderMasked : RenderBatch.quadBufferBuilderNonMasked;
 
-        if (minX != maxX && minZ != maxZ) {
+        if (!sameX && !sameZ) {
             if (mask) quadMaskedCount.getAndIncrement();
             else quadNonMaskedCount.getAndIncrement();
             bufferBuilder.vertex(matrixEntry.getModel(), minX, minY, minZ).color(red, green, blue, alpha).next();
             bufferBuilder.vertex(matrixEntry.getModel(), maxX, minY, minZ).color(red, green, blue, alpha).next();
             bufferBuilder.vertex(matrixEntry.getModel(), maxX, minY, maxZ).color(red, green, blue, alpha).next();
             bufferBuilder.vertex(matrixEntry.getModel(), minX, minY, maxZ).color(red, green, blue, alpha).next();
+            if (!sameY) {
+                if (mask) quadMaskedCount.getAndIncrement();
+                else quadNonMaskedCount.getAndIncrement();
+                bufferBuilder.vertex(matrixEntry.getModel(), minX, maxY, minZ).color(red, green, blue, alpha).next();
+                bufferBuilder.vertex(matrixEntry.getModel(), minX, maxY, maxZ).color(red, green, blue, alpha).next();
+                bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, maxZ).color(red, green, blue, alpha).next();
+                bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, minZ).color(red, green, blue, alpha).next();
+            }
         }
 
-        if (minX != maxX && minZ != maxZ) {
-            if (mask) quadMaskedCount.getAndIncrement();
-            else quadNonMaskedCount.getAndIncrement();
-            bufferBuilder.vertex(matrixEntry.getModel(), minX, maxY, minZ).color(red, green, blue, alpha).next();
-            bufferBuilder.vertex(matrixEntry.getModel(), minX, maxY, maxZ).color(red, green, blue, alpha).next();
-            bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, maxZ).color(red, green, blue, alpha).next();
-            bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, minZ).color(red, green, blue, alpha).next();
-        }
-
-        if (minX != maxX && minY != maxY) {
+        if (!sameX && !sameY) {
             if (mask) quadMaskedCount.getAndIncrement();
             else quadNonMaskedCount.getAndIncrement();
             bufferBuilder.vertex(matrixEntry.getModel(), minX, minY, minZ).color(red, green, blue, alpha).next();
             bufferBuilder.vertex(matrixEntry.getModel(), minX, maxY, minZ).color(red, green, blue, alpha).next();
             bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, minZ).color(red, green, blue, alpha).next();
             bufferBuilder.vertex(matrixEntry.getModel(), maxX, minY, minZ).color(red, green, blue, alpha).next();
+            if (!sameZ) {
+                if (mask) quadMaskedCount.getAndIncrement();
+                else quadNonMaskedCount.getAndIncrement();
+                bufferBuilder.vertex(matrixEntry.getModel(), minX, minY, maxZ).color(red, green, blue, alpha).next();
+                bufferBuilder.vertex(matrixEntry.getModel(), maxX, minY, maxZ).color(red, green, blue, alpha).next();
+                bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, maxZ).color(red, green, blue, alpha).next();
+                bufferBuilder.vertex(matrixEntry.getModel(), minX, maxY, maxZ).color(red, green, blue, alpha).next();
+            }
         }
 
-        if (minY != maxY && minZ != maxZ) {
-            if (mask) quadMaskedCount.getAndIncrement();
-            else quadNonMaskedCount.getAndIncrement();
-            bufferBuilder.vertex(matrixEntry.getModel(), maxX, minY, minZ).color(red, green, blue, alpha).next();
-            bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, minZ).color(red, green, blue, alpha).next();
-            bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, maxZ).color(red, green, blue, alpha).next();
-            bufferBuilder.vertex(matrixEntry.getModel(), maxX, minY, maxZ).color(red, green, blue, alpha).next();
-        }
-
-        if (minX != maxX && minY != maxY) {
-            if (mask) quadMaskedCount.getAndIncrement();
-            else quadNonMaskedCount.getAndIncrement();
-            bufferBuilder.vertex(matrixEntry.getModel(), minX, minY, maxZ).color(red, green, blue, alpha).next();
-            bufferBuilder.vertex(matrixEntry.getModel(), maxX, minY, maxZ).color(red, green, blue, alpha).next();
-            bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, maxZ).color(red, green, blue, alpha).next();
-            bufferBuilder.vertex(matrixEntry.getModel(), minX, maxY, maxZ).color(red, green, blue, alpha).next();
-        }
-
-        if (minY != maxY && minZ != maxZ) {
+        if (!sameY && !sameZ) {
             if (mask) quadMaskedCount.getAndIncrement();
             else quadNonMaskedCount.getAndIncrement();
             bufferBuilder.vertex(matrixEntry.getModel(), minX, minY, minZ).color(red, green, blue, alpha).next();
             bufferBuilder.vertex(matrixEntry.getModel(), minX, minY, maxZ).color(red, green, blue, alpha).next();
             bufferBuilder.vertex(matrixEntry.getModel(), minX, maxY, maxZ).color(red, green, blue, alpha).next();
             bufferBuilder.vertex(matrixEntry.getModel(), minX, maxY, minZ).color(red, green, blue, alpha).next();
+            if (!sameX) {
+                if (mask) quadMaskedCount.getAndIncrement();
+                else quadNonMaskedCount.getAndIncrement();
+                bufferBuilder.vertex(matrixEntry.getModel(), maxX, minY, minZ).color(red, green, blue, alpha).next();
+                bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, minZ).color(red, green, blue, alpha).next();
+                bufferBuilder.vertex(matrixEntry.getModel(), maxX, maxY, maxZ).color(red, green, blue, alpha).next();
+                bufferBuilder.vertex(matrixEntry.getModel(), maxX, minY, maxZ).color(red, green, blue, alpha).next();
+            }
         }
     }
 
index 5e53961256b007e67b3b0d8e52a3012a0cf08001..4580f611cbbea79fed0bbdec4ace34180754d14f 100644 (file)
@@ -6,6 +6,7 @@ import com.mojang.blaze3d.platform.GlStateManager;
 import com.mojang.blaze3d.systems.RenderSystem;
 import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.math.Quaternion;
+import net.minecraft.util.math.Vec3d;
 import org.lwjgl.opengl.GL11;
 
 public class RenderHelper {
@@ -162,4 +163,23 @@ public class RenderHelper {
         matrixStack.translate(regionX - Camera.getX(), -Camera.getY(),
                 regionZ - Camera.getZ());
     }
+
+    /**
+     * Compute hash code for vec3d
+     * @see Vec3d#hashCode()
+     *
+     * @param x x value
+     * @param y y value
+     * @param z z value
+     * @return hash code
+     */
+    public static long hashVec3d(double x, double y, double z) {
+        long l = Double.doubleToLongBits(x);
+        int i = (int)(l ^ l >>> 32);
+        l = Double.doubleToLongBits(y);
+        i = 31 * i + (int)(l ^ l >>> 32);
+        l = Double.doubleToLongBits(z);
+        i = 31 * i + (int)(l ^ l >>> 32);
+        return i;
+    }
 }
index 768224936c72b6987334c24e39bc373a861fabf0..9036fb29a68c0978b52bbb0e3fc31f91e79136da 100644 (file)
@@ -33,4 +33,8 @@ public abstract class AbstractBoundingBox {
     public AbstractRenderer<?> getRenderer() {
         return ClientRenderer.getRenderer(this.getClass());
     }
+
+    public boolean isVisibleCulling() {
+        return true;
+    }
 }
index 6cfa81a40e930c769aaad2321c9d724988b1da4a..1e55a4e13dc82aec5aa8750a74e6edf1cb5b68a0 100644 (file)
@@ -1,6 +1,7 @@
 package com.irtimaled.bbor.common.models;
 
 import com.irtimaled.bbor.client.ClientRenderer;
+import com.irtimaled.bbor.client.RenderCulling;
 import com.irtimaled.bbor.client.renderers.AbstractRenderer;
 import com.irtimaled.bbor.client.renderers.CuboidRenderer;
 import com.irtimaled.bbor.common.BoundingBoxType;
@@ -8,7 +9,7 @@ import com.irtimaled.bbor.common.MathHelper;
 import com.irtimaled.bbor.common.TypeHelper;
 
 public class BoundingBoxCuboid extends AbstractBoundingBox {
-    private static final AbstractRenderer<BoundingBoxCuboid> RENDERER = ClientRenderer.registerRenderer(BoundingBoxCuboid.class, new CuboidRenderer());
+    private static final AbstractRenderer<BoundingBoxCuboid> RENDERER = ClientRenderer.registerRenderer(BoundingBoxCuboid.class, () -> new CuboidRenderer());
 
     private final Coords minCoords;
     private final Coords maxCoords;
@@ -80,4 +81,9 @@ public class BoundingBoxCuboid extends AbstractBoundingBox {
     public AbstractRenderer<?> getRenderer() {
         return RENDERER;
     }
+
+    @Override
+    public boolean isVisibleCulling() {
+        return RenderCulling.isVisibleCulling(minCoords.getX(), minCoords.getY(), minCoords.getZ(), maxCoords.getX(), maxCoords.getY(), maxCoords.getZ());
+    }
 }
index 6000c6ca9ed4cc3e30e72f0bfe0c169f887df6a2..3c2704b3d023182dfb335c618b27b21dabc7cb13 100644 (file)
@@ -2,6 +2,7 @@ package com.irtimaled.bbor.mixin.client.network.play;
 
 import com.irtimaled.bbor.client.interop.ClientInterop;
 import net.minecraft.client.network.ClientPlayNetworkHandler;
+import net.minecraft.network.packet.s2c.play.UnloadChunkS2CPacket;
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.injection.At;
 import org.spongepowered.asm.mixin.injection.Inject;
@@ -13,4 +14,9 @@ public class MixinClientPlayNetHandler {
     private void onDisconnect(CallbackInfo ci) {
         ClientInterop.disconnectedFromRemoteServer();
     }
+
+    @Inject(method = "onUnloadChunk", at = @At("RETURN"))
+    private void onChunkUnload(UnloadChunkS2CPacket packet, CallbackInfo ci) {
+        ClientInterop.unloadChunk(packet.getX(), packet.getZ());
+    }
 }