From 1ca7ac66713582c1b3c1c23289169e2bfad5071e Mon Sep 17 00:00:00 2001 From: James Seibel Date: Thu, 11 Nov 2021 23:16:59 -0600 Subject: [PATCH] Replace Matrix4f (MC) with Mat4f (ours) in LodRenderer --- .../java/com/seibel/lod/api/ClientApi.java | 14 +++- .../seibel/lod/mixin/MixinWorldRenderer.java | 9 ++- .../com/seibel/lod/objects/rending/Mat4f.java | 69 +++++++++++-------- .../com/seibel/lod/objects/rending/Vec3f.java | 25 ++++--- .../com/seibel/lod/proxy/ClientProxy.java | 7 +- .../com/seibel/lod/render/LodRenderer.java | 50 +++++--------- .../lod/render/shader/LodShaderProgram.java | 4 +- .../java/com/seibel/lod/util/LodUtil.java | 13 +++- .../com/seibel/lod/util/ThreadMapUtil.java | 2 + .../lod/wrappers/McObjectConverter.java | 36 ++++++++++ 10 files changed, 148 insertions(+), 81 deletions(-) create mode 100644 src/main/java/com/seibel/lod/wrappers/McObjectConverter.java diff --git a/src/main/java/com/seibel/lod/api/ClientApi.java b/src/main/java/com/seibel/lod/api/ClientApi.java index e13ace499..67b760e7e 100644 --- a/src/main/java/com/seibel/lod/api/ClientApi.java +++ b/src/main/java/com/seibel/lod/api/ClientApi.java @@ -1,9 +1,14 @@ package com.seibel.lod.api; import com.seibel.lod.LodMain; +import com.seibel.lod.objects.rending.Mat4f; -import net.minecraft.util.math.vector.Matrix4f; - +/** + * TODO + * + * @author James Seibel + * @version 11-11-2021 + */ public class ClientApi { @@ -15,9 +20,12 @@ public class ClientApi - public void renderLods(Matrix4f mcModelViewMatrix, float partialTicks) + public static void renderLods(Mat4f mcModelViewMatrix, float partialTicks) { LodMain.client_proxy.renderLods(mcModelViewMatrix, partialTicks); } + + + } diff --git a/src/main/java/com/seibel/lod/mixin/MixinWorldRenderer.java b/src/main/java/com/seibel/lod/mixin/MixinWorldRenderer.java index 23ba25de0..2ce84ff89 100644 --- a/src/main/java/com/seibel/lod/mixin/MixinWorldRenderer.java +++ b/src/main/java/com/seibel/lod/mixin/MixinWorldRenderer.java @@ -25,7 +25,9 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.mojang.blaze3d.matrix.MatrixStack; -import com.seibel.lod.LodMain; +import com.seibel.lod.api.ClientApi; +import com.seibel.lod.objects.rending.Mat4f; +import com.seibel.lod.wrappers.McObjectConverter; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.WorldRenderer; @@ -59,6 +61,9 @@ public class MixinWorldRenderer // only render if LODs are enabled and // only render before solid blocks if (renderType.equals(RenderType.solid())) - LodMain.client_proxy.renderLods(matrixStackIn, previousPartialTicks); + { + Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose()); + ClientApi.renderLods(mcModelViewMatrix, previousPartialTicks); + } } } diff --git a/src/main/java/com/seibel/lod/objects/rending/Mat4f.java b/src/main/java/com/seibel/lod/objects/rending/Mat4f.java index 6f3be5c15..4a1a39594 100644 --- a/src/main/java/com/seibel/lod/objects/rending/Mat4f.java +++ b/src/main/java/com/seibel/lod/objects/rending/Mat4f.java @@ -2,33 +2,31 @@ package com.seibel.lod.objects.rending; import java.nio.FloatBuffer; -import net.minecraft.util.math.vector.Vector3f; - /** * A (almost) exact copy of Minecraft's 1.16.5 * implementation of a 4x4 matrix. * * @author James Seibel - * + * @version 11-11-2021 */ public class Mat4f { - protected float m00; - protected float m01; - protected float m02; - protected float m03; - protected float m10; - protected float m11; - protected float m12; - protected float m13; - protected float m20; - protected float m21; - protected float m22; - protected float m23; - protected float m30; - protected float m31; - protected float m32; - protected float m33; + private float m00; + private float m01; + private float m02; + private float m03; + private float m10; + private float m11; + private float m12; + private float m13; + private float m20; + private float m21; + private float m22; + private float m23; + private float m30; + private float m31; + private float m32; + private float m33; public Mat4f() @@ -377,20 +375,18 @@ public class Mat4f this.m33 *= scalar; } - /* not currently needed/implemented - * Also the parameter names should be double checked as they may be incorrect - public static Matrix4Float perspective(double fov, float heightWidthRatio, float nearClipPlane, float farClipPlane) + public static Mat4f perspective(double fov, float widthHeightRatio, float nearClipPlane, float farClipPlane) { float f = (float) (1.0D / Math.tan(fov * ((float) Math.PI / 180F) / 2.0D)); - Matrix4Float matrix = new Matrix4Float(); - matrix.m00 = f / heightWidthRatio; + Mat4f matrix = new Mat4f(); + matrix.m00 = f / widthHeightRatio; matrix.m11 = f; matrix.m22 = (farClipPlane + nearClipPlane) / (nearClipPlane - farClipPlane); matrix.m32 = -1.0F; matrix.m23 = 2.0F * farClipPlane * nearClipPlane / (nearClipPlane - farClipPlane); return matrix; } - */ + /* not currently needed/implemented * Also the parameter names should be double checked as they may be incorrect @@ -409,11 +405,21 @@ public class Mat4f } */ - public void translate(Vector3f vec) + /** + * TODO: what kind of translation is this? + * and how is this different from "multiplyTranslationMatrix"? + */ + public void translate(Vec3f vec) { - this.m03 += vec.x(); - this.m13 += vec.y(); - this.m23 += vec.z(); + this.m03 += vec.x; + this.m13 += vec.y; + this.m23 += vec.z; + } + + /** originally "translate" from Minecraft's MatrixStack */ + public void multiplyTranslationMatrix(double x, double y, double z) + { + multiply(createTranslateMatrix((float)x, (float)y, (float)z)); } public Mat4f copy() @@ -466,6 +472,11 @@ public class Mat4f m33 = values[15]; } + public Mat4f(FloatBuffer buffer) + { + this(buffer.array()); + } + public void set(Mat4f mat) { this.m00 = mat.m00; diff --git a/src/main/java/com/seibel/lod/objects/rending/Vec3f.java b/src/main/java/com/seibel/lod/objects/rending/Vec3f.java index 38909e2eb..98f14d461 100644 --- a/src/main/java/com/seibel/lod/objects/rending/Vec3f.java +++ b/src/main/java/com/seibel/lod/objects/rending/Vec3f.java @@ -2,16 +2,23 @@ package com.seibel.lod.objects.rending; import com.seibel.lod.util.LodUtil; -import net.minecraft.util.math.MathHelper; - +/** + * A (almost) exact copy of Minecraft's 1.16.5 + * implementation of a 3 element vector. + * + * @author James Seibel + * @version 11-11-2021 + */ public class Vec3f { - public static Vec3f XN = new Vec3f(-1.0F, 0.0F, 0.0F); - public static Vec3f XP = new Vec3f(1.0F, 0.0F, 0.0F); - public static Vec3f YN = new Vec3f(0.0F, -1.0F, 0.0F); - public static Vec3f YP = new Vec3f(0.0F, 1.0F, 0.0F); - public static Vec3f ZN = new Vec3f(0.0F, 0.0F, -1.0F); - public static Vec3f ZP = new Vec3f(0.0F, 0.0F, 1.0F); + public static Vec3f XNeg = new Vec3f(-1.0F, 0.0F, 0.0F); + public static Vec3f XPos = new Vec3f(1.0F, 0.0F, 0.0F); + public static Vec3f YNeg = new Vec3f(0.0F, -1.0F, 0.0F); + public static Vec3f YPos = new Vec3f(0.0F, 1.0F, 0.0F); + public static Vec3f ZNeg = new Vec3f(0.0F, 0.0F, -1.0F); + public static Vec3f ZPos = new Vec3f(0.0F, 0.0F, 1.0F); + + public float x; public float y; public float z; @@ -130,7 +137,7 @@ public class Vec3f } else { - float f1 = MathHelper.fastInvSqrt(squaredSum); + float f1 = LodUtil.fastInvSqrt(squaredSum); this.x *= f1; this.y *= f1; this.z *= f1; diff --git a/src/main/java/com/seibel/lod/proxy/ClientProxy.java b/src/main/java/com/seibel/lod/proxy/ClientProxy.java index 3f4dac5e0..0ffec18cf 100644 --- a/src/main/java/com/seibel/lod/proxy/ClientProxy.java +++ b/src/main/java/com/seibel/lod/proxy/ClientProxy.java @@ -24,7 +24,6 @@ import org.apache.logging.log4j.Logger; import org.lwjgl.glfw.GLFW; import org.lwjgl.opengl.GL15; -import com.mojang.blaze3d.matrix.MatrixStack; import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder; import com.seibel.lod.builders.lodBuilding.LodBuilder; import com.seibel.lod.builders.worldGeneration.LodGenWorker; @@ -34,6 +33,7 @@ import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.objects.lod.LodDimension; import com.seibel.lod.objects.lod.LodWorld; import com.seibel.lod.objects.lod.RegionPos; +import com.seibel.lod.objects.rending.Mat4f; import com.seibel.lod.render.LodRenderer; import com.seibel.lod.util.DataPointUtil; import com.seibel.lod.util.DetailDistanceUtil; @@ -43,7 +43,6 @@ import com.seibel.lod.wrappers.MinecraftWrapper; import com.seibel.lod.wrappers.Chunk.ChunkWrapper; import net.minecraft.profiler.IProfiler; -import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.text.StringTextComponent; import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.event.TickEvent; @@ -101,7 +100,7 @@ public class ClientProxy //==============// /** Do any setup that is required to draw LODs and then tell the LodRenderer to draw. */ - public void renderLods(MatrixStack mcModelViewMatrix, float partialTicks) + public void renderLods(Mat4f mcModelViewMatrix, float partialTicks) { // comment out when creating a release // applyConfigOverrides(); @@ -135,7 +134,7 @@ public class ClientProxy // reset it after drawing the LODs float[] mcProjMatrixRaw = new float[16]; GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw); - Matrix4f mcProjectionMatrix = new Matrix4f(mcProjMatrixRaw); + Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw); // OpenGl outputs their matrices in col,row form instead of row,col // (or maybe vice versa I have no idea :P) mcProjectionMatrix.transpose(); diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index df2b7a086..67c04255d 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -26,7 +26,6 @@ import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.NVFogDistance; -import com.mojang.blaze3d.matrix.MatrixStack; import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder; import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder.VertexBuffersAndOffset; import com.seibel.lod.config.LodConfig; @@ -38,6 +37,7 @@ import com.seibel.lod.enums.GpuUploadMethod; import com.seibel.lod.handlers.ReflectionHandler; import com.seibel.lod.objects.lod.LodDimension; import com.seibel.lod.objects.lod.RegionPos; +import com.seibel.lod.objects.rending.Mat4f; import com.seibel.lod.objects.rending.NearFarFogSettings; import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.proxy.GlProxy; @@ -45,6 +45,7 @@ import com.seibel.lod.render.shader.LodShaderProgram; import com.seibel.lod.util.DetailDistanceUtil; import com.seibel.lod.util.LevelPosUtil; import com.seibel.lod.util.LodUtil; +import com.seibel.lod.wrappers.McObjectConverter; import com.seibel.lod.wrappers.MinecraftWrapper; import com.seibel.lod.wrappers.Block.BlockPosWrapper; import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper; @@ -55,7 +56,6 @@ import net.minecraft.client.renderer.vertex.VertexBuffer; import net.minecraft.potion.Effects; import net.minecraft.profiler.IProfiler; import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3f; @@ -157,7 +157,7 @@ public class LodRenderer * @param mcProjectionMatrix * @param partialTicks how far into the current tick this method was called. */ - public void drawLODs(LodDimension lodDim, MatrixStack mcModelViewMatrix, Matrix4f mcProjectionMatrix, float partialTicks, IProfiler newProfiler) + public void drawLODs(LodDimension lodDim, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfiler newProfiler) { //=================================// // determine if LODs should render // @@ -248,7 +248,7 @@ public class LodRenderer int currentProgram = GL20.glGetInteger(GL20.GL_CURRENT_PROGRAM); - Matrix4f modelViewMatrix = offsetTheModelViewMatrix(mcModelViewMatrix, partialTicks); + Mat4f modelViewMatrix = offsetTheModelViewMatrix(mcModelViewMatrix, partialTicks); vanillaBlockRenderedDistance = mc.getRenderDistance() * LodUtil.CHUNK_WIDTH; // required for setupFog and setupProjectionMatrix if (mc.getClientLevel().dimensionType().hasCeiling()) @@ -257,7 +257,7 @@ public class LodRenderer farPlaneBlockDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH; - Matrix4f projectionMatrix = createProjectionMatrix(mcProjectionMatrix, vanillaBlockRenderedDistance, partialTicks); + Mat4f projectionMatrix = createProjectionMatrix(mcProjectionMatrix, vanillaBlockRenderedDistance, partialTicks); // commented out until we can add shaders to handle lighting @@ -543,12 +543,8 @@ public class LodRenderer * (since AxisAlignedBoundingBoxes (LODs) use doubles and thus have a higher * accuracy vs the model view matrix, which only uses floats) */ - private Matrix4f offsetTheModelViewMatrix(MatrixStack mcModelViewMatrix, float partialTicks) + private Mat4f offsetTheModelViewMatrix(Mat4f mcModelViewMatrix, float partialTicks) { - // duplicate the last matrix - mcModelViewMatrix.pushPose(); - - // get all relevant camera info ActiveRenderInfo camera = mc.getGameRenderer().getMainCamera(); Vector3d projectedView = camera.getPosition(); @@ -559,16 +555,9 @@ public class LodRenderer BlockPosWrapper bufferPos = vbosCenter.getWorldPosition(); double xDiff = projectedView.x - bufferPos.getX(); double zDiff = projectedView.z - bufferPos.getZ(); - mcModelViewMatrix.translate(-xDiff, -projectedView.y, -zDiff); + mcModelViewMatrix.multiplyTranslationMatrix(-xDiff, -projectedView.y, -zDiff); - - - // get the modified model view matrix - Matrix4f lodModelViewMatrix = mcModelViewMatrix.last().pose(); - // remove the lod ModelViewMatrix - mcModelViewMatrix.popPose(); - - return lodModelViewMatrix; + return mcModelViewMatrix; } /** @@ -577,30 +566,30 @@ public class LodRenderer * @param vanillaBlockRenderedDistance Minecraft's vanilla far plane distance * @param partialTicks how many ticks into the frame we are */ - private Matrix4f createProjectionMatrix(Matrix4f currentProjectionMatrix, float vanillaBlockRenderedDistance, float partialTicks) + private Mat4f createProjectionMatrix(Mat4f currentProjectionMatrix, float vanillaBlockRenderedDistance, float partialTicks) { // create the new projection matrix - Matrix4f lodProj = - Matrix4f.perspective( - getFov(partialTicks, true), - (float) this.mc.getWindow().getScreenWidth() / (float) this.mc.getWindow().getScreenHeight(), - LodConfig.CLIENT.graphics.advancedGraphicsOption.useExtendedNearClipPlane.get() ? vanillaBlockRenderedDistance / 5 : 1, - farPlaneBlockDistance * LodUtil.CHUNK_WIDTH / 2); + + Mat4f lodProj = Mat4f.perspective( + getFov(partialTicks, true), + (float) this.mc.getWindow().getScreenWidth() / (float) this.mc.getWindow().getScreenHeight(), + LodConfig.CLIENT.graphics.advancedGraphicsOption.useExtendedNearClipPlane.get() ? vanillaBlockRenderedDistance / 5 : 1, + farPlaneBlockDistance * LodUtil.CHUNK_WIDTH / 2); + // get Minecraft's un-edited projection matrix // (this is before it is zoomed, distorted, etc.) - Matrix4f defaultMcProj = mc.getGameRenderer().getProjectionMatrix(mc.getGameRenderer().getMainCamera(), partialTicks, true); + Mat4f defaultMcProj = McObjectConverter.Convert(mc.getGameRenderer().getProjectionMatrix(mc.getGameRenderer().getMainCamera(), partialTicks, true)); // true here means use "use fov setting" (probably) - // this logic strips away the defaultMcProj matrix, so we // can get the distortionMatrix, which represents all // transformations, zooming, distortions, etc. done // to Minecraft's Projection matrix - Matrix4f defaultMcProjInv = defaultMcProj.copy(); + Mat4f defaultMcProjInv = defaultMcProj.copy(); defaultMcProjInv.invert(); - Matrix4f distortionMatrix = defaultMcProjInv.copy(); + Mat4f distortionMatrix = defaultMcProjInv.copy(); distortionMatrix.multiply(currentProjectionMatrix); @@ -611,7 +600,6 @@ public class LodRenderer return lodProj; } - ///** setup the lighting to be used for the LODs */ /*private void setupLighting(LodDimension lodDimension, float partialTicks) { diff --git a/src/main/java/com/seibel/lod/render/shader/LodShaderProgram.java b/src/main/java/com/seibel/lod/render/shader/LodShaderProgram.java index df90cef5b..ae0671c2b 100644 --- a/src/main/java/com/seibel/lod/render/shader/LodShaderProgram.java +++ b/src/main/java/com/seibel/lod/render/shader/LodShaderProgram.java @@ -24,7 +24,7 @@ import java.nio.FloatBuffer; import org.lwjgl.opengl.GL20; import org.lwjgl.system.MemoryStack; -import net.minecraft.util.math.vector.Matrix4f; +import com.seibel.lod.objects.rending.Mat4f; /** @@ -169,7 +169,7 @@ public class LodShaderProgram * @param location Uniform location * @param value Value to set */ - public void setUniform(int location, Matrix4f value) + public void setUniform(int location, Mat4f value) { try (MemoryStack stack = MemoryStack.stackPush()) { diff --git a/src/main/java/com/seibel/lod/util/LodUtil.java b/src/main/java/com/seibel/lod/util/LodUtil.java index e6bacffa9..931c3437a 100644 --- a/src/main/java/com/seibel/lod/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/util/LodUtil.java @@ -29,9 +29,9 @@ import com.seibel.lod.enums.HorizontalResolution; import com.seibel.lod.enums.VanillaOverdraw; import com.seibel.lod.objects.lod.LodDimension; import com.seibel.lod.objects.lod.RegionPos; +import com.seibel.lod.wrappers.MinecraftWrapper; import com.seibel.lod.wrappers.Block.BlockPosWrapper; import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper; -import com.seibel.lod.wrappers.MinecraftWrapper; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.renderer.WorldRenderer; @@ -498,4 +498,15 @@ public class LodUtil } return false; } + + + /** 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); + } } diff --git a/src/main/java/com/seibel/lod/util/ThreadMapUtil.java b/src/main/java/com/seibel/lod/util/ThreadMapUtil.java index 9eca7fbf6..8d7f705fd 100644 --- a/src/main/java/com/seibel/lod/util/ThreadMapUtil.java +++ b/src/main/java/com/seibel/lod/util/ThreadMapUtil.java @@ -58,6 +58,8 @@ public class ThreadMapUtil public static final ConcurrentMap> adjDataMap = new ConcurrentHashMap<>(); public static final ConcurrentMap boxMap = new ConcurrentHashMap<>(); + + /** returns the array NOT cleared every time */ public static boolean[] getAdjShadeDisabledArray() { diff --git a/src/main/java/com/seibel/lod/wrappers/McObjectConverter.java b/src/main/java/com/seibel/lod/wrappers/McObjectConverter.java new file mode 100644 index 000000000..e05a486f0 --- /dev/null +++ b/src/main/java/com/seibel/lod/wrappers/McObjectConverter.java @@ -0,0 +1,36 @@ +package com.seibel.lod.wrappers; + +import java.nio.FloatBuffer; + +import com.seibel.lod.objects.rending.Mat4f; + +import net.minecraft.util.math.vector.Matrix4f; + +/** + * This class converts between Minecraft objects (Ex: Matrix4f) + * and objects we created (Ex: Mat4f). + * Since we don't want to deal with a bunch of tiny changes + * every time Minecraft renames a variable in Matrix4f or something. + * + * @author James Seibel + * @version 11-11-2021 + */ +public class McObjectConverter +{ + + public McObjectConverter() + { + + } + + + /** 4x4 float matrix converter */ + public static Mat4f Convert(Matrix4f mcMatrix) + { + FloatBuffer buffer = FloatBuffer.allocate(16); + mcMatrix.store(buffer); + Mat4f matrix = new Mat4f(buffer); + matrix.transpose(); + return matrix; + } +}