Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into

1.16.5

# Conflicts:
#	src/main/java/com/seibel/lod/render/LodRenderer.java
This commit is contained in:
James Seibel
2021-09-17 23:11:28 -05:00
10 changed files with 204 additions and 84 deletions
@@ -307,7 +307,7 @@ public class LodBufferBuilder
}
}
LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPosRounded, dataPoint, adjData,
detailLevel, posX, posZ, boxCache[xR][zR],renderer.previousDebugMode, lodDim.dimension);
detailLevel, posX, posZ, boxCache[xR][zR],renderer.previousDebugMode, renderer.lightMap);
}
} else if (region.getLodQualityMode() == LodQualityMode.MULTI_LOD)
@@ -318,7 +318,7 @@ public class LodBufferBuilder
if (!DataPointUtil.isItVoid(dataPoint) && DataPointUtil.doesItExist(dataPoint))
{
LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPosRounded, dataPoint, adjData,
detailLevel, posX, posZ, boxCache[xR][zR], renderer.previousDebugMode, lodDim.dimension);
detailLevel, posX, posZ, boxCache[xR][zR], renderer.previousDebugMode, renderer.lightMap);
}
}
}
@@ -18,6 +18,8 @@
package com.seibel.lod.builders;
import java.awt.Color;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
@@ -35,17 +37,26 @@ import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.block.*;
import net.minecraft.block.material.MaterialColor;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.DimensionType;
import net.minecraft.world.IWorld;
import net.minecraft.world.LightType;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeColors;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.gen.Heightmap;
import net.minecraftforge.client.extensions.IForgeBakedModel;
import net.minecraftforge.client.model.data.ModelDataMap;
import javax.swing.*;
/**
* This object is in charge of creating Lod related objects. (specifically: Lod
@@ -63,6 +74,9 @@ public class LodBuilder
public static final int CHUNK_SECTION_HEIGHT = CHUNK_DATA_WIDTH;
public static final Heightmap.Type DEFAULT_HEIGHTMAP = Heightmap.Type.WORLD_SURFACE_WG;
public static final ConcurrentMap<Block, Integer> colorMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<Block, VoxelShape> shapeMap = new ConcurrentHashMap<>();
public static final ModelDataMap dataMap = new ModelDataMap.Builder().build() ;
/**
* If no blocks are found in the area in determineBottomPointForArea return this
@@ -246,6 +260,8 @@ public class LodBuilder
int depth = 0;
int color = 0;
int light = 0;
int lightSky = 0;
int lightBlock = 0;
int generation = config.distanceGenerationMode.complexity;
int xRel;
@@ -253,6 +269,7 @@ public class LodBuilder
int xAbs;
int yAbs;
int zAbs;
boolean hasCeiling = MinecraftWrapper.INSTANCE.getWorld().dimensionType().hasCeiling();
BlockPos.Mutable blockPos = new BlockPos.Mutable(0, 0, 0);
int index = 0;
@@ -276,6 +293,7 @@ public class LodBuilder
//Calculate the height of the lod
yAbs = 255;
int count = 0;
boolean topBlock = true;
while (yAbs > 0)
{
height = determineHeightPointFrom(chunk, config, xRel, zRel, yAbs, blockPos);
@@ -289,14 +307,31 @@ public class LodBuilder
yAbs = height - 1;
// We search light on above air block
color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos);
depth = determineBottomPointFrom(chunk, config, xRel, zRel, yAbs, blockPos);
if(hasCeiling && topBlock)
{
yAbs = depth;
color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos);
blockPos.set(xAbs, yAbs - 1, zAbs);
light = getLightValue(chunk, blockPos, true);
}
else
{
color = generateLodColor(chunk, config, xRel, yAbs, zRel, blockPos);
blockPos.set(xAbs, yAbs + 1, zAbs);
light = getLightValue(chunk, blockPos, false);
}
blockPos.set(xAbs, yAbs + 1, zAbs);
light = getLightValue(chunk, blockPos);
light = getLightValue(chunk, blockPos, hasCeiling && topBlock);
lightBlock = light & 0b1111;
if(!hasCeiling && topBlock)
lightSky = 15; //default max light
else
lightSky = (light >> 4) & 0b1111;
//System.out.println(dataToMerge.length + " " + index +" " + count + " " + yAbs);
//System.out.println(dataToMerge.length + " " + dataToMerge[index].length);
dataToMerge[index][count] = DataPointUtil.createDataPoint(height, depth, color, (light >> 4) & 0b1111, light & 0b1111, generation);
topBlock = false;
dataToMerge[index][count] = DataPointUtil.createDataPoint(height, depth, color, lightSky, lightBlock, generation);
yAbs = depth - 1;
count++;
}
@@ -427,9 +462,10 @@ public class LodBuilder
depth = determineBottomPoint(chunk, config, xRel, zRel, blockPos);
blockPos.set(xAbs, yAbs + 1, zAbs);
light = getLightValue(chunk, blockPos);
light = getLightValue(chunk, blockPos, false);
lightBlock = light & 0b1111;
lightSky = (light >> 4) & 0b1111;
//lightSky = (light >> 4) & 0b1111;
lightSky = 15; //default max light
dataToMerge[index] = DataPointUtil.createDataPoint(height, depth, color, lightSky, lightBlock, generation);
}
return dataToMerge;
@@ -542,37 +578,63 @@ public class LodBuilder
return colorInt;
}
private int getLightValue(IChunk chunk, BlockPos.Mutable blockPos)
private int getLightValue(IChunk chunk, BlockPos.Mutable blockPos, boolean ceilingTopBlock)
{
int light;
//*TODO choose the best one between those options*/
//lightBlock = MinecraftWrapper.INSTANCE.getPlayer().level.getLightEngine().getLayerListener(LightType.BLOCK).getLightValue(blockPos);
//lightBlock = (byte) MinecraftWrapper.INSTANCE.getPlayer().level.getLightEngine().blockEngine.getLightValue(blockPos);
int skyLight;
int blockLight;
if (MinecraftWrapper.INSTANCE.getPlayer() == null)
return 0;
if (MinecraftWrapper.INSTANCE.getPlayer().level == null)
return 0;
light = MinecraftWrapper.INSTANCE.getPlayer().level.getBrightness(LightType.BLOCK, blockPos);
light += MinecraftWrapper.INSTANCE.getPlayer().level.getBrightness(LightType.SKY, blockPos) << 4;
//BlockState blockState = chunk.getBlockState(blockPos);
//lightBlock = (byte) blockState.getLightBlock(chunk, blockPos);
//lightBlock = (byte) blockState.getLightBlock(chunk, blockPos);
return light;
IWorld world = MinecraftWrapper.INSTANCE.getPlayer().level;
blockLight = world.getBrightness(LightType.BLOCK, blockPos);
skyLight = world.getBrightness(LightType.SKY, blockPos);
if(ceilingTopBlock)
blockPos.set(blockPos.getX(), blockPos.getY() + 1, blockPos.getZ());
else
blockPos.set(blockPos.getX(), blockPos.getY() - 1, blockPos.getZ());
BlockState blockState = chunk.getBlockState(blockPos);
blockLight = LodUtil.clamp(0, blockLight + blockState.getLightValue(chunk, blockPos), 15);
return blockLight + (skyLight << 4);
}
private int getColorTextureForBlock(BlockState blockState, BlockPos blockPos)
private int getColorTextureForBlock(BlockState blockState, BlockPos blockPos, boolean topTextureRequired)
{
if (colorMap.containsKey(blockState.getBlock()))
return colorMap.get(blockState.getBlock());
World world = MinecraftWrapper.INSTANCE.getPlayer().level;
TextureAtlasSprite texture = MinecraftWrapper.INSTANCE.getModelManager().getBlockModelShaper().getTexture(blockState, world, blockPos);
World world = MinecraftWrapper.INSTANCE.getWorld();
TextureAtlasSprite texture;
if(topTextureRequired)
{
List<BakedQuad> quad = ((IForgeBakedModel) MinecraftWrapper.INSTANCE.getModelManager().getBlockModelShaper().getBlockModel(blockState)).getQuads(blockState, Direction.UP, new Random(0), dataMap);
if (!quad.isEmpty())
{
texture = quad.get(0).getSprite();
}
else
{
texture = MinecraftWrapper.INSTANCE.getModelManager().getBlockModelShaper().getTexture(blockState, world, blockPos);
}
}
else
{
texture = MinecraftWrapper.INSTANCE.getModelManager().getBlockModelShaper().getTexture(blockState, world, blockPos);
}
int count = 0;
int alpha = 0;
int red = 0;
int green = 0;
int blue = 0;
;
int color = 0;
for (int k = 0; k < texture.getFrameCount(); k++)
{
@@ -582,9 +644,9 @@ public class LodBuilder
{
if (texture.isTransparent(k, i, j))
{
if (blockState.getBlock() instanceof LeavesBlock)
/*if (blockState.getBlock() instanceof LeavesBlock)
color = 0;
else
else*/
continue;
} else
{
@@ -660,7 +722,8 @@ public class LodBuilder
} else if (blockState.getBlock().equals(Blocks.TWISTING_VINES)
|| blockState.equals(Blocks.TWISTING_VINES_PLANT)
|| blockState == Blocks.WARPED_ROOTS.defaultBlockState()
|| blockState == Blocks.WARPED_FUNGUS.defaultBlockState())
|| blockState == Blocks.WARPED_FUNGUS.defaultBlockState()
|| blockState == Blocks.NETHER_SPROUTS.defaultBlockState())
{
colorInt = Blocks.WARPED_NYLIUM.defaultMaterialColor().col;
}
@@ -669,30 +732,31 @@ public class LodBuilder
// plant life
else if (blockState.getBlock() instanceof LeavesBlock || blockState.getBlock() == Blocks.VINE)
{
brightness = getColorTextureForBlock(blockState, blockPos);
colorInt = ColorUtil.changeBrightnessValue(biome.getFoliageColor(), brightness);
brightness = getColorTextureForBlock(blockState, blockPos, false);
//colorInt = ColorUtil.changeBrightnessValue(biome.getFoliageColor(), brightness);
colorInt = ColorUtil.multiplyRGBcolors(biome.getFoliageColor(), brightness);
} else if ((blockState.getBlock() instanceof GrassBlock || blockState.getBlock() instanceof AbstractPlantBlock
|| blockState.getBlock() instanceof BushBlock || blockState.getBlock() instanceof IGrowable)
&& !(blockState.getBlock() == Blocks.BROWN_MUSHROOM || blockState.getBlock() == Blocks.RED_MUSHROOM))
{
brightness = getColorTextureForBlock(blockState, blockPos);
brightness = ColorUtil.applySaturationAndBrightnessMultipliers(getColorTextureForBlock(blockState, blockPos, true),1f, 1.2f);
//colorInt = ColorUtil.changeBrightnessValue(biome.getGrassColor(x, z), brightness);
colorInt = ColorUtil.applySaturationAndBrightnessMultipliers(biome.getGrassColor(x, z),1f,0.65f);
//colorInt = ColorUtil.applySaturationAndBrightnessMultipliers(biome.getGrassColor(x, z), 1f, 0.65f);
colorInt = ColorUtil.multiplyRGBcolors(biome.getGrassColor(x, z), brightness);
}
// water
else if (blockState.getBlock() == Blocks.WATER)
{
brightness = getColorTextureForBlock(blockState, blockPos);
brightness = getColorTextureForBlock(blockState, blockPos, true);
//colorInt = ColorUtil.changeBrightnessValue(biome.getWaterColor(), brightness);
colorInt = ColorUtil.applySaturationAndBrightnessMultipliers(biome.getWaterColor(),1f,0.75f);
//colorInt = ColorUtil.applySaturationAndBrightnessMultipliers(biome.getWaterColor(), 1f, 0.75f);
colorInt = ColorUtil.multiplyRGBcolors(biome.getWaterColor(), brightness);
}
// everything else
else
{
colorInt = getColorTextureForBlock(blockState, blockPos);
//colorInt = blockState.materialColor.col;
//colorInt = blockState.getBlock().defaultMaterialColor().col;
colorInt = getColorTextureForBlock(blockState, blockPos, false);
}
return colorInt;
@@ -767,29 +831,49 @@ public class LodBuilder
{
BlockState blockState = chunk.getBlockState(blockPos);
boolean onlyUseFullBlock = false;
boolean avoidSmallBlock = false;
if (blockState != null)
{
//blockState.isCollisionShapeFullBlock(chunk, blockPos);
/*if (!blockState.getFluidState().isEmpty())
if (avoidSmallBlock || onlyUseFullBlock)
{
return true;
}
VoxelShape voxelShape = blockState.getShape(chunk, blockPos);
if (!voxelShape.isEmpty())
{
AxisAlignedBB bbox = voxelShape.bounds();
int xWidth = (int) (bbox.maxX - bbox.minX);
int yWidth = (int) (bbox.maxY - bbox.minY);
int zWidth = (int) (bbox.maxZ - bbox.minZ);
if (xWidth < 0.7 && zWidth < 0.7 && yWidth < 1)
if (!blockState.getFluidState().isEmpty())
{
return true;
}
VoxelShape voxelShape;
if (shapeMap.containsKey(blockState.getBlock()))
{
voxelShape = shapeMap.get(blockState.getBlock());
} else
{
voxelShape = blockState.getShape(chunk, blockPos);
shapeMap.put(blockState.getBlock(), voxelShape);
}
if (!voxelShape.isEmpty())
{
AxisAlignedBB bbox = voxelShape.bounds();
int xWidth = (int) (bbox.maxX - bbox.minX);
int yWidth = (int) (bbox.maxY - bbox.minY);
int zWidth = (int) (bbox.maxZ - bbox.minZ);
if (xWidth < 1 && zWidth < 1 && yWidth < 1 && onlyUseFullBlock)
{
return false;
}
if (xWidth < 0.7 && zWidth < 0.7 && yWidth < 1 && avoidSmallBlock)
{
return false;
}
} else
{
return false;
}
} else
{
return false;
}*/
}
if (blockState.getBlock() != Blocks.AIR
&& blockState.getBlock() != Blocks.CAVE_AIR
&& blockState.getBlock() != Blocks.BARRIER)
@@ -20,6 +20,7 @@ package com.seibel.lod.builders.lodTemplates;
import com.seibel.lod.enums.DebugMode;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.texture.NativeImage;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DimensionType;
@@ -36,7 +37,7 @@ public abstract class AbstractLodTemplate
public abstract void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, long[] adjData,
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, DimensionType dimensionType);
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap);
/**
* add the given position and color to the buffer
@@ -29,10 +29,13 @@ import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.NativeImage;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DimensionType;
import java.lang.annotation.Native;
/**
* Builds LODs as rectangular prisms.
*
@@ -50,7 +53,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
@Override
public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, long[] adjData,
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, DimensionType dimensionType)
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap)
{
int width = 1 << detailLevel;
@@ -65,11 +68,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
posZ * width,
bufferCenterBlockPos);
int color;
boolean hasSkyLight = dimensionType.hasSkyLight();
boolean hasRoof = dimensionType.hasCeiling();
boolean isDay = MinecraftWrapper.INSTANCE.getPlayer().level.getDayTime() < 13000;
color = DataPointUtil.getLightColor(data, (hasRoof || hasSkyLight), isDay);
color = DataPointUtil.getLightColor(data,lightMap);
//color = DataPointUtil.getColor(data);
@@ -20,6 +20,7 @@ package com.seibel.lod.builders.lodTemplates;
import com.seibel.lod.enums.DebugMode;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.texture.NativeImage;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DimensionType;
@@ -36,7 +37,7 @@ public class DynamicLodTemplate extends AbstractLodTemplate
{
@Override
public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, long[] adjData,
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, DimensionType dimensionType)
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap)
{
System.err.println("DynamicLodTemplate not implemented!");
}
@@ -20,6 +20,7 @@ package com.seibel.lod.builders.lodTemplates;
import com.seibel.lod.enums.DebugMode;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.texture.NativeImage;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DimensionType;
@@ -34,7 +35,7 @@ public class TriangularLodTemplate extends AbstractLodTemplate
{
@Override
public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, long[] adjData,
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, DimensionType dimensionType)
byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap)
{
System.err.println("DynamicLodTemplate not implemented!");
}
@@ -52,6 +52,7 @@ import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.GameRenderer;
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;
@@ -122,6 +123,12 @@ public class LodRenderer
* This is used to determine if the LODs should be regenerated
*/
private int[] previousPos = new int[]{0,0,0};
public NativeImage lightMap = null;
// these variables are used to determine if the buffers should be rebuilt
private long prevDayTime = 0;
private double prevBrightness = 0;
private int prevRenderDistance = 0;
private long prevPlayerPosTime = 0;
private long prevVanillaChunkTime = 0;
@@ -253,7 +260,8 @@ public class LodRenderer
farPlaneBlockDistance = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH;
setupProjectionMatrix(mcProjectionMatrix, partialTicks);
setupLighting(lodDim, partialTicks);
// commented out until we can add shaders to handle lighting
//setupLighting(lodDim, partialTicks);
NearFarFogSettings fogSettings = determineFogSettings();
@@ -836,6 +844,15 @@ public class LodRenderer
prevChunkTime = newTime;
}
// check if the lighting has changed
if (mc.getWorld().getDayTime() - prevDayTime > 1000 || mc.getOptions().gamma != prevBrightness || lightMap == null)
{
fullRegen = true;
lightMap = mc.getCurrentLightMap();
prevBrightness = mc.getOptions().gamma;
prevDayTime = mc.getWorld().getDayTime();
}
@@ -92,4 +92,23 @@ public class ColorUtil
hsv[1],
brightness).getRGB();
}
public static int multiplyRGBcolors(int color1, int color2)
{
/**TODO FIX the alpha*/
return 0xFF000000 | (((getRed(color1) * getRed(color2)) << 8) & 0xFF0000) | ((getGreen(color1) * getGreen(color2)) & 0xFF00) | (((getBlue(color1) * getBlue(color2)) >> 8) & 0xFF);
}
public static String toString(int color)
{
StringBuilder s = new StringBuilder();
s.append(Integer.toHexString(getAlpha(color)));
s.append(" ");
s.append(Integer.toHexString(getRed(color)));
s.append(" ");
s.append(Integer.toHexString(getGreen(color)));
s.append(" ");
s.append(Integer.toHexString(getBlue(color)));
return s.toString();
}
}
@@ -1,7 +1,12 @@
package com.seibel.lod.util;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.NativeImage;
import javax.xml.crypto.Data;
import java.lang.annotation.Native;
public class DataPointUtil
{
@@ -171,32 +176,17 @@ public class DataPointUtil
return (int) (dataPoint >>> COLOR_SHIFT);
}
public static int getLightColor(long dataPoint, boolean roof, boolean day)
public static int getLightColor(long dataPoint, NativeImage lightMap)
{
int lightBlock = getLightBlock(dataPoint);
int lightSky = getLightSky(dataPoint);
/**TODO ALL of this should be dimension dependent and lightMap dependent*/
int red;
int green;
int blue;
if(roof)
{
red = LodUtil.clamp(0, getRed(dataPoint) + -30 + lightBlock*4,255);
green = LodUtil.clamp(0, getGreen(dataPoint) + -30 + lightBlock*4,255);
blue = LodUtil.clamp(0, getBlue(dataPoint) + -30 + lightBlock*2,255);
}else{
if(day){
red = LodUtil.clamp(0, getRed(dataPoint) + -30 + LodUtil.clamp(0, lightBlock + lightSky,15)*4,255);
green = LodUtil.clamp(0, getGreen(dataPoint) + -30 + LodUtil.clamp(0, lightBlock + lightSky,15)*4,255);
blue = LodUtil.clamp(0, getBlue(dataPoint) + -30 + LodUtil.clamp(0, lightBlock/2 + lightSky,15)*4,255);
}else{
red = LodUtil.clamp(0, getRed(dataPoint) + -60 + lightBlock*6,255);
green = LodUtil.clamp(0, getGreen(dataPoint) + -60 + lightBlock*6,255);
blue = LodUtil.clamp(0, getBlue(dataPoint) + -30 + lightBlock*2,255);
}
}
return ColorUtil.rgbToInt(red, green, blue);
int color = lightMap.getPixelRGBA(lightBlock, lightSky);
int red = ColorUtil.getBlue(color);
int green = ColorUtil.getGreen(color);
int blue = ColorUtil.getRed(color);
return ColorUtil.multiplyRGBcolors(getColor(dataPoint), ColorUtil.rgbToInt(red, green, blue));
}
public static String toString(long dataPoint)
@@ -21,6 +21,9 @@ import net.minecraft.profiler.IProfiler;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.util.Direction;
import net.minecraft.world.DimensionType;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import org.lwjgl.system.CallbackI;
/**
* A singleton that wraps the Minecraft class
@@ -172,6 +175,11 @@ public class MinecraftWrapper
return mc.getModelManager();
}
public World getWorld()
{
return mc.level;
}
/** Measured in chunks */
public int getRenderDistance()
{