Add AbstractChunkPosWrapper

This commit is contained in:
James Seibel
2021-11-18 22:15:24 -06:00
parent e3fd2c4501
commit 40eb05a07e
27 changed files with 335 additions and 227 deletions
@@ -51,10 +51,10 @@ public class ClientApi
public static LodRenderer renderer = new LodRenderer(ApiShared.lodBufferBuilderFactory); public static LodRenderer renderer = new LodRenderer(ApiShared.lodBufferBuilderFactory);
private final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private final IMinecraftRenderWrapper mcRender = SingletonHandler.get(IMinecraftRenderWrapper.class); private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.get(IMinecraftRenderWrapper.class);
private final EventApi eventApi = EventApi.INSTANCE; private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final EventApi EVENT_API = EventApi.INSTANCE;
/** /**
* there is some setup that should only happen once, * there is some setup that should only happen once,
@@ -79,7 +79,7 @@ public class ClientApi
applyConfigOverrides(); applyConfigOverrides();
// clear any out of date objects // clear any out of date objects
mc.clearFrameObjectCache(); MC.clearFrameObjectCache();
try try
{ {
@@ -88,31 +88,31 @@ public class ClientApi
firstFrameSetup(); firstFrameSetup();
if (!mc.playerExists() || ApiShared.lodWorld.getIsWorldNotLoaded()) if (!MC.playerExists() || ApiShared.lodWorld.getIsWorldNotLoaded())
return; return;
LodDimension lodDim = ApiShared.lodWorld.getLodDimension(mc.getCurrentDimension()); LodDimension lodDim = ApiShared.lodWorld.getLodDimension(MC.getCurrentDimension());
if (lodDim == null) if (lodDim == null)
return; return;
DetailDistanceUtil.updateSettings(); DetailDistanceUtil.updateSettings();
eventApi.viewDistanceChangedEvent(); EVENT_API.viewDistanceChangedEvent();
eventApi.playerMoveEvent(lodDim); EVENT_API.playerMoveEvent(lodDim);
lodDim.cutRegionNodesAsync(mc.getPlayerBlockPos().getX(), mc.getPlayerBlockPos().getZ()); lodDim.cutRegionNodesAsync(MC.getPlayerBlockPos().getX(), MC.getPlayerBlockPos().getZ());
lodDim.expandOrLoadRegionsAsync(mc.getPlayerBlockPos().getX(), mc.getPlayerBlockPos().getZ()); lodDim.expandOrLoadRegionsAsync(MC.getPlayerBlockPos().getX(), MC.getPlayerBlockPos().getZ());
// Note to self: // Note to self:
// if "unspecified" shows up in the pie chart, it is // if "unspecified" shows up in the pie chart, it is
// possibly because the amount of time between sections // possibly because the amount of time between sections
// is too small for the profiler to measure // is too small for the profiler to measure
IProfiler profiler = mc.getProfiler(); IProfiler profiler = MC.getProfiler();
profiler.pop(); // get out of "terrain" profiler.pop(); // get out of "terrain"
profiler.push("LOD"); profiler.push("LOD");
ClientApi.renderer.drawLODs(lodDim, mcModelViewMatrix, mcProjectionMatrix, partialTicks, mc.getProfiler()); ClientApi.renderer.drawLODs(lodDim, mcModelViewMatrix, mcProjectionMatrix, partialTicks, MC.getProfiler());
profiler.pop(); // end LOD profiler.pop(); // end LOD
profiler.push("terrain"); // go back into "terrain" profiler.push("terrain"); // go back into "terrain"
@@ -120,8 +120,8 @@ public class ClientApi
// these can't be set until after the buffers are built (in renderer.drawLODs) // 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 // otherwise the buffers may be set to the wrong size, or not changed at all
ApiShared.previousChunkRenderDistance = mcRender.getRenderDistance(); ApiShared.previousChunkRenderDistance = MC_RENDER.getRenderDistance();
ApiShared.previousLodRenderDistance = config.client().graphics().quality().getLodChunkRenderDistance(); ApiShared.previousLodRenderDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance();
} }
catch (Exception e) catch (Exception e)
{ {
@@ -140,13 +140,13 @@ public class ClientApi
// mc.getPlayer().sendMessage(new StringTextComponent("LOD experimental build 1.5.1"), mc.getPlayer().getUUID()); // mc.getPlayer().sendMessage(new StringTextComponent("LOD experimental build 1.5.1"), mc.getPlayer().getUUID());
// mc.getPlayer().sendMessage(new StringTextComponent("Here be dragons!"), mc.getPlayer().getUUID()); // mc.getPlayer().sendMessage(new StringTextComponent("Here be dragons!"), mc.getPlayer().getUUID());
mc.sendChatMessage("Debug settings enabled!"); MC.sendChatMessage("Debug settings enabled!");
configOverrideReminderPrinted = true; configOverrideReminderPrinted = true;
} }
config.client().advanced().debugging().setDebugKeybindingsEnabled(true); CONFIG.client().advanced().debugging().setDebugKeybindingsEnabled(true);
} }
@@ -49,8 +49,8 @@ public class EventApi
{ {
public static final EventApi INSTANCE = new EventApi(); public static final EventApi INSTANCE = new EventApi();
private final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
/** /**
* can be set if we want to recalculate variables related * can be set if we want to recalculate variables related
@@ -73,10 +73,10 @@ public class EventApi
public void serverTickEvent() public void serverTickEvent()
{ {
if (!mc.playerExists() || ApiShared.lodWorld.getIsWorldNotLoaded()) if (!MC.playerExists() || ApiShared.lodWorld.getIsWorldNotLoaded())
return; return;
LodDimension lodDim = ApiShared.lodWorld.getLodDimension(mc.getCurrentDimension()); LodDimension lodDim = ApiShared.lodWorld.getLodDimension(MC.getCurrentDimension());
if (lodDim == null) if (lodDim == null)
return; return;
@@ -121,7 +121,7 @@ public class EventApi
ThreadMapUtil.clearMaps(); ThreadMapUtil.clearMaps();
if (mc.getWrappedClientWorld() == null) if (MC.getWrappedClientWorld() == null)
{ {
// the player just left the server // the player just left the server
@@ -165,16 +165,16 @@ public class EventApi
public void onKeyInput(int key, int keyAction) public void onKeyInput(int key, int keyAction)
{ {
if (config.client().advanced().debugging().getDebugKeybindingsEnabled()) if (CONFIG.client().advanced().debugging().getDebugKeybindingsEnabled())
{ {
if (key == GLFW.GLFW_KEY_F4 && keyAction == GLFW.GLFW_PRESS) if (key == GLFW.GLFW_KEY_F4 && keyAction == GLFW.GLFW_PRESS)
{ {
config.client().advanced().debugging().setDebugMode(config.client().advanced().debugging().getDebugMode().getNext()); CONFIG.client().advanced().debugging().setDebugMode(CONFIG.client().advanced().debugging().getDebugMode().getNext());
} }
if (key == GLFW.GLFW_KEY_F6 && keyAction == GLFW.GLFW_PRESS) if (key == GLFW.GLFW_KEY_F6 && keyAction == GLFW.GLFW_PRESS)
{ {
config.client().advanced().debugging().setDrawLods(!config.client().advanced().debugging().getDrawLods()); CONFIG.client().advanced().debugging().setDrawLods(!CONFIG.client().advanced().debugging().getDrawLods());
} }
} }
} }
@@ -183,7 +183,7 @@ public class EventApi
public void playerMoveEvent(LodDimension lodDim) public void playerMoveEvent(LodDimension lodDim)
{ {
// make sure the dimension is centered // make sure the dimension is centered
RegionPos playerRegionPos = new RegionPos(mc.getPlayerBlockPos()); RegionPos playerRegionPos = new RegionPos(MC.getPlayerBlockPos());
RegionPos worldRegionOffset = new RegionPos(playerRegionPos.x - lodDim.getCenterRegionPosX(), playerRegionPos.z - lodDim.getCenterRegionPosZ()); RegionPos worldRegionOffset = new RegionPos(playerRegionPos.x - lodDim.getCenterRegionPosX(), playerRegionPos.z - lodDim.getCenterRegionPosZ());
if (worldRegionOffset.x != 0 || worldRegionOffset.z != 0) if (worldRegionOffset.x != 0 || worldRegionOffset.z != 0)
{ {
@@ -198,10 +198,10 @@ public class EventApi
{ {
// calculate how wide the dimension(s) should be in regions // calculate how wide the dimension(s) should be in regions
int chunksWide; int chunksWide;
if (mc.getWrappedClientWorld().getDimensionType().hasCeiling()) if (MC.getWrappedClientWorld().getDimensionType().hasCeiling())
chunksWide = Math.min(config.client().graphics().quality().getLodChunkRenderDistance(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * 2 + 1; chunksWide = Math.min(CONFIG.client().graphics().quality().getLodChunkRenderDistance(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * 2 + 1;
else else
chunksWide = config.client().graphics().quality().getLodChunkRenderDistance() * 2 + 1; chunksWide = CONFIG.client().graphics().quality().getLodChunkRenderDistance() * 2 + 1;
int newWidth = (int) Math.ceil(chunksWide / (float) LodUtil.REGION_WIDTH_IN_CHUNKS); int newWidth = (int) Math.ceil(chunksWide / (float) LodUtil.REGION_WIDTH_IN_CHUNKS);
// make sure we have an odd number of regions // make sure we have an odd number of regions
@@ -215,7 +215,7 @@ public class EventApi
// update the dimensions to fit the new width // update the dimensions to fit the new width
ApiShared.lodWorld.resizeDimensionRegionWidth(newWidth); ApiShared.lodWorld.resizeDimensionRegionWidth(newWidth);
ApiShared.lodBuilder.defaultDimensionWidthInRegions = newWidth; ApiShared.lodBuilder.defaultDimensionWidthInRegions = newWidth;
ClientApi.renderer.setupBuffers(ApiShared.lodWorld.getLodDimension(mc.getCurrentDimension())); ClientApi.renderer.setupBuffers(ApiShared.lodWorld.getLodDimension(MC.getCurrentDimension()));
recalculateWidths = false; recalculateWidths = false;
//LOGGER.info("new dimension width in regions: " + newWidth + "\t potential: " + newWidth ); //LOGGER.info("new dimension width in regions: " + newWidth + "\t potential: " + newWidth );
@@ -56,11 +56,12 @@ import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodThreadFactory; import com.seibel.lod.core.util.LodThreadFactory;
import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.util.ThreadMapUtil; import com.seibel.lod.core.util.ThreadMapUtil;
import com.seibel.lod.core.wrapperAdapters.IWrapperFactory;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
/** /**
* This object creates the buffers that are * This object creates the buffers that are
@@ -71,13 +72,14 @@ import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
*/ */
public class LodBufferBuilderFactory public class LodBufferBuilderFactory
{ {
private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private static final IWrapperFactory WRAPPER_FACTORY = SingletonHandler.get(IWrapperFactory.class);
/** The thread used to generate new LODs off the main thread. */ /** The thread used to generate new LODs off the main thread. */
public static final ExecutorService mainGenThread = Executors.newSingleThreadExecutor(new LodThreadFactory(LodBufferBuilderFactory.class.getSimpleName() + " - main")); public static final ExecutorService mainGenThread = Executors.newSingleThreadExecutor(new LodThreadFactory(LodBufferBuilderFactory.class.getSimpleName() + " - main"));
/** The threads used to generate buffers. */ /** The threads used to generate buffers. */
public static final ExecutorService bufferBuilderThreads = Executors.newFixedThreadPool(config.client().advanced().threading().getNumberOfBufferBuilderThreads(), new ThreadFactoryBuilder().setNameFormat("Buffer-Builder-%d").build()); public static final ExecutorService bufferBuilderThreads = Executors.newFixedThreadPool(CONFIG.client().advanced().threading().getNumberOfBufferBuilderThreads(), new ThreadFactoryBuilder().setNameFormat("Buffer-Builder-%d").build());
/** /**
* When uploading to a buffer that is too small, * When uploading to a buffer that is too small,
@@ -144,8 +146,8 @@ public class LodBufferBuilderFactory
* This is the ChunkPosWrapper the player was at the last time the buffers were built. * This is the ChunkPosWrapper the player was at the last time the buffers were built.
* IE the center of the buffers last time they were built * IE the center of the buffers last time they were built
*/ */
private volatile ChunkPosWrapper drawableCenterChunkPos = new ChunkPosWrapper(0, 0); private volatile AbstractChunkPosWrapper drawableCenterChunkPos = WRAPPER_FACTORY.createChunkPos();
private volatile ChunkPosWrapper buildableCenterChunkPos = new ChunkPosWrapper(0, 0); private volatile AbstractChunkPosWrapper buildableCenterChunkPos = WRAPPER_FACTORY.createChunkPos();
@@ -197,7 +199,7 @@ public class LodBufferBuilderFactory
try try
{ {
// round the player's block position down to the nearest chunk BlockPos // round the player's block position down to the nearest chunk BlockPos
ChunkPosWrapper playerChunkPos = new ChunkPosWrapper(playerBlockPos); AbstractChunkPosWrapper playerChunkPos = WRAPPER_FACTORY.createChunkPos(playerBlockPos);
AbstractBlockPosWrapper playerBlockPosRounded = playerChunkPos.getWorldPosition(); AbstractBlockPosWrapper playerBlockPosRounded = playerChunkPos.getWorldPosition();
@@ -232,7 +234,7 @@ public class LodBufferBuilderFactory
// create the nodeToRenderThreads // // create the nodeToRenderThreads //
//================================// //================================//
skyLightPlayer = mc.getWrappedClientWorld().getSkyLight(playerBlockPos); skyLightPlayer = MC.getWrappedClientWorld().getSkyLight(playerBlockPos);
for (int xRegion = 0; xRegion < lodDim.getWidth(); xRegion++) for (int xRegion = 0; xRegion < lodDim.getWidth(); xRegion++)
{ {
@@ -405,7 +407,7 @@ public class LodBufferBuilderFactory
break; break;
//We send the call to create the vertices //We send the call to create the vertices
config.client().graphics().advancedGraphics().getLodTemplate().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData, CONFIG.client().graphics().advancedGraphics().getLodTemplate().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData,
detailLevel, posX, posZ, box, renderer.previousDebugMode, adjShadeDisabled); detailLevel, posX, posZ, box, renderer.previousDebugMode, adjShadeDisabled);
} }
@@ -475,7 +477,7 @@ public class LodBufferBuilderFactory
} }
} }
private boolean isThisPositionGoingToBeRendered(byte detailLevel, int posX, int posZ, ChunkPosWrapper playerChunkPos, boolean[][] vanillaRenderedChunks, int gameChunkRenderDistance){ private boolean isThisPositionGoingToBeRendered(byte detailLevel, int posX, int posZ, AbstractChunkPosWrapper playerChunkPos, boolean[][] vanillaRenderedChunks, int gameChunkRenderDistance){
// skip any chunks that Minecraft is going to render // skip any chunks that Minecraft is going to render
@@ -484,7 +486,7 @@ public class LodBufferBuilderFactory
// check if the chunk is on the border // check if the chunk is on the border
boolean isItBorderPos; boolean isItBorderPos;
if (config.client().graphics().advancedGraphics().getVanillaOverdraw() == VanillaOverdraw.BORDER) if (CONFIG.client().graphics().advancedGraphics().getVanillaOverdraw() == VanillaOverdraw.BORDER)
isItBorderPos = LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1); isItBorderPos = LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1);
else else
isItBorderPos = false; isItBorderPos = false;
@@ -762,12 +764,12 @@ public class LodBufferBuilderFactory
glProxy.setGlContext(GlProxyContext.LOD_BUILDER); glProxy.setGlContext(GlProxyContext.LOD_BUILDER);
// determine the upload method // determine the upload method
GpuUploadMethod uploadMethod = config.client().graphics().advancedGraphics().getGpuUploadMethod(); GpuUploadMethod uploadMethod = CONFIG.client().graphics().advancedGraphics().getGpuUploadMethod();
if (!glProxy.bufferStorageSupported && uploadMethod == GpuUploadMethod.BUFFER_STORAGE) if (!glProxy.bufferStorageSupported && uploadMethod == GpuUploadMethod.BUFFER_STORAGE)
{ {
// if buffer storage isn't supported // if buffer storage isn't supported
// default to SUB_DATA // default to SUB_DATA
config.client().graphics().advancedGraphics().setGpuUploadMethod(GpuUploadMethod.SUB_DATA); CONFIG.client().graphics().advancedGraphics().setGpuUploadMethod(GpuUploadMethod.SUB_DATA);
uploadMethod = GpuUploadMethod.SUB_DATA; uploadMethod = GpuUploadMethod.SUB_DATA;
} }
@@ -958,9 +960,9 @@ public class LodBufferBuilderFactory
{ {
public final LodVertexBuffer[][][] vbos; public final LodVertexBuffer[][][] vbos;
public final int[][][] storageBufferIds; public final int[][][] storageBufferIds;
public final ChunkPosWrapper drawableCenterChunkPos; public final AbstractChunkPosWrapper drawableCenterChunkPos;
public VertexBuffersAndOffset(LodVertexBuffer[][][] newVbos, int[][][] newStorageBufferIds, ChunkPosWrapper newDrawableCenterChunkPos) public VertexBuffersAndOffset(LodVertexBuffer[][][] newVbos, int[][][] newStorageBufferIds, AbstractChunkPosWrapper newDrawableCenterChunkPos)
{ {
vbos = newVbos; vbos = newVbos;
storageBufferIds = newStorageBufferIds; storageBufferIds = newStorageBufferIds;
@@ -40,13 +40,13 @@ import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.block.IBlockColorSingletonWrapper; import com.seibel.lod.core.wrapperAdapters.block.IBlockColorSingletonWrapper;
import com.seibel.lod.core.wrapperAdapters.block.IBlockColorWrapper; import com.seibel.lod.core.wrapperAdapters.block.IBlockColorWrapper;
import com.seibel.lod.core.wrapperAdapters.block.IBlockShapeWrapper; import com.seibel.lod.core.wrapperAdapters.block.IBlockShapeWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperAdapters.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper;
import com.seibel.lod.core.wrapperAdapters.world.IBiomeWrapper; import com.seibel.lod.core.wrapperAdapters.world.IBiomeWrapper;
import com.seibel.lod.core.wrapperAdapters.world.IDimensionTypeWrapper; import com.seibel.lod.core.wrapperAdapters.world.IDimensionTypeWrapper;
import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper; import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
/** /**
* This object is in charge of creating Lod related objects. * This object is in charge of creating Lod related objects.
@@ -58,12 +58,9 @@ import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
*/ */
public class LodBuilder public class LodBuilder
{ {
private static final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private static final IBlockColorSingletonWrapper blockColorSingleton = SingletonHandler.get(IBlockColorSingletonWrapper.class); private static final IBlockColorSingletonWrapper BLOCK_COLOR = SingletonHandler.get(IBlockColorSingletonWrapper.class);
private final IWrapperFactory wrapperFactory = SingletonHandler.get(IWrapperFactory.class); private static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class);
private final ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName()));
private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class);
/** If no blocks are found in the area in determineBottomPointForArea return this */ /** If no blocks are found in the area in determineBottomPointForArea return this */
public static final short DEFAULT_DEPTH = 0; public static final short DEFAULT_DEPTH = 0;
@@ -73,6 +70,11 @@ public class LodBuilder
public static final short DEFAULT_MAX_LIGHT = 15; public static final short DEFAULT_MAX_LIGHT = 15;
private final ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName()));
private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class);
/** /**
* How wide LodDimensions should be in regions <br> * How wide LodDimensions should be in regions <br>
* Is automatically set before the first frame in ClientProxy. * Is automatically set before the first frame in ClientProxy.
@@ -111,12 +113,12 @@ public class LodBuilder
{ {
// we need a loaded client world in order to // we need a loaded client world in order to
// get the textures for blocks // get the textures for blocks
if (mc.getWrappedClientWorld() == null) if (MC.getWrappedClientWorld() == null)
return; return;
// don't try to generate LODs if the user isn't in the world anymore // don't try to generate LODs if the user isn't in the world anymore
// (this happens a lot when the user leaves a world/server) // (this happens a lot when the user leaves a world/server)
if (!mc.hasSinglePlayerServer() && !mc.connectedToServer()) if (!MC.hasSinglePlayerServer() && !MC.connectedToServer())
return; return;
// make sure the dimension exists // make sure the dimension exists
@@ -171,7 +173,7 @@ public class LodBuilder
return; return;
// this happens if a LOD is generated after the user leaves the world. // this happens if a LOD is generated after the user leaves the world.
if (mc.getWrappedClientWorld() == null) if (MC.getWrappedClientWorld() == null)
return; return;
// determine how many LODs to generate horizontally // determine how many LODs to generate horizontally
@@ -217,7 +219,7 @@ public class LodBuilder
long[] dataToMerge = ThreadMapUtil.getBuilderVerticalArray(detail.detailLevel); long[] dataToMerge = ThreadMapUtil.getBuilderVerticalArray(detail.detailLevel);
int verticalData = DataPointUtil.worldHeight / 2 + 1; int verticalData = DataPointUtil.worldHeight / 2 + 1;
ChunkPosWrapper chunkPos = chunk.getPos(); AbstractChunkPosWrapper chunkPos = chunk.getPos();
int height; int height;
int depth; int depth;
int color; int color;
@@ -231,10 +233,10 @@ public class LodBuilder
int xAbs; int xAbs;
int yAbs; int yAbs;
int zAbs; int zAbs;
boolean hasCeiling = mc.getWrappedClientWorld().getDimensionType().hasCeiling(); boolean hasCeiling = MC.getWrappedClientWorld().getDimensionType().hasCeiling();
boolean hasSkyLight = mc.getWrappedClientWorld().getDimensionType().hasSkyLight(); boolean hasSkyLight = MC.getWrappedClientWorld().getDimensionType().hasSkyLight();
boolean isDefault; boolean isDefault;
AbstractBlockPosWrapper blockPos = wrapperFactory.createBlockPos(); AbstractBlockPosWrapper blockPos = FACTORY.createBlockPos();
int index; int index;
for (index = 0; index < size * size; index++) for (index = 0; index < size * size; index++)
@@ -387,7 +389,7 @@ public class LodBuilder
// 1 means the lighting is a guess // 1 means the lighting is a guess
int isDefault = 0; int isDefault = 0;
IWorldWrapper world = mc.getWrappedServerWorld(); IWorldWrapper world = MC.getWrappedServerWorld();
int blockBrightness = chunk.getEmittedBrightness(blockPos); int blockBrightness = chunk.getEmittedBrightness(blockPos);
// get the air block above or below this block // get the air block above or below this block
@@ -415,7 +417,7 @@ public class LodBuilder
{ {
// we are on predicted terrain, and we don't know what the light here is, // we are on predicted terrain, and we don't know what the light here is,
// lets just take a guess // lets just take a guess
if (blockPos.getY() >= mc.getWrappedClientWorld().getSeaLevel() - 5) if (blockPos.getY() >= MC.getWrappedClientWorld().getSeaLevel() - 5)
{ {
skyLight = 12; skyLight = 12;
isDefault = 1; isDefault = 1;
@@ -426,7 +428,7 @@ public class LodBuilder
} }
else else
{ {
world = mc.getWrappedServerWorld(); world = MC.getWrappedServerWorld();
if (world.isEmpty()) if (world.isEmpty())
return 0; return 0;
// client world sky light (almost never accurate) // client world sky light (almost never accurate)
@@ -448,7 +450,7 @@ public class LodBuilder
{ {
// we don't know what the light here is, // we don't know what the light here is,
// lets just take a guess // lets just take a guess
if (blockPos.getY() >= mc.getWrappedClientWorld().getSeaLevel() - 5) if (blockPos.getY() >= MC.getWrappedClientWorld().getSeaLevel() - 5)
{ {
skyLight = 12; skyLight = 12;
isDefault = 1; isDefault = 1;
@@ -483,7 +485,7 @@ public class LodBuilder
IBlockShapeWrapper blockShapeWrapper = chunk.getBlockShapeWrapper(blockPos); IBlockShapeWrapper blockShapeWrapper = chunk.getBlockShapeWrapper(blockPos);
if (chunk.isWaterLogged(blockPos)) if (chunk.isWaterLogged(blockPos))
blockColorWrapper = blockColorSingleton.getWaterColor(); blockColorWrapper = BLOCK_COLOR.getWaterColor();
else else
blockColorWrapper = chunk.getBlockColorWrapper(blockPos); blockColorWrapper = chunk.getBlockColorWrapper(blockPos);
@@ -29,9 +29,9 @@ import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.objects.lod.LodDimension; import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper; import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
import com.seibel.lod.wrappers.worldGeneration.WorldGeneratorWrapper; import com.seibel.lod.wrappers.worldGeneration.WorldGeneratorWrapper;
import net.minecraftforge.common.WorldWorkerManager.IWorker; import net.minecraftforge.common.WorldWorkerManager.IWorker;
@@ -44,16 +44,16 @@ import net.minecraftforge.common.WorldWorkerManager.IWorker;
*/ */
public class LodGenWorker implements IWorker // TODO is there a way to have this fabric/forge independent? public class LodGenWorker implements IWorker // TODO is there a way to have this fabric/forge independent?
{ {
private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static ExecutorService genThreads = Executors.newFixedThreadPool(config.client().advanced().threading().getNumberOfWorldGenerationThreads(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build()); public static ExecutorService genThreads = Executors.newFixedThreadPool(CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
private boolean threadStarted = false; private boolean threadStarted = false;
private final LodChunkGenThread thread; private final LodChunkGenThread thread;
public LodGenWorker(ChunkPosWrapper newPos, DistanceGenerationMode newGenerationMode, public LodGenWorker(AbstractChunkPosWrapper newPos, DistanceGenerationMode newGenerationMode,
LodBuilder newLodBuilder, LodBuilder newLodBuilder,
LodDimension newLodDimension, IWorldWrapper serverWorld) LodDimension newLodDimension, IWorldWrapper serverWorld)
{ {
@@ -82,7 +82,7 @@ public class LodGenWorker implements IWorker // TODO is there a way to have this
{ {
if (!threadStarted) if (!threadStarted)
{ {
if (config.client().worldGenerator().getDistanceGenerationMode() == DistanceGenerationMode.SERVER) if (CONFIG.client().worldGenerator().getDistanceGenerationMode() == DistanceGenerationMode.SERVER)
{ {
// if we are using SERVER generation that has to be done // if we are using SERVER generation that has to be done
// synchronously to prevent crashing and harmful // synchronously to prevent crashing and harmful
@@ -124,9 +124,9 @@ public class LodGenWorker implements IWorker // TODO is there a way to have this
public final LodDimension lodDim; public final LodDimension lodDim;
public final DistanceGenerationMode generationMode; public final DistanceGenerationMode generationMode;
private final ChunkPosWrapper pos; private final AbstractChunkPosWrapper pos;
public LodChunkGenThread(ChunkPosWrapper newPos, DistanceGenerationMode newGenerationMode, public LodChunkGenThread(AbstractChunkPosWrapper newPos, DistanceGenerationMode newGenerationMode,
LodBuilder newLodBuilder, LodBuilder newLodBuilder,
LodDimension newLodDimension, IWorldWrapper worldWrapper) LodDimension newLodDimension, IWorldWrapper worldWrapper)
{ {
@@ -220,7 +220,7 @@ public class LodGenWorker implements IWorker // TODO is there a way to have this
{ {
genThreads.shutdownNow(); genThreads.shutdownNow();
} }
genThreads = Executors.newFixedThreadPool(config.client().advanced().threading().getNumberOfWorldGenerationThreads(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build()); genThreads = Executors.newFixedThreadPool(CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
} }
} }
@@ -34,12 +34,12 @@ import com.seibel.lod.core.util.DetailDistanceUtil;
import com.seibel.lod.core.util.LevelPosUtil; import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodThreadFactory; import com.seibel.lod.core.util.LodThreadFactory;
import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperAdapters.IWrapperFactory;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper;
import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper; import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
import com.seibel.lod.wrappers.minecraft.MinecraftWrapper;
import net.minecraftforge.common.WorldWorkerManager; import net.minecraftforge.common.WorldWorkerManager;
@@ -51,13 +51,14 @@ import net.minecraftforge.common.WorldWorkerManager;
*/ */
public class LodWorldGenerator public class LodWorldGenerator
{ {
private static final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private static final IWrapperFactory WRAPPER_FACTORY = SingletonHandler.get(IWrapperFactory.class);
/** This holds the thread used to generate new LODs off the main thread. */ /** 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")); private final ExecutorService mainGenThread = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " world generator"));
private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class);
/** we only want to queue up one generator thread at a time */ /** we only want to queue up one generator thread at a time */
private boolean generatorThreadRunning = false; private boolean generatorThreadRunning = false;
@@ -77,7 +78,7 @@ public class LodWorldGenerator
*/ */
public final AtomicInteger numberOfChunksWaitingToGenerate = new AtomicInteger(0); public final AtomicInteger numberOfChunksWaitingToGenerate = new AtomicInteger(0);
public final Set<ChunkPosWrapper> positionsWaitingToBeGenerated = new HashSet<>(); public final Set<AbstractChunkPosWrapper> positionsWaitingToBeGenerated = new HashSet<>();
/** /**
* Singleton copy of this object * Singleton copy of this object
@@ -85,6 +86,7 @@ public class LodWorldGenerator
public static final LodWorldGenerator INSTANCE = new LodWorldGenerator(); public static final LodWorldGenerator INSTANCE = new LodWorldGenerator();
private LodWorldGenerator() private LodWorldGenerator()
{ {
@@ -97,23 +99,23 @@ public class LodWorldGenerator
*/ */
public void queueGenerationRequests(LodDimension lodDim, LodRenderer renderer, LodBuilder lodBuilder) public void queueGenerationRequests(LodDimension lodDim, LodRenderer renderer, LodBuilder lodBuilder)
{ {
if (config.client().worldGenerator().getDistanceGenerationMode() != DistanceGenerationMode.NONE if (CONFIG.client().worldGenerator().getDistanceGenerationMode() != DistanceGenerationMode.NONE
&& !generatorThreadRunning && !generatorThreadRunning
&& mc.hasSinglePlayerServer()) && MC.hasSinglePlayerServer())
{ {
// the thread is now running, don't queue up another thread // the thread is now running, don't queue up another thread
generatorThreadRunning = true; generatorThreadRunning = true;
// just in case the config changed // just in case the config changed
maxChunkGenRequests = config.client().advanced().threading().getNumberOfWorldGenerationThreads() * 8; maxChunkGenRequests = CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads() * 8;
Thread generatorThread = new Thread(() -> Thread generatorThread = new Thread(() ->
{ {
try try
{ {
// round the player's block position down to the nearest chunk BlockPos // round the player's block position down to the nearest chunk BlockPos
int playerPosX = mc.getPlayerBlockPos().getX(); int playerPosX = MC.getPlayerBlockPos().getX();
int playerPosZ = mc.getPlayerBlockPos().getZ(); int playerPosZ = MC.getPlayerBlockPos().getZ();
//=======================================// //=======================================//
@@ -147,7 +149,7 @@ public class LodWorldGenerator
posZ = posToGenerate.getNthPosZ(nearIndex, true); posZ = posToGenerate.getNthPosZ(nearIndex, true);
nearIndex++; nearIndex++;
ChunkPosWrapper chunkPos = new ChunkPosWrapper(LevelPosUtil.getChunkPos(detailLevel, posX), LevelPosUtil.getChunkPos(detailLevel, posZ)); AbstractChunkPosWrapper chunkPos = WRAPPER_FACTORY.createChunkPos(LevelPosUtil.getChunkPos(detailLevel, posX), LevelPosUtil.getChunkPos(detailLevel, posZ));
// prevent generating the same chunk multiple times // prevent generating the same chunk multiple times
if (positionsWaitingToBeGenerated.contains(chunkPos)) if (positionsWaitingToBeGenerated.contains(chunkPos))
@@ -172,7 +174,7 @@ public class LodWorldGenerator
posZ = posToGenerate.getNthPosZ(farIndex, false); posZ = posToGenerate.getNthPosZ(farIndex, false);
farIndex++; farIndex++;
ChunkPosWrapper chunkPos = new ChunkPosWrapper(LevelPosUtil.getChunkPos(detailLevel, posX), LevelPosUtil.getChunkPos(detailLevel, posZ)); AbstractChunkPosWrapper chunkPos = WRAPPER_FACTORY.createChunkPos(LevelPosUtil.getChunkPos(detailLevel, posX), LevelPosUtil.getChunkPos(detailLevel, posZ));
// don't add more to the generation queue then allowed // don't add more to the generation queue then allowed
if (numberOfChunksWaitingToGenerate.get() >= maxChunkGenRequests) if (numberOfChunksWaitingToGenerate.get() >= maxChunkGenRequests)
@@ -41,8 +41,8 @@ import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper;
*/ */
public class Box public class Box
{ {
private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private static final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public static final int ADJACENT_HEIGHT_INDEX = 0; public static final int ADJACENT_HEIGHT_INDEX = 0;
public static final int ADJACENT_DEPTH_INDEX = 1; public static final int ADJACENT_DEPTH_INDEX = 1;
@@ -257,7 +257,7 @@ public class Box
for (LodDirection lodDirection : DIRECTIONS) for (LodDirection lodDirection : DIRECTIONS)
{ {
if (!adjShadeDisabled[DIRECTION_INDEX.get(lodDirection)]) if (!adjShadeDisabled[DIRECTION_INDEX.get(lodDirection)])
colorMap[DIRECTION_INDEX.get(lodDirection)] = ColorUtil.applyShade(color, mc.getShade(lodDirection)); colorMap[DIRECTION_INDEX.get(lodDirection)] = ColorUtil.applyShade(color, MC.getShade(lodDirection));
else else
colorMap[DIRECTION_INDEX.get(lodDirection)] = color; colorMap[DIRECTION_INDEX.get(lodDirection)] = color;
} }
@@ -269,10 +269,10 @@ public class Box
*/ */
public int getColor(LodDirection lodDirection) public int getColor(LodDirection lodDirection)
{ {
if (config.client().advanced().debugging().getDebugMode() != DebugMode.SHOW_DETAIL) if (CONFIG.client().advanced().debugging().getDebugMode() != DebugMode.SHOW_DETAIL)
return colorMap[DIRECTION_INDEX.get(lodDirection)]; return colorMap[DIRECTION_INDEX.get(lodDirection)];
else else
return ColorUtil.applyShade(color, mc.getShade(lodDirection)); return ColorUtil.applyShade(color, MC.getShade(lodDirection));
} }
/** /**
@@ -35,13 +35,13 @@ import com.seibel.lod.core.util.DetailDistanceUtil;
import com.seibel.lod.core.util.LevelPosUtil; import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodThreadFactory; import com.seibel.lod.core.util.LodThreadFactory;
import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperAdapters.IWrapperFactory;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper;
import com.seibel.lod.core.wrapperAdapters.world.IDimensionTypeWrapper; import com.seibel.lod.core.wrapperAdapters.world.IDimensionTypeWrapper;
import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper; import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
import com.seibel.lod.wrappers.minecraft.MinecraftWrapper;
@@ -59,8 +59,9 @@ import com.seibel.lod.wrappers.minecraft.MinecraftWrapper;
*/ */
public class LodDimension public class LodDimension
{ {
private final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class);
public final IDimensionTypeWrapper dimension; public final IDimensionTypeWrapper dimension;
@@ -92,9 +93,9 @@ public class LodDimension
private final RegionPos center; private final RegionPos center;
/** prevents the cutAndExpandThread from expanding at the same location multiple times */ /** prevents the cutAndExpandThread from expanding at the same location multiple times */
private volatile ChunkPosWrapper lastExpandedChunk; private volatile AbstractChunkPosWrapper lastExpandedChunk;
/** prevents the cutAndExpandThread from cutting at the same location multiple times */ /** prevents the cutAndExpandThread from cutting at the same location multiple times */
private volatile ChunkPosWrapper lastCutChunk; private volatile AbstractChunkPosWrapper lastCutChunk;
private final ExecutorService cutAndExpandThread = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " - Cut and Expand")); private final ExecutorService cutAndExpandThread = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " - Cut and Expand"));
/** /**
@@ -115,7 +116,7 @@ public class LodDimension
{ {
// determine the save folder // determine the save folder
File saveDir; File saveDir;
if (mc.hasSinglePlayerServer()) if (MC.hasSinglePlayerServer())
{ {
// local world // local world
@@ -126,8 +127,8 @@ public class LodDimension
{ {
// connected to server // connected to server
saveDir = new File(mc.getGameDirectory().getCanonicalFile().getPath() + saveDir = new File(MC.getGameDirectory().getCanonicalFile().getPath() +
File.separatorChar + "lod server data" + File.separatorChar + mc.getCurrentDimensionId()); File.separatorChar + "lod server data" + File.separatorChar + MC.getCurrentDimensionId());
} }
fileHandler = new LodDimensionFileHandler(saveDir, this); fileHandler = new LodDimensionFileHandler(saveDir, this);
@@ -317,10 +318,10 @@ public class LodDimension
*/ */
public void cutRegionNodesAsync(int playerPosX, int playerPosZ) public void cutRegionNodesAsync(int playerPosX, int playerPosZ)
{ {
ChunkPosWrapper newPlayerChunk = new ChunkPosWrapper(LevelPosUtil.getChunkPos((byte) 0, playerPosX), LevelPosUtil.getChunkPos((byte) 0, playerPosZ)); AbstractChunkPosWrapper newPlayerChunk = FACTORY.createChunkPos(LevelPosUtil.getChunkPos((byte) 0, playerPosX), LevelPosUtil.getChunkPos((byte) 0, playerPosZ));
if (lastCutChunk == null) if (lastCutChunk == null)
lastCutChunk = new ChunkPosWrapper(newPlayerChunk.getX() + 1, newPlayerChunk.getZ() - 1); lastCutChunk = FACTORY.createChunkPos(newPlayerChunk.getX() + 1, newPlayerChunk.getZ() - 1);
// don't run the tree cutter multiple times // don't run the tree cutter multiple times
// for the same location // for the same location
@@ -369,13 +370,13 @@ public class LodDimension
/** Either expands or loads all regions in the rendered LOD area */ /** Either expands or loads all regions in the rendered LOD area */
public void expandOrLoadRegionsAsync(int playerPosX, int playerPosZ) public void expandOrLoadRegionsAsync(int playerPosX, int playerPosZ)
{ {
DistanceGenerationMode generationMode = config.client().worldGenerator().getDistanceGenerationMode(); DistanceGenerationMode generationMode = CONFIG.client().worldGenerator().getDistanceGenerationMode();
ChunkPosWrapper newPlayerChunk = new ChunkPosWrapper(LevelPosUtil.getChunkPos((byte) 0, playerPosX), LevelPosUtil.getChunkPos((byte) 0, playerPosZ)); AbstractChunkPosWrapper newPlayerChunk = FACTORY.createChunkPos(LevelPosUtil.getChunkPos((byte) 0, playerPosX), LevelPosUtil.getChunkPos((byte) 0, playerPosZ));
VerticalQuality verticalQuality = config.client().graphics().quality().getVerticalQuality(); VerticalQuality verticalQuality = CONFIG.client().graphics().quality().getVerticalQuality();
if (lastExpandedChunk == null) if (lastExpandedChunk == null)
lastExpandedChunk = new ChunkPosWrapper(newPlayerChunk.getX() + 1, newPlayerChunk.getZ() - 1); lastExpandedChunk = FACTORY.createChunkPos(newPlayerChunk.getX() + 1, newPlayerChunk.getZ() - 1);
// don't run the expander multiple times // don't run the expander multiple times
// for the same location // for the same location
@@ -548,7 +549,7 @@ public class LodDimension
dz = -1; dz = -1;
// We can use two type of generation scheduling // We can use two type of generation scheduling
switch (config.client().worldGenerator().getGenerationPriority()) switch (CONFIG.client().worldGenerator().getGenerationPriority())
{ {
default: default:
case NEAR_FIRST: case NEAR_FIRST:
@@ -605,7 +606,7 @@ public class LodDimension
//if(lodRegion.isChunkPreGenerated(xChunkToCheck,zChunkToCheck)) //if(lodRegion.isChunkPreGenerated(xChunkToCheck,zChunkToCheck))
// complexity = DistanceGenerationMode.SERVER.complexity; // complexity = DistanceGenerationMode.SERVER.complexity;
//else //else
complexity = config.client().worldGenerator().getDistanceGenerationMode().complexity; complexity = CONFIG.client().worldGenerator().getDistanceGenerationMode().complexity;
//we create the level position info of the chunk //we create the level position info of the chunk
@@ -680,7 +681,7 @@ public class LodDimension
{ {
LodRegion region = getRegion(regionPos.x, regionPos.z); LodRegion region = getRegion(regionPos.x, regionPos.z);
if (region != null) if (region != null)
region.getPosToRender(posToRender, playerPosX, playerPosZ, config.client().worldGenerator().getGenerationPriority() == GenerationPriority.NEAR_FIRST); region.getPosToRender(posToRender, playerPosX, playerPosZ, CONFIG.client().worldGenerator().getGenerationPriority() == GenerationPriority.NEAR_FIRST);
} }
/** /**
@@ -20,8 +20,10 @@
package com.seibel.lod.core.objects.lod; package com.seibel.lod.core.objects.lod;
import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperAdapters.IWrapperFactory;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
/** /**
* This object is similar to ChunkPos or BlockPos. * This object is similar to ChunkPos or BlockPos.
@@ -31,15 +33,14 @@ import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
*/ */
public class RegionPos public class RegionPos
{ {
private static final IWrapperFactory WRAPPER_FACTORY = SingletonHandler.get(IWrapperFactory.class);
public int x; public int x;
public int z; public int z;
/** /** Sets x and z to 0 */
* Default Constructor <br><br>
* <p>
* Sets x and z to 0
*/
public RegionPos() public RegionPos()
{ {
x = 0; x = 0;
@@ -56,20 +57,20 @@ public class RegionPos
/** Converts from a BlockPos to a RegionPos */ /** Converts from a BlockPos to a RegionPos */
public RegionPos(AbstractBlockPosWrapper pos) public RegionPos(AbstractBlockPosWrapper pos)
{ {
this(new ChunkPosWrapper(pos)); this(WRAPPER_FACTORY.createChunkPos(pos));
} }
/** Converts from a ChunkPos to a RegionPos */ /** Converts from a ChunkPos to a RegionPos */
public RegionPos(ChunkPosWrapper pos) public RegionPos(AbstractChunkPosWrapper pos)
{ {
x = Math.floorDiv(pos.getX(), LodUtil.REGION_WIDTH_IN_CHUNKS); x = Math.floorDiv(pos.getX(), LodUtil.REGION_WIDTH_IN_CHUNKS);
z = Math.floorDiv(pos.getZ(), LodUtil.REGION_WIDTH_IN_CHUNKS); z = Math.floorDiv(pos.getZ(), LodUtil.REGION_WIDTH_IN_CHUNKS);
} }
/** Returns the ChunkPos at the center of this region */ /** Returns the ChunkPos at the center of this region */
public ChunkPosWrapper chunkPos() public AbstractChunkPosWrapper chunkPos()
{ {
return new ChunkPosWrapper( return WRAPPER_FACTORY.createChunkPos(
(x * LodUtil.REGION_WIDTH_IN_CHUNKS) + LodUtil.REGION_WIDTH_IN_CHUNKS / 2, (x * LodUtil.REGION_WIDTH_IN_CHUNKS) + LodUtil.REGION_WIDTH_IN_CHUNKS / 2,
(z * LodUtil.REGION_WIDTH_IN_CHUNKS) + LodUtil.REGION_WIDTH_IN_CHUNKS / 2); (z * LodUtil.REGION_WIDTH_IN_CHUNKS) + LodUtil.REGION_WIDTH_IN_CHUNKS / 2);
} }
@@ -35,7 +35,6 @@ import com.seibel.lod.core.render.shader.LodShader;
import com.seibel.lod.core.render.shader.LodShaderProgram; import com.seibel.lod.core.render.shader.LodShaderProgram;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper;
import com.seibel.lod.wrappers.minecraft.MinecraftWrapper;
/** /**
* A singleton that holds references to different openGL contexts * A singleton that holds references to different openGL contexts
@@ -53,11 +52,11 @@ import com.seibel.lod.wrappers.minecraft.MinecraftWrapper;
*/ */
public class GlProxy public class GlProxy
{ {
private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private static GlProxy instance = null; private static GlProxy instance = null;
private static IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class);
/** Minecraft's GLFW window */ /** Minecraft's GLFW window */
public final long minecraftGlContext; public final long minecraftGlContext;
/** Minecraft's GL capabilities */ /** Minecraft's GL capabilities */
@@ -140,7 +139,7 @@ public class GlProxy
// Note: as of MC 1.17 this shouldn't happen since MC // Note: as of MC 1.17 this shouldn't happen since MC
// requires OpenGL 3.3, but just in case. // requires OpenGL 3.3, but just in case.
String errorMessage = ModInfo.READABLE_NAME + " was initializing " + GlProxy.class.getSimpleName() + " and discoverd this GPU doesn't support OpenGL 2.0 or greater."; String errorMessage = ModInfo.READABLE_NAME + " was initializing " + GlProxy.class.getSimpleName() + " and discoverd this GPU doesn't support OpenGL 2.0 or greater.";
mc.crashMinecraft(errorMessage + " Sorry I couldn't tell you sooner :(", new UnsupportedOperationException("This GPU doesn't support OpenGL 2.0 or greater.")); MC.crashMinecraft(errorMessage + " Sorry I couldn't tell you sooner :(", new UnsupportedOperationException("This GPU doesn't support OpenGL 2.0 or greater."));
} }
@@ -44,11 +44,12 @@ import com.seibel.lod.core.render.shader.LodShaderProgram;
import com.seibel.lod.core.util.DetailDistanceUtil; import com.seibel.lod.core.util.DetailDistanceUtil;
import com.seibel.lod.core.util.LevelPosUtil; import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperAdapters.IWrapperFactory;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
import com.seibel.lod.wrappers.handlers.ReflectionHandler; import com.seibel.lod.wrappers.handlers.ReflectionHandler;
import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper;
@@ -63,6 +64,12 @@ import net.minecraft.profiler.IProfiler;
*/ */
public class LodRenderer public class LodRenderer
{ {
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);
private static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class);
// /** // /**
// * this is the light used when rendering the LODs, // * this is the light used when rendering the LODs,
// * it should be something different from what is used by Minecraft // * it should be something different from what is used by Minecraft
@@ -75,10 +82,6 @@ public class LodRenderer
*/ */
public DebugMode previousDebugMode = DebugMode.OFF; public DebugMode previousDebugMode = DebugMode.OFF;
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 IProfiler profiler;
private int farPlaneBlockDistance; private int farPlaneBlockDistance;
@@ -96,7 +99,7 @@ public class LodRenderer
@SuppressWarnings("unused") @SuppressWarnings("unused")
private int[][][] storageBufferIds; private int[][][] storageBufferIds;
private ChunkPosWrapper vbosCenter = new ChunkPosWrapper(0, 0); private AbstractChunkPosWrapper vbosCenter = FACTORY.createChunkPos();
/** This is used to determine if the LODs should be regenerated */ /** This is used to determine if the LODs should be regenerated */
@@ -165,7 +168,7 @@ public class LodRenderer
return; return;
} }
if (mcRenderer.playerHasBlindnessEffect()) if (MC_RENDER.playerHasBlindnessEffect())
{ {
// if the player is blind don't render LODs, // if the player is blind don't render LODs,
// and don't change minecraft's fog // and don't change minecraft's fog
@@ -193,7 +196,7 @@ public class LodRenderer
if ((partialRegen || fullRegen) && !lodBufferBuilderFactory.generatingBuffers && !lodBufferBuilderFactory.newBuffersAvailable()) if ((partialRegen || fullRegen) && !lodBufferBuilderFactory.generatingBuffers && !lodBufferBuilderFactory.newBuffersAvailable())
{ {
// generate the LODs on a separate thread to prevent stuttering or freezing // generate the LODs on a separate thread to prevent stuttering or freezing
lodBufferBuilderFactory.generateLodBuffersAsync(this, lodDim, mc.getPlayerBlockPos(), true); lodBufferBuilderFactory.generateLodBuffersAsync(this, lodDim, MC.getPlayerBlockPos(), true);
// the regen process has been started, // the regen process has been started,
// it will be done when lodBufferBuilder.newBuffersAvailable() // it will be done when lodBufferBuilder.newBuffersAvailable()
@@ -227,7 +230,7 @@ public class LodRenderer
// set the required open GL settings // set the required open GL settings
if (config.client().advanced().debugging().getDebugMode() == DebugMode.SHOW_DETAIL_WIREFRAME) if (CONFIG.client().advanced().debugging().getDebugMode() == DebugMode.SHOW_DETAIL_WIREFRAME)
GL15.glPolygonMode(GL15.GL_FRONT_AND_BACK, GL15.GL_LINE); GL15.glPolygonMode(GL15.GL_FRONT_AND_BACK, GL15.GL_LINE);
else else
GL15.glPolygonMode(GL15.GL_FRONT_AND_BACK, GL15.GL_FILL); GL15.glPolygonMode(GL15.GL_FRONT_AND_BACK, GL15.GL_FILL);
@@ -244,12 +247,12 @@ public class LodRenderer
Mat4f modelViewMatrix = offsetTheModelViewMatrix(mcModelViewMatrix, partialTicks); Mat4f modelViewMatrix = offsetTheModelViewMatrix(mcModelViewMatrix, partialTicks);
vanillaBlockRenderedDistance = mcRenderer.getRenderDistance() * LodUtil.CHUNK_WIDTH; vanillaBlockRenderedDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH;
// required for setupFog and setupProjectionMatrix // required for setupFog and setupProjectionMatrix
if (mc.getWrappedClientWorld().getDimensionType().hasCeiling()) if (MC.getWrappedClientWorld().getDimensionType().hasCeiling())
farPlaneBlockDistance = Math.min(config.client().graphics().quality().getLodChunkRenderDistance(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * LodUtil.CHUNK_WIDTH; farPlaneBlockDistance = Math.min(CONFIG.client().graphics().quality().getLodChunkRenderDistance(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * LodUtil.CHUNK_WIDTH;
else else
farPlaneBlockDistance = config.client().graphics().quality().getLodChunkRenderDistance() * LodUtil.CHUNK_WIDTH; farPlaneBlockDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance() * LodUtil.CHUNK_WIDTH;
Mat4f projectionMatrix = createProjectionMatrix(mcProjectionMatrix, vanillaBlockRenderedDistance, partialTicks); Mat4f projectionMatrix = createProjectionMatrix(mcProjectionMatrix, vanillaBlockRenderedDistance, partialTicks);
@@ -282,7 +285,7 @@ public class LodRenderer
if (vbos != null) if (vbos != null)
{ {
Vec3f cameraDir = mcRenderer.getLookAtVector(); Vec3f cameraDir = MC_RENDER.getLookAtVector();
// TODO re-enable once rendering is totally working // TODO re-enable once rendering is totally working
boolean cullingDisabled = true; //LodConfig.client().graphics.advancedGraphicsOption.disableDirectionalCulling.get(); boolean cullingDisabled = true; //LodConfig.client().graphics.advancedGraphicsOption.disableDirectionalCulling.get();
@@ -330,7 +333,7 @@ public class LodRenderer
x + vboCenterRegionPos.x - (lodDim.getWidth() / 2), x + vboCenterRegionPos.x - (lodDim.getWidth() / 2),
z + vboCenterRegionPos.z - (lodDim.getWidth() / 2)); z + vboCenterRegionPos.z - (lodDim.getWidth() / 2));
if (cullingDisabled || RenderUtil.isRegionInViewFrustum(mcRenderer.getCameraBlockPosition(), cameraDir, vboPos.blockPos())) if (cullingDisabled || RenderUtil.isRegionInViewFrustum(MC_RENDER.getCameraBlockPosition(), cameraDir, vboPos.blockPos()))
{ {
// TODO add fog to the fragment shader // TODO add fog to the fragment shader
// if ((x > halfWidth - quarterWidth && x < halfWidth + quarterWidth) // if ((x > halfWidth - quarterWidth && x < halfWidth + quarterWidth)
@@ -459,7 +462,7 @@ public class LodRenderer
if (fogQuality == FogQuality.FANCY) if (fogQuality == FogQuality.FANCY)
{ {
// for more realistic fog when using FAR // for more realistic fog when using FAR
if (config.client().graphics().fogQuality().getFogDistance() == FogDistance.NEAR_AND_FAR) if (CONFIG.client().graphics().fogQuality().getFogDistance() == FogDistance.NEAR_AND_FAR)
GL15.glFogf(GL15.GL_FOG_START, farPlaneBlockDistance * 1.6f * 0.9f); GL15.glFogf(GL15.GL_FOG_START, farPlaneBlockDistance * 1.6f * 0.9f);
else else
GL15.glFogf(GL15.GL_FOG_START, Math.min(vanillaBlockRenderedDistance * 1.5f, farPlaneBlockDistance * 0.9f * 1.6f)); GL15.glFogf(GL15.GL_FOG_START, Math.min(vanillaBlockRenderedDistance * 1.5f, farPlaneBlockDistance * 0.9f * 1.6f));
@@ -515,7 +518,7 @@ public class LodRenderer
// disable fog if Minecraft wasn't rendering fog // disable fog if Minecraft wasn't rendering fog
// or we want it disabled // or we want it disabled
if (!fogSettings.vanillaIsRenderingFog if (!fogSettings.vanillaIsRenderingFog
|| config.client().graphics().fogQuality().getDisableVanillaFog()) || CONFIG.client().graphics().fogQuality().getDisableVanillaFog())
{ {
// Make fog render a infinite distance away. // Make fog render a infinite distance away.
// This doesn't technically disable Minecraft's fog // This doesn't technically disable Minecraft's fog
@@ -542,7 +545,7 @@ public class LodRenderer
private Mat4f offsetTheModelViewMatrix(Mat4f mcModelViewMatrix, float partialTicks) private Mat4f offsetTheModelViewMatrix(Mat4f mcModelViewMatrix, float partialTicks)
{ {
// get all relevant camera info // get all relevant camera info
Vec3d projectedView = mcRenderer.getCameraExactPosition(); Vec3d projectedView = MC_RENDER.getCameraExactPosition();
// translate the camera relative to the regions' center // translate the camera relative to the regions' center
// (AxisAlignedBoundingBoxes (LODs) use doubles and thus have a higher // (AxisAlignedBoundingBoxes (LODs) use doubles and thus have a higher
@@ -566,15 +569,15 @@ public class LodRenderer
// create the new projection matrix // create the new projection matrix
Mat4f lodProj = Mat4f.perspective( Mat4f lodProj = Mat4f.perspective(
mcRenderer.getFov(partialTicks), MC_RENDER.getFov(partialTicks),
(float) this.mcRenderer.getScreenWidth() / (float) this.mcRenderer.getScreenHeight(), (float) this.MC_RENDER.getScreenWidth() / (float) this.MC_RENDER.getScreenHeight(),
config.client().graphics().advancedGraphics().getUseExtendedNearClipPlane() ? vanillaBlockRenderedDistance / 5 : 1, CONFIG.client().graphics().advancedGraphics().getUseExtendedNearClipPlane() ? vanillaBlockRenderedDistance / 5 : 1,
farPlaneBlockDistance * LodUtil.CHUNK_WIDTH / 2); farPlaneBlockDistance * LodUtil.CHUNK_WIDTH / 2);
// get Minecraft's un-edited projection matrix // get Minecraft's un-edited projection matrix
// (this is before it is zoomed, distorted, etc.) // (this is before it is zoomed, distorted, etc.)
Mat4f defaultMcProj = mcRenderer.getDefaultProjectionMatrix(partialTicks); Mat4f defaultMcProj = MC_RENDER.getDefaultProjectionMatrix(partialTicks);
// true here means use "use fov setting" (probably) // true here means use "use fov setting" (probably)
// this logic strips away the defaultMcProj matrix, so we // this logic strips away the defaultMcProj matrix, so we
@@ -688,7 +691,7 @@ public class LodRenderer
FogQuality quality = ReflectionHandler.INSTANCE.getFogQuality(); FogQuality quality = ReflectionHandler.INSTANCE.getFogQuality();
FogDrawOverride override = config.client().graphics().fogQuality().getFogDrawOverride(); FogDrawOverride override = CONFIG.client().graphics().fogQuality().getFogDrawOverride();
fogSettings.vanillaIsRenderingFog = quality != FogQuality.OFF; fogSettings.vanillaIsRenderingFog = quality != FogQuality.OFF;
@@ -729,7 +732,7 @@ public class LodRenderer
fogSettings.near.quality = FogQuality.FANCY; fogSettings.near.quality = FogQuality.FANCY;
fogSettings.far.quality = FogQuality.FANCY; fogSettings.far.quality = FogQuality.FANCY;
switch (config.client().graphics().fogQuality().getFogDistance()) switch (CONFIG.client().graphics().fogQuality().getFogDistance())
{ {
case NEAR_AND_FAR: case NEAR_AND_FAR:
fogSettings.near.distance = FogDistance.NEAR; fogSettings.near.distance = FogDistance.NEAR;
@@ -756,7 +759,7 @@ public class LodRenderer
// fog, since the LODs are separated into a near // fog, since the LODs are separated into a near
// and far portion; and fast fog is rendered from the // and far portion; and fast fog is rendered from the
// frustrum's perspective instead of the camera // frustrum's perspective instead of the camera
switch (config.client().graphics().fogQuality().getFogDistance()) switch (CONFIG.client().graphics().fogQuality().getFogDistance())
{ {
case NEAR_AND_FAR: case NEAR_AND_FAR:
case NEAR: case NEAR:
@@ -783,7 +786,7 @@ public class LodRenderer
/** Determines if the LODs should have a fullRegen or partialRegen */ /** Determines if the LODs should have a fullRegen or partialRegen */
private void determineIfLodsShouldRegenerate(LodDimension lodDim, float partialTicks) private void determineIfLodsShouldRegenerate(LodDimension lodDim, float partialTicks)
{ {
short chunkRenderDistance = (short) mcRenderer.getRenderDistance(); short chunkRenderDistance = (short) MC_RENDER.getRenderDistance();
int vanillaRenderedChunksWidth = chunkRenderDistance * 2 + 2; int vanillaRenderedChunksWidth = chunkRenderDistance * 2 + 2;
//=============// //=============//
@@ -791,23 +794,23 @@ public class LodRenderer
//=============// //=============//
// check if the view distance changed // check if the view distance changed
if (ApiShared.previousLodRenderDistance != config.client().graphics().quality().getLodChunkRenderDistance() if (ApiShared.previousLodRenderDistance != CONFIG.client().graphics().quality().getLodChunkRenderDistance()
|| chunkRenderDistance != prevRenderDistance || chunkRenderDistance != prevRenderDistance
|| prevFogDistance != config.client().graphics().fogQuality().getFogDistance()) || prevFogDistance != CONFIG.client().graphics().fogQuality().getFogDistance())
{ {
vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth]; vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth];
DetailDistanceUtil.updateSettings(); DetailDistanceUtil.updateSettings();
fullRegen = true; fullRegen = true;
previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayerChunkPos().getZ(), mc.getPlayerChunkPos().getZ()); previousPos = LevelPosUtil.createLevelPos((byte) 4, MC.getPlayerChunkPos().getZ(), MC.getPlayerChunkPos().getZ());
prevFogDistance = config.client().graphics().fogQuality().getFogDistance(); prevFogDistance = CONFIG.client().graphics().fogQuality().getFogDistance();
prevRenderDistance = chunkRenderDistance; prevRenderDistance = chunkRenderDistance;
} }
// did the user change the debug setting? // did the user change the debug setting?
if (config.client().advanced().debugging().getDebugMode() != previousDebugMode) if (CONFIG.client().advanced().debugging().getDebugMode() != previousDebugMode)
{ {
previousDebugMode = config.client().advanced().debugging().getDebugMode(); previousDebugMode = CONFIG.client().advanced().debugging().getDebugMode();
fullRegen = true; fullRegen = true;
} }
@@ -815,15 +818,15 @@ public class LodRenderer
long newTime = System.currentTimeMillis(); long newTime = System.currentTimeMillis();
// check if the player has moved // check if the player has moved
if (newTime - prevPlayerPosTime > config.client().advanced().buffers().getRebuildTimes().playerMoveTimeout) if (newTime - prevPlayerPosTime > CONFIG.client().advanced().buffers().getRebuildTimes().playerMoveTimeout)
{ {
if (LevelPosUtil.getDetailLevel(previousPos) == 0 if (LevelPosUtil.getDetailLevel(previousPos) == 0
|| mc.getPlayerChunkPos().getX() != LevelPosUtil.getPosX(previousPos) || MC.getPlayerChunkPos().getX() != LevelPosUtil.getPosX(previousPos)
|| mc.getPlayerChunkPos().getZ() != LevelPosUtil.getPosZ(previousPos)) || MC.getPlayerChunkPos().getZ() != LevelPosUtil.getPosZ(previousPos))
{ {
vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth]; vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth];
fullRegen = true; fullRegen = true;
previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayerChunkPos().getX(), mc.getPlayerChunkPos().getZ()); previousPos = LevelPosUtil.createLevelPos((byte) 4, MC.getPlayerChunkPos().getX(), MC.getPlayerChunkPos().getZ());
} }
prevPlayerPosTime = newTime; prevPlayerPosTime = newTime;
} }
@@ -834,9 +837,9 @@ public class LodRenderer
// change in order to rebuild the buffers // change in order to rebuild the buffers
// the max brightness is 1 and the minimum is 0.2 // the max brightness is 1 and the minimum is 0.2
float skyBrightness = lodDim.dimension.hasSkyLight() ? mc.getSkyDarken(partialTicks) : 0.2f; float skyBrightness = lodDim.dimension.hasSkyLight() ? MC.getSkyDarken(partialTicks) : 0.2f;
float minLightingDifference; float minLightingDifference;
switch (config.client().advanced().buffers().getRebuildTimes()) switch (CONFIG.client().advanced().buffers().getRebuildTimes())
{ {
case FREQUENT: case FREQUENT:
minLightingDifference = 0.025f; minLightingDifference = 0.025f;
@@ -856,10 +859,10 @@ public class LodRenderer
// (just in case the minLightingDifference is too large to notice the change) // (just in case the minLightingDifference is too large to notice the change)
|| (skyBrightness == 1.0f && prevSkyBrightness != 1.0f) // noon || (skyBrightness == 1.0f && prevSkyBrightness != 1.0f) // noon
|| (skyBrightness == 0.2f && prevSkyBrightness != 0.2f) // midnight || (skyBrightness == 0.2f && prevSkyBrightness != 0.2f) // midnight
|| mcRenderer.getGamma() != prevBrightness) || MC_RENDER.getGamma() != prevBrightness)
{ {
fullRegen = true; fullRegen = true;
prevBrightness = mcRenderer.getGamma(); prevBrightness = MC_RENDER.getGamma();
prevSkyBrightness = skyBrightness; prevSkyBrightness = skyBrightness;
} }
@@ -875,7 +878,7 @@ public class LodRenderer
// check if the vanilla rendered chunks changed // check if the vanilla rendered chunks changed
if (newTime - prevVanillaChunkTime > config.client().advanced().buffers().getRebuildTimes().renderedChunkTimeout) if (newTime - prevVanillaChunkTime > CONFIG.client().advanced().buffers().getRebuildTimes().renderedChunkTimeout)
{ {
if (vanillaRenderedChunksChanged) if (vanillaRenderedChunksChanged)
{ {
@@ -887,7 +890,7 @@ public class LodRenderer
// check if there is any newly generated terrain to show // check if there is any newly generated terrain to show
if (newTime - prevChunkTime > config.client().advanced().buffers().getRebuildTimes().chunkChangeTimeout) if (newTime - prevChunkTime > CONFIG.client().advanced().buffers().getRebuildTimes().chunkChangeTimeout)
{ {
if (lodDim.regenDimensionBuffers) if (lodDim.regenDimensionBuffers)
{ {
@@ -904,15 +907,15 @@ public class LodRenderer
//==============// //==============//
// determine which LODs should not be rendered close to the player // determine which LODs should not be rendered close to the player
HashSet<ChunkPosWrapper> chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, mc.getPlayerBlockPos()); HashSet<AbstractChunkPosWrapper> chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, MC.getPlayerBlockPos());
int xIndex; int xIndex;
int zIndex; int zIndex;
for (ChunkPosWrapper pos : chunkPosToSkip) for (AbstractChunkPosWrapper pos : chunkPosToSkip)
{ {
vanillaRenderedChunksEmptySkip = false; vanillaRenderedChunksEmptySkip = false;
xIndex = (pos.getX() - mc.getPlayerChunkPos().getX()) + (chunkRenderDistance + 1); xIndex = (pos.getX() - MC.getPlayerChunkPos().getX()) + (chunkRenderDistance + 1);
zIndex = (pos.getZ() - mc.getPlayerChunkPos().getZ()) + (chunkRenderDistance + 1); zIndex = (pos.getZ() - MC.getPlayerChunkPos().getZ()) + (chunkRenderDistance + 1);
// sometimes we are given chunks that are outside the render distance, // sometimes we are given chunks that are outside the render distance,
// This prevents index out of bounds exceptions // This prevents index out of bounds exceptions
@@ -931,7 +934,7 @@ public class LodRenderer
// if the player is high enough, draw all LODs // if the player is high enough, draw all LODs
if (chunkPosToSkip.isEmpty() && mc.getPlayerBlockPos().getY() > 256 && !vanillaRenderedChunksEmptySkip) if (chunkPosToSkip.isEmpty() && MC.getPlayerBlockPos().getY() > 256 && !vanillaRenderedChunksEmptySkip)
{ {
vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth]; vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth];
vanillaRenderedChunksChanged = true; vanillaRenderedChunksChanged = true;
@@ -22,7 +22,7 @@ package com.seibel.lod.core.render;
import com.seibel.lod.core.objects.math.Vec3f; import com.seibel.lod.core.objects.math.Vec3f;
import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper;
/** /**
@@ -41,7 +41,7 @@ public class RenderUtil
* Returns if the given ChunkPos is in the loaded area of the world. * Returns if the given ChunkPos is in the loaded area of the world.
* @param center the center of the loaded world (probably the player's ChunkPos) * @param center the center of the loaded world (probably the player's ChunkPos)
*/ */
public static boolean isChunkPosInLoadedArea(ChunkPosWrapper pos, ChunkPosWrapper center) public static boolean isChunkPosInLoadedArea(AbstractChunkPosWrapper pos, AbstractChunkPosWrapper center)
{ {
return (pos.getX() >= center.getX() - MC_RENDER.getRenderDistance() return (pos.getX() >= center.getX() - MC_RENDER.getRenderDistance()
&& pos.getX() <= center.getX() + MC_RENDER.getRenderDistance()) && pos.getX() <= center.getX() + MC_RENDER.getRenderDistance())
@@ -23,7 +23,6 @@ import java.awt.Color;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper;
import com.seibel.lod.wrappers.minecraft.MinecraftWrapper;
/** /**
* *
@@ -33,7 +32,7 @@ import com.seibel.lod.wrappers.minecraft.MinecraftWrapper;
*/ */
public class ColorUtil public class ColorUtil
{ {
private static final IMinecraftWrapper mc = SingletonHandler.get(IMinecraftWrapper.class); private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
public static int rgbToInt(int red, int green, int blue) public static int rgbToInt(int red, int green, int blue)
@@ -89,7 +88,7 @@ public class ColorUtil
/** This method apply the lightmap to the color to use */ /** This method apply the lightmap to the color to use */
public static int applyLightValue(int color, int skyLight, int blockLight) public static int applyLightValue(int color, int skyLight, int blockLight)
{ {
int lightColor = mc.getColorIntFromLightMap(blockLight, skyLight); int lightColor = MC.getColorIntFromLightMap(blockLight, skyLight);
int red = ColorUtil.getBlue(lightColor); int red = ColorUtil.getBlue(lightColor);
int green = ColorUtil.getGreen(lightColor); int green = ColorUtil.getGreen(lightColor);
int blue = ColorUtil.getRed(lightColor); int blue = ColorUtil.getRed(lightColor);
@@ -31,13 +31,14 @@ import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.objects.lod.RegionPos; import com.seibel.lod.core.objects.lod.RegionPos;
import com.seibel.lod.core.objects.opengl.DefaultLodVertexFormats; import com.seibel.lod.core.objects.opengl.DefaultLodVertexFormats;
import com.seibel.lod.core.objects.opengl.LodVertexFormat; import com.seibel.lod.core.objects.opengl.LodVertexFormat;
import com.seibel.lod.core.wrapperAdapters.IWrapperFactory;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftWrapper;
import com.seibel.lod.core.wrapperAdapters.world.IDimensionTypeWrapper; import com.seibel.lod.core.wrapperAdapters.world.IDimensionTypeWrapper;
import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper; import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.lod.wrappers.minecraft.MinecraftRenderWrapper;
import net.minecraft.world.chunk.ChunkSection; import net.minecraft.world.chunk.ChunkSection;
@@ -55,6 +56,7 @@ public class LodUtil
private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private static final MinecraftRenderWrapper MC_RENDER = MinecraftRenderWrapper.INSTANCE; private static final MinecraftRenderWrapper MC_RENDER = MinecraftRenderWrapper.INSTANCE;
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class);
/** /**
* Vanilla render distances less than or equal to this will not allow partial * Vanilla render distances less than or equal to this will not allow partial
@@ -324,10 +326,10 @@ public class LodUtil
* Get a HashSet of all ChunkPos within the normal render distance * Get a HashSet of all ChunkPos within the normal render distance
* that should not be rendered. * that should not be rendered.
*/ */
public static HashSet<ChunkPosWrapper> getNearbyLodChunkPosToSkip(LodDimension lodDim, AbstractBlockPosWrapper blockPosWrapper) public static HashSet<AbstractChunkPosWrapper> getNearbyLodChunkPosToSkip(LodDimension lodDim, AbstractBlockPosWrapper blockPosWrapper)
{ {
int chunkRenderDist = MC_RENDER.getRenderDistance(); int chunkRenderDist = MC_RENDER.getRenderDistance();
ChunkPosWrapper centerChunk = new ChunkPosWrapper(blockPosWrapper); AbstractChunkPosWrapper centerChunk = FACTORY.createChunkPos(blockPosWrapper);
int skipRadius; int skipRadius;
VanillaOverdraw overdraw = CONFIG.client().graphics().advancedGraphics().getVanillaOverdraw(); VanillaOverdraw overdraw = CONFIG.client().graphics().advancedGraphics().getVanillaOverdraw();
@@ -394,7 +396,7 @@ public class LodUtil
// get the chunks that are going to be rendered by Minecraft // get the chunks that are going to be rendered by Minecraft
HashSet<ChunkPosWrapper> posToSkip = MC_RENDER.getRenderedChunks(); HashSet<AbstractChunkPosWrapper> posToSkip = MC_RENDER.getRenderedChunks();
// remove everything outside the skipRadius, // remove everything outside the skipRadius,
@@ -407,7 +409,7 @@ public class LodUtil
{ {
if (x <= centerChunk.getX() - skipRadius || x >= centerChunk.getX() + skipRadius if (x <= centerChunk.getX() - skipRadius || x >= centerChunk.getX() + skipRadius
|| z <= centerChunk.getZ() - skipRadius || z >= centerChunk.getZ() + skipRadius) || z <= centerChunk.getZ() - skipRadius || z >= centerChunk.getZ() + skipRadius)
posToSkip.remove(new ChunkPosWrapper(x, z)); posToSkip.remove(FACTORY.createChunkPos(x, z));
} }
} }
} }
@@ -1,6 +1,7 @@
package com.seibel.lod.core.wrapperAdapters; package com.seibel.lod.core.wrapperAdapters;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
/** /**
* *
@@ -11,4 +12,10 @@ public interface IWrapperFactory
{ {
public AbstractBlockPosWrapper createBlockPos(); public AbstractBlockPosWrapper createBlockPos();
public AbstractBlockPosWrapper createBlockPos(int x, int y, int z); public AbstractBlockPosWrapper createBlockPos(int x, int y, int z);
public AbstractChunkPosWrapper createChunkPos();
public AbstractChunkPosWrapper createChunkPos(int x, int z);
public AbstractChunkPosWrapper createChunkPos(AbstractChunkPosWrapper newChunkPos);
public AbstractChunkPosWrapper createChunkPos(AbstractBlockPosWrapper blockPos);
} }
@@ -66,11 +66,13 @@ public class SingletonHandler
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T get(Class<T> objectClass) throws NullPointerException, ClassCastException public static <T> T get(Class<T> objectClass) throws NullPointerException, ClassCastException
{ {
//
if (!singletons.containsKey(objectClass)) if (!singletons.containsKey(objectClass))
{ {
throw new NullPointerException("The singleton [" + objectClass.getSimpleName() + "] was never bound."); throw new NullPointerException("The singleton [" + objectClass.getSimpleName() + "] was never bound.");
} }
return (T) singletons.get(objectClass); return (T) singletons.get(objectClass);
} }
@@ -4,15 +4,10 @@ import com.seibel.lod.core.enums.LodDirection;
public abstract class AbstractBlockPosWrapper public abstract class AbstractBlockPosWrapper
{ {
public AbstractBlockPosWrapper() public AbstractBlockPosWrapper() { }
{ public AbstractBlockPosWrapper(int x, int y, int z) { }
}
public AbstractBlockPosWrapper(int x, int y, int z)
{
}
public abstract void set(int x, int y, int z); public abstract void set(int x, int y, int z);
@@ -0,0 +1,32 @@
package com.seibel.lod.core.wrapperAdapters.chunk;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
/**
* This class wraps minecraft's ChunkPos class
*
* @author James Seibel
* @version 11-18-2021
*/
public abstract class AbstractChunkPosWrapper
{
public AbstractChunkPosWrapper(AbstractChunkPosWrapper newChunkPos) { }
public AbstractChunkPosWrapper(AbstractBlockPosWrapper blockPos) { }
public AbstractChunkPosWrapper(int chunkX, int chunkZ) { }
public AbstractChunkPosWrapper() { }
public abstract int getX();
public abstract int getZ();
public abstract int getMinBlockX();
public abstract int getMinBlockZ();
public abstract int getRegionX();
public abstract int getRegionZ();
public abstract AbstractBlockPosWrapper getWorldPosition();
}
@@ -3,7 +3,6 @@ package com.seibel.lod.core.wrapperAdapters.chunk;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.block.IBlockColorWrapper; import com.seibel.lod.core.wrapperAdapters.block.IBlockColorWrapper;
import com.seibel.lod.core.wrapperAdapters.block.IBlockShapeWrapper; import com.seibel.lod.core.wrapperAdapters.block.IBlockShapeWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
import com.seibel.lod.wrappers.world.BiomeWrapper; import com.seibel.lod.wrappers.world.BiomeWrapper;
/** /**
@@ -25,7 +24,7 @@ public interface IChunkWrapper
public IBlockShapeWrapper getBlockShapeWrapper(AbstractBlockPosWrapper blockPos); public IBlockShapeWrapper getBlockShapeWrapper(AbstractBlockPosWrapper blockPos);
public ChunkPosWrapper getPos(); public AbstractChunkPosWrapper getPos();
public boolean isLightCorrect(); public boolean isLightCorrect();
@@ -6,7 +6,7 @@ import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.objects.math.Vec3d; import com.seibel.lod.core.objects.math.Vec3d;
import com.seibel.lod.core.objects.math.Vec3f; import com.seibel.lod.core.objects.math.Vec3f;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
/** /**
* Contains everything related to * Contains everything related to
@@ -39,11 +39,7 @@ public interface IMinecraftRenderWrapper
/** /**
* This method returns the ChunkPos of all chunks that Minecraft * This method returns the ChunkPos of all chunks that Minecraft
* is going to render this frame. <br><br> * is going to render this frame.
* <p>
* 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<ChunkPosWrapper> getRenderedChunks(); public HashSet<AbstractChunkPosWrapper> getRenderedChunks();
} }
@@ -25,9 +25,9 @@ import java.util.ArrayList;
import com.seibel.lod.core.enums.LodDirection; import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.misc.ILightMapWrapper; import com.seibel.lod.core.wrapperAdapters.misc.ILightMapWrapper;
import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper; import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
import com.seibel.lod.wrappers.world.DimensionTypeWrapper; import com.seibel.lod.wrappers.world.DimensionTypeWrapper;
import com.seibel.lod.wrappers.world.WorldWrapper; import com.seibel.lod.wrappers.world.WorldWrapper;
@@ -105,7 +105,7 @@ public interface IMinecraftWrapper
public AbstractBlockPosWrapper getPlayerBlockPos(); public AbstractBlockPosWrapper getPlayerBlockPos();
public ChunkPosWrapper getPlayerChunkPos(); public AbstractChunkPosWrapper getPlayerChunkPos();
/** /**
* Attempts to get the ServerWorld for the dimension * Attempts to get the ServerWorld for the dimension
@@ -2,9 +2,12 @@ package com.seibel.lod.wrappers;
import com.seibel.lod.core.wrapperAdapters.IWrapperFactory; import com.seibel.lod.core.wrapperAdapters.IWrapperFactory;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.wrappers.block.BlockPosWrapper; import com.seibel.lod.wrappers.block.BlockPosWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
/** /**
* This handles creating abstract wrapper objects.
* *
* @author James Seibel * @author James Seibel
* @version 11-18-2021 * @version 11-18-2021
@@ -26,4 +29,34 @@ public class WrapperFactory implements IWrapperFactory
return new BlockPosWrapper(x,y,z); return new BlockPosWrapper(x,y,z);
} }
@Override
public AbstractChunkPosWrapper createChunkPos()
{
return new ChunkPosWrapper();
}
@Override
public AbstractChunkPosWrapper createChunkPos(int x, int z)
{
return new ChunkPosWrapper(x, z);
}
@Override
public AbstractChunkPosWrapper createChunkPos(AbstractChunkPosWrapper newChunkPos)
{
return new ChunkPosWrapper(newChunkPos);
}
@Override
public AbstractChunkPosWrapper createChunkPos(AbstractBlockPosWrapper blockPos)
{
return new ChunkPosWrapper(blockPos);
}
} }
@@ -29,7 +29,7 @@ import net.minecraftforge.client.model.data.ModelDataMap;
/** /**
* This class wraps the minecraft Block class * This class wraps the minecraft Block color class
* *
* @author ?? * @author ??
* @version 11-17-2021 * @version 11-17-2021
@@ -19,7 +19,12 @@ import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
//This class wraps the minecraft Block class /**
* This class wraps Minecraft's Block class
*
* @author ??
* @version 11-18-2021
*/
public class BlockShapeWrapper implements IBlockShapeWrapper public class BlockShapeWrapper implements IBlockShapeWrapper
{ {
//set of block which require tint //set of block which require tint
@@ -3,14 +3,20 @@ package com.seibel.lod.wrappers.chunk;
import java.util.Objects; import java.util.Objects;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.wrappers.block.BlockPosWrapper; import com.seibel.lod.wrappers.block.BlockPosWrapper;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
//This class wraps the minecraft ChunkPos class /**
public class ChunkPosWrapper * This class wraps minecraft's ChunkPos class
*
* @author James Seibel
* @version 11-18-2021
*/
public class ChunkPosWrapper extends AbstractChunkPosWrapper
{ {
private final ChunkPos chunkPos; private final ChunkPos chunkPos;
@@ -25,9 +31,9 @@ public class ChunkPosWrapper
} }
public ChunkPosWrapper(ChunkPosWrapper newChunkPos) public ChunkPosWrapper(AbstractChunkPosWrapper newChunkPos)
{ {
this.chunkPos = newChunkPos.chunkPos; this.chunkPos = ((ChunkPosWrapper) newChunkPos).chunkPos;
} }
public ChunkPosWrapper(AbstractBlockPosWrapper blockPos) public ChunkPosWrapper(AbstractBlockPosWrapper blockPos)
@@ -40,31 +46,44 @@ public class ChunkPosWrapper
this.chunkPos = new ChunkPos(chunkX, chunkZ); this.chunkPos = new ChunkPos(chunkX, chunkZ);
} }
public ChunkPosWrapper()
{
this.chunkPos = new ChunkPos(0, 0);
}
@Override
public int getX() public int getX()
{ {
return chunkPos.x; return chunkPos.x;
} }
@Override
public int getZ() public int getZ()
{ {
return chunkPos.z; return chunkPos.z;
} }
@Override
public int getMinBlockX() public int getMinBlockX()
{ {
return chunkPos.getMinBlockX(); return chunkPos.getMinBlockX();
} }
@Override
public int getMinBlockZ() public int getMinBlockZ()
{ {
return chunkPos.getMinBlockZ(); return chunkPos.getMinBlockZ();
} }
@Override
public int getRegionX() public int getRegionX()
{ {
return chunkPos.getRegionX(); return chunkPos.getRegionX();
} }
@Override
public int getRegionZ() public int getRegionZ()
{ {
return chunkPos.getRegionZ(); return chunkPos.getRegionZ();
@@ -75,19 +94,25 @@ public class ChunkPosWrapper
return chunkPos; return chunkPos;
} }
@Override public boolean equals(Object o)
@Override
public boolean equals(Object o)
{ {
return chunkPos.equals(o); return chunkPos.equals(o);
} }
@Override public int hashCode() @Override
public int hashCode()
{ {
return Objects.hash(chunkPos); return Objects.hash(chunkPos);
} }
public BlockPosWrapper getWorldPosition() @Override
{ public BlockPosWrapper getWorldPosition()
BlockPos blockPos = chunkPos.getWorldPosition(); {
return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ()); BlockPos blockPos = chunkPos.getWorldPosition();
} return new BlockPosWrapper(blockPos.getX(), blockPos.getY(), blockPos.getZ());
}
} }
@@ -6,6 +6,7 @@ import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.objects.math.Vec3d; import com.seibel.lod.core.objects.math.Vec3d;
import com.seibel.lod.core.objects.math.Vec3f; import com.seibel.lod.core.objects.math.Vec3f;
import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper; import com.seibel.lod.core.wrapperAdapters.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftRenderWrapper; import com.seibel.lod.core.wrapperAdapters.minecraft.IMinecraftRenderWrapper;
import com.seibel.lod.wrappers.block.BlockPosWrapper; import com.seibel.lod.wrappers.block.BlockPosWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
@@ -112,9 +113,9 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
* will be incorrectly added, even though they are outside render range). * will be incorrectly added, even though they are outside render range).
*/ */
@Override @Override
public HashSet<ChunkPosWrapper> getRenderedChunks() public HashSet<AbstractChunkPosWrapper> getRenderedChunks()
{ {
HashSet<ChunkPosWrapper> loadedPos = new HashSet<>(); HashSet<AbstractChunkPosWrapper> loadedPos = new HashSet<>();
// Wow, those are some long names! // Wow, those are some long names!
@@ -13,6 +13,7 @@ import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.objects.lod.LodDimension; import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperAdapters.SingletonHandler; import com.seibel.lod.core.wrapperAdapters.SingletonHandler;
import com.seibel.lod.core.wrapperAdapters.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperAdapters.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper; import com.seibel.lod.core.wrapperAdapters.world.IWorldWrapper;
import com.seibel.lod.wrappers.chunk.ChunkPosWrapper; import com.seibel.lod.wrappers.chunk.ChunkPosWrapper;
@@ -44,13 +45,14 @@ import net.minecraft.world.server.ServerWorldLightManager;
*/ */
public class WorldGeneratorWrapper public class WorldGeneratorWrapper
{ {
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
/** /**
* If a configured feature fails for whatever reason, * If a configured feature fails for whatever reason,
* add it to this list. This is to hopefully remove any * add it to this list. This is to hopefully remove any
* features that could cause issues down the line. * features that could cause issues down the line.
*/ */
private static final ConcurrentHashMap<Integer, ConfiguredFeature<?, ?>> configuredFeaturesToAvoid = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<Integer, ConfiguredFeature<?, ?>> FEATURES_TO_AVOID = new ConcurrentHashMap<>();
private static final ILodConfigWrapperSingleton config = SingletonHandler.get(ILodConfigWrapperSingleton.class);
public final ServerWorld serverWorld; public final ServerWorld serverWorld;
@@ -71,10 +73,10 @@ public class WorldGeneratorWrapper
/** takes about 2-5 ms */ /** takes about 2-5 ms */
public void generateUsingBiomesOnly(ChunkPosWrapper pos, DistanceGenerationMode generationMode) public void generateUsingBiomesOnly(AbstractChunkPosWrapper pos, DistanceGenerationMode generationMode)
{ {
List<IChunk> chunkList = new LinkedList<>(); List<IChunk> chunkList = new LinkedList<>();
ChunkPrimer chunk = new ChunkPrimer(pos.getChunkPos(), UpgradeData.EMPTY); ChunkPrimer chunk = new ChunkPrimer(((ChunkPosWrapper) pos).getChunkPos(), UpgradeData.EMPTY);
chunkList.add(chunk); chunkList.add(chunk);
ServerChunkProvider chunkSource = serverWorld.getChunkSource(); ServerChunkProvider chunkSource = serverWorld.getChunkSource();
@@ -181,10 +183,10 @@ public class WorldGeneratorWrapper
/** takes about 10 - 20 ms */ /** takes about 10 - 20 ms */
public void generateUsingSurface(ChunkPosWrapper pos) public void generateUsingSurface(AbstractChunkPosWrapper pos)
{ {
List<IChunk> chunkList = new LinkedList<>(); List<IChunk> chunkList = new LinkedList<>();
ChunkPrimer chunk = new ChunkPrimer(pos.getChunkPos(), UpgradeData.EMPTY); ChunkPrimer chunk = new ChunkPrimer(((ChunkPosWrapper) pos).getChunkPos(), UpgradeData.EMPTY);
chunkList.add(chunk); chunkList.add(chunk);
LodServerWorld lodServerWorld = new LodServerWorld(serverWorld, chunk); LodServerWorld lodServerWorld = new LodServerWorld(serverWorld, chunk);
@@ -221,10 +223,10 @@ public class WorldGeneratorWrapper
* Causes concurrentModification Exceptions, * Causes concurrentModification Exceptions,
* which could cause instability or world generation bugs * which could cause instability or world generation bugs
*/ */
public void generateUsingFeatures(ChunkPosWrapper pos) public void generateUsingFeatures(AbstractChunkPosWrapper pos)
{ {
List<IChunk> chunkList = new LinkedList<>(); List<IChunk> chunkList = new LinkedList<>();
ChunkPrimer chunk = new ChunkPrimer(pos.getChunkPos(), UpgradeData.EMPTY); ChunkPrimer chunk = new ChunkPrimer(((ChunkPosWrapper) pos).getChunkPos(), UpgradeData.EMPTY);
chunkList.add(chunk); chunkList.add(chunk);
LodServerWorld lodServerWorld = new LodServerWorld(serverWorld, chunk); LodServerWorld lodServerWorld = new LodServerWorld(serverWorld, chunk);
@@ -266,7 +268,7 @@ public class WorldGeneratorWrapper
} }
} }
boolean allowUnstableFeatures = config.client().worldGenerator().getAllowUnstableFeatureGeneration(); boolean allowUnstableFeatures = CONFIG.client().worldGenerator().getAllowUnstableFeatureGeneration();
// generate all the features related to this chunk. // generate all the features related to this chunk.
// this may or may not be thread safe // this may or may not be thread safe
@@ -281,7 +283,7 @@ public class WorldGeneratorWrapper
ConfiguredFeature<?, ?> configuredFeature = featureSupplier.get(); ConfiguredFeature<?, ?> configuredFeature = featureSupplier.get();
if (!allowUnstableFeatures && if (!allowUnstableFeatures &&
configuredFeaturesToAvoid.containsKey(configuredFeature.hashCode())) FEATURES_TO_AVOID.containsKey(configuredFeature.hashCode()))
continue; continue;
@@ -306,7 +308,7 @@ public class WorldGeneratorWrapper
// https://github.com/EsotericSoftware/kryo ) // https://github.com/EsotericSoftware/kryo )
if (!allowUnstableFeatures) if (!allowUnstableFeatures)
configuredFeaturesToAvoid.put(configuredFeature.hashCode(), configuredFeature); FEATURES_TO_AVOID.put(configuredFeature.hashCode(), configuredFeature);
// ClientProxy.LOGGER.info(configuredFeaturesToAvoid.mappingCount()); // ClientProxy.LOGGER.info(configuredFeaturesToAvoid.mappingCount());
} }
// This will happen when the LodServerWorld // This will happen when the LodServerWorld
@@ -319,7 +321,7 @@ public class WorldGeneratorWrapper
e.printStackTrace(); e.printStackTrace();
if (!allowUnstableFeatures) if (!allowUnstableFeatures)
configuredFeaturesToAvoid.put(configuredFeature.hashCode(), configuredFeature); FEATURES_TO_AVOID.put(configuredFeature.hashCode(), configuredFeature);
// ClientProxy.LOGGER.info(configuredFeaturesToAvoid.mappingCount()); // ClientProxy.LOGGER.info(configuredFeaturesToAvoid.mappingCount());
} }
} }
@@ -340,7 +342,7 @@ public class WorldGeneratorWrapper
* Note this should not be multithreaded and does cause server/simulation lag * Note this should not be multithreaded and does cause server/simulation lag
* (Higher lag for generating than loading) * (Higher lag for generating than loading)
*/ */
public void generateWithServer(ChunkPosWrapper pos) public void generateWithServer(AbstractChunkPosWrapper pos)
{ {
lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(serverWorld.getChunk(pos.getX(), pos.getZ(), ChunkStatus.FEATURES)), new LodBuilderConfig(DistanceGenerationMode.SERVER)); lodBuilder.generateLodNodeFromChunk(lodDim, new ChunkWrapper(serverWorld.getChunk(pos.getX(), pos.getZ(), ChunkStatus.FEATURES)), new LodBuilderConfig(DistanceGenerationMode.SERVER));
} }