package com.irtimaled.bbor.client;
+import com.irtimaled.bbor.common.BoundingBoxCache;
import com.irtimaled.bbor.common.models.BoundingBox;
import com.irtimaled.bbor.common.models.BoundingBoxSlimeChunk;
import com.irtimaled.bbor.common.models.BoundingBoxWorldSpawn;
import com.irtimaled.bbor.common.models.WorldData;
import com.irtimaled.bbor.config.ConfigManager;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
+import java.util.stream.Collectors;
class ClientBoundingBoxProvider {
private final ClientDimensionCache dimensionCache;
this.dimensionCache = dimensionCache;
}
- Set<BoundingBox> getClientBoundingBoxes(DimensionType dimensionType) {
- WorldData worldData = dimensionCache.getWorldData();
-
- if (worldData == null) {
- return null;
+ Set<BoundingBox> getBoundingBoxes(DimensionType dimensionType, Boolean outerBoxOnly, WorldClient world) {
+ Set<BoundingBox> boundingBoxes = getClientBoundingBoxes(dimensionType);
+ BoundingBoxCache boundingBoxCache = dimensionCache.getBoundingBoxes(dimensionType);
+ if (boundingBoxCache != null) {
+ if (outerBoxOnly) {
+ boundingBoxes.addAll(boundingBoxCache.getBoundingBoxes().keySet());
+ } else {
+ boundingBoxCache.getBoundingBoxes()
+ .values()
+ .forEach(boundingBoxes::addAll);
+ }
}
+ return boundingBoxes.stream()
+ .filter(bb -> world.isAreaLoaded(bb.getMinBlockPos(), bb.getMaxBlockPos()))
+ .collect(Collectors.toSet());
+ }
+
+ private Set<BoundingBox> getClientBoundingBoxes(DimensionType dimensionType) {
+ WorldData worldData = dimensionCache.getWorldData();
+
Set<BoundingBox> boundingBoxes = new HashSet<>();
- if (dimensionType == DimensionType.OVERWORLD) {
+ if (worldData != null && dimensionType == DimensionType.OVERWORLD) {
if (ConfigManager.drawWorldSpawn.getBoolean()) {
boundingBoxes.add(getWorldSpawnBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
boundingBoxes.add(buildSpawnChunksBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
package com.irtimaled.bbor.client;
-import com.irtimaled.bbor.common.BoundingBoxCache;
import com.irtimaled.bbor.common.CommonProxy;
import com.irtimaled.bbor.common.VillageColorCache;
import com.irtimaled.bbor.common.VillageProcessor;
-import com.irtimaled.bbor.common.models.*;
import com.irtimaled.bbor.config.ConfigManager;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.multiplayer.WorldClient;
-import net.minecraft.client.renderer.BufferBuilder;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.NetworkManager;
-import net.minecraft.util.math.AxisAlignedBB;
-import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DimensionType;
import org.apache.commons.lang3.ArrayUtils;
import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
-import java.awt.*;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
public class ClientProxy extends CommonProxy {
private boolean active;
private boolean outerBoxOnly;
private KeyBinding activeHotKey;
private KeyBinding outerBoxOnlyHotKey;
- private ClientBoundingBoxProvider clientBoundingBoxProvider;
+ private ClientRenderer renderer;
public void keyPressed() {
if (activeHotKey.isPressed()) {
outerBoxOnlyHotKey = new KeyBinding("Toggle Display Outer Box Only", Keyboard.KEY_O, category);
Minecraft.getMinecraft().gameSettings.keyBindings = ArrayUtils.addAll(Minecraft.getMinecraft().gameSettings.keyBindings, activeHotKey, outerBoxOnlyHotKey);
ClientDimensionCache clientDimensionCache = new ClientDimensionCache();
- clientBoundingBoxProvider = new ClientBoundingBoxProvider(clientDimensionCache);
+ renderer = new ClientRenderer(clientDimensionCache);
dimensionCache = clientDimensionCache;
}
PlayerData.setPlayerPosition(partialTicks, entityPlayer);
if (this.active) {
- DimensionType dimensionType = DimensionType.getById(entityPlayer.dimension);
- Map<BoundingBox, Set<BoundingBox>> boundingBoxes = null;
- BoundingBoxCache boundingBoxCache = dimensionCache.getBoundingBoxes(dimensionType);
- if (boundingBoxCache != null) {
- boundingBoxes = boundingBoxCache.getBoundingBoxes();
- }
- renderBoundingBoxes(boundingBoxes, clientBoundingBoxProvider.getClientBoundingBoxes(dimensionType));
+ renderer.render(DimensionType.getById(entityPlayer.dimension), outerBoxOnly);
}
}
dimensionCache.clear();
villageProcessors.forEach(VillageProcessor::clear);
}
-
- private void renderBoundingBoxes(Map<BoundingBox, Set<BoundingBox>> map, Set<BoundingBox> clientBoundingBoxes) {
- if (map == null && clientBoundingBoxes == null)
- return;
-
- GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GL11.glLineWidth(2.0f);
- GL11.glDisable(GL11.GL_TEXTURE_2D);
- GL11.glDisable(GL11.GL_CULL_FACE);
-
- if (ConfigManager.alwaysVisible.getBoolean()) {
- GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
- }
-
- if (map != null)
- for (BoundingBox bb : map.keySet()) {
- if (outerBoxOnly) {
- renderBoundingBoxSet(map.get(bb));
- } else {
- renderBoundingBoxByType(bb);
- }
- }
-
- if (clientBoundingBoxes != null)
- renderBoundingBoxSet(clientBoundingBoxes);
-
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
- GL11.glEnable(GL11.GL_CULL_FACE);
- GL11.glEnable(GL11.GL_TEXTURE_2D);
- }
-
- private void renderBoundingBoxSet(Set<BoundingBox> bbList) {
- if (bbList != null)
- for (BoundingBox bb : bbList) {
- renderBoundingBoxByType(bb);
- }
- }
-
- private void renderBoundingBoxByType(BoundingBox bb) {
- WorldClient world = Minecraft.getMinecraft().world;
- if (!world.isAreaLoaded(bb.getMinBlockPos(), bb.getMaxBlockPos())) {
- return;
- }
-
- if (bb instanceof BoundingBoxVillage) {
- BoundingBoxVillage villageBB = (BoundingBoxVillage) bb;
- if (ConfigManager.renderVillageAsSphere.getBoolean()) {
- renderBoundingBoxVillageAsSphere(villageBB);
- } else {
- renderBoundingBox(villageBB);
- }
- if (ConfigManager.drawIronGolemSpawnArea.getBoolean() &&
- villageBB.getSpawnsIronGolems()) {
- renderIronGolemSpawnArea(villageBB);
- }
- if (ConfigManager.drawVillageDoors.getBoolean())
- renderVillageDoors(villageBB);
- } else if (bb instanceof BoundingBoxSlimeChunk) {
- renderSlimeChunk((BoundingBoxSlimeChunk) bb);
- } else if (bb instanceof BoundingBoxWorldSpawn) {
- renderWorldSpawn((BoundingBoxWorldSpawn) bb);
- } else {
- renderBoundingBox(bb);
- }
- }
-
- private void renderBoundingBox(BoundingBox bb) {
- AxisAlignedBB aaBB = bb.toAxisAlignedBB();
- Color color = bb.getColor();
- renderCuboid(aaBB, color, fill());
- }
-
- private void renderWorldSpawn(BoundingBoxWorldSpawn bb) {
- AxisAlignedBB aaBB = bb.toAxisAlignedBB(false);
- Color color = bb.getColor();
- double y = PlayerData.getMaxY(ConfigManager.worldSpawnMaxY.getInt()) + 0.001F;
- renderRectangle(aaBB, y, y, color, false);
- }
-
- private void renderSlimeChunk(BoundingBoxSlimeChunk bb) {
- AxisAlignedBB aaBB = bb.toAxisAlignedBB();
- Color color = bb.getColor();
- renderCuboid(aaBB, color, fill());
-
- double maxY = PlayerData.getMaxY(ConfigManager.slimeChunkMaxY.getInt());
- if (maxY > 39) {
- renderRectangle(aaBB, 39, maxY, color, fill());
- }
- }
-
- private void renderRectangle(AxisAlignedBB aaBB, double minY, double maxY, Color color, Boolean fill) {
- aaBB = new AxisAlignedBB(aaBB.minX, minY, aaBB.minZ, aaBB.maxX, maxY, aaBB.maxZ);
- renderCuboid(aaBB, color, fill);
- }
-
- private boolean fill() {
- return ConfigManager.fill.getBoolean();
- }
-
- private void renderIronGolemSpawnArea(BoundingBoxVillage villageBB) {
- BlockPos center = villageBB.getCenter();
- AxisAlignedBB abb = new AxisAlignedBB(new BlockPos(center.getX() - 8,
- center.getY() - 3,
- center.getZ() - 8),
- new BlockPos(center.getX() + 8,
- center.getY() + 3,
- center.getZ() + 8))
- .offset(villageBB.getCenterOffsetX(), 0.0, villageBB.getCenterOffsetZ());
-
- renderCuboid(abb, villageBB.getColor(), false);
- }
-
- private void renderVillageDoors(BoundingBoxVillage villageBB) {
- OffsetPoint center = new OffsetPoint(villageBB.getCenter())
- .add(villageBB.getCenterOffsetX(), 0.0, villageBB.getCenterOffsetZ());
- Color color = villageBB.getColor();
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
-
- int colorR = color.getRed();
- int colorG = color.getGreen();
- int colorB = color.getBlue();
-
- worldRenderer.begin(GL11.GL_LINES, worldRenderer.getVertexFormat());
- for (BlockPos door : villageBB.getDoors()) {
- OffsetPoint point = new OffsetPoint(door).add(0.5, 0, 0.5);
-
- worldRenderer.pos(point.getX(), point.getY(), point.getZ()).color(colorR, colorG, colorB, 255).endVertex();
- worldRenderer.pos(center.getX(), center.getY(), center.getZ()).color(colorR, colorG, colorB, 255).endVertex();
- }
- tessellator.draw();
- }
-
- private void renderCuboid(AxisAlignedBB aaBB, Color color, boolean fill) {
- aaBB = offsetAxisAlignedBB(aaBB);
- if (fill) {
- renderFilledCuboid(aaBB, color);
- }
- renderUnfilledCuboid(aaBB, color);
- }
-
- private void renderFilledCuboid(AxisAlignedBB aaBB, Color color) {
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
- GL11.glEnable(GL11.GL_BLEND);
- renderCuboid(aaBB, 30, color);
- GL11.glDisable(GL11.GL_BLEND);
- GL11.glEnable(GL11.GL_POLYGON_OFFSET_LINE);
- GL11.glPolygonOffset(-1.f, -1.f);
- }
-
- private void renderUnfilledCuboid(AxisAlignedBB aaBB, Color color) {
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
- renderCuboid(aaBB, 255, color);
- }
-
- private void renderCuboid(AxisAlignedBB bb, int alphaChannel, Color color) {
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
-
- int colorR = color.getRed();
- int colorG = color.getGreen();
- int colorB = color.getBlue();
-
- worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
- worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- if (bb.minY != bb.maxY) {
- worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- }
- tessellator.draw();
- }
-
- private AxisAlignedBB offsetAxisAlignedBB(AxisAlignedBB axisAlignedBB) {
- double growXZ = 0.001F;
- double growY = 0;
- if (axisAlignedBB.minY != axisAlignedBB.maxY) {
- growY = growXZ;
- }
- return axisAlignedBB
- .grow(growXZ, growY, growXZ)
- .offset(-PlayerData.getX(), -PlayerData.getY(), -PlayerData.getZ());
- }
-
- private void renderBoundingBoxVillageAsSphere(BoundingBoxVillage bb) {
- OffsetPoint center = new OffsetPoint(bb.getCenter())
- .add(bb.getCenterOffsetX(), 0.0, bb.getCenterOffsetZ());
- ;
- int radius = bb.getRadius();
- Color color = bb.getColor();
- renderSphere(center, radius, color);
- }
-
- private void renderSphere(OffsetPoint center, double radius, Color color) {
- GL11.glEnable(GL11.GL_POINT_SMOOTH);
- GL11.glPointSize(2f);
-
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
- worldRenderer.begin(GL11.GL_POINTS, DefaultVertexFormats.POSITION_COLOR);
- for (OffsetPoint point : buildPoints(center, radius)) {
- worldRenderer.pos(point.getX(), point.getY(), point.getZ())
- .color(color.getRed(), color.getGreen(), color.getBlue(), 255)
- .endVertex();
- }
- tessellator.draw();
- }
-
- private class OffsetPoint {
- private final double x;
- private final double y;
- private final double z;
-
- public OffsetPoint(double x, double y, double z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- public OffsetPoint(BlockPos blockPos) {
- x = blockPos.getX();
- y = blockPos.getY();
- z = blockPos.getZ();
- }
-
- public double getX() {
- return x - PlayerData.getX();
- }
-
- public double getY() {
- return y - PlayerData.getY();
- }
-
- public double getZ() {
- return z - PlayerData.getZ();
- }
-
- public OffsetPoint add(double x, double y, double z) {
- return new OffsetPoint(this.x + x, this.y + y, this.z + z);
- }
- }
-
- private Set<OffsetPoint> buildPoints(OffsetPoint center, double radius) {
- Set<OffsetPoint> points = new HashSet<>(1200);
-
- double tau = 6.283185307179586D;
- double pi = tau / 2D;
- double segment = tau / 48D;
-
- for (double t = 0.0D; t < tau; t += segment)
- for (double theta = 0.0D; theta < pi; theta += segment) {
- double dx = radius * Math.sin(t) * Math.cos(theta);
- double dz = radius * Math.sin(t) * Math.sin(theta);
- double dy = radius * Math.cos(t);
-
- points.add(center.add(dx, dy, dz));
- }
- return points;
- }
}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import com.irtimaled.bbor.client.renderers.*;
+import com.irtimaled.bbor.common.models.*;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.Minecraft;
+import net.minecraft.world.DimensionType;
+import org.lwjgl.opengl.GL11;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class ClientRenderer {
+ private final ClientBoundingBoxProvider clientBoundingBoxProvider;
+ private static final Map<Class<? extends BoundingBox>, Renderer> boundingBoxRendererMap = new HashMap<>();
+
+ ClientRenderer(ClientDimensionCache dimensionCache) {
+ this.clientBoundingBoxProvider = new ClientBoundingBoxProvider(dimensionCache);
+ boundingBoxRendererMap.put(BoundingBoxVillage.class, new VillageRenderer());
+ boundingBoxRendererMap.put(BoundingBoxSlimeChunk.class, new SlimeChunkRenderer());
+ boundingBoxRendererMap.put(BoundingBoxWorldSpawn.class, new WorldSpawnRenderer());
+ boundingBoxRendererMap.put(BoundingBoxStructure.class, new StructureRenderer());
+ }
+
+ public void render(DimensionType dimensionType, Boolean outerBoxesOnly) {
+ Set<BoundingBox> boundingBoxes = clientBoundingBoxProvider.getBoundingBoxes(dimensionType, outerBoxesOnly, Minecraft.getMinecraft().world);
+ if (boundingBoxes == null || boundingBoxes.size() == 0)
+ return;
+
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glLineWidth(2.0f);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_CULL_FACE);
+
+ if (ConfigManager.alwaysVisible.getBoolean()) {
+ GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
+ }
+ for (BoundingBox bb : boundingBoxes) {
+ Renderer renderer = boundingBoxRendererMap.get(bb.getClass());
+ if (renderer != null) {
+ renderer.render(bb);
+ }
+ }
+
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
+ GL11.glEnable(GL11.GL_CULL_FACE);
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.client.PlayerData;
+import com.irtimaled.bbor.common.models.BoundingBox;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.util.math.AxisAlignedBB;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+
+public abstract class Renderer<T extends BoundingBox> {
+ public abstract void render(T boundingBox);
+
+ void renderBoundingBox(T boundingBox) {
+ renderCuboid(boundingBox.toAxisAlignedBB(), boundingBox.getColor(), fill());
+ }
+
+ boolean fill() {
+ return ConfigManager.fill.getBoolean();
+ }
+
+ void renderRectangle(AxisAlignedBB aaBB, double minY, double maxY, Color color, Boolean fill) {
+ aaBB = new AxisAlignedBB(aaBB.minX, minY, aaBB.minZ, aaBB.maxX, maxY, aaBB.maxZ);
+ renderCuboid(aaBB, color, fill);
+ }
+
+ void renderCuboid(AxisAlignedBB aaBB, Color color, boolean fill) {
+ aaBB = offsetAxisAlignedBB(aaBB);
+ if (fill) {
+ renderFilledCuboid(aaBB, color);
+ }
+ renderUnfilledCuboid(aaBB, color);
+ }
+
+ private AxisAlignedBB offsetAxisAlignedBB(AxisAlignedBB axisAlignedBB) {
+ double growXZ = 0.001F;
+ double growY = 0;
+ if (axisAlignedBB.minY != axisAlignedBB.maxY) {
+ growY = growXZ;
+ }
+ return axisAlignedBB
+ .grow(growXZ, growY, growXZ)
+ .offset(-PlayerData.getX(), -PlayerData.getY(), -PlayerData.getZ());
+ }
+
+ private void renderFilledCuboid(AxisAlignedBB aaBB, Color color) {
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
+ GL11.glEnable(GL11.GL_BLEND);
+ renderCuboid(aaBB, 30, color);
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glEnable(GL11.GL_POLYGON_OFFSET_LINE);
+ GL11.glPolygonOffset(-1.f, -1.f);
+ }
+
+ private void renderUnfilledCuboid(AxisAlignedBB aaBB, Color color) {
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
+ renderCuboid(aaBB, 255, color);
+ }
+
+ private void renderCuboid(AxisAlignedBB bb, int alphaChannel, Color color) {
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder worldRenderer = tessellator.getBuffer();
+
+ int colorR = color.getRed();
+ int colorG = color.getGreen();
+ int colorB = color.getBlue();
+
+ worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
+ worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ if (bb.minY != bb.maxY) {
+
+ worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ }
+ tessellator.draw();
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.common.models.BoundingBoxSlimeChunk;
+import com.irtimaled.bbor.client.PlayerData;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.util.math.AxisAlignedBB;
+
+import java.awt.*;
+
+public class SlimeChunkRenderer extends Renderer<BoundingBoxSlimeChunk> {
+ @Override
+ public void render(BoundingBoxSlimeChunk boundingBox) {
+ AxisAlignedBB aaBB = boundingBox.toAxisAlignedBB();
+ Color color = boundingBox.getColor();
+ renderCuboid(aaBB, color, fill());
+
+ double maxY = PlayerData.getMaxY(ConfigManager.slimeChunkMaxY.getInt());
+ if (maxY > 39) {
+ renderRectangle(aaBB, 39, maxY, color, fill());
+ }
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.common.models.BoundingBoxStructure;
+
+public class StructureRenderer extends Renderer<BoundingBoxStructure> {
+ @Override
+ public void render(BoundingBoxStructure boundingBox) {
+ renderBoundingBox(boundingBox);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.common.models.BoundingBoxVillage;
+import com.irtimaled.bbor.client.PlayerData;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Set;
+
+public class VillageRenderer extends Renderer<BoundingBoxVillage> {
+ @Override
+ public void render(BoundingBoxVillage boundingBox) {
+ if (ConfigManager.renderVillageAsSphere.getBoolean()) {
+ renderBoundingBoxVillageAsSphere(boundingBox);
+ } else {
+ renderBoundingBox(boundingBox);
+ }
+ if (ConfigManager.drawIronGolemSpawnArea.getBoolean() &&
+ boundingBox.getSpawnsIronGolems()) {
+ renderIronGolemSpawnArea(boundingBox);
+ }
+ if (ConfigManager.drawVillageDoors.getBoolean()) {
+ renderVillageDoors(boundingBox);
+ }
+ }
+
+ private void renderIronGolemSpawnArea(BoundingBoxVillage boundingBox) {
+ BlockPos center = boundingBox.getCenter();
+ AxisAlignedBB abb = new AxisAlignedBB(new BlockPos(center.getX() - 8,
+ center.getY() - 3,
+ center.getZ() - 8),
+ new BlockPos(center.getX() + 8,
+ center.getY() + 3,
+ center.getZ() + 8))
+ .offset(boundingBox.getCenterOffsetX(), 0.0, boundingBox.getCenterOffsetZ());
+
+ renderCuboid(abb, boundingBox.getColor(), false);
+ }
+
+ private void renderVillageDoors(BoundingBoxVillage boundingBox) {
+ OffsetPoint center = new OffsetPoint(boundingBox.getCenter())
+ .add(boundingBox.getCenterOffsetX(), 0.0, boundingBox.getCenterOffsetZ());
+ Color color = boundingBox.getColor();
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder worldRenderer = tessellator.getBuffer();
+
+ int colorR = color.getRed();
+ int colorG = color.getGreen();
+ int colorB = color.getBlue();
+
+ worldRenderer.begin(GL11.GL_LINES, worldRenderer.getVertexFormat());
+ for (BlockPos door : boundingBox.getDoors()) {
+ OffsetPoint point = new OffsetPoint(door).add(0.5, 0, 0.5);
+
+ worldRenderer.pos(point.getX(), point.getY(), point.getZ()).color(colorR, colorG, colorB, 255).endVertex();
+ worldRenderer.pos(center.getX(), center.getY(), center.getZ()).color(colorR, colorG, colorB, 255).endVertex();
+ }
+ tessellator.draw();
+ }
+
+ private void renderBoundingBoxVillageAsSphere(BoundingBoxVillage boundingBox) {
+ OffsetPoint center = new OffsetPoint(boundingBox.getCenter())
+ .add(boundingBox.getCenterOffsetX(), 0.0, boundingBox.getCenterOffsetZ());
+ int radius = boundingBox.getRadius();
+ Color color = boundingBox.getColor();
+ renderSphere(center, radius, color);
+ }
+
+ private void renderSphere(OffsetPoint center, double radius, Color color) {
+ GL11.glEnable(GL11.GL_POINT_SMOOTH);
+ GL11.glPointSize(2f);
+
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder worldRenderer = tessellator.getBuffer();
+ worldRenderer.begin(GL11.GL_POINTS, DefaultVertexFormats.POSITION_COLOR);
+ for (OffsetPoint point : buildPoints(center, radius)) {
+ worldRenderer.pos(point.getX(), point.getY(), point.getZ())
+ .color(color.getRed(), color.getGreen(), color.getBlue(), 255)
+ .endVertex();
+ }
+ tessellator.draw();
+ }
+
+ private class OffsetPoint {
+ private final double x;
+ private final double y;
+ private final double z;
+
+ OffsetPoint(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ OffsetPoint(BlockPos blockPos) {
+ this.x = blockPos.getX();
+ this.y = blockPos.getY();
+ this.z = blockPos.getZ();
+ }
+
+ double getX() {
+ return x - PlayerData.getX();
+ }
+
+ double getY() {
+ return y - PlayerData.getY();
+ }
+
+ double getZ() {
+ return z - PlayerData.getZ();
+ }
+
+ public OffsetPoint add(double x, double y, double z) {
+ return new OffsetPoint(this.x + x, this.y + y, this.z + z);
+ }
+ }
+
+ private Set<OffsetPoint> buildPoints(OffsetPoint center, double radius) {
+ Set<OffsetPoint> points = new HashSet<>(1200);
+
+ double tau = 6.283185307179586D;
+ double pi = tau / 2D;
+ double segment = tau / 48D;
+
+ for (double t = 0.0D; t < tau; t += segment)
+ for (double theta = 0.0D; theta < pi; theta += segment) {
+ double dx = radius * Math.sin(t) * Math.cos(theta);
+ double dz = radius * Math.sin(t) * Math.sin(theta);
+ double dy = radius * Math.cos(t);
+
+ points.add(center.add(dx, dy, dz));
+ }
+ return points;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.common.models.BoundingBoxWorldSpawn;
+import com.irtimaled.bbor.client.PlayerData;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.util.math.AxisAlignedBB;
+
+import java.awt.*;
+
+public class WorldSpawnRenderer extends Renderer<BoundingBoxWorldSpawn> {
+ @Override
+ public void render(BoundingBoxWorldSpawn boundingBox) {
+ AxisAlignedBB aaBB = boundingBox.toAxisAlignedBB(false);
+ Color color = boundingBox.getColor();
+ double y = PlayerData.getMaxY(ConfigManager.worldSpawnMaxY.getInt()) + 0.001F;
+ renderRectangle(aaBB, y, y, color, false);
+ }
+}
\ No newline at end of file