diff --git a/src/main/java/com/seibel/lod/api/lod/ClientApi.java b/src/main/java/com/seibel/lod/api/lod/ClientApi.java index 26ed9d850..c258fce05 100644 --- a/src/main/java/com/seibel/lod/api/lod/ClientApi.java +++ b/src/main/java/com/seibel/lod/api/lod/ClientApi.java @@ -31,8 +31,8 @@ import com.seibel.lod.core.util.DetailDistanceUtil; import com.seibel.lod.core.util.ThreadMapUtil; import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; +import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftRenderWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; -import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; import net.minecraft.profiler.IProfiler; @@ -51,7 +51,8 @@ public class ClientApi public static LodRenderer renderer = new LodRenderer(ApiShared.lodBufferBuilderFactory); - private final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); + private final IMinecraftRenderWrapper mcRender = SingletonHandler.get(IMinecraftRenderWrapper.class); private final EventApi eventApi = EventApi.INSTANCE; private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); @@ -119,7 +120,7 @@ public class ClientApi // these can't be set until after the buffers are built (in renderer.drawLODs) // otherwise the buffers may be set to the wrong size, or not changed at all - ApiShared.previousChunkRenderDistance = mc.getRenderDistance(); + ApiShared.previousChunkRenderDistance = mcRender.getRenderDistance(); ApiShared.previousLodRenderDistance = config.client().graphics().quality().getLodChunkRenderDistance(); } catch (Exception e) diff --git a/src/main/java/com/seibel/lod/api/lod/EventApi.java b/src/main/java/com/seibel/lod/api/lod/EventApi.java index 3a2608ead..473da95f5 100644 --- a/src/main/java/com/seibel/lod/api/lod/EventApi.java +++ b/src/main/java/com/seibel/lod/api/lod/EventApi.java @@ -36,7 +36,6 @@ import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperAdapters.world.IDimensionTypeWrapper; import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper; -import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; /** * This holds the methods that should be called @@ -50,7 +49,7 @@ public class EventApi { public static final EventApi INSTANCE = new EventApi(); - private final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); /** diff --git a/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java b/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java index a704f0451..b9367f8d6 100644 --- a/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java +++ b/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java @@ -61,7 +61,6 @@ import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.wrappers.block.BlockPosWrapper; import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; -import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; /** * This object creates the buffers that are @@ -73,7 +72,7 @@ import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; public class LodBufferBuilderFactory { private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); - private final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); /** The thread used to generate new LODs off the main thread. */ public static final ExecutorService mainGenThread = Executors.newSingleThreadExecutor(new LodThreadFactory(LodBufferBuilderFactory.class.getSimpleName() + " - main")); diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java index 246e3d980..40b7248e0 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java @@ -58,7 +58,7 @@ import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; */ public class LodBuilder { - private static final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private static final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private static final IBlockColorSingletonWrapper blockColorSingleton = SingletonHandler.get(IBlockColorSingletonWrapper.class); private final ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName())); diff --git a/src/main/java/com/seibel/lod/core/builders/worldGeneration/LodWorldGenerator.java b/src/main/java/com/seibel/lod/core/builders/worldGeneration/LodWorldGenerator.java index 6b0f346d3..fec761056 100644 --- a/src/main/java/com/seibel/lod/core/builders/worldGeneration/LodWorldGenerator.java +++ b/src/main/java/com/seibel/lod/core/builders/worldGeneration/LodWorldGenerator.java @@ -51,7 +51,7 @@ import net.minecraftforge.common.WorldWorkerManager; */ public class LodWorldGenerator { - private static final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private static final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); /** This holds the thread used to generate new LODs off the main thread. */ private final ExecutorService mainGenThread = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " world generator")); diff --git a/src/main/java/com/seibel/lod/core/objects/Box.java b/src/main/java/com/seibel/lod/core/objects/Box.java index f8a46d687..1a5764a45 100644 --- a/src/main/java/com/seibel/lod/core/objects/Box.java +++ b/src/main/java/com/seibel/lod/core/objects/Box.java @@ -43,7 +43,7 @@ import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; public class Box { private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); - private static final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private static final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); public static final int ADJACENT_HEIGHT_INDEX = 0; public static final int ADJACENT_DEPTH_INDEX = 1; diff --git a/src/main/java/com/seibel/lod/core/objects/lod/LodDimension.java b/src/main/java/com/seibel/lod/core/objects/lod/LodDimension.java index 62ddd5d1b..1b087c9a8 100644 --- a/src/main/java/com/seibel/lod/core/objects/lod/LodDimension.java +++ b/src/main/java/com/seibel/lod/core/objects/lod/LodDimension.java @@ -60,7 +60,7 @@ import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; public class LodDimension { private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); - private final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); public final IDimensionTypeWrapper dimension; diff --git a/src/main/java/com/seibel/lod/core/objects/math/Vec3d.java b/src/main/java/com/seibel/lod/core/objects/math/Vec3d.java new file mode 100644 index 000000000..c2ba8aa24 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/objects/math/Vec3d.java @@ -0,0 +1,257 @@ +/* + * This file is part of the Distant Horizon mod (formerly the LOD Mod), + * licensed under the GNU GPL v3 License. + * + * Copyright (C) 2020 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.seibel.lod.core.objects.math; + +import com.seibel.lod.core.util.LodUtil; + +/** + * This is closer to MC's implementation of a + * 3 element float vector than a 3 element double + * vector. Hopefully that shouldn't cause any issues. + * + * @author James Seibel + * @version 11-18-2021 + */ +public class Vec3d +{ + public static Vec3d XNeg = new Vec3d(-1.0F, 0.0F, 0.0F); + public static Vec3d XPos = new Vec3d(1.0F, 0.0F, 0.0F); + public static Vec3d YNeg = new Vec3d(0.0F, -1.0F, 0.0F); + public static Vec3d YPos = new Vec3d(0.0F, 1.0F, 0.0F); + public static Vec3d ZNeg = new Vec3d(0.0F, 0.0F, -1.0F); + public static Vec3d ZPos = new Vec3d(0.0F, 0.0F, 1.0F); + + public static final Vec3d ZERO_VECTOR = new Vec3d(0.0D, 0.0D, 0.0D); + + public double x; + public double y; + public double z; + + + + public Vec3d() + { + + } + + public Vec3d(double x, double y, double z) + { + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + else if (obj != null && this.getClass() == obj.getClass()) + { + Vec3d Vec3f = (Vec3d) obj; + if (Double.compare(Vec3f.x, this.x) != 0) + { + return false; + } + else if (Double.compare(Vec3f.y, this.y) != 0) + { + return false; + } + else + { + return Double.compare(Vec3f.z, this.z) == 0; + } + } + else + { + return false; + } + } + + @Override + public int hashCode() + { + long longVal = Double.doubleToLongBits(this.x); + + int intVal = (int) (longVal ^ longVal >>> 32); + longVal = Double.doubleToLongBits(this.y); + intVal = 31 * intVal + (int) (longVal ^ longVal >>> 32); + longVal = Double.doubleToLongBits(this.z); + + return 31 * intVal + (int) (longVal ^ longVal >>> 32); + } + + public void mul(double scalar) + { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + } + + public void mul(double x, double y, double z) + { + this.x *= x; + this.y *= y; + this.z *= z; + } + + public void clamp(double min, double max) + { + this.x = LodUtil.clamp(min, this.x, max); + this.y = LodUtil.clamp(min, this.y, max); + this.z = LodUtil.clamp(min, this.z, max); + } + + public void set(double x, double y, double z) + { + this.x = x; + this.y = y; + this.z = z; + } + + public void add(double x, double y, double z) + { + this.x += x; + this.y += y; + this.z += z; + } + + public void add(Vec3d vector) + { + this.x += vector.x; + this.y += vector.y; + this.z += vector.z; + } + + public void subtract(Vec3d vector) + { + this.x -= vector.x; + this.y -= vector.y; + this.z -= vector.z; + } + + public double dotProduct(Vec3d vector) + { + return this.x * vector.x + this.y * vector.y + this.z * vector.z; + } + + public Vec3d normalize() + { + double value = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + return value < 1.0E-4D ? ZERO_VECTOR : new Vec3d(this.x / value, this.y / value, this.z / value); + } + + public void crossProduct(Vec3d vector) + { + double f = this.x; + double f1 = this.y; + double f2 = this.z; + double f3 = vector.x; + double f4 = vector.y; + double f5 = vector.z; + this.x = f1 * f5 - f2 * f4; + this.y = f2 * f3 - f * f5; + this.z = f * f4 - f1 * f3; + } + + /* Matrix3f is not currently needed/implemented + public void transform(Matrix3f p_229188_1_) + { + double f = this.x; + double f1 = this.y; + double f2 = this.z; + this.x = p_229188_1_.m00 * f + p_229188_1_.m01 * f1 + p_229188_1_.m02 * f2; + this.y = p_229188_1_.m10 * f + p_229188_1_.m11 * f1 + p_229188_1_.m12 * f2; + this.z = p_229188_1_.m20 * f + p_229188_1_.m21 * f1 + p_229188_1_.m22 * f2; + } + */ + + /* Quaternions are not currently needed/implemented + public void transform(Quaternion p_214905_1_) + { + Quaternion quaternion = new Quaternion(p_214905_1_); + quaternion.mul(new Quaternion(this.x(), this.y(), this.z(), 0.0F)); + Quaternion quaternion1 = new Quaternion(p_214905_1_); + quaternion1.conj(); + quaternion.mul(quaternion1); + this.set(quaternion.i(), quaternion.j(), quaternion.k()); + } + */ + + /* not currently needed + * percent may actually be partial ticks (which is available when rendering) + public void linearInterp(Vec3f resultingVector, double percent) + { + double f = 1.0F - percent; + this.x = this.x * f + resultingVector.x * percent; + this.y = this.y * f + resultingVector.y * percent; + this.z = this.z * f + resultingVector.z * percent; + } + */ + + /* Quaternions are not currently needed/implemented + public Quaternion rotation(double p_229193_1_) + { + return new Quaternion(this, p_229193_1_, false); + } + + + @OnlyIn(Dist.CLIENT) + public Quaternion rotationDegrees(double p_229187_1_) + { + return new Quaternion(this, p_229187_1_, true); + } + */ + + public Vec3d copy() + { + return new Vec3d(this.x, this.y, this.z); + } + + /* not currently needed/implemented + public void map(double2doubleFunction p_229191_1_) + { + this.x = p_229191_1_.get(this.x); + this.y = p_229191_1_.get(this.y); + this.z = p_229191_1_.get(this.z); + } + */ + + @Override + public String toString() + { + return "[" + this.x + ", " + this.y + ", " + this.z + "]"; + } + + // Forge start + public Vec3d(double[] values) + { + set(values); + } + + public void set(double[] values) + { + this.x = values[0]; + this.y = values[1]; + this.z = values[2]; + } +} diff --git a/src/main/java/com/seibel/lod/core/render/GlProxy.java b/src/main/java/com/seibel/lod/core/render/GlProxy.java index 610f7b958..c3099717b 100644 --- a/src/main/java/com/seibel/lod/core/render/GlProxy.java +++ b/src/main/java/com/seibel/lod/core/render/GlProxy.java @@ -55,7 +55,7 @@ public class GlProxy { private static GlProxy instance = null; - private static IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private static IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); /** Minecraft's GLFW window */ diff --git a/src/main/java/com/seibel/lod/core/render/LodRenderer.java b/src/main/java/com/seibel/lod/core/render/LodRenderer.java index 7bd2f3357..7ecb7f41b 100644 --- a/src/main/java/com/seibel/lod/core/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/core/render/LodRenderer.java @@ -29,7 +29,6 @@ import org.lwjgl.opengl.NVFogDistance; import com.seibel.lod.api.lod.ApiShared; import com.seibel.lod.core.builders.bufferBuilding.LodBufferBuilderFactory; import com.seibel.lod.core.builders.bufferBuilding.LodBufferBuilderFactory.VertexBuffersAndOffset; -import com.seibel.lod.core.enums.config.GpuUploadMethod; import com.seibel.lod.core.enums.rendering.DebugMode; import com.seibel.lod.core.enums.rendering.FogDistance; import com.seibel.lod.core.enums.rendering.FogDrawOverride; @@ -37,6 +36,8 @@ import com.seibel.lod.core.enums.rendering.FogQuality; import com.seibel.lod.core.objects.lod.LodDimension; import com.seibel.lod.core.objects.lod.RegionPos; import com.seibel.lod.core.objects.math.Mat4f; +import com.seibel.lod.core.objects.math.Vec3d; +import com.seibel.lod.core.objects.math.Vec3f; import com.seibel.lod.core.objects.opengl.LodVertexBuffer; import com.seibel.lod.core.objects.rending.NearFarFogSettings; import com.seibel.lod.core.render.shader.LodShaderProgram; @@ -49,16 +50,9 @@ import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.wrappers.block.BlockPosWrapper; import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; import com.seibel.lod.wrappers.handlers.ReflectionHandler; -import com.seibel.lod.wrappers.minecraft.McObjectConverter; -import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; +import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper; -import net.minecraft.client.renderer.ActiveRenderInfo; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.potion.Effects; import net.minecraft.profiler.IProfiler; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.vector.Vector3d; -import net.minecraft.util.math.vector.Vector3f; /** * This is where all the magic happens.
@@ -69,11 +63,11 @@ import net.minecraft.util.math.vector.Vector3f; */ public class LodRenderer { - /** - * this is the light used when rendering the LODs, - * it should be something different from what is used by Minecraft - */ - private static final int LOD_GL_LIGHT_NUMBER = GL15.GL_LIGHT2; +// /** +// * this is the light used when rendering the LODs, +// * it should be something different from what is used by Minecraft +// */ +// private static final int LOD_GL_LIGHT_NUMBER = GL15.GL_LIGHT2; /** * If true the LODs colors will be replaced with @@ -81,9 +75,10 @@ public class LodRenderer */ public DebugMode previousDebugMode = DebugMode.OFF; - private final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); - private final GameRenderer gameRender; + private final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); + private final MinecraftRenderWrapper mcRenderer = MinecraftRenderWrapper.INSTANCE; private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); + private IProfiler profiler; private int farPlaneBlockDistance; @@ -98,6 +93,7 @@ public class LodRenderer * These have to be separate because we can't override the * buffers in the VBOs (and we don't want to) */ + @SuppressWarnings("unused") private int[][][] storageBufferIds; private ChunkPosWrapper vbosCenter = new ChunkPosWrapper(0, 0); @@ -139,9 +135,6 @@ public class LodRenderer public LodRenderer(LodBufferBuilderFactory newLodNodeBufferBuilder) { - mc = MinecraftWrapper.INSTANCE; - gameRender = mc.getGameRenderer(); - lodBufferBuilderFactory = newLodNodeBufferBuilder; } @@ -172,7 +165,7 @@ public class LodRenderer return; } - if (mc.getPlayer().getActiveEffectsMap().get(Effects.BLINDNESS) != null) + if (mcRenderer.playerHasBlindnessEffect()) { // if the player is blind don't render LODs, // and don't change minecraft's fog @@ -251,7 +244,7 @@ public class LodRenderer Mat4f modelViewMatrix = offsetTheModelViewMatrix(mcModelViewMatrix, partialTicks); - vanillaBlockRenderedDistance = mc.getRenderDistance() * LodUtil.CHUNK_WIDTH; + vanillaBlockRenderedDistance = mcRenderer.getRenderDistance() * LodUtil.CHUNK_WIDTH; // required for setupFog and setupProjectionMatrix if (mc.getWrappedClientWorld().getDimensionType().hasCeiling()) farPlaneBlockDistance = Math.min(config.client().graphics().quality().getLodChunkRenderDistance(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * LodUtil.CHUNK_WIDTH; @@ -289,16 +282,15 @@ public class LodRenderer if (vbos != null) { - ActiveRenderInfo camera = mc.getGameRenderer().getMainCamera(); - Vector3f cameraDir = camera.getLookVector(); + Vec3f cameraDir = mcRenderer.getLookAtVector(); // TODO re-enable once rendering is totally working boolean cullingDisabled = true; //LodConfig.client().graphics.advancedGraphicsOption.disableDirectionalCulling.get(); - boolean renderBufferStorage = config.client().graphics().advancedGraphics().getGpuUploadMethod() == GpuUploadMethod.BUFFER_STORAGE && glProxy.bufferStorageSupported; +// boolean renderBufferStorage = config.client().graphics().advancedGraphics().getGpuUploadMethod() == GpuUploadMethod.BUFFER_STORAGE && glProxy.bufferStorageSupported; // used to determine what type of fog to render - int halfWidth = vbos.length / 2; - int quarterWidth = vbos.length / 4; +// int halfWidth = vbos.length / 2; +// int quarterWidth = vbos.length / 4; // where the center of the built buffers is (needed when culling regions) RegionPos vboCenterRegionPos = new RegionPos(vbosCenter); @@ -338,7 +330,7 @@ public class LodRenderer x + vboCenterRegionPos.x - (lodDim.getWidth() / 2), z + vboCenterRegionPos.z - (lodDim.getWidth() / 2)); - if (cullingDisabled || RenderUtil.isRegionInViewFrustum(camera.getBlockPosition(), cameraDir, vboPos.blockPos())) + if (cullingDisabled || RenderUtil.isRegionInViewFrustum(mcRenderer.getCameraBlockPosition(), cameraDir, vboPos.blockPos())) { // TODO add fog to the fragment shader // if ((x > halfWidth - quarterWidth && x < halfWidth + quarterWidth) @@ -428,6 +420,7 @@ public class LodRenderer // Setup Functions // //=================// + @SuppressWarnings("unused") private void setupFog(FogDistance fogDistance, FogQuality fogQuality) { if (fogQuality == FogQuality.OFF) @@ -506,6 +499,7 @@ public class LodRenderer * Revert any changes that were made to the fog * and sets up the fog for Minecraft. */ + @SuppressWarnings("unused") private void cleanupFog(NearFarFogSettings fogSettings, float defaultFogStartDist, float defaultFogEndDist, int defaultFogMode, int defaultFogDistance) @@ -548,8 +542,7 @@ public class LodRenderer private Mat4f offsetTheModelViewMatrix(Mat4f mcModelViewMatrix, float partialTicks) { // get all relevant camera info - ActiveRenderInfo camera = mc.getGameRenderer().getMainCamera(); - Vector3d projectedView = camera.getPosition(); + Vec3d projectedView = mcRenderer.getCameraExactPosition(); // translate the camera relative to the regions' center // (AxisAlignedBoundingBoxes (LODs) use doubles and thus have a higher @@ -573,15 +566,15 @@ public class LodRenderer // create the new projection matrix Mat4f lodProj = Mat4f.perspective( - getFov(partialTicks, true), - (float) this.mc.getWindow().getScreenWidth() / (float) this.mc.getWindow().getScreenHeight(), + mcRenderer.getFov(partialTicks), + (float) this.mcRenderer.getScreenWidth() / (float) this.mcRenderer.getScreenHeight(), config.client().graphics().advancedGraphics().getUseExtendedNearClipPlane() ? vanillaBlockRenderedDistance / 5 : 1, farPlaneBlockDistance * LodUtil.CHUNK_WIDTH / 2); // get Minecraft's un-edited projection matrix // (this is before it is zoomed, distorted, etc.) - Mat4f defaultMcProj = McObjectConverter.Convert(mc.getGameRenderer().getProjectionMatrix(mc.getGameRenderer().getMainCamera(), partialTicks, true)); + Mat4f defaultMcProj = mcRenderer.getDefaultProjectionMatrix(partialTicks); // true here means use "use fov setting" (probably) // this logic strips away the defaultMcProj matrix, so we @@ -686,15 +679,9 @@ public class LodRenderer { lodBufferBuilderFactory.destroyBuffers(); } - - // TODO move this into the MC wrapper - private double getFov(float partialTicks, boolean useFovSetting) - { - return mc.getGameRenderer().getFov(mc.getGameRenderer().getMainCamera(), partialTicks, useFovSetting); - } - - + /** Return what fog settings should be used when rendering. */ + @SuppressWarnings("unused") private NearFarFogSettings determineFogSettings() { NearFarFogSettings fogSettings = new NearFarFogSettings(); @@ -796,7 +783,7 @@ public class LodRenderer /** Determines if the LODs should have a fullRegen or partialRegen */ private void determineIfLodsShouldRegenerate(LodDimension lodDim, float partialTicks) { - short chunkRenderDistance = (short) mc.getRenderDistance(); + short chunkRenderDistance = (short) mcRenderer.getRenderDistance(); int vanillaRenderedChunksWidth = chunkRenderDistance * 2 + 2; //=============// @@ -869,10 +856,10 @@ public class LodRenderer // (just in case the minLightingDifference is too large to notice the change) || (skyBrightness == 1.0f && prevSkyBrightness != 1.0f) // noon || (skyBrightness == 0.2f && prevSkyBrightness != 0.2f) // midnight - || mc.getOptions().gamma != prevBrightness) + || mcRenderer.getGamma() != prevBrightness) { fullRegen = true; - prevBrightness = mc.getOptions().gamma; + prevBrightness = mcRenderer.getGamma(); prevSkyBrightness = skyBrightness; } @@ -917,15 +904,15 @@ public class LodRenderer //==============// // determine which LODs should not be rendered close to the player - HashSet chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, mc.getPlayerBlockPos()); + HashSet chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, mc.getPlayerBlockPos()); int xIndex; int zIndex; - for (ChunkPos pos : chunkPosToSkip) + for (ChunkPosWrapper pos : chunkPosToSkip) { vanillaRenderedChunksEmptySkip = false; - xIndex = (pos.x - mc.getPlayerChunkPos().getX()) + (chunkRenderDistance + 1); - zIndex = (pos.z - mc.getPlayerChunkPos().getZ()) + (chunkRenderDistance + 1); + xIndex = (pos.getX() - mc.getPlayerChunkPos().getX()) + (chunkRenderDistance + 1); + zIndex = (pos.getZ() - mc.getPlayerChunkPos().getZ()) + (chunkRenderDistance + 1); // sometimes we are given chunks that are outside the render distance, // This prevents index out of bounds exceptions diff --git a/src/main/java/com/seibel/lod/core/render/RenderUtil.java b/src/main/java/com/seibel/lod/core/render/RenderUtil.java index 3a7023258..9a517dc40 100644 --- a/src/main/java/com/seibel/lod/core/render/RenderUtil.java +++ b/src/main/java/com/seibel/lod/core/render/RenderUtil.java @@ -19,15 +19,11 @@ package com.seibel.lod.core.render; +import com.seibel.lod.core.objects.math.Vec3f; import com.seibel.lod.core.util.LodUtil; -import com.seibel.lod.core.wrapperAdapters.SingletonHandler; -import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; -import com.seibel.lod.wrappers.block.BlockPosWrapper; +import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; -import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; - -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.vector.Vector3f; +import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper; /** * This holds miscellaneous helper code @@ -38,7 +34,7 @@ import net.minecraft.util.math.vector.Vector3f; */ public class RenderUtil { - private static final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private static final MinecraftRenderWrapper MC_RENDER = MinecraftRenderWrapper.INSTANCE; /** @@ -47,11 +43,11 @@ public class RenderUtil */ public static boolean isChunkPosInLoadedArea(ChunkPosWrapper pos, ChunkPosWrapper center) { - return (pos.getX() >= center.getX() - mc.getRenderDistance() - && pos.getX() <= center.getX() + mc.getRenderDistance()) + return (pos.getX() >= center.getX() - MC_RENDER.getRenderDistance() + && pos.getX() <= center.getX() + MC_RENDER.getRenderDistance()) && - (pos.getZ() >= center.getZ() - mc.getRenderDistance() - && pos.getZ() <= center.getZ() + mc.getRenderDistance()); + (pos.getZ() >= center.getZ() - MC_RENDER.getRenderDistance() + && pos.getZ() <= center.getZ() + MC_RENDER.getRenderDistance()); } /** @@ -60,11 +56,11 @@ public class RenderUtil */ public static boolean isCoordinateInLoadedArea(int x, int z, int centerCoordinate) { - return (x >= centerCoordinate - mc.getRenderDistance() - && x <= centerCoordinate + mc.getRenderDistance()) + return (x >= centerCoordinate - MC_RENDER.getRenderDistance() + && x <= centerCoordinate + MC_RENDER.getRenderDistance()) && - (z >= centerCoordinate - mc.getRenderDistance() - && z <= centerCoordinate + mc.getRenderDistance()); + (z >= centerCoordinate - MC_RENDER.getRenderDistance() + && z <= centerCoordinate + MC_RENDER.getRenderDistance()); } @@ -88,24 +84,24 @@ public class RenderUtil * Returns true if one of the region's 4 corners is in front * of the camera. */ - public static boolean isRegionInViewFrustum(BlockPos playerBlockPos, Vector3f cameraDir, BlockPosWrapper vboCenterPos) + public static boolean isRegionInViewFrustum(AbstractBlockPosWrapper playerBlockPos, Vec3f cameraDir, AbstractBlockPosWrapper vboCenterPos) { // convert the vbo position into a direction vector // starting from the player's position - Vector3f vboVec = new Vector3f(vboCenterPos.getX(), 0, vboCenterPos.getZ()); - Vector3f playerVec = new Vector3f(playerBlockPos.getX(), playerBlockPos.getY(), playerBlockPos.getZ()); + Vec3f vboVec = new Vec3f(vboCenterPos.getX(), 0, vboCenterPos.getZ()); + Vec3f playerVec = new Vec3f(playerBlockPos.getX(), playerBlockPos.getY(), playerBlockPos.getZ()); - vboVec.sub(playerVec); - Vector3f vboCenterVec = vboVec; + vboVec.subtract(playerVec); + Vec3f vboCenterVec = vboVec; int halfRegionWidth = LodUtil.REGION_WIDTH / 2; // calculate the 4 corners - Vector3f vboSeVec = new Vector3f(vboCenterVec.x() + halfRegionWidth, vboCenterVec.y(), vboCenterVec.z() + halfRegionWidth); - Vector3f vboSwVec = new Vector3f(vboCenterVec.x() - halfRegionWidth, vboCenterVec.y(), vboCenterVec.z() + halfRegionWidth); - Vector3f vboNwVec = new Vector3f(vboCenterVec.x() - halfRegionWidth, vboCenterVec.y(), vboCenterVec.z() - halfRegionWidth); - Vector3f vboNeVec = new Vector3f(vboCenterVec.x() + halfRegionWidth, vboCenterVec.y(), vboCenterVec.z() - halfRegionWidth); + Vec3f vboSeVec = new Vec3f(vboCenterVec.x + halfRegionWidth, vboCenterVec.y, vboCenterVec.z + halfRegionWidth); + Vec3f vboSwVec = new Vec3f(vboCenterVec.x - halfRegionWidth, vboCenterVec.y, vboCenterVec.z + halfRegionWidth); + Vec3f vboNwVec = new Vec3f(vboCenterVec.x - halfRegionWidth, vboCenterVec.y, vboCenterVec.z - halfRegionWidth); + Vec3f vboNeVec = new Vec3f(vboCenterVec.x + halfRegionWidth, vboCenterVec.y, vboCenterVec.z - halfRegionWidth); // if any corner is visible, this region should be rendered return isNormalizedVectorInViewFrustum(vboSeVec, cameraDir) || @@ -118,11 +114,11 @@ public class RenderUtil * Currently takes the dot product of the two vectors, * but in the future could do more complicated frustum culling tests. */ - private static boolean isNormalizedVectorInViewFrustum(Vector3f objectVector, Vector3f cameraDir) + private static boolean isNormalizedVectorInViewFrustum(Vec3f objectVector, Vec3f cameraDir) { // the -0.1 is to offer a slight buffer, so we are // more likely to render LODs and thus, hopefully prevent // flickering or odd disappearances - return objectVector.dot(cameraDir) > -0.1; + return objectVector.dotProduct(cameraDir) > -0.1; } } diff --git a/src/main/java/com/seibel/lod/core/util/ColorUtil.java b/src/main/java/com/seibel/lod/core/util/ColorUtil.java index 94f30e0ba..161d83e52 100644 --- a/src/main/java/com/seibel/lod/core/util/ColorUtil.java +++ b/src/main/java/com/seibel/lod/core/util/ColorUtil.java @@ -33,7 +33,7 @@ import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; */ public class ColorUtil { - private static final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private static final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); public static int rgbToInt(int red, int green, int blue) diff --git a/src/main/java/com/seibel/lod/core/util/DetailDistanceUtil.java b/src/main/java/com/seibel/lod/core/util/DetailDistanceUtil.java index 04755bc2a..0f9137f43 100644 --- a/src/main/java/com/seibel/lod/core/util/DetailDistanceUtil.java +++ b/src/main/java/com/seibel/lod/core/util/DetailDistanceUtil.java @@ -25,6 +25,7 @@ import com.seibel.lod.core.enums.config.HorizontalResolution; import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; +import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; /** @@ -34,18 +35,19 @@ import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; */ public class DetailDistanceUtil { - private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); - private static final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); + private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); + private static final MinecraftRenderWrapper MC_RENDER = MinecraftRenderWrapper.INSTANCE; private static final double genMultiplier = 1.0; private static final double treeGenMultiplier = 1.0; private static final double treeCutMultiplier = 1.0; - private static byte minGenDetail = config.client().graphics().quality().getDrawResolution().detailLevel; - private static byte minDrawDetail = (byte) Math.max(config.client().graphics().quality().getDrawResolution().detailLevel, config.client().graphics().quality().getDrawResolution().detailLevel); + private static byte minGenDetail = CONFIG.client().graphics().quality().getDrawResolution().detailLevel; + private static byte minDrawDetail = (byte) Math.max(CONFIG.client().graphics().quality().getDrawResolution().detailLevel, CONFIG.client().graphics().quality().getDrawResolution().detailLevel); private static final int maxDetail = LodUtil.REGION_DETAIL_LEVEL + 1; private static final int minDistance = 0; - private static int minDetailDistance = (int) (mc.getRenderDistance()*16 * 1.42f); - private static int maxDistance = config.client().graphics().quality().getLodChunkRenderDistance() * 16 * 2; + private static int minDetailDistance = (int) (MC_RENDER.getRenderDistance()*16 * 1.42f); + private static int maxDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance() * 16 * 2; private static final HorizontalResolution[] lodGenDetails = { @@ -65,10 +67,10 @@ public class DetailDistanceUtil public static void updateSettings() { - minDetailDistance = (int) (mc.getRenderDistance()*16 * 1.42f); - minGenDetail = config.client().graphics().quality().getDrawResolution().detailLevel; - minDrawDetail = (byte) Math.max(config.client().graphics().quality().getDrawResolution().detailLevel, config.client().graphics().quality().getDrawResolution().detailLevel); - maxDistance = config.client().graphics().quality().getLodChunkRenderDistance() * 16 * 8; + minDetailDistance = (int) (MC_RENDER.getRenderDistance()*16 * 1.42f); + minGenDetail = CONFIG.client().graphics().quality().getDrawResolution().detailLevel; + minDrawDetail = (byte) Math.max(CONFIG.client().graphics().quality().getDrawResolution().detailLevel, CONFIG.client().graphics().quality().getDrawResolution().detailLevel); + maxDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance() * 16 * 8; } public static int baseDistanceFunction(int detail) @@ -78,15 +80,15 @@ public class DetailDistanceUtil if (detail >= maxDetail) return maxDistance; - if (config.client().graphics().advancedGraphics().getAlwaysDrawAtMaxQuality()) + if (CONFIG.client().graphics().advancedGraphics().getAlwaysDrawAtMaxQuality()) return detail * 0x10000; //if you want more you are doing wrong - int distanceUnit = config.client().graphics().quality().getHorizontalScale().distanceUnit; - if (config.client().graphics().quality().getHorizontalQuality() == HorizontalQuality.LOWEST) + int distanceUnit = CONFIG.client().graphics().quality().getHorizontalScale().distanceUnit; + if (CONFIG.client().graphics().quality().getHorizontalQuality() == HorizontalQuality.LOWEST) return (detail * distanceUnit); else { - double base = config.client().graphics().quality().getHorizontalQuality().quadraticBase; + double base = CONFIG.client().graphics().quality().getHorizontalQuality().quadraticBase; return (int) (Math.pow(base, detail) * distanceUnit); } } @@ -101,14 +103,14 @@ public class DetailDistanceUtil int detail; if (distance == 0 || (distance < minDetailDistance && useRenderMinDistance) - || config.client().graphics().advancedGraphics().getAlwaysDrawAtMaxQuality()) + || CONFIG.client().graphics().advancedGraphics().getAlwaysDrawAtMaxQuality()) return minDetail; - int distanceUnit = config.client().graphics().quality().getHorizontalScale().distanceUnit; - if (config.client().graphics().quality().getHorizontalQuality() == HorizontalQuality.LOWEST) + int distanceUnit = CONFIG.client().graphics().quality().getHorizontalScale().distanceUnit; + if (CONFIG.client().graphics().quality().getHorizontalQuality() == HorizontalQuality.LOWEST) detail = (byte) distance / distanceUnit; else { - double base = config.client().graphics().quality().getHorizontalQuality().quadraticBase; + double base = CONFIG.client().graphics().quality().getHorizontalQuality().quadraticBase; double logBase = Math.log(base); //noinspection IntegerDivisionInFloatingPointContext detail = (byte) (Math.log(distance / distanceUnit) / logBase); @@ -138,7 +140,7 @@ public class DetailDistanceUtil public static DistanceGenerationMode getDistanceGenerationMode(int detail) { - return config.client().worldGenerator().getDistanceGenerationMode(); + return CONFIG.client().worldGenerator().getDistanceGenerationMode(); } public static byte getLodDrawDetail(int detail) @@ -170,7 +172,7 @@ public class DetailDistanceUtil public static int getMaxVerticalData(int detail) { - return config.client().graphics().quality().getVerticalQuality().maxVerticalData[LodUtil.clamp(minGenDetail, detail, LodUtil.REGION_DETAIL_LEVEL)]; + return CONFIG.client().graphics().quality().getVerticalQuality().maxVerticalData[LodUtil.clamp(minGenDetail, detail, LodUtil.REGION_DETAIL_LEVEL)]; } } diff --git a/src/main/java/com/seibel/lod/core/util/LodUtil.java b/src/main/java/com/seibel/lod/core/util/LodUtil.java index 188ad86da..4f7ac15f6 100644 --- a/src/main/java/com/seibel/lod/core/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/core/util/LodUtil.java @@ -38,13 +38,8 @@ import com.seibel.lod.core.wrapperAdapters.world.IDimensionTypeWrapper; import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper; import com.seibel.lod.wrappers.block.BlockPosWrapper; import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; -import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; +import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper; -import net.minecraft.client.multiplayer.ServerData; -import net.minecraft.client.renderer.WorldRenderer; -import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher.CompiledChunk; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.ChunkPos; import net.minecraft.world.chunk.ChunkSection; import net.minecraft.world.chunk.IChunk; import net.minecraft.world.gen.Heightmap; @@ -57,8 +52,9 @@ import net.minecraft.world.gen.Heightmap; */ public class LodUtil { - private static final IMinecraftWrapper mc = SingletonHandler.get(MinecraftWrapper.class); - private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); + private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); + private static final MinecraftRenderWrapper MC_RENDER = MinecraftRenderWrapper.INSTANCE; + private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); /** * Vanilla render distances less than or equal to this will not allow partial @@ -158,33 +154,16 @@ public class LodUtil - /** - * Gets the first valid ServerWorld. - * @return null if there are no ServerWorlds - */ -// public static ServerWorld getFirstValidServerWorld() -// { -// if (mc.hasSinglePlayerServer()) -// return null; -// -// Iterable worlds = mc.getSinglePlayerServer().getAllLevels(); -// -// for (ServerWorld world : worlds) -// return world; -// -// return null; -// } - /** * Gets the ServerWorld for the relevant dimension. * @return null if there is no ServerWorld for the given dimension */ public static IWorldWrapper getServerWorldFromDimension(IDimensionTypeWrapper newDimension) { - if(!mc.hasSinglePlayerServer()) + if(!MC.hasSinglePlayerServer()) return null; - Iterable worlds = mc.getAllServerWorlds(); + Iterable worlds = MC.getAllServerWorlds(); IWorldWrapper returnWorld = null; for (IWorldWrapper world : worlds) @@ -239,7 +218,7 @@ public class LodUtil */ public static String getWorldID(IWorldWrapper world) { - if (mc.hasSinglePlayerServer()) + if (MC.hasSinglePlayerServer()) { // chop off the dimension ID as it is not needed/wanted String dimId = getDimensionIDFromWorld(world); @@ -267,7 +246,7 @@ public class LodUtil */ public static String getDimensionIDFromWorld(IWorldWrapper world) { - if (mc.hasSinglePlayerServer()) + if (MC.hasSinglePlayerServer()) { // this will return the world save location // and the dimension folder @@ -287,10 +266,9 @@ public class LodUtil /** returns the server name, IP and game version. */ public static String getServerId() { - ServerData server = mc.getCurrentServer(); - String serverName = server.name.replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); - String serverIp = server.ip.replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); - String serverMcVersion = server.version.getString().replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); + String serverName = MC.getCurrentServerName().replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); + String serverIp = MC.getCurrentServerIp().replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); + String serverMcVersion = MC.getCurrentServerVersion().replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); return serverName + ", IP " + serverIp + ", GameVersion " + serverMcVersion; } @@ -346,14 +324,14 @@ public class LodUtil * Get a HashSet of all ChunkPos within the normal render distance * that should not be rendered. */ - public static HashSet getNearbyLodChunkPosToSkip(LodDimension lodDim, BlockPosWrapper blockPosWrapper) + public static HashSet getNearbyLodChunkPosToSkip(LodDimension lodDim, BlockPosWrapper blockPosWrapper) { - int chunkRenderDist = mc.getRenderDistance(); + int chunkRenderDist = MC_RENDER.getRenderDistance(); ChunkPosWrapper centerChunk = new ChunkPosWrapper(blockPosWrapper); int skipRadius; - VanillaOverdraw overdraw = config.client().graphics().advancedGraphics().getVanillaOverdraw(); - HorizontalResolution drawRes = config.client().graphics().quality().getDrawResolution(); + VanillaOverdraw overdraw = CONFIG.client().graphics().advancedGraphics().getVanillaOverdraw(); + HorizontalResolution drawRes = CONFIG.client().graphics().quality().getDrawResolution(); // apply distance based rules for dynamic overdraw if (overdraw == VanillaOverdraw.DYNAMIC @@ -416,7 +394,7 @@ public class LodUtil // get the chunks that are going to be rendered by Minecraft - HashSet posToSkip = getRenderedChunks(); + HashSet posToSkip = MC_RENDER.getRenderedChunks(); // remove everything outside the skipRadius, @@ -429,8 +407,7 @@ public class LodUtil { if (x <= centerChunk.getX() - skipRadius || x >= centerChunk.getX() + skipRadius || z <= centerChunk.getZ() - skipRadius || z >= centerChunk.getZ() + skipRadius) - posToSkip.remove(new ChunkPos(x, z)); - + posToSkip.remove(new ChunkPosWrapper(x, z)); } } } @@ -438,38 +415,6 @@ public class LodUtil } - /** - * This method returns the ChunkPos of all chunks that Minecraft - * is going to render this frame.

- *

- * Note: This isn't perfect. It will return some chunks that are outside - * the clipping plane. (For example, if you are high above the ground some chunks - * will be incorrectly added, even though they are outside render range). - */ - public static HashSet getRenderedChunks() - { - HashSet loadedPos = new HashSet<>(); - - // Wow, those are some long names! - - // go through every RenderInfo to get the compiled chunks - WorldRenderer renderer = mc.getLevelRenderer(); - for (WorldRenderer.LocalRenderInformationContainer worldRenderer$LocalRenderInformationContainer : renderer.renderChunks) - { - CompiledChunk compiledChunk = worldRenderer$LocalRenderInformationContainer.chunk.getCompiledChunk(); - if (!compiledChunk.hasNoRenderableLayers()) - { - // add the ChunkPos for every rendered chunk - BlockPos bpos = worldRenderer$LocalRenderInformationContainer.chunk.getOrigin(); - - loadedPos.add(new ChunkPos(bpos)); - } - } - - - return loadedPos; - } - /** * This method find if a given chunk is a border chunk of the renderable ones * @param vanillaRenderedChunks matrix of the vanilla rendered chunks @@ -498,10 +443,10 @@ public class LodUtil /** This is copied from Minecraft's MathHelper class */ public static float fastInvSqrt(float numb) { - float half = 0.5F * numb; - int i = Float.floatToIntBits(numb); - i = 1597463007 - (i >> 1); - numb = Float.intBitsToFloat(i); - return numb * (1.5F - half * numb * numb); - } + float half = 0.5F * numb; + int i = Float.floatToIntBits(numb); + i = 1597463007 - (i >> 1); + numb = Float.intBitsToFloat(i); + return numb * (1.5F - half * numb * numb); + } } diff --git a/src/main/java/com/seibel/lod/core/wrapperAdapters/block/AbstractBlockPosWrapper.java b/src/main/java/com/seibel/lod/core/wrapperAdapters/block/AbstractBlockPosWrapper.java new file mode 100644 index 000000000..ba005186b --- /dev/null +++ b/src/main/java/com/seibel/lod/core/wrapperAdapters/block/AbstractBlockPosWrapper.java @@ -0,0 +1,27 @@ +package com.seibel.lod.core.wrapperAdapters.block; + +import com.seibel.lod.core.enums.LodDirection; + +public abstract class AbstractBlockPosWrapper +{ + public AbstractBlockPosWrapper() + { + + } + + public AbstractBlockPosWrapper(int x, int y, int z) + { + + } + + public abstract void set(int x, int y, int z); + + public abstract int getX(); + public abstract int getY(); + public abstract int getZ(); + + public abstract int get(LodDirection.Axis axis); + + /** returns itself */ + public abstract AbstractBlockPosWrapper offset(int x, int y, int z); +} diff --git a/src/main/java/com/seibel/lod/core/wrapperAdapters/minecraft/IMinecraftRenderWrapper.java b/src/main/java/com/seibel/lod/core/wrapperAdapters/minecraft/IMinecraftRenderWrapper.java new file mode 100644 index 000000000..a7e777dd0 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/wrapperAdapters/minecraft/IMinecraftRenderWrapper.java @@ -0,0 +1,49 @@ +package com.seibel.lod.core.wrapperAdapters.minecraft; + +import java.util.HashSet; + +import com.seibel.lod.core.objects.math.Mat4f; +import com.seibel.lod.core.objects.math.Vec3d; +import com.seibel.lod.core.objects.math.Vec3f; +import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; +import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; + +/** + * Contains everything related to + * rendering in Minecraft. + * + * @author James Seibel + * @version 11-18-2021 + */ +public interface IMinecraftRenderWrapper +{ + public Vec3f getLookAtVector(); + + public AbstractBlockPosWrapper getCameraBlockPosition(); + + public boolean playerHasBlindnessEffect(); + + public Vec3d getCameraExactPosition(); + + public Mat4f getDefaultProjectionMatrix(float partialTicks); + + public double getGamma(); + + public double getFov(float partialTicks); + + /** Measured in chunks */ + public int getRenderDistance(); + + public int getScreenWidth(); + public int getScreenHeight(); + + /** + * This method returns the ChunkPos of all chunks that Minecraft + * is going to render this frame.

+ *

+ * Note: This isn't perfect. It will return some chunks that are outside + * the clipping plane. (For example, if you are high above the ground some chunks + * will be incorrectly added, even though they are outside render range). + */ + public HashSet getRenderedChunks(); +} diff --git a/src/main/java/com/seibel/lod/core/wrapperAdapters/minecraft/IMinecraftWrapper.java b/src/main/java/com/seibel/lod/core/wrapperAdapters/minecraft/IMinecraftWrapper.java index fef941410..5c5dd6022 100644 --- a/src/main/java/com/seibel/lod/core/wrapperAdapters/minecraft/IMinecraftWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperAdapters/minecraft/IMinecraftWrapper.java @@ -66,6 +66,10 @@ public interface IMinecraftWrapper public boolean hasSinglePlayerServer(); + public String getCurrentServerName(); + public String getCurrentServerIp(); + public String getCurrentServerVersion(); + /** Returns the dimension the player is currently in */ public DimensionTypeWrapper getCurrentDimension(); @@ -112,9 +116,6 @@ public interface IMinecraftWrapper public WorldWrapper getWrappedClientWorld(); - /** Measured in chunks */ - public int getRenderDistance(); - public File getGameDirectory(); public IProfiler getProfiler(); @@ -140,8 +141,12 @@ public interface IMinecraftWrapper */ public void crashMinecraft(String errorMessage, Throwable exception); - - + + + + + + diff --git a/src/main/java/com/seibel/lod/wrappers/DependencySetup.java b/src/main/java/com/seibel/lod/wrappers/DependencySetup.java index 8f35e82bc..a7498e269 100644 --- a/src/main/java/com/seibel/lod/wrappers/DependencySetup.java +++ b/src/main/java/com/seibel/lod/wrappers/DependencySetup.java @@ -3,9 +3,11 @@ package com.seibel.lod.wrappers; import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.block.IBlockColorSingletonWrapper; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; +import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftRenderWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.wrappers.block.BlockColorSingletonWrapper; import com.seibel.lod.wrappers.config.LodConfigWrapperSingleton; +import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.lod.wrappers.minecraft.MinecraftWrapper; /** @@ -24,5 +26,6 @@ public class DependencySetup SingletonHandler.bind(ILodConfigWrapperSingleton.class, LodConfigWrapperSingleton.INSTANCE); SingletonHandler.bind(IBlockColorSingletonWrapper.class, BlockColorSingletonWrapper.INSTANCE); SingletonHandler.bind(IMinecraftWrapper.class, MinecraftWrapper.INSTANCE); + SingletonHandler.bind(IMinecraftRenderWrapper.class, MinecraftRenderWrapper.INSTANCE); } } diff --git a/src/main/java/com/seibel/lod/wrappers/minecraft/MinecraftRenderWrapper.java b/src/main/java/com/seibel/lod/wrappers/minecraft/MinecraftRenderWrapper.java new file mode 100644 index 000000000..cfc30b7cd --- /dev/null +++ b/src/main/java/com/seibel/lod/wrappers/minecraft/MinecraftRenderWrapper.java @@ -0,0 +1,137 @@ +package com.seibel.lod.wrappers.minecraft; + +import java.util.HashSet; + +import com.seibel.lod.core.objects.math.Mat4f; +import com.seibel.lod.core.objects.math.Vec3d; +import com.seibel.lod.core.objects.math.Vec3f; +import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; +import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftRenderWrapper; +import com.seibel.lod.wrappers.block.BlockPosWrapper; +import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher.CompiledChunk; +import net.minecraft.potion.Effects; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.math.vector.Vector3f; + +/** + * A singleton that contains everything + * related to rendering in Minecraft. + * + * @author James Seibel + * @version 11-18-2021 + */ +public class MinecraftRenderWrapper implements IMinecraftRenderWrapper +{ + public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper(); + + private final GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer; + private final static Minecraft mc = Minecraft.getInstance(); + + + + @Override + public Vec3f getLookAtVector() + { + ActiveRenderInfo camera = gameRenderer.getMainCamera(); + Vector3f cameraDir = camera.getLookVector(); + return new Vec3f(cameraDir.x(), cameraDir.y(), cameraDir.z()); + } + + @Override + public AbstractBlockPosWrapper getCameraBlockPosition() + { + ActiveRenderInfo camera = gameRenderer.getMainCamera(); + BlockPos blockPos = camera.getBlockPosition(); + return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ()); + } + + @Override + public boolean playerHasBlindnessEffect() + { + return mc.player.getActiveEffectsMap().get(Effects.BLINDNESS) != null; + } + + @Override + public Vec3d getCameraExactPosition() + { + ActiveRenderInfo camera = gameRenderer.getMainCamera(); + Vector3d projectedView = camera.getPosition(); + + return new Vec3d(projectedView.x, projectedView.y, projectedView.z); + } + + @Override + public Mat4f getDefaultProjectionMatrix(float partialTicks) + { + return McObjectConverter.Convert(gameRenderer.getProjectionMatrix(gameRenderer.getMainCamera(), partialTicks, true)); + } + + @Override + public double getGamma() + { + return mc.options.gamma; + } + + @Override + public double getFov(float partialTicks) + { + return gameRenderer.getFov(gameRenderer.getMainCamera(), partialTicks, true); + } + + /** Measured in chunks */ + @Override + public int getRenderDistance() + { + return mc.options.renderDistance; + } + + @Override + public int getScreenWidth() + { + return mc.getWindow().getWidth(); + } + @Override + public int getScreenHeight() + { + return mc.getWindow().getHeight(); + } + + /** + * This method returns the ChunkPos of all chunks that Minecraft + * is going to render this frame.

+ *

+ * Note: This isn't perfect. It will return some chunks that are outside + * the clipping plane. (For example, if you are high above the ground some chunks + * will be incorrectly added, even though they are outside render range). + */ + @Override + public HashSet getRenderedChunks() + { + HashSet loadedPos = new HashSet<>(); + + // Wow, those are some long names! + + // go through every RenderInfo to get the compiled chunks + WorldRenderer renderer = mc.levelRenderer; + for (WorldRenderer.LocalRenderInformationContainer worldRenderer$LocalRenderInformationContainer : renderer.renderChunks) + { + CompiledChunk compiledChunk = worldRenderer$LocalRenderInformationContainer.chunk.getCompiledChunk(); + if (!compiledChunk.hasNoRenderableLayers()) + { + // add the ChunkPos for every rendered chunk + BlockPos bpos = worldRenderer$LocalRenderInformationContainer.chunk.getOrigin(); + + loadedPos.add(new ChunkPosWrapper(bpos)); + } + } + + return loadedPos; + } +} diff --git a/src/main/java/com/seibel/lod/wrappers/minecraft/MinecraftWrapper.java b/src/main/java/com/seibel/lod/wrappers/minecraft/MinecraftWrapper.java index c137fbeae..23bafd476 100644 --- a/src/main/java/com/seibel/lod/wrappers/minecraft/MinecraftWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/minecraft/MinecraftWrapper.java @@ -121,6 +121,24 @@ public class MinecraftWrapper implements IMinecraftWrapper return mc.hasSingleplayerServer(); } + @Override + public String getCurrentServerName() + { + return mc.getCurrentServer().name; + } + + @Override + public String getCurrentServerIp() + { + return mc.getCurrentServer().ip; + } + + @Override + public String getCurrentServerVersion() + { + return mc.getCurrentServer().version.getString(); + } + /** Returns the dimension the player is currently in */ @Override public DimensionTypeWrapper getCurrentDimension() @@ -259,13 +277,6 @@ public class MinecraftWrapper implements IMinecraftWrapper return WorldWrapper.getWorldWrapper(mc.level); } - /** Measured in chunks */ - @Override - public int getRenderDistance() - { - return mc.options.renderDistance; - } - @Override public File getGameDirectory() { @@ -364,6 +375,7 @@ public class MinecraftWrapper implements IMinecraftWrapper Minecraft.crash(report); } +