]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/ClientRenderer.java
Add support for custom sphere
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / ClientRenderer.java
1 package com.irtimaled.bbor.client;
2
3 import com.irtimaled.bbor.client.config.ConfigManager;
4 import com.irtimaled.bbor.client.interop.ClientInterop;
5 import com.irtimaled.bbor.client.models.*;
6 import com.irtimaled.bbor.client.providers.*;
7 import com.irtimaled.bbor.client.renderers.*;
8 import com.irtimaled.bbor.common.MathHelper;
9 import com.irtimaled.bbor.common.models.AbstractBoundingBox;
10 import com.irtimaled.bbor.common.models.BoundingBoxCuboid;
11 import com.irtimaled.bbor.common.models.BoundingBoxSphere;
12 import com.irtimaled.bbor.common.models.BoundingBoxVillage;
13 import org.lwjgl.opengl.GL11;
14
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.Map;
18 import java.util.Set;
19
20 public class ClientRenderer {
21     private static final int CHUNK_SIZE = 16;
22     private static final Map<Class<? extends AbstractBoundingBox>, AbstractRenderer> boundingBoxRendererMap = new HashMap<>();
23
24     private static boolean active;
25     private static final Set<IBoundingBoxProvider> providers = new HashSet<>();
26
27     public static boolean getActive() {
28         return active;
29     }
30
31     public static void toggleActive() {
32         active = !active;
33         if (!active) return;
34
35         Player.setActiveY();
36     }
37
38     static void deactivate() {
39         active = false;
40     }
41
42     static {
43         registerRenderer(BoundingBoxVillage.class, new VillageRenderer());
44         registerRenderer(BoundingBoxSlimeChunk.class, new SlimeChunkRenderer());
45         registerRenderer(BoundingBoxWorldSpawn.class, new WorldSpawnRenderer());
46         registerRenderer(BoundingBoxCuboid.class, new CuboidRenderer());
47         registerRenderer(BoundingBoxMobSpawner.class, new MobSpawnerRenderer());
48         registerRenderer(BoundingBoxSpawningSphere.class, new SpawningSphereRenderer());
49         registerRenderer(BoundingBoxBeacon.class, new BeaconRenderer());
50         registerRenderer(BoundingBoxBiomeBorder.class, new BiomeBorderRenderer());
51         registerRenderer(BoundingBoxConduit.class, new ConduitRenderer());
52         registerRenderer(BoundingBoxSpawnableBlocks.class, new SpawnableBlocksRenderer());
53         registerRenderer(BoundingBoxLine.class, new LineRenderer());
54         registerRenderer(BoundingBoxSphere.class, new SphereRenderer());
55
56         registerProvider(new SlimeChunkProvider());
57         registerProvider(new WorldSpawnProvider());
58         registerProvider(new SpawningSphereProvider());
59         registerProvider(new BeaconProvider());
60         registerProvider(new CustomBoxProvider());
61         registerProvider(new CustomBeaconProvider());
62         registerProvider(new BiomeBorderProvider());
63         registerProvider(new MobSpawnerProvider());
64         registerProvider(new ConduitProvider());
65         registerProvider(new SpawnableBlocksProvider());
66         registerProvider(new CustomLineProvider());
67         registerProvider(new CustomSphereProvider());
68     }
69
70     public static <T extends AbstractBoundingBox> void registerProvider(IBoundingBoxProvider<T> provider) {
71         providers.add(provider);
72     }
73
74     public static <T extends AbstractBoundingBox> void registerRenderer(Class<? extends T> type, AbstractRenderer<T> renderer) {
75         boundingBoxRendererMap.put(type, renderer);
76     }
77
78     private static boolean isWithinRenderDistance(AbstractBoundingBox boundingBox) {
79         int renderDistanceBlocks = ClientInterop.getRenderDistanceChunks() * CHUNK_SIZE;
80         int minX = MathHelper.floor(Player.getX() - renderDistanceBlocks);
81         int maxX = MathHelper.floor(Player.getX() + renderDistanceBlocks);
82         int minZ = MathHelper.floor(Player.getZ() - renderDistanceBlocks);
83         int maxZ = MathHelper.floor(Player.getZ() + renderDistanceBlocks);
84
85         return boundingBox.intersectsBounds(minX, minZ, maxX, maxZ);
86     }
87
88     public static void render(int dimensionId) {
89         if (!active) return;
90
91         Set<AbstractBoundingBox> boundingBoxes = getBoundingBoxes(dimensionId);
92
93         GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
94         GL11.glLineWidth(2.0f);
95         GL11.glDisable(GL11.GL_TEXTURE_2D);
96         GL11.glDisable(GL11.GL_CULL_FACE);
97
98         if (ConfigManager.alwaysVisible.get()) {
99             GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
100         }
101
102         for (AbstractBoundingBox key : boundingBoxes) {
103             AbstractRenderer renderer = boundingBoxRendererMap.get(key.getClass());
104             if (renderer == null) continue;
105
106             renderer.render(key);
107         }
108
109         GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
110         GL11.glEnable(GL11.GL_CULL_FACE);
111         GL11.glEnable(GL11.GL_TEXTURE_2D);
112     }
113
114     private static Set<AbstractBoundingBox> getBoundingBoxes(int dimensionId) {
115         Set<AbstractBoundingBox> boundingBoxes = new HashSet<>();
116         for (IBoundingBoxProvider<?> provider : providers) {
117             if (provider.canProvide(dimensionId)) {
118                 for (AbstractBoundingBox boundingBox : provider.get(dimensionId)) {
119                     if (isWithinRenderDistance(boundingBox)) {
120                         boundingBoxes.add(boundingBox);
121                     }
122                 }
123             }
124         }
125         return boundingBoxes;
126     }
127 }