Merge branch '1.16.5' into '1.16.5'
Add vivecraft support See merge request jeseibel/minecraft-lod-mod!7
This commit is contained in:
@@ -25,20 +25,21 @@ import java.lang.reflect.Method;
|
||||
import com.seibel.lod.enums.FogQuality;
|
||||
import com.seibel.lod.proxy.ClientProxy;
|
||||
import com.seibel.lod.wrappers.MinecraftWrapper;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
||||
/**
|
||||
* This object is used to get variables from methods
|
||||
* where they are private. Specifically the fog setting
|
||||
* in Optifine.
|
||||
*
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 9-25-2021
|
||||
* @version 9 -25-2021
|
||||
*/
|
||||
public class ReflectionHandler
|
||||
{
|
||||
public static final ReflectionHandler INSTANCE = new ReflectionHandler();
|
||||
private final MinecraftWrapper mc = MinecraftWrapper.INSTANCE;
|
||||
|
||||
|
||||
public Field ofFogField = null;
|
||||
public Method vertexBufferUploadMethod = null;
|
||||
|
||||
@@ -73,48 +74,82 @@ public class ReflectionHandler
|
||||
// optifine changed the name of the variable
|
||||
ClientProxy.LOGGER.info(ReflectionHandler.class.getSimpleName() + ": unable to find the Optifine fog field. If Optifine isn't installed this can be ignored.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get what type of fog optifine is currently set to render.
|
||||
*
|
||||
* @return the fog quality
|
||||
*/
|
||||
public FogQuality getFogQuality()
|
||||
{
|
||||
if (ofFogField == null)
|
||||
{
|
||||
public FogQuality getFogQuality() {
|
||||
if (ofFogField == null) {
|
||||
// either optifine isn't installed,
|
||||
// the variable name was changed, or
|
||||
// the setup method wasn't called yet.
|
||||
return FogQuality.FANCY;
|
||||
}
|
||||
|
||||
|
||||
int returnNum = 0;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
try {
|
||||
returnNum = (int) ofFogField.get(mc.getOptions());
|
||||
}
|
||||
catch (IllegalArgumentException | IllegalAccessException e)
|
||||
{
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
switch (returnNum)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
// optifine's "default" option,
|
||||
// it should never be called in this case
|
||||
|
||||
// normal options
|
||||
case 1:
|
||||
return FogQuality.FAST;
|
||||
case 2:
|
||||
return FogQuality.FANCY;
|
||||
case 3:
|
||||
return FogQuality.OFF;
|
||||
|
||||
switch (returnNum) {
|
||||
default:
|
||||
case 0:
|
||||
// optifine's "default" option,
|
||||
// it should never be called in this case
|
||||
|
||||
// normal options
|
||||
case 1:
|
||||
return FogQuality.FAST;
|
||||
case 2:
|
||||
return FogQuality.FANCY;
|
||||
case 3:
|
||||
return FogQuality.OFF;
|
||||
}
|
||||
}
|
||||
|
||||
/** Detect if Vivecraft is present using reflection. Attempts to find the "VRRenderer" class. */
|
||||
public boolean detectVivecraft(){
|
||||
try {
|
||||
Class.forName("org.vivecraft.provider.VRRenderer");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored){
|
||||
System.out.println("Vivecraft not detected.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies a projection matrix's clip planes.
|
||||
* The projection matrix must be in a column-major format.
|
||||
*
|
||||
* @param projectionMatrix The projection matrix to be modified.
|
||||
* @param n the new near clip plane value.
|
||||
* @param f the new far clip plane value.
|
||||
* @return The modified matrix.
|
||||
*
|
||||
*/
|
||||
public Matrix4f Matrix4fModifyClipPlanes(Matrix4f projectionMatrix, float n,float f){
|
||||
//find the matrix values.
|
||||
float nMatrixValue = -((f+n)/(f-n));
|
||||
float fMatrixValue = -((2*f*n)/(f-n));
|
||||
try{
|
||||
//get the fields of the projectionMatrix
|
||||
Field[] fields = projectionMatrix.getClass().getDeclaredFields();
|
||||
//bypass the security protections on the fields that encode near and far plane values.
|
||||
fields[10].setAccessible(true);
|
||||
fields[11].setAccessible(true);
|
||||
//Change the values of the near and far plane.
|
||||
fields[10].set(projectionMatrix, nMatrixValue);
|
||||
fields[11].set(projectionMatrix, fMatrixValue);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return projectionMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,6 +130,8 @@ public class LodRenderer
|
||||
public boolean vanillaRenderedChunksChanged;
|
||||
public boolean vanillaRenderedChunksEmptySkip = false;
|
||||
public int vanillaBlockRenderedDistance;
|
||||
|
||||
boolean vivecraftDetected = ReflectionHandler.INSTANCE.detectVivecraft();
|
||||
|
||||
|
||||
|
||||
@@ -559,35 +561,46 @@ public class LodRenderer
|
||||
*/
|
||||
private void setupProjectionMatrix(Matrix4f currentProjectionMatrix, float vanillaBlockRenderedDistance, float partialTicks)
|
||||
{
|
||||
// create the new projection matrix
|
||||
Matrix4f lodPoj =
|
||||
Matrix4f.perspective(
|
||||
Matrix4f lodPoj;
|
||||
float nearClipPlane = LodConfig.CLIENT.graphics.advancedGraphicsOption.useExtendedNearClipPlane.get() ? vanillaBlockRenderedDistance / 5 : 1;
|
||||
float farClipPlane = farPlaneBlockDistance * LodUtil.CHUNK_WIDTH / 2;
|
||||
|
||||
if (vivecraftDetected){
|
||||
//use modify clip plane method to modify the current projection matrix's clip planes.
|
||||
lodPoj = ReflectionHandler.INSTANCE.Matrix4fModifyClipPlanes(
|
||||
currentProjectionMatrix,
|
||||
nearClipPlane,
|
||||
farClipPlane);
|
||||
} else {
|
||||
// create the new projection matrix
|
||||
lodPoj = 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);
|
||||
|
||||
// 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);
|
||||
// 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();
|
||||
defaultMcProjInv.invert();
|
||||
|
||||
Matrix4f distortionMatrix = defaultMcProjInv.copy();
|
||||
distortionMatrix.multiply(currentProjectionMatrix);
|
||||
|
||||
|
||||
// edit the lod projection to match Minecraft's
|
||||
// (so the LODs line up with the real world)
|
||||
lodPoj.multiply(distortionMatrix);
|
||||
|
||||
nearClipPlane,
|
||||
farClipPlane);
|
||||
|
||||
// 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);
|
||||
// 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();
|
||||
defaultMcProjInv.invert();
|
||||
|
||||
Matrix4f distortionMatrix = defaultMcProjInv.copy();
|
||||
distortionMatrix.multiply(currentProjectionMatrix);
|
||||
|
||||
|
||||
// edit the lod projection to match Minecraft's
|
||||
// (so the LODs line up with the real world)
|
||||
lodPoj.multiply(distortionMatrix);
|
||||
}
|
||||
|
||||
// send the projection over to the GPU
|
||||
gameRender.resetProjectionMatrix(lodPoj);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user