Fix #67 (LODs not rotating with camera) and #68 (LODs culled based on player direction, not camera)

This commit is contained in:
James Seibel
2021-09-19 19:25:01 -05:00
parent 01a850eb9d
commit 34b92d1053
3 changed files with 44 additions and 36 deletions
@@ -32,11 +32,12 @@ import net.minecraft.client.renderer.WorldRenderer;
/**
* This class is used to mix in my rendering code
* before Minecraft starts rendering blocks.
* If this wasn't done the LODs would render on top
* If this wasn't done and we used Forge's
* render last event, the LODs would render on top
* of the normal terrain.
*
* @author James Seibel
* @version 05-29-2021
* @version 9-19-2021
*/
@Mixin(WorldRenderer.class)
public class MixinWorldRenderer
@@ -57,6 +58,6 @@ public class MixinWorldRenderer
// only render if LODs are enabled and
// only render before solid blocks
if (LodConfig.CLIENT.graphics.drawLODs.get() && renderType.equals(RenderType.solid()))
LodMain.client_proxy.renderLods(previousPartialTicks);
LodMain.client_proxy.renderLods(matrixStackIn, previousPartialTicks);
}
}
@@ -21,12 +21,14 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.seibel.lod.builders.LodBufferBuilder;
import com.seibel.lod.builders.LodBuilder;
import com.seibel.lod.builders.worldGeneration.LodNodeGenWorker;
import com.seibel.lod.builders.worldGeneration.LodWorldGenerator;
import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodWorld;
import com.seibel.lod.objects.RegionPos;
@@ -49,7 +51,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
* and is the starting point for most of the mod.
*
* @author James_Seibel
* @version 9-16-2021
* @version 9-19-2021
*/
public class ClientProxy
{
@@ -97,8 +99,9 @@ public class ClientProxy
/**
* Do any setup that is required to draw LODs
* and then tell the LodRenderer to draw.
* @param mcMatrixStack
*/
public void renderLods(float partialTicks)
public void renderLods(MatrixStack mcMatrixStack, float partialTicks)
{
// clear any out of date objects
mc.clearFrameObjectCache();
@@ -141,7 +144,7 @@ public class ClientProxy
profiler.pop(); // get out of "terrain"
profiler.push("LOD");
renderer.drawLODs(lodDim, partialTicks, mc.getProfiler());
renderer.drawLODs(lodDim, mcMatrixStack, partialTicks, mc.getProfiler());
profiler.pop(); // end LOD
profiler.push("terrain"); // go back into "terrain"
@@ -151,8 +154,10 @@ public class ClientProxy
// otherwise the buffers may be set to the wrong size, or not changed at all
previousChunkRenderDistance = mc.getRenderDistance();
previousLodRenderDistance = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get();
}catch (Exception e){
}
catch (Exception e)
{
LOGGER.error(e.getMessage());
}
}
@@ -170,8 +175,8 @@ public class ClientProxy
//LodConfig.CLIENT.debugMode.set(true);
// LodConfig.CLIENT.graphics.maxDrawDetail.set(LodDetail.FULL);
// LodConfig.CLIENT.worldGenerator.maxGenerationDetail.set(LodDetail.FULL);
LodConfig.CLIENT.graphics.maxDrawDetail.set(LodDetail.FULL);
LodConfig.CLIENT.worldGenerator.maxGenerationDetail.set(LodDetail.FULL);
// requires a world restart?
// LodConfig.CLIENT.worldGenerator.lodQualityMode.set(LodQualityMode.HEIGHTMAP);
@@ -56,7 +56,6 @@ import net.minecraft.client.renderer.texture.NativeImage;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexBuffer;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.entity.Entity;
import net.minecraft.potion.EffectInstance;
import net.minecraft.potion.Effects;
import net.minecraft.profiler.IProfiler;
@@ -64,7 +63,6 @@ import net.minecraft.util.math.BlockPos;
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;
/**
@@ -72,7 +70,7 @@ import net.minecraft.util.math.vector.Vector3f;
* This is where LODs are draw to the world.
*
* @author James Seibel
* @version 9-18-2021
* @version 9-19-2021
*/
public class LodRenderer
{
@@ -169,10 +167,10 @@ public class LodRenderer
* the async process of generating the Buffers that hold those LODs.
*
* @param lodDim The dimension to draw, if null doesn't replace the current dimension.
* @param mcMatrixStack This matrix stack should come straight from MC's renderChunkLayer (or future equivalent) method
* @param partialTicks how far into the current tick this method was called.
*/
@SuppressWarnings("deprecation")
public void drawLODs(LodDimension lodDim, float partialTicks, IProfiler newProfiler)
public void drawLODs(LodDimension lodDim, MatrixStack mcMatrixStack, float partialTicks, IProfiler newProfiler)
{
if (lodDim == null)
{
@@ -254,7 +252,7 @@ public class LodRenderer
// (or maybe vice versa I have no idea :P)
mcProjectionMatrix.transpose();
Matrix4f modelViewMatrix = generateModelViewMatrix(partialTicks);
Matrix4f modelViewMatrix = offsetTheModelViewMatrix(mcMatrixStack, partialTicks);
// required for setupFog and setupProjectionMatrix
farPlaneBlockDistance = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH;
@@ -281,9 +279,8 @@ public class LodRenderer
if (vbos != null)
{
Entity cameraEntity = mc.getCameraEntity();
Vector3d cameraDir = cameraEntity.getLookAngle().normalize();
cameraDir = mc.getOptions().getCameraType().isMirrored() ? cameraDir.reverse() : cameraDir;
ActiveRenderInfo renderInfo = mc.getGameRenderer().getMainCamera();
Vector3d cameraDir = new Vector3d(renderInfo.getLookVector());
boolean cullingDisabled = LodConfig.CLIENT.graphics.disableDirectionalCulling.get();
@@ -296,7 +293,7 @@ public class LodRenderer
for (int j = 0; j < vbos.length; j++)
{
RegionPos vboPos = new RegionPos(i + lodDim.getCenterX() - lodDim.getWidth() / 2, j + lodDim.getCenterZ() - lodDim.getWidth() / 2);
if (cullingDisabled || RenderUtil.isRegionInViewFrustum(cameraEntity.blockPosition(), cameraDir, vboPos.blockPos()))
if (cullingDisabled || RenderUtil.isRegionInViewFrustum(renderInfo.getBlockPosition(), cameraDir, vboPos.blockPos()))
{
if ((i > halfWidth - quarterWidth && i < halfWidth + quarterWidth) && (j > halfWidth - quarterWidth && j < halfWidth + quarterWidth))
setupFog(fogSettings.near.distance, fogSettings.near.quality);
@@ -448,7 +445,6 @@ public class LodRenderer
/**
* Revert any changes that were made to the fog.
*/
@SuppressWarnings("deprecation")
private void cleanupFog(NearFarFogSettings fogSettings,
float defaultFogStartDist, float defaultFogEndDist,
int defaultFogMode, int defaultFogDistance)
@@ -470,22 +466,22 @@ public class LodRenderer
/**
* Create the model view matrix to move the LODs
* from object space into world space.
* Translate the camera relative to the LodDimension's center,
* this is done since all LOD buffers are created in world space
* instead of object space.
* (since AxisAlignedBoundingBoxes (LODs) use doubles and thus have a higher
* accuracy vs the model view matrix, which only uses floats)
*/
private Matrix4f generateModelViewMatrix(float partialTicks)
private Matrix4f offsetTheModelViewMatrix(MatrixStack mcMatrixStack, float partialTicks)
{
// duplicate the last matrix
mcMatrixStack.pushPose();
// get all relevant camera info
ActiveRenderInfo renderInfo = mc.getGameRenderer().getMainCamera();
Vector3d projectedView = renderInfo.getPosition();
// generate the model view matrix
MatrixStack matrixStack = new MatrixStack();
matrixStack.pushPose();
// rotate to the current camera's direction
matrixStack.mulPose(Vector3f.XP.rotationDegrees(renderInfo.getXRot()));
matrixStack.mulPose(Vector3f.YP.rotationDegrees(renderInfo.getYRot() + 180));
// translate the camera relative to the regions' center
// (AxisAlignedBoundingBoxes (LODs) use doubles and thus have a higher
// accuracy vs the model view matrix, which only uses floats)
@@ -493,9 +489,15 @@ public class LodRenderer
Vector3d eyePos = mc.getPlayer().getEyePosition(partialTicks);
double xDiff = eyePos.x - bufferPos.getX();
double zDiff = eyePos.z - bufferPos.getZ();
matrixStack.translate(-xDiff, -projectedView.y, -zDiff);
return matrixStack.last().pose();
mcMatrixStack.translate(-xDiff, -projectedView.y, -zDiff);
// get the modified model view matrix
Matrix4f lodModelViewMatrix = mcMatrixStack.last().pose();
// remove the lod ModelViewMatrix
mcMatrixStack.popPose();
return lodModelViewMatrix;
}
@@ -544,7 +546,7 @@ public class LodRenderer
/**
* setup the lighting to be used for the LODs
*/
@SuppressWarnings({ "deprecation", "unused" })
@SuppressWarnings( "unused" )
private void setupLighting(LodDimension lodDimension, float partialTicks)
{
// Determine if the player has night vision