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;
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<>();
}
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) {
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();
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);
}
}
}
}
- 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) {
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;
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.");
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;
import java.util.HashMap;
import java.util.Map;
-import java.util.stream.IntStream;
class IntSettingSlider extends AbstractSlider {
private final String format;
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();
}
}
},
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),
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);
}
}
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) {
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;
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);
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;
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;
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);
+ }
}
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;
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;
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;
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());
+ }
}
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;
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;
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
+ }
}
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;
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);
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<>();
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;
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;
public Point getPoint() {
return point;
}
+
+ @Override
+ public AbstractRenderer<?> getRenderer() {
+ return RENDERER;
+ }
}
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);
(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();
}
}
- 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())) {
// return;
// }
+ if (cullIfEmpty && startPoint.equals(endPoint)) return;
if (!RenderCulling.isVisibleCulling(new OffsetBox(startPoint, endPoint).toBox())) return; // TODO better culling
matrixStack.push();
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) {
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;
}
if (distance <= 20) {
OffsetPoint playerPoint = playerPos.offset(0, 0.1, 0);
- renderLine(matrixStack, centerPoint, playerPoint, getColor(distance));
+ renderLine(matrixStack, centerPoint, playerPoint, getColor(distance), false);
}
}
import com.irtimaled.bbor.client.models.Point;
import com.irtimaled.bbor.common.models.Coords;
+import java.util.Objects;
+
class OffsetPoint {
private final Point point;
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);
+ }
}
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;
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();
+ }
}
}
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 {
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;
+ }
}
public AbstractRenderer<?> getRenderer() {
return ClientRenderer.getRenderer(this.getClass());
}
+
+ public boolean isVisibleCulling() {
+ return true;
+ }
}
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;
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;
public AbstractRenderer<?> getRenderer() {
return RENDERER;
}
+
+ @Override
+ public boolean isVisibleCulling() {
+ return RenderCulling.isVisibleCulling(minCoords.getX(), minCoords.getY(), minCoords.getZ(), maxCoords.getX(), maxCoords.getY(), maxCoords.getZ());
+ }
}
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;
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());
+ }
}