Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f767215ff0 | |||
| ef87a4e595 | |||
| 1e4fb66e9a | |||
| d38711ca4b | |||
| c9b650fb7f | |||
| 3cef8b9a4f | |||
| d9d9f3dad8 | |||
| 44fe1eafb1 | |||
| 36fcc46445 | |||
| 64895ba521 | |||
| 589340f2db | |||
| de7d22766a | |||
| 568ff40df6 | |||
| 17b5ba0ae1 | |||
| 4d4eeacbdd | |||
| 99dc644adf | |||
| f442ab56c0 | |||
| 9147b139c7 | |||
| fef87df09b |
@@ -61,15 +61,14 @@ public class DhApi
|
||||
* Note: Don't use this string in your code. It may change and is only for reference.
|
||||
*/
|
||||
public static final String READ_ME =
|
||||
"If you don't see Javadocs something is wrong. \n" +
|
||||
"If you are only using the full DH Mod in your build script, you won't have access to our javadocs and could potentially call into unsafe code. \n" +
|
||||
"\n" +
|
||||
"Please use the API jar in your build script as a compile time dependency " +
|
||||
"and the full DH jar as a runtime dependency. \n" +
|
||||
"\n" +
|
||||
"Please refer to the example API project or the DH Developer Wiki for additional information " +
|
||||
"and suggested setup. \n" + // DH Dev note: no links were included to prevent link rot.
|
||||
"";
|
||||
"""
|
||||
If you don't see Javadocs something is wrong.
|
||||
If you are only using the full DH Mod in your build script, you won't have access to our javadocs and could potentially call into unsafe code.
|
||||
|
||||
Please use the API jar in your build script as a compile time dependency and the full DH jar as a runtime dependency.
|
||||
|
||||
Please refer to the example API project or the DH Developer Wiki for additional information and suggested setup.
|
||||
"""; // DH Dev note: no links were included to prevent link rot.
|
||||
public static String readMe() { return READ_ME; }
|
||||
|
||||
/**
|
||||
|
||||
+13
-24
@@ -56,34 +56,23 @@ public enum EDhApiDebugRendering
|
||||
|
||||
public static EDhApiDebugRendering next(EDhApiDebugRendering type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case OFF:
|
||||
return SHOW_DETAIL;
|
||||
case SHOW_DETAIL:
|
||||
return SHOW_BLOCK_MATERIAL;
|
||||
case SHOW_BLOCK_MATERIAL:
|
||||
return SHOW_OVERLAPPING_QUADS;
|
||||
case SHOW_OVERLAPPING_QUADS:
|
||||
return SHOW_RENDER_SOURCE_FLAG;
|
||||
default:
|
||||
return OFF;
|
||||
}
|
||||
return switch (type) {
|
||||
case OFF -> SHOW_DETAIL;
|
||||
case SHOW_DETAIL -> SHOW_BLOCK_MATERIAL;
|
||||
case SHOW_BLOCK_MATERIAL -> SHOW_OVERLAPPING_QUADS;
|
||||
case SHOW_OVERLAPPING_QUADS -> SHOW_RENDER_SOURCE_FLAG;
|
||||
default -> OFF;
|
||||
};
|
||||
}
|
||||
|
||||
public static EDhApiDebugRendering previous(EDhApiDebugRendering type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case OFF:
|
||||
return SHOW_RENDER_SOURCE_FLAG;
|
||||
case SHOW_RENDER_SOURCE_FLAG:
|
||||
return SHOW_OVERLAPPING_QUADS;
|
||||
case SHOW_OVERLAPPING_QUADS:
|
||||
return SHOW_DETAIL;
|
||||
default:
|
||||
return OFF;
|
||||
}
|
||||
return switch (type) {
|
||||
case OFF -> SHOW_RENDER_SOURCE_FLAG;
|
||||
case SHOW_RENDER_SOURCE_FLAG -> SHOW_OVERLAPPING_QUADS;
|
||||
case SHOW_OVERLAPPING_QUADS -> SHOW_DETAIL;
|
||||
default -> OFF;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-18
@@ -42,29 +42,21 @@ public enum EDhApiRendererMode
|
||||
/** Used by the config GUI to cycle through the available rendering options */
|
||||
public static EDhApiRendererMode next(EDhApiRendererMode type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DEFAULT:
|
||||
return DEBUG;
|
||||
case DEBUG:
|
||||
return DISABLED;
|
||||
default:
|
||||
return DEFAULT;
|
||||
}
|
||||
return switch (type) {
|
||||
case DEFAULT -> DEBUG;
|
||||
case DEBUG -> DISABLED;
|
||||
default -> DEFAULT;
|
||||
};
|
||||
}
|
||||
|
||||
/** Used by the config GUI to cycle through the available rendering options */
|
||||
public static EDhApiRendererMode previous(EDhApiRendererMode type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DEFAULT:
|
||||
return DISABLED;
|
||||
case DEBUG:
|
||||
return DEFAULT;
|
||||
default:
|
||||
return DEBUG;
|
||||
}
|
||||
return switch (type) {
|
||||
case DEFAULT -> DISABLED;
|
||||
case DEBUG -> DEFAULT;
|
||||
default -> DEBUG;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
@@ -36,4 +36,13 @@ public interface IDhApiGpuBuffersConfig extends IDhApiConfigGroup
|
||||
/** Defines how geometry data is uploaded to the GPU. */
|
||||
IDhApiConfigValue<EDhApiGpuUploadMethod> gpuUploadMethod();
|
||||
|
||||
/**
|
||||
* Defines how long we should wait after uploading one
|
||||
* Megabyte of geometry data to the GPU before uploading
|
||||
* the next Megabyte of data. <br>
|
||||
* This can be set to a non-zero number to reduce stuttering caused by
|
||||
* uploading buffers to the GPU.
|
||||
*/
|
||||
IDhApiConfigValue<Integer> gpuUploadPerMegabyteInMilliseconds();
|
||||
|
||||
}
|
||||
|
||||
+29
-6
@@ -79,11 +79,34 @@ public interface IDhApiWrapperFactory
|
||||
|
||||
|
||||
|
||||
///**
|
||||
// * Specifically designed to be used with the API.
|
||||
// *
|
||||
// * @throws ClassCastException with instructions on expected objects if the object couldn't be cast
|
||||
// */
|
||||
//IChunkWrapper createChunkWrapper(Object[] objectArray) throws ClassCastException;
|
||||
/**
|
||||
* Constructs a {@link IDhApiBiomeWrapper} for use by other DhApi methods.
|
||||
*
|
||||
* @param resourceLocationString example: "minecraft:plains"
|
||||
*
|
||||
* @param levelWrapper Expects a {@link IDhApiLevelWrapper} returned by one of DH's {@link DhApi.Delayed#worldProxy} methods. <br>
|
||||
* A custom implementation of {@link IDhApiLevelWrapper} will not be accepted.
|
||||
*
|
||||
* @throws IOException if the resourceLocationString wasn't able to be parsed or converted into a valid {@link IDhApiBiomeWrapper}
|
||||
* @throws ClassCastException if the wrong levelWrapper type was given
|
||||
*
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
IDhApiBiomeWrapper getBiomeWrapper(String resourceLocationString, IDhApiLevelWrapper levelWrapper) throws IOException, ClassCastException;
|
||||
|
||||
/**
|
||||
* Constructs a {@link IDhApiBlockStateWrapper} for use by other DhApi methods.
|
||||
* This returns the default blockstate for the given resource location.
|
||||
*
|
||||
* @param resourceLocationString examples: "minecraft:bedrock", "minecraft:stone", "minecraft:grass_block"
|
||||
* @param levelWrapper Expects a {@link IDhApiBlockStateWrapper} returned by one of DH's {@link DhApi.Delayed#worldProxy} methods. <br>
|
||||
* A custom implementation of {@link IDhApiBlockStateWrapper} will not be accepted.
|
||||
*
|
||||
* @throws IOException if the resourceLocationString wasn't able to be parsed or converted into a valid {@link IDhApiBlockStateWrapper}
|
||||
* @throws ClassCastException if the wrong levelWrapper type was given
|
||||
*
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
IDhApiBlockStateWrapper getDefaultBlockStateWrapper(String resourceLocationString, IDhApiLevelWrapper levelWrapper) throws IOException, ClassCastException;
|
||||
|
||||
}
|
||||
|
||||
+48
-1
@@ -22,6 +22,8 @@ package com.seibel.distanthorizons.api.interfaces.override.worldGenerator;
|
||||
import com.seibel.distanthorizons.api.enums.EDhApiDetailLevel;
|
||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.api.objects.data.DhApiChunk;
|
||||
import com.seibel.distanthorizons.api.objects.data.DhApiTerrainDataPoint;
|
||||
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
@@ -77,13 +79,41 @@ public abstract class AbstractDhApiChunkWorldGenerator implements Closeable, IDh
|
||||
}, worldGeneratorThreadPool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CompletableFuture<Void> generateApiChunks(
|
||||
int chunkPosMinX,
|
||||
int chunkPosMinZ,
|
||||
byte granularity,
|
||||
byte targetDataDetail,
|
||||
EDhApiDistantGeneratorMode generatorMode,
|
||||
ExecutorService worldGeneratorThreadPool,
|
||||
Consumer<DhApiChunk> resultConsumer
|
||||
)
|
||||
{
|
||||
return CompletableFuture.runAsync(() ->
|
||||
{
|
||||
// TODO what does this mean?
|
||||
int genChunkWidth = BitShiftUtil.powerOfTwo(granularity - 4);
|
||||
|
||||
for (int chunkX = chunkPosMinX; chunkX < chunkPosMinX + genChunkWidth; chunkX++)
|
||||
{
|
||||
for (int chunkZ = chunkPosMinZ; chunkZ < chunkPosMinZ + genChunkWidth; chunkZ++)
|
||||
{
|
||||
DhApiChunk apiChunk = this.generateApiChunk(chunkX, chunkZ, generatorMode);
|
||||
resultConsumer.accept(apiChunk);
|
||||
}
|
||||
}
|
||||
}, worldGeneratorThreadPool);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is called to generate terrain over a given area
|
||||
* from a thread defined by Distant Horizons. <br><br>
|
||||
*
|
||||
* @param chunkPosX the chunk X position in the level (not to be confused with the chunk's BlockPos in the level)
|
||||
* @param chunkPosZ the chunk Z position in the level (not to be confused with the chunk's BlockPos in the level)
|
||||
* @param generatorMode how far into the world gen pipeline this method run. See {@link EDhApiDistantGeneratorMode} for additional documentation.
|
||||
* @param generatorMode how far into the world gen pipeline this method should run. See {@link EDhApiDistantGeneratorMode} for additional documentation.
|
||||
*
|
||||
* @return See {@link IDhApiWorldGenerator#generateChunks(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer) IDhApiWorldGenerator.generateChunks}
|
||||
* for the list of Object's this method should return along with additional documentation.
|
||||
@@ -92,4 +122,21 @@ public abstract class AbstractDhApiChunkWorldGenerator implements Closeable, IDh
|
||||
*/
|
||||
public abstract Object[] generateChunk(int chunkPosX, int chunkPosZ, EDhApiDistantGeneratorMode generatorMode);
|
||||
|
||||
/**
|
||||
* This method is called to generate terrain over a given area
|
||||
* from a thread defined by Distant Horizons. <br><br>
|
||||
*
|
||||
* @param chunkPosX the chunk X position in the level (not to be confused with the chunk's BlockPos in the level)
|
||||
* @param chunkPosZ the chunk Z position in the level (not to be confused with the chunk's BlockPos in the level)
|
||||
* @param generatorMode how far into the world gen pipeline this method should run. See {@link EDhApiDistantGeneratorMode} for additional documentation.
|
||||
*
|
||||
* @return A {@link DhApiChunk} with the generated {@link DhApiTerrainDataPoint} including air blocks.
|
||||
* Note: if air blocks aren't included with the proper lighting, lower detail levels will appear as black/unlit.
|
||||
*
|
||||
* @see IDhApiWorldGenerator#generateApiChunks(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer)
|
||||
*
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public abstract DhApiChunk generateApiChunk(int chunkPosX, int chunkPosZ, EDhApiDistantGeneratorMode generatorMode);
|
||||
|
||||
}
|
||||
|
||||
+1
@@ -154,6 +154,7 @@ public interface IDhApiWorldGenerator extends Closeable, IDhApiOverrideable
|
||||
*
|
||||
* After the {@link DhApiChunk} has been generated, it should be passed into the
|
||||
* resultConsumer's {@link Consumer#accept(Object)} method.
|
||||
* Note: if air blocks aren't included in the with the {@link DhApiChunk} with proper lighting, lower detail levels will appear as black/unlit.
|
||||
*
|
||||
* @implNote the default implementation of this method throws an {@link UnsupportedOperationException},
|
||||
* and must be overridden when {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#API_CHUNKS}.
|
||||
|
||||
@@ -59,12 +59,12 @@ public class DhApiResult<T>
|
||||
|
||||
|
||||
public static <Pt> DhApiResult<Pt> createSuccess() { return new DhApiResult<>(true, ""); }
|
||||
public static <Pt> DhApiResult<Pt> createSuccess(Pt payload) { return new DhApiResult<Pt>(true, "", payload); }
|
||||
public static <Pt> DhApiResult<Pt> createSuccess(Pt payload) { return new DhApiResult<>(true, "", payload); }
|
||||
// There is no createSuccess(String message) method because it would be too easy to confuse with createSuccess(Pt payload) when returning null
|
||||
public static <Pt> DhApiResult<Pt> createSuccess(String message, Pt payload) { return new DhApiResult<Pt>(true, message, payload); }
|
||||
public static <Pt> DhApiResult<Pt> createSuccess(String message, Pt payload) { return new DhApiResult<>(true, message, payload); }
|
||||
|
||||
// there is no createFail() since all fail results should give a reason for their failure
|
||||
public static <Pt> DhApiResult<Pt> createFail(String message) { return new DhApiResult<>(false, message); }
|
||||
public static <Pt> DhApiResult<Pt> createFail(String message, Pt payload) { return new DhApiResult<Pt>(false, message, payload); }
|
||||
public static <Pt> DhApiResult<Pt> createFail(String message, Pt payload) { return new DhApiResult<>(false, message, payload); }
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.List;
|
||||
* Contains a list of {@link DhApiTerrainDataPoint} representing the blocks in a Minecraft chunk.
|
||||
*
|
||||
* @author Builderb0y, James Seibel
|
||||
* @version 2023-12-21
|
||||
* @version 2024-7-21
|
||||
* @since API 2.0.0
|
||||
*
|
||||
* @see IDhApiWrapperFactory
|
||||
@@ -41,8 +41,8 @@ public class DhApiChunk
|
||||
public final int chunkPosX;
|
||||
public final int chunkPosZ;
|
||||
|
||||
public final int topYBlockPos;
|
||||
public final int bottomYBlockPos;
|
||||
public final int topYBlockPos;
|
||||
|
||||
private final List<List<DhApiTerrainDataPoint>> dataPoints;
|
||||
|
||||
@@ -52,12 +52,12 @@ public class DhApiChunk
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public DhApiChunk(int chunkPosX, int chunkPosZ, int topYBlockPos, int bottomYBlockPos)
|
||||
public DhApiChunk(int chunkPosX, int chunkPosZ, int bottomYBlockPos, int topYBlockPos)
|
||||
{
|
||||
this.chunkPosX = chunkPosX;
|
||||
this.chunkPosZ = chunkPosZ;
|
||||
this.topYBlockPos = topYBlockPos;
|
||||
this.bottomYBlockPos = bottomYBlockPos;
|
||||
this.topYBlockPos = topYBlockPos;
|
||||
|
||||
// populate the array to prevent null pointers
|
||||
this.dataPoints = new ArrayList<>(16 * 16); // 256
|
||||
|
||||
+4
-4
@@ -26,7 +26,7 @@ import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
|
||||
* Holds a single datapoint of terrain data.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2022-11-13
|
||||
* @version 2024-7-20
|
||||
* @since API 1.0.0
|
||||
*/
|
||||
public class DhApiTerrainDataPoint
|
||||
@@ -42,22 +42,22 @@ public class DhApiTerrainDataPoint
|
||||
|
||||
public final int blockLightLevel;
|
||||
public final int skyLightLevel;
|
||||
public final int topYBlockPos;
|
||||
public final int bottomYBlockPos;
|
||||
public final int topYBlockPos;
|
||||
|
||||
public final IDhApiBlockStateWrapper blockStateWrapper;
|
||||
public final IDhApiBiomeWrapper biomeWrapper;
|
||||
|
||||
|
||||
|
||||
public DhApiTerrainDataPoint(byte detailLevel, int blockLightLevel, int skyLightLevel, int topYBlockPos, int bottomYBlockPos, IDhApiBlockStateWrapper blockStateWrapper, IDhApiBiomeWrapper biomeWrapper)
|
||||
public DhApiTerrainDataPoint(byte detailLevel, int blockLightLevel, int skyLightLevel, int bottomYBlockPos, int topYBlockPos, IDhApiBlockStateWrapper blockStateWrapper, IDhApiBiomeWrapper biomeWrapper)
|
||||
{
|
||||
this.detailLevel = detailLevel;
|
||||
|
||||
this.blockLightLevel = blockLightLevel;
|
||||
this.skyLightLevel = skyLightLevel;
|
||||
this.topYBlockPos = topYBlockPos;
|
||||
this.bottomYBlockPos = bottomYBlockPos;
|
||||
this.topYBlockPos = topYBlockPos;
|
||||
|
||||
this.blockStateWrapper = blockStateWrapper;
|
||||
this.biomeWrapper = biomeWrapper;
|
||||
|
||||
+1
-2
@@ -163,9 +163,8 @@ public class ApiEventInjector extends DependencyInjector<IDhApiEvent> implements
|
||||
DhApiEventParam<T> eventParam = createEventParamWrapper(event, input);
|
||||
event.fireEvent(eventParam);
|
||||
|
||||
if (eventParam instanceof DhApiCancelableEventParam)
|
||||
if (eventParam instanceof DhApiCancelableEventParam<T> cancelableEventParam)
|
||||
{
|
||||
DhApiCancelableEventParam<T> cancelableEventParam = (DhApiCancelableEventParam<T>) eventParam;
|
||||
cancelEvent |= cancelableEventParam.isEventCanceled();
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -87,7 +87,7 @@ public class DependencyInjector<BindableType extends IBindable> implements IDepe
|
||||
// make sure the hashSet has an array to hold the dependency
|
||||
if (!this.dependencies.containsKey(dependencyInterface))
|
||||
{
|
||||
this.dependencies.put(dependencyInterface, new ArrayList<BindableType>());
|
||||
this.dependencies.put(dependencyInterface, new ArrayList<>());
|
||||
}
|
||||
|
||||
// add the dependency
|
||||
@@ -134,7 +134,7 @@ public class DependencyInjector<BindableType extends IBindable> implements IDepe
|
||||
@Override
|
||||
public <T extends BindableType> T get(Class<T> interfaceClass) throws ClassCastException
|
||||
{
|
||||
return (T) this.getInternalLogic(interfaceClass, false).get(0);
|
||||
return (T) this.getInternalLogic(interfaceClass, false).getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,7 +146,7 @@ public class DependencyInjector<BindableType extends IBindable> implements IDepe
|
||||
@Override
|
||||
public <T extends BindableType> T get(Class<T> interfaceClass, boolean allowIncompleteDependencies) throws ClassCastException
|
||||
{
|
||||
return (T) this.getInternalLogic(interfaceClass, allowIncompleteDependencies).get(0);
|
||||
return (T) this.getInternalLogic(interfaceClass, allowIncompleteDependencies).getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,7 +175,7 @@ public class DependencyInjector<BindableType extends IBindable> implements IDepe
|
||||
|
||||
|
||||
// return an empty list to prevent null pointers
|
||||
ArrayList<T> emptyList = new ArrayList<T>();
|
||||
ArrayList<T> emptyList = new ArrayList<>();
|
||||
emptyList.add(null);
|
||||
return emptyList;
|
||||
}
|
||||
|
||||
+2
-2
@@ -64,14 +64,14 @@ public class OverridePriorityListContainer implements IBindable
|
||||
else
|
||||
{
|
||||
// last item should have the highest priority
|
||||
return this.overridePairList.get(this.overridePairList.size() - 1).override;
|
||||
return this.overridePairList.getLast().override;
|
||||
}
|
||||
}
|
||||
public IDhApiOverrideable getOverrideWithHighestPriority()
|
||||
{
|
||||
if (this.overridePairList.size() != 0)
|
||||
{
|
||||
return this.overridePairList.get(0).override;
|
||||
return this.overridePairList.getFirst().override;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+2
-1
@@ -67,10 +67,11 @@ public interface IConfigEntry<T>
|
||||
* Checks if the option is valid
|
||||
*
|
||||
* 0 == valid
|
||||
* 2 == invalid
|
||||
* 1 == number too high
|
||||
* -1 == number too low
|
||||
*/
|
||||
byte isValid();
|
||||
byte isValid(); // TODO replace with an enum
|
||||
/** Checks if a value is valid */
|
||||
byte isValid(T value);
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.coreapi.util;
|
||||
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.StringCharacterIterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@@ -86,25 +85,4 @@ public class StringUtil
|
||||
return new String(hexChars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Source:
|
||||
* https://stackoverflow.com/questions/3758606/how-can-i-convert-byte-size-into-a-human-readable-format-in-java#3758880
|
||||
*/
|
||||
public static String convertByteCountToHumanReadableSI(long bytes)
|
||||
{
|
||||
if (-1000 < bytes && bytes < 1000)
|
||||
{
|
||||
return bytes + " B";
|
||||
}
|
||||
|
||||
CharacterIterator ci = new StringCharacterIterator("kMGTPE");
|
||||
while (bytes <= -999_950 || bytes >= 999_950)
|
||||
{
|
||||
bytes /= 1000;
|
||||
ci.next();
|
||||
}
|
||||
|
||||
return String.format("%.1f %cB", bytes / 1000.0, ci.current());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-12
@@ -10,7 +10,7 @@ application {
|
||||
}
|
||||
|
||||
configurations {
|
||||
shadowedArtifact // Used by DH to specify that we want to implement the shadowed core JAR file instead of the regular JAR file
|
||||
downgradedArtifact // Used by DH to specify that we want to implement the shadowed core JAR file instead of the regular JAR file
|
||||
shade
|
||||
implementation.extendsFrom shade
|
||||
}
|
||||
@@ -39,9 +39,7 @@ dependencies { // All of these dependencies are in Vanilla Minecraft, but we nee
|
||||
runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
|
||||
runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
|
||||
runtimeOnly "org.lwjgl:lwjgl-tinyfd::$lwjglNatives"
|
||||
|
||||
// FIXME for some reason this line doesn't actually shade in the library
|
||||
// shade "it.unimi.dsi:fastutil:${rootProject.fastutil_version}" // Add our own fastutil version
|
||||
implementation "org.joml:joml:${rootProject.joml_version}"
|
||||
|
||||
|
||||
// Some other dependencies
|
||||
@@ -49,15 +47,8 @@ dependencies { // All of these dependencies are in Vanilla Minecraft, but we nee
|
||||
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
||||
implementation("com.google.common:google-collect:0.5")
|
||||
implementation("com.google.guava:guava:31.1-jre")
|
||||
|
||||
}
|
||||
|
||||
artifacts {
|
||||
shadowedArtifact shadowJar // Setup the configuration shadowedArtifact to be the shadowJar
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
def librariesLocation = "DistantHorizons.libraries"
|
||||
// relocate "it.unimi.dsi.fastutil", "${librariesLocation}.unimi.dsi.fastutil"
|
||||
mergeServiceFiles()
|
||||
downgradedArtifact shadeDowngradedApi // Setup the configuration downgradedArtifact to be the `shadeDowngradedApi` which downgrades the core to a specified Java version
|
||||
}
|
||||
+7
-7
@@ -35,30 +35,30 @@ public class DhApiAmbientOcclusionConfig implements IDhApiAmbientOcclusionConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> enabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.Ssao.enabled); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Ssao.enabled); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> sampleCount()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.Ssao.sampleCount); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Ssao.sampleCount); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> radius()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Ssao.radius); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Ssao.radius); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> strength()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Ssao.strength); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Ssao.strength); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> bias()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Ssao.bias); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Ssao.bias); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> minLight()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Ssao.minLight); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Ssao.minLight); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> blurRadius()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.Ssao.blurRadius); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Ssao.blurRadius); }
|
||||
|
||||
}
|
||||
|
||||
+5
-5
@@ -34,18 +34,18 @@ public class DhApiDebuggingConfig implements IDhApiDebuggingConfig
|
||||
|
||||
|
||||
public IDhApiConfigValue<EDhApiDebugRendering> debugRendering()
|
||||
{ return new DhApiConfigValue<EDhApiDebugRendering, EDhApiDebugRendering>(Config.Client.Advanced.Debugging.debugRendering); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Debugging.debugRendering); }
|
||||
|
||||
public IDhApiConfigValue<Boolean> debugKeybindings()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Debugging.enableDebugKeybindings); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Debugging.enableDebugKeybindings); }
|
||||
|
||||
public IDhApiConfigValue<Boolean> renderWireframe()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Debugging.renderWireframe); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Debugging.renderWireframe); }
|
||||
|
||||
public IDhApiConfigValue<Boolean> lodOnlyMode()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Debugging.lodOnlyMode); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Debugging.lodOnlyMode); }
|
||||
|
||||
public IDhApiConfigValue<Boolean> debugWireframeRendering()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Debugging.DebugWireframe.enableRendering); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Debugging.DebugWireframe.enableRendering); }
|
||||
|
||||
}
|
||||
|
||||
+6
-6
@@ -35,26 +35,26 @@ public class DhApiFarFogConfig implements IDhApiFarFogConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> farFogStartDistance()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogStart); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogStart); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> farFogEndDistance()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogEnd); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogEnd); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> farFogMinThickness()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogMin); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogMin); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> farFogMaxThickness()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogMax); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogMax); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiFogFalloff> farFogFalloff()
|
||||
{ return new DhApiConfigValue<EDhApiFogFalloff, EDhApiFogFalloff>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogFalloff); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogFalloff); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> farFogDensity()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogDensity); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.farFogDensity); }
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -35,12 +35,12 @@ public class DhApiGenericRenderingConfig implements IDhApiGenericRenderingConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> renderingEnabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.GenericRendering.enableRendering); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.GenericRendering.enableRendering); }
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> beaconRenderingEnabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.GenericRendering.enableBeaconRendering); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.GenericRendering.enableBeaconRendering); }
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> cloudRenderingEnabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.GenericRendering.enableCloudRendering); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.GenericRendering.enableCloudRendering); }
|
||||
|
||||
}
|
||||
|
||||
+3
@@ -36,4 +36,7 @@ public class DhApiGpuBuffersConfig implements IDhApiGpuBuffersConfig
|
||||
public IDhApiConfigValue<EDhApiGpuUploadMethod> gpuUploadMethod()
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.GpuBuffers.gpuUploadMethod); }
|
||||
|
||||
public IDhApiConfigValue<Integer> gpuUploadPerMegabyteInMilliseconds()
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.GpuBuffers.gpuUploadPerMegabyteInMilliseconds); }
|
||||
|
||||
}
|
||||
|
||||
+20
-20
@@ -56,15 +56,15 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> chunkRenderDistance()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> renderingEnabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.quickEnableRendering); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.quickEnableRendering); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiRendererMode> renderingMode()
|
||||
{ return new DhApiConfigValue<EDhApiRendererMode, EDhApiRendererMode>(Config.Client.Advanced.Debugging.rendererMode); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Debugging.rendererMode); }
|
||||
|
||||
|
||||
|
||||
@@ -74,27 +74,27 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiMaxHorizontalResolution> maxHorizontalResolution()
|
||||
{ return new DhApiConfigValue<EDhApiMaxHorizontalResolution, EDhApiMaxHorizontalResolution>(Config.Client.Advanced.Graphics.Quality.maxHorizontalResolution); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Quality.maxHorizontalResolution); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiVerticalQuality> verticalQuality()
|
||||
{ return new DhApiConfigValue<EDhApiVerticalQuality, EDhApiVerticalQuality>(Config.Client.Advanced.Graphics.Quality.verticalQuality); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Quality.verticalQuality); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiHorizontalQuality> horizontalQuality()
|
||||
{ return new DhApiConfigValue<EDhApiHorizontalQuality, EDhApiHorizontalQuality>(Config.Client.Advanced.Graphics.Quality.horizontalQuality); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Quality.horizontalQuality); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiTransparency> transparency()
|
||||
{ return new DhApiConfigValue<EDhApiTransparency, EDhApiTransparency>(Config.Client.Advanced.Graphics.Quality.transparency); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Quality.transparency); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiBlocksToAvoid> blocksToAvoid()
|
||||
{ return new DhApiConfigValue<EDhApiBlocksToAvoid, EDhApiBlocksToAvoid>(Config.Client.Advanced.Graphics.Quality.blocksToIgnore); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Quality.blocksToIgnore); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> tintWithAvoidedBlocks()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.Quality.tintWithAvoidedBlocks); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Quality.tintWithAvoidedBlocks); }
|
||||
|
||||
// TODO re-implement
|
||||
// @Override
|
||||
@@ -109,47 +109,47 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> overdrawPreventionRadius()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.AdvancedGraphics.overdrawPrevention); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.overdrawPrevention); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> brightnessMultiplier()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.AdvancedGraphics.brightnessMultiplier); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.brightnessMultiplier); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> saturationMultiplier()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.AdvancedGraphics.saturationMultiplier); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.saturationMultiplier); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> caveCullingEnabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.AdvancedGraphics.enableCaveCulling); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.enableCaveCulling); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> caveCullingHeight()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.AdvancedGraphics.caveCullingHeight); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.caveCullingHeight); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> earthCurvatureRatio()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.AdvancedGraphics.earthCurveRatio); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.earthCurveRatio); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> lodOnlyMode()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Debugging.lodOnlyMode); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Debugging.lodOnlyMode); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> lodBias()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.AdvancedGraphics.lodBias); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.lodBias); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiLodShading> lodShading()
|
||||
{ return new DhApiConfigValue<EDhApiLodShading, EDhApiLodShading>(Config.Client.Advanced.Graphics.AdvancedGraphics.lodShading); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.lodShading); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> disableFrustumCulling()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.AdvancedGraphics.disableFrustumCulling); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.disableFrustumCulling); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> disableShadowFrustumCulling()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.AdvancedGraphics.disableShadowPassFrustumCulling); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.AdvancedGraphics.disableShadowPassFrustumCulling); }
|
||||
|
||||
|
||||
|
||||
|
||||
+9
-9
@@ -37,38 +37,38 @@ public class DhApiHeightFogConfig implements IDhApiHeightFogConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiHeightFogMixMode> heightFogMixMode()
|
||||
{ return new DhApiConfigValue<EDhApiHeightFogMixMode, EDhApiHeightFogMixMode>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogMixMode); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogMixMode); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiHeightFogMode> heightFogMode()
|
||||
{ return new DhApiConfigValue<EDhApiHeightFogMode, EDhApiHeightFogMode>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogMode); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogMode); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> heightFogBaseHeight()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogBaseHeight); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogBaseHeight); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> heightFogStartingHeightPercent()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogStart); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogStart); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> heightFogEndingHeightPercent()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogEnd); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogEnd); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> heightFogMinThickness()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogMin); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogMin); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> heightFogMaxThickness()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogMax); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogMax); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<EDhApiFogFalloff> heightFogFalloff()
|
||||
{ return new DhApiConfigValue<EDhApiFogFalloff, EDhApiFogFalloff>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogFalloff); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogFalloff); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> heightFogDensity()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogDensity); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.Fog.AdvancedFog.HeightFog.heightFogDensity); }
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -34,14 +34,14 @@ public class DhApiMultiThreadingConfig implements IDhApiMultiThreadingConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> worldGeneratorThreads()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.MultiThreading.numberOfWorldGenerationThreads); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.MultiThreading.numberOfWorldGenerationThreads); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> fileHandlerThreads()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.MultiThreading.numberOfFileHandlerThreads); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.MultiThreading.numberOfFileHandlerThreads); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> lodBuilderThreads()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.MultiThreading.numberOfLodBuilderThreads); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.MultiThreading.numberOfLodBuilderThreads); }
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -34,9 +34,9 @@ public class DhApiMultiplayerConfig implements IDhApiMultiplayerConfig
|
||||
|
||||
|
||||
public IDhApiConfigValue<EDhApiServerFolderNameMode> folderSavingMode()
|
||||
{ return new DhApiConfigValue<EDhApiServerFolderNameMode, EDhApiServerFolderNameMode>(Config.Client.Advanced.Multiplayer.serverFolderNameMode); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Multiplayer.serverFolderNameMode); }
|
||||
|
||||
public IDhApiConfigValue<Double> multiverseSimilarityRequirement()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Multiplayer.multiverseSimilarityRequiredPercent); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Multiplayer.multiverseSimilarityRequiredPercent); }
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -34,18 +34,18 @@ public class DhApiNoiseTextureConfig implements IDhApiNoiseTextureConfig
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> noiseEnabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseEnabled); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseEnabled); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> noiseSteps()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseSteps); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseSteps); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Double> noiseIntensity()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseIntensity); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseIntensity); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Integer> noiseDropoff()
|
||||
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseDropoff); }
|
||||
{ return new DhApiConfigValue<>(Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseDropoff); }
|
||||
|
||||
}
|
||||
|
||||
+2
-4
@@ -187,22 +187,20 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
return DhApiResult.createFail("Unable to get terrain data before the world has loaded.");
|
||||
}
|
||||
|
||||
if (!(levelWrapper instanceof ILevelWrapper))
|
||||
if (!(levelWrapper instanceof ILevelWrapper coreLevelWrapper))
|
||||
{
|
||||
// custom level wrappers aren't supported,
|
||||
// the API user must get a level wrapper from our code somewhere
|
||||
return DhApiResult.createFail("Unsupported [" + IDhApiLevelWrapper.class.getSimpleName() + "] implementation, only the core class [" + IDhLevel.class.getSimpleName() + "] is a valid parameter.");
|
||||
}
|
||||
ILevelWrapper coreLevelWrapper = (ILevelWrapper) levelWrapper;
|
||||
|
||||
|
||||
if (!(apiDataCache instanceof DhApiTerrainDataCache))
|
||||
if (!(apiDataCache instanceof DhApiTerrainDataCache dataCache))
|
||||
{
|
||||
// custom level wrappers aren't supported,
|
||||
// the API user must get a level wrapper from our code somewhere
|
||||
return DhApiResult.createFail("Unsupported [" + IDhApiTerrainDataCache.class.getSimpleName() + "] implementation, only the core class [" + DhApiTerrainDataCache.class.getSimpleName() + "] is a valid parameter.");
|
||||
}
|
||||
DhApiTerrainDataCache dataCache = (DhApiTerrainDataCache) apiDataCache;
|
||||
|
||||
|
||||
IDhLevel level = currentWorld.getLevel(coreLevelWrapper);
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.seibel.distanthorizons.api.DhApi;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||
import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
||||
@@ -53,6 +54,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Queue;
|
||||
@@ -125,9 +127,28 @@ public class ClientApi
|
||||
public synchronized void onClientOnlyConnected()
|
||||
{
|
||||
// only continue if the client is connected to a different server
|
||||
if (MC.clientConnectedToDedicatedServer())
|
||||
boolean connectedToServer = MC.clientConnectedToDedicatedServer();
|
||||
boolean connectedToReplay = MC.connectedToReplay();
|
||||
if (connectedToServer || connectedToReplay)
|
||||
{
|
||||
if (connectedToServer)
|
||||
{
|
||||
LOGGER.info("Client on ClientOnly mode connecting.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.info("Replay on ClientServer mode connecting.");
|
||||
|
||||
if (Config.Client.Advanced.Logging.showReplayWarningOnStartup.get())
|
||||
{
|
||||
MC.sendChatMessage("\u00A76" + "Distant Horizons: Replay detected." + "\u00A7r"); // gold color
|
||||
MC.sendChatMessage("DH may behave strangely or have missing functionality.");
|
||||
MC.sendChatMessage("In order to use pre-generated LODs, put your DH database(s) in:");
|
||||
MC.sendChatMessage("\u00A77"+".Minecraft" + File.separator + ClientOnlySaveStructure.SERVER_DATA_FOLDER_NAME + File.separator + ClientOnlySaveStructure.REPLAY_SERVER_FOLDER_NAME + File.separator + "DIMENSION_NAME"+"\u00A7r"); // light gray color
|
||||
MC.sendChatMessage("This can be disabled in DH's config under Advanced -> Logging.");
|
||||
MC.sendChatMessage("");
|
||||
}
|
||||
}
|
||||
|
||||
// firing after clientLevelLoadEvent
|
||||
// TODO if level has prepped to load it should fire level load event
|
||||
|
||||
@@ -172,11 +172,10 @@ public class SharedApi
|
||||
AbstractDhWorld dhWorld = SharedApi.getAbstractDhWorld();
|
||||
if (dhWorld == null)
|
||||
{
|
||||
if (level instanceof IClientLevelWrapper)
|
||||
if (level instanceof IClientLevelWrapper clientLevel)
|
||||
{
|
||||
// If the client world isn't loaded yet, keep track of which chunks were loaded so we can use them later.
|
||||
// This may happen if the client world and client level load events happen out of order
|
||||
IClientLevelWrapper clientLevel = (IClientLevelWrapper) level;
|
||||
ClientApi.INSTANCE.waitingChunkByClientLevelAndPos.replace(new Pair<>(clientLevel, chunkWrapper.getChunkPos()), chunkWrapper);
|
||||
}
|
||||
|
||||
@@ -187,10 +186,9 @@ public class SharedApi
|
||||
IDhLevel dhLevel = dhWorld.getLevel(level);
|
||||
if (dhLevel == null)
|
||||
{
|
||||
if (level instanceof IClientLevelWrapper)
|
||||
if (level instanceof IClientLevelWrapper clientLevel)
|
||||
{
|
||||
// the client level isn't loaded yet
|
||||
IClientLevelWrapper clientLevel = (IClientLevelWrapper) level;
|
||||
ClientApi.INSTANCE.waitingChunkByClientLevelAndPos.replace(new Pair<>(clientLevel, chunkWrapper.getChunkPos()), chunkWrapper);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,17 +20,20 @@
|
||||
package com.seibel.distanthorizons.core.config;
|
||||
|
||||
|
||||
import com.seibel.distanthorizons.api.DhApi;
|
||||
import com.seibel.distanthorizons.api.enums.config.*;
|
||||
import com.seibel.distanthorizons.api.enums.config.quickOptions.*;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.*;
|
||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
|
||||
import com.seibel.distanthorizons.core.config.eventHandlers.*;
|
||||
import com.seibel.distanthorizons.core.config.eventHandlers.presets.*;
|
||||
import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener;
|
||||
import com.seibel.distanthorizons.core.config.types.*;
|
||||
import com.seibel.distanthorizons.core.config.types.enums.*;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.coreapi.util.StringUtil;
|
||||
@@ -610,8 +613,10 @@ public class Config
|
||||
+ " does not have a ceiling.")
|
||||
.build();
|
||||
|
||||
@Deprecated
|
||||
public static ConfigEntry<Integer> caveCullingHeight = new ConfigEntry.Builder<Integer>()
|
||||
.setMinDefaultMax(-4096, 40, 4096)
|
||||
.setAppearance(EConfigEntryAppearance.ONLY_IN_API)
|
||||
.comment(""
|
||||
+ "At what Y value should cave culling start?")
|
||||
.build();
|
||||
@@ -843,13 +848,47 @@ public class Config
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
//public static ConfigEntry<Boolean> showMigrationChatWarning = new ConfigEntry.Builder<Boolean>()
|
||||
// .set(true)
|
||||
// .comment(""
|
||||
// + "Determines if a message should be displayed in the chat when LOD migration starts. \n"
|
||||
// + "")
|
||||
// .build();
|
||||
public static ConfigEntry<String> ignoredRenderBlockCsv = new ConfigEntry.Builder<String>()
|
||||
.set("minecraft:barrier,minecraft:structure_void,minecraft:light,minecraft:tripwire")
|
||||
.comment(""
|
||||
+ "A comma separated list of block resource locations that won't be rendered by DH. \n"
|
||||
+ "Note: air is always included in this list. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<String> ignoredRenderCaveBlockCsv = new ConfigEntry.Builder<String>()
|
||||
.set("minecraft:glow_lichen,minecraft:rail,minecraft:water,minecraft:lava,minecraft:bubble_column")
|
||||
.comment(""
|
||||
+ "A comma separated list of block resource locations that shouldn't be rendered \n"
|
||||
+ "if they are in a 0 sky light underground area. \n"
|
||||
+ "Note: air is always included in this list. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
static
|
||||
{
|
||||
ignoredRenderBlockCsv.addListener(new ConfigChangeListener<>(Config.Client.Advanced.LodBuilding.ignoredRenderBlockCsv,
|
||||
(blockCsv) ->
|
||||
{
|
||||
IWrapperFactory wrapperFactory = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
|
||||
if (wrapperFactory != null)
|
||||
{
|
||||
wrapperFactory.resetRendererIgnoredBlocksSet();
|
||||
DhApi.Delayed.renderProxy.clearRenderDataCache();
|
||||
}
|
||||
}));
|
||||
|
||||
ignoredRenderCaveBlockCsv.addListener(new ConfigChangeListener<>(Config.Client.Advanced.LodBuilding.ignoredRenderCaveBlockCsv,
|
||||
(blockCsv) ->
|
||||
{
|
||||
IWrapperFactory wrapperFactory = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
|
||||
if (wrapperFactory != null)
|
||||
{
|
||||
wrapperFactory.resetRendererIgnoredCaveBlocks();
|
||||
DhApi.Delayed.renderProxy.clearRenderDataCache();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Multiplayer
|
||||
@@ -1054,6 +1093,20 @@ public class Config
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Integer> gpuUploadPerMegabyteInMilliseconds = new ConfigEntry.Builder<Integer>()
|
||||
.setMinDefaultMax(0, 0, 50)
|
||||
.comment(""
|
||||
+ "How long should a buffer wait per Megabyte of data uploaded? \n"
|
||||
+ "Helpful resource for frame times: https://fpstoms.com \n"
|
||||
+ "\n"
|
||||
+ "Longer times may reduce stuttering but will make LODs \n"
|
||||
+ "transition and load slower. Change this to [0] for no timeout. \n"
|
||||
+ "\n"
|
||||
+ "NOTE:\n"
|
||||
+ "Before changing this config, try changing the \"GPU Upload method\" first. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
public static class AutoUpdater
|
||||
@@ -1157,6 +1210,13 @@ public class Config
|
||||
+ "memory allocated to run DH well.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Boolean> showReplayWarningOnStartup = new ConfigEntry.Builder<Boolean>()
|
||||
.set(true)
|
||||
.comment(""
|
||||
+ "If enabled, a chat message will be displayed when a replay is started \n"
|
||||
+ "giving some basic information about how DH will function.")
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
public static class Debugging
|
||||
@@ -1437,15 +1497,14 @@ public class Config
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<List<String>> listTest = new ConfigEntry.Builder<List<String>>()
|
||||
.set(new ArrayList<String>(Arrays.asList("option 1", "option 2", "option 3")))
|
||||
.set(new ArrayList<>(Arrays.asList("option 1", "option 2", "option 3")))
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Map<String, String>> mapTest = new ConfigEntry.Builder<Map<String, String>>()
|
||||
.set(new HashMap<String, String>())
|
||||
.set(new HashMap<>())
|
||||
.build();
|
||||
|
||||
public static ConfigUIButton uiButtonTest = new ConfigUIButton(() ->
|
||||
{
|
||||
new Thread(() ->
|
||||
{
|
||||
if (!GraphicsEnvironment.isHeadless())
|
||||
@@ -1456,8 +1515,7 @@ public class Config
|
||||
{
|
||||
LOGGER.info("button pressed!");
|
||||
}
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
public static ConfigCategory categoryTest = new ConfigCategory.Builder().set(CategoryTest.class).build();
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ public class ConfigBase
|
||||
* <br> Map<String, T>
|
||||
* <br> HashMap<String, T>
|
||||
*/
|
||||
public static final List<Class<?>> acceptableInputs = new ArrayList<Class<?>>()
|
||||
public static final List<Class<?>> acceptableInputs = new ArrayList<>()
|
||||
{{
|
||||
add(Boolean.class);
|
||||
add(Byte.class);
|
||||
@@ -149,7 +149,7 @@ public class ConfigBase
|
||||
LOGGER.warn(exception);
|
||||
}
|
||||
|
||||
AbstractConfigType<?, ?> entry = entries.get(entries.size() - 1);
|
||||
AbstractConfigType<?, ?> entry = entries.getLast();
|
||||
entry.category = category;
|
||||
entry.name = field.getName();
|
||||
entry.configBase = this;
|
||||
@@ -160,7 +160,7 @@ public class ConfigBase
|
||||
{
|
||||
LOGGER.error("Invalid variable type at [" + (category.isEmpty() ? "" : category + ".") + field.getName() + "].");
|
||||
LOGGER.error("Type [" + entry.getType() + "] is not one of these types [" + acceptableInputs.toString() + "]");
|
||||
entries.remove(entries.size() - 1); // Delete the entry if it is invalid so the game can still run
|
||||
entries.removeLast(); // Delete the entry if it is invalid so the game can still run
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.Map;
|
||||
public class NumberUtil
|
||||
{
|
||||
// Is there no better way of doing this?
|
||||
public static Map<Class<?>, Number> minValues = new HashMap<Class<?>, Number>()
|
||||
public static Map<Class<?>, Number> minValues = new HashMap<>()
|
||||
{{
|
||||
put(Byte.class, Byte.MIN_VALUE);
|
||||
put(Short.class, Short.MIN_VALUE);
|
||||
@@ -41,7 +41,7 @@ public class NumberUtil
|
||||
put(Double.class, Double.MIN_VALUE);
|
||||
put(Float.class, Float.MIN_VALUE);
|
||||
}};
|
||||
public static Map<Class<?>, Number> maxValues = new HashMap<Class<?>, Number>()
|
||||
public static Map<Class<?>, Number> maxValues = new HashMap<>()
|
||||
{{
|
||||
put(Byte.class, Byte.MAX_VALUE);
|
||||
put(Short.class, Short.MAX_VALUE);
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@ public class QuickRenderToggleConfigEventHandler
|
||||
/** private since we only ever need one handler at a time */
|
||||
private QuickRenderToggleConfigEventHandler()
|
||||
{
|
||||
this.quickRenderChangeListener = new ConfigChangeListener<>(Config.Client.quickEnableRendering, (val) -> { Config.Client.Advanced.Debugging.rendererMode.set(Config.Client.quickEnableRendering.get() ? EDhApiRendererMode.DEFAULT : EDhApiRendererMode.DISABLED); });
|
||||
this.rendererModeChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Debugging.rendererMode, (val) -> { Config.Client.quickEnableRendering.set(Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED); });
|
||||
this.quickRenderChangeListener = new ConfigChangeListener<>(Config.Client.quickEnableRendering, (val) -> Config.Client.Advanced.Debugging.rendererMode.set(Config.Client.quickEnableRendering.get() ? EDhApiRendererMode.DEFAULT : EDhApiRendererMode.DISABLED));
|
||||
this.rendererModeChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Debugging.rendererMode, (val) -> Config.Client.quickEnableRendering.set(Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ public class ResetConfigEventHandler
|
||||
/** private since we only ever need one handler at a time */
|
||||
private ResetConfigEventHandler()
|
||||
{
|
||||
this.configChangeListener = new ConfigChangeListener<>(Config.Client.ResetConfirmation.resetAllSettings, (resetSettings) -> { doStuff(resetSettings); });
|
||||
this.configChangeListener = new ConfigChangeListener<>(Config.Client.ResetConfirmation.resetAllSettings, this::doStuff);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ public abstract class AbstractPresetConfigEventHandler<TPresetEnum extends Enum<
|
||||
|
||||
public AbstractPresetConfigEventHandler()
|
||||
{
|
||||
configGui.addOnScreenChangeListener(() -> this.onConfigUiClosed());
|
||||
configGui.addOnScreenChangeListener(this::onConfigUiClosed);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ public abstract class AbstractPresetConfigEventHandler<TPresetEnum extends Enum<
|
||||
possiblePrestList.add(this.getCustomPresetEnum());
|
||||
}
|
||||
|
||||
return possiblePrestList.get(0);
|
||||
return possiblePrestList.getFirst();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-6
@@ -41,7 +41,7 @@ public class RenderQualityPresetConfigEventHandler extends AbstractPresetConfigE
|
||||
|
||||
|
||||
private final ConfigEntryWithPresetOptions<EDhApiQualityPreset, EDhApiMaxHorizontalResolution> drawResolution = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.Graphics.Quality.maxHorizontalResolution,
|
||||
new HashMap<EDhApiQualityPreset, EDhApiMaxHorizontalResolution>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiQualityPreset.MINIMUM, EDhApiMaxHorizontalResolution.TWO_BLOCKS);
|
||||
this.put(EDhApiQualityPreset.LOW, EDhApiMaxHorizontalResolution.BLOCK);
|
||||
@@ -50,7 +50,7 @@ public class RenderQualityPresetConfigEventHandler extends AbstractPresetConfigE
|
||||
this.put(EDhApiQualityPreset.EXTREME, EDhApiMaxHorizontalResolution.BLOCK);
|
||||
}});
|
||||
private final ConfigEntryWithPresetOptions<EDhApiQualityPreset, EDhApiVerticalQuality> verticalQuality = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.Graphics.Quality.verticalQuality,
|
||||
new HashMap<EDhApiQualityPreset, EDhApiVerticalQuality>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiQualityPreset.MINIMUM, EDhApiVerticalQuality.HEIGHT_MAP);
|
||||
this.put(EDhApiQualityPreset.LOW, EDhApiVerticalQuality.LOW);
|
||||
@@ -59,7 +59,7 @@ public class RenderQualityPresetConfigEventHandler extends AbstractPresetConfigE
|
||||
this.put(EDhApiQualityPreset.EXTREME, EDhApiVerticalQuality.EXTREME);
|
||||
}});
|
||||
private final ConfigEntryWithPresetOptions<EDhApiQualityPreset, EDhApiHorizontalQuality> horizontalQuality = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.Graphics.Quality.horizontalQuality,
|
||||
new HashMap<EDhApiQualityPreset, EDhApiHorizontalQuality>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiQualityPreset.MINIMUM, EDhApiHorizontalQuality.LOWEST);
|
||||
this.put(EDhApiQualityPreset.LOW, EDhApiHorizontalQuality.LOW);
|
||||
@@ -68,7 +68,7 @@ public class RenderQualityPresetConfigEventHandler extends AbstractPresetConfigE
|
||||
this.put(EDhApiQualityPreset.EXTREME, EDhApiHorizontalQuality.EXTREME);
|
||||
}});
|
||||
private final ConfigEntryWithPresetOptions<EDhApiQualityPreset, EDhApiTransparency> transparency = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.Graphics.Quality.transparency,
|
||||
new HashMap<EDhApiQualityPreset, EDhApiTransparency>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiQualityPreset.MINIMUM, EDhApiTransparency.DISABLED);
|
||||
this.put(EDhApiQualityPreset.LOW, EDhApiTransparency.DISABLED); // should be fake if/when fake is fixed
|
||||
@@ -77,7 +77,7 @@ public class RenderQualityPresetConfigEventHandler extends AbstractPresetConfigE
|
||||
this.put(EDhApiQualityPreset.EXTREME, EDhApiTransparency.COMPLETE);
|
||||
}});
|
||||
private final ConfigEntryWithPresetOptions<EDhApiQualityPreset, Boolean> ssaoEnabled = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.Graphics.Ssao.enabled,
|
||||
new HashMap<EDhApiQualityPreset, Boolean>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiQualityPreset.MINIMUM, false);
|
||||
this.put(EDhApiQualityPreset.LOW, false);
|
||||
@@ -106,7 +106,7 @@ public class RenderQualityPresetConfigEventHandler extends AbstractPresetConfigE
|
||||
for (ConfigEntryWithPresetOptions<EDhApiQualityPreset, ?> config : this.configList)
|
||||
{
|
||||
// ignore try-using, the listener should only ever be added once and should never be removed
|
||||
new ConfigChangeListener<>(config.configEntry, (val) -> { this.onConfigValueChanged(); });
|
||||
new ConfigChangeListener<>(config.configEntry, (val) -> this.onConfigValueChanged());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-9
@@ -42,7 +42,7 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
|
||||
public static int getWorldGenDefaultThreadCount() { return getThreadCountByPercent(0.1); }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Integer> worldGenThreadCount = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.numberOfWorldGenerationThreads,
|
||||
new HashMap<EDhApiThreadPreset, Integer>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getWorldGenDefaultThreadCount());
|
||||
@@ -52,7 +52,7 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
}});
|
||||
public static double getWorldGenDefaultRunTimeRatio() { return 0.5; }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Double> worldGenRunTime = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.runTimeRatioForWorldGenerationThreads,
|
||||
new HashMap<EDhApiThreadPreset, Double>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getWorldGenDefaultRunTimeRatio());
|
||||
@@ -64,7 +64,7 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
|
||||
public static int getFileHandlerDefaultThreadCount() { return getThreadCountByPercent(0.1); }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Integer> fileHandlerThreadCount = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.numberOfFileHandlerThreads,
|
||||
new HashMap<EDhApiThreadPreset, Integer>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getFileHandlerDefaultThreadCount());
|
||||
@@ -74,7 +74,7 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
}});
|
||||
public static double getFileHandlerDefaultRunTimeRatio() { return 0.5; }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Double> fileHandlerRunTime = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.runTimeRatioForFileHandlerThreads,
|
||||
new HashMap<EDhApiThreadPreset, Double>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.25);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getFileHandlerDefaultRunTimeRatio());
|
||||
@@ -86,7 +86,7 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
|
||||
public static int getUpdatePropagatorDefaultThreadCount() { return getThreadCountByPercent(0.10); }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Integer> UpdatePropagatorThreadCount = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.numberOfUpdatePropagatorThreads,
|
||||
new HashMap<EDhApiThreadPreset, Integer>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getUpdatePropagatorDefaultThreadCount());
|
||||
@@ -96,7 +96,7 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
}});
|
||||
public static double getUpdatePropagatorDefaultRunTimeRatio() { return 0.25; }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Double> UpdatePropagatorRunTime = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.runTimeRatioForUpdatePropagatorThreads,
|
||||
new HashMap<EDhApiThreadPreset, Double>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getUpdatePropagatorDefaultRunTimeRatio());
|
||||
@@ -108,7 +108,7 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
|
||||
public static int getLodBuilderDefaultThreadCount() { return getThreadCountByPercent(0.1); }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Integer> lodBuilderThreadCount = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.numberOfLodBuilderThreads,
|
||||
new HashMap<EDhApiThreadPreset, Integer>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getLodBuilderDefaultThreadCount());
|
||||
@@ -118,7 +118,7 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
}});
|
||||
public static double getLodBuilderDefaultRunTimeRatio() { return 0.25; }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Double> lodBuilderRunTime = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.runTimeRatioForLodBuilderThreads,
|
||||
new HashMap<EDhApiThreadPreset, Double>()
|
||||
new HashMap<>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getLodBuilderDefaultRunTimeRatio());
|
||||
@@ -153,7 +153,7 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
for (ConfigEntryWithPresetOptions<EDhApiThreadPreset, ?> config : this.configList)
|
||||
{
|
||||
// ignore try-using, the listeners should only ever be added once and should never be removed
|
||||
new ConfigChangeListener<>(config.configEntry, (val) -> { this.onConfigValueChanged(); });
|
||||
new ConfigChangeListener<>(config.configEntry, (val) -> this.onConfigValueChanged());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import java.util.Map;
|
||||
public class ConfigTypeConverters
|
||||
{
|
||||
// Once you've made a converter add it to here where the first value is the type you want to convert and the 2nd value is the converter
|
||||
public static final Map<Class<?>, ConverterBase> convertObjects = new HashMap<Class<?>, ConverterBase>()
|
||||
public static final Map<Class<?>, ConverterBase> convertObjects = new HashMap<>()
|
||||
{{
|
||||
this.put(Short.class, new ShortConverter());
|
||||
this.put(Long.class, new LongConverter());
|
||||
|
||||
+14
-19
@@ -73,33 +73,28 @@ public final class EmbeddedFrameUtil
|
||||
|
||||
private static String getEmbeddedFrameImpl()
|
||||
{
|
||||
switch (EPlatform.get())
|
||||
return switch (EPlatform.get())
|
||||
{
|
||||
case LINUX:
|
||||
return "sun.awt.X11.XEmbeddedFrame";
|
||||
case WINDOWS:
|
||||
return "sun.awt.windows.WEmbeddedFrame";
|
||||
case MACOS:
|
||||
return "sun.lwawt.macosx.CViewEmbeddedFrame";
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
case LINUX -> "sun.awt.X11.XEmbeddedFrame";
|
||||
case WINDOWS -> "sun.awt.windows.WEmbeddedFrame";
|
||||
case MACOS -> "sun.lwawt.macosx.CViewEmbeddedFrame";
|
||||
default -> throw new IllegalStateException();
|
||||
};
|
||||
}
|
||||
|
||||
private static long getEmbeddedFrameHandle(long window)
|
||||
{
|
||||
switch (EPlatform.get())
|
||||
return switch (EPlatform.get())
|
||||
{
|
||||
case LINUX -> glfwGetX11Window(window);
|
||||
case WINDOWS -> glfwGetWin32Window(window);
|
||||
case MACOS ->
|
||||
{
|
||||
case LINUX:
|
||||
return glfwGetX11Window(window);
|
||||
case WINDOWS:
|
||||
return glfwGetWin32Window(window);
|
||||
case MACOS:
|
||||
long objc_msgSend = ObjCRuntime.getLibrary().getFunctionAddress("objc_msgSend");
|
||||
return invokePPP(glfwGetCocoaWindow(window), sel_getUid("contentView"), objc_msgSend);
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
yield invokePPP(glfwGetCocoaWindow(window), sel_getUid("contentView"), objc_msgSend);
|
||||
}
|
||||
default -> throw new IllegalStateException();
|
||||
};
|
||||
}
|
||||
|
||||
public static Frame embeddedFrameCreate(long window)
|
||||
|
||||
@@ -256,21 +256,39 @@ public class ConfigEntry<T> extends AbstractConfigType<T, ConfigEntry<T>> implem
|
||||
public byte isValid(T value, T min, T max)
|
||||
{
|
||||
if (this.configBase.disableMinMax)
|
||||
{
|
||||
return 0;
|
||||
|
||||
if (value == null || this.value == null || value.getClass() != this.value.getClass()) // If the 2 variables aren't the same type then it will be invalid
|
||||
}
|
||||
else if (min == null && max == null)
|
||||
{
|
||||
// no validation is needed for this field
|
||||
return 0;
|
||||
}
|
||||
else if (value == null || this.value == null
|
||||
|| value.getClass() != this.value.getClass())
|
||||
{
|
||||
// If the 2 variables aren't the same type then it will be invalid
|
||||
return 2;
|
||||
if (Number.class.isAssignableFrom(value.getClass()))
|
||||
{ // Only check min max if it is a number
|
||||
}
|
||||
else if (Number.class.isAssignableFrom(value.getClass()))
|
||||
{
|
||||
// Only check min max if it is a number
|
||||
if (max != null && NumberUtil.greaterThan((Number) value, (Number) max))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (min != null && NumberUtil.lessThan((Number) value, (Number) min))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** This should normally not be called since set() automatically calls this */
|
||||
public void save() { configBase.configFileINSTANCE.saveEntry(this); }
|
||||
|
||||
+1
-2
@@ -516,10 +516,9 @@ public class FullDataPointIdMap
|
||||
if (otherObj == this)
|
||||
return true;
|
||||
|
||||
if (!(otherObj instanceof Entry))
|
||||
if (!(otherObj instanceof Entry other))
|
||||
return false;
|
||||
|
||||
Entry other = (Entry) otherObj;
|
||||
return other.biome.getSerialString().equals(this.biome.getSerialString())
|
||||
&& other.blockState.getSerialString().equals(this.blockState.getSerialString());
|
||||
}
|
||||
|
||||
+3
-2
@@ -62,6 +62,8 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
|
||||
/** measured in data columns */
|
||||
public static final int WIDTH = 64;
|
||||
/** how many chunks wide this datasource is. */
|
||||
public static final int NUMB_OF_CHUNKS_WIDE = WIDTH / LodUtil.CHUNK_WIDTH;
|
||||
|
||||
public static final byte DATA_FORMAT_VERSION = 1;
|
||||
|
||||
@@ -925,11 +927,10 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (!(obj instanceof FullDataSourceV2))
|
||||
if (!(obj instanceof FullDataSourceV2 other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
FullDataSourceV2 other = (FullDataSourceV2) obj;
|
||||
|
||||
if (other.pos != this.pos)
|
||||
{
|
||||
|
||||
+1
-1
@@ -182,7 +182,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
EDhApiWorldGenerationStep worldGenStep = inputFullDataSource.getWorldGenStepAtRelativePos(x, z);
|
||||
if (dataColumn != null && worldGenStep != EDhApiWorldGenerationStep.EMPTY)
|
||||
{
|
||||
FullDataToRenderDataTransformer.convertColumnData(
|
||||
FullDataToRenderDataTransformer.updateRenderDataViewWithFullDataColumn(
|
||||
level, inputFullDataSource.mapping,
|
||||
minBlockPos.x + x,
|
||||
minBlockPos.z + z,
|
||||
|
||||
+12
-22
@@ -99,33 +99,23 @@ public final class BufferQuad
|
||||
|
||||
if (compareDirection == BufferMergeDirectionEnum.EastWest)
|
||||
{
|
||||
switch (this.direction.getAxis())
|
||||
return switch (this.direction.getAxis())
|
||||
{
|
||||
case X:
|
||||
return threeDimensionalCompare(this.x, this.y, this.z, quad.x, quad.y, quad.z);
|
||||
case Y:
|
||||
return threeDimensionalCompare(this.y, this.z, this.x, quad.y, quad.z, quad.x);
|
||||
case Z:
|
||||
return threeDimensionalCompare(this.z, this.y, this.x, quad.z, quad.y, quad.x);
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid Axis enum: " + this.direction.getAxis());
|
||||
}
|
||||
case X -> threeDimensionalCompare(this.x, this.y, this.z, quad.x, quad.y, quad.z);
|
||||
case Y -> threeDimensionalCompare(this.y, this.z, this.x, quad.y, quad.z, quad.x);
|
||||
case Z -> threeDimensionalCompare(this.z, this.y, this.x, quad.z, quad.y, quad.x);
|
||||
default -> throw new IllegalArgumentException("Invalid Axis enum: " + this.direction.getAxis());
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (this.direction.getAxis())
|
||||
return switch (this.direction.getAxis())
|
||||
{
|
||||
case X:
|
||||
return threeDimensionalCompare(this.x, this.z, this.y, quad.x, quad.z, quad.y);
|
||||
case Y:
|
||||
return threeDimensionalCompare(this.y, this.x, this.z, quad.y, quad.x, quad.z);
|
||||
case Z:
|
||||
return threeDimensionalCompare(this.z, this.x, this.y, quad.z, quad.x, quad.y);
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid Axis enum: " + this.direction.getAxis());
|
||||
}
|
||||
case X -> threeDimensionalCompare(this.x, this.z, this.y, quad.x, quad.z, quad.y);
|
||||
case Y -> threeDimensionalCompare(this.y, this.x, this.z, quad.y, quad.x, quad.z);
|
||||
case Z -> threeDimensionalCompare(this.z, this.x, this.y, quad.z, quad.x, quad.y);
|
||||
default -> throw new IllegalArgumentException("Invalid Axis enum: " + this.direction.getAxis());
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
||||
+204
-98
@@ -20,11 +20,15 @@
|
||||
package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.StatsMap;
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.core.util.*;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
@@ -49,18 +53,19 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
/** number of bytes a single quad takes */
|
||||
public static final int QUADS_BYTE_SIZE = LodUtil.LOD_VERTEX_FORMAT.getByteSize() * 4;
|
||||
/** how big a single VBO can be in bytes */
|
||||
public static final int MAX_VBO_BYTE_SIZE = 1024 * 1024; // 1 MB
|
||||
public static final int MAX_VBO_BYTE_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||
public static final int MAX_QUADS_PER_BUFFER = MAX_VBO_BYTE_SIZE / QUADS_BYTE_SIZE;
|
||||
public static final int FULL_SIZED_BUFFER = MAX_QUADS_PER_BUFFER * QUADS_BYTE_SIZE;
|
||||
|
||||
|
||||
|
||||
|
||||
public final DhBlockPos pos;
|
||||
|
||||
public boolean buffersUploaded = false;
|
||||
|
||||
public SharedVbo.BufferSlice[] opaqueBufferSlices;
|
||||
public SharedVbo.BufferSlice[] transparentBufferSlices;
|
||||
private GLVertexBuffer[] vbos;
|
||||
private GLVertexBuffer[] vbosTransparent;
|
||||
|
||||
|
||||
|
||||
@@ -71,12 +76,14 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
public ColumnRenderBuffer(DhBlockPos pos)
|
||||
{
|
||||
this.pos = pos;
|
||||
this.opaqueBufferSlices = new SharedVbo.BufferSlice[0];
|
||||
this.transparentBufferSlices = new SharedVbo.BufferSlice[0];
|
||||
this.vbos = new GLVertexBuffer[0];
|
||||
this.vbosTransparent = new GLVertexBuffer[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// buffer uploading //
|
||||
//==================//
|
||||
@@ -121,132 +128,193 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
}
|
||||
private void uploadBuffersUsingUploadMethod(LodQuadBuilder builder, EDhApiGpuUploadMethod gpuUploadMethod) throws InterruptedException
|
||||
{
|
||||
//if (gpuUploadMethod.useEarlyMapping)
|
||||
//{
|
||||
// this.uploadBuffersMapped(builder, gpuUploadMethod);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
this.uploadBuffersDirect(builder);
|
||||
//}
|
||||
if (gpuUploadMethod.useEarlyMapping)
|
||||
{
|
||||
this.uploadBuffersMapped(builder, gpuUploadMethod);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.uploadBuffersDirect(builder, gpuUploadMethod);
|
||||
}
|
||||
|
||||
this.buffersUploaded = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//private void uploadBuffersMapped(LodQuadBuilder builder, EDhApiGpuUploadMethod method)
|
||||
//{
|
||||
// // opaque vbos //
|
||||
//
|
||||
// this.vbos = ColumnRenderBufferBuilder.resizeBuffer(this.vbos, builder.getCurrentNeededOpaqueVertexBufferCount());
|
||||
// for (int i = 0; i < this.vbos.length; i++)
|
||||
// {
|
||||
// if (this.vbos[i] == null)
|
||||
// {
|
||||
// this.vbos[i] = new GLVertexBuffer(method.useBufferStorage);
|
||||
// }
|
||||
// }
|
||||
// LodQuadBuilder.BufferFiller func = builder.makeOpaqueBufferFiller(method);
|
||||
// for (GLVertexBuffer vbo : this.vbos)
|
||||
// {
|
||||
// func.fill(vbo);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // transparent vbos //
|
||||
//
|
||||
// this.vbosTransparent = ColumnRenderBufferBuilder.resizeBuffer(this.vbosTransparent, builder.getCurrentNeededTransparentVertexBufferCount());
|
||||
// for (int i = 0; i < this.vbosTransparent.length; i++)
|
||||
// {
|
||||
// if (this.vbosTransparent[i] == null)
|
||||
// {
|
||||
// this.vbosTransparent[i] = new GLVertexBuffer(method.useBufferStorage);
|
||||
// }
|
||||
// }
|
||||
// LodQuadBuilder.BufferFiller transparentFillerFunc = builder.makeTransparentBufferFiller(method);
|
||||
// for (GLVertexBuffer vbo : this.vbosTransparent)
|
||||
// {
|
||||
// transparentFillerFunc.fill(vbo);
|
||||
// }
|
||||
//}
|
||||
private void uploadBuffersMapped(LodQuadBuilder builder, EDhApiGpuUploadMethod method)
|
||||
{
|
||||
// opaque vbos //
|
||||
|
||||
private void uploadBuffersDirect(LodQuadBuilder builder)
|
||||
this.vbos = ColumnRenderBufferBuilder.resizeBuffer(this.vbos, builder.getCurrentNeededOpaqueVertexBufferCount());
|
||||
for (int i = 0; i < this.vbos.length; i++)
|
||||
{
|
||||
int opaqueSliceCount = builder.getCurrentNeededOpaqueVertexBufferCount();
|
||||
if (this.opaqueBufferSlices.length != opaqueSliceCount)
|
||||
if (this.vbos[i] == null)
|
||||
{
|
||||
SharedVbo.OPAQUE.deallocate(this.opaqueBufferSlices);
|
||||
this.opaqueBufferSlices = new SharedVbo.BufferSlice[opaqueSliceCount];
|
||||
this.vbos[i] = new GLVertexBuffer(method.useBufferStorage);
|
||||
}
|
||||
uploadBuffersDirect(SharedVbo.OPAQUE, this.opaqueBufferSlices, builder.makeOpaqueVertexBuffers());
|
||||
|
||||
|
||||
int transparentSliceCount = builder.getCurrentNeededTransparentVertexBufferCount();
|
||||
if (this.transparentBufferSlices.length != transparentSliceCount)
|
||||
{
|
||||
SharedVbo.TRANSPARENT.deallocate(this.transparentBufferSlices);
|
||||
this.transparentBufferSlices = new SharedVbo.BufferSlice[transparentSliceCount];
|
||||
}
|
||||
uploadBuffersDirect(SharedVbo.TRANSPARENT, this.transparentBufferSlices, builder.makeTransparentVertexBuffers());
|
||||
LodQuadBuilder.BufferFiller func = builder.makeOpaqueBufferFiller(method);
|
||||
for (GLVertexBuffer vbo : this.vbos)
|
||||
{
|
||||
func.fill(vbo);
|
||||
}
|
||||
|
||||
private static void uploadBuffersDirect(SharedVbo handler, SharedVbo.BufferSlice[] bufferSlices, Iterator<ByteBuffer> iter)
|
||||
|
||||
// transparent vbos //
|
||||
|
||||
this.vbosTransparent = ColumnRenderBufferBuilder.resizeBuffer(this.vbosTransparent, builder.getCurrentNeededTransparentVertexBufferCount());
|
||||
for (int i = 0; i < this.vbosTransparent.length; i++)
|
||||
{
|
||||
int i = 0;
|
||||
if (this.vbosTransparent[i] == null)
|
||||
{
|
||||
this.vbosTransparent[i] = new GLVertexBuffer(method.useBufferStorage);
|
||||
}
|
||||
}
|
||||
LodQuadBuilder.BufferFiller transparentFillerFunc = builder.makeTransparentBufferFiller(method);
|
||||
for (GLVertexBuffer vbo : this.vbosTransparent)
|
||||
{
|
||||
transparentFillerFunc.fill(vbo);
|
||||
}
|
||||
}
|
||||
|
||||
private void uploadBuffersDirect(LodQuadBuilder builder, EDhApiGpuUploadMethod method) throws InterruptedException
|
||||
{
|
||||
this.vbos = ColumnRenderBufferBuilder.resizeBuffer(this.vbos, builder.getCurrentNeededOpaqueVertexBufferCount());
|
||||
uploadBuffersDirect(this.vbos, builder.makeOpaqueVertexBuffers(), method);
|
||||
|
||||
this.vbosTransparent = ColumnRenderBufferBuilder.resizeBuffer(this.vbosTransparent, builder.getCurrentNeededTransparentVertexBufferCount());
|
||||
uploadBuffersDirect(this.vbosTransparent, builder.makeTransparentVertexBuffers(), method);
|
||||
}
|
||||
private static void uploadBuffersDirect(GLVertexBuffer[] vbos, Iterator<ByteBuffer> iter, EDhApiGpuUploadMethod method) throws InterruptedException
|
||||
{
|
||||
long remainingMS = 0;
|
||||
long MBPerMS = Config.Client.Advanced.GpuBuffers.gpuUploadPerMegabyteInMilliseconds.get();
|
||||
int vboIndex = 0;
|
||||
while (iter.hasNext())
|
||||
{
|
||||
if (i >= bufferSlices.length)
|
||||
if (vboIndex >= vbos.length)
|
||||
{
|
||||
throw new RuntimeException("Too many vertex buffers!!");
|
||||
}
|
||||
|
||||
// get or create the buffer
|
||||
if (bufferSlices[i] == null)
|
||||
|
||||
// get or create the VBO
|
||||
if (vbos[vboIndex] == null)
|
||||
{
|
||||
bufferSlices[i] = handler.allocateSlice();
|
||||
vbos[vboIndex] = new GLVertexBuffer(method.useBufferStorage);
|
||||
}
|
||||
SharedVbo.BufferSlice slice = bufferSlices[i];
|
||||
GLVertexBuffer vbo = vbos[vboIndex];
|
||||
|
||||
|
||||
ByteBuffer buffer = iter.next();
|
||||
ByteBuffer bb = iter.next();
|
||||
int size = bb.limit() - bb.position();
|
||||
|
||||
try
|
||||
{
|
||||
handler.updateBuffer(slice, buffer);
|
||||
vbo.bind();
|
||||
vbo.uploadBuffer(bb, size / LodUtil.LOD_VERTEX_FORMAT.getByteSize(), method, FULL_SIZED_BUFFER);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
bufferSlices[i] = null;
|
||||
handler.deallocate(slice);
|
||||
LOGGER.error("Failed to upload buffer. Error: ["+e.getMessage()+"].", e);
|
||||
vbos[vboIndex] = null;
|
||||
vbo.close();
|
||||
LOGGER.error("Failed to upload buffer: ", e);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < bufferSlices.length)
|
||||
if (MBPerMS > 0)
|
||||
{
|
||||
throw new RuntimeException("Too few buffer chunks!");
|
||||
// upload buffers over an extended period of time
|
||||
// to hopefully prevent stuttering.
|
||||
remainingMS += size * MBPerMS;
|
||||
if (remainingMS >= TimeUnit.NANOSECONDS.convert(1000 / 60, TimeUnit.MILLISECONDS))
|
||||
{
|
||||
if (remainingMS > MAX_BUFFER_UPLOAD_TIMEOUT_NANOSECONDS)
|
||||
{
|
||||
remainingMS = MAX_BUFFER_UPLOAD_TIMEOUT_NANOSECONDS;
|
||||
}
|
||||
|
||||
Thread.sleep(remainingMS / 1000000, (int) (remainingMS % 1000000));
|
||||
remainingMS = 0;
|
||||
}
|
||||
}
|
||||
|
||||
vboIndex++;
|
||||
}
|
||||
|
||||
if (vboIndex < vbos.length)
|
||||
{
|
||||
throw new RuntimeException("Too few vertex buffers!!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
|
||||
//public void renderOpaque(LodRenderer renderContext, DhApiRenderParam renderEventParam)
|
||||
//{
|
||||
// renderContext.setModelViewMatrixOffset(this.pos, renderEventParam);
|
||||
// renderContext.drawSharedVbo(SharedVbo.OPAQUE, this.opaqueBufferSlices);
|
||||
//}
|
||||
//
|
||||
//public void renderTransparent(LodRenderer renderContext, DhApiRenderParam renderEventParam)
|
||||
//{
|
||||
// renderContext.setModelViewMatrixOffset(this.pos, renderEventParam);
|
||||
// renderContext.drawSharedVbo(SharedVbo.TRANSPARENT, this.transparentBufferSlices);
|
||||
//}
|
||||
/** @return true if something was rendered, false otherwise */
|
||||
public boolean renderOpaque(LodRenderer renderContext, DhApiRenderParam renderEventParam)
|
||||
{
|
||||
boolean hasRendered = false;
|
||||
renderContext.setModelViewMatrixOffset(this.pos, renderEventParam);
|
||||
for (GLVertexBuffer vbo : this.vbos)
|
||||
{
|
||||
if (vbo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vbo.getVertexCount() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hasRendered = true;
|
||||
renderContext.drawVbo(vbo);
|
||||
//LodRenderer.tickLogger.info("Vertex buffer: {}", vbo);
|
||||
}
|
||||
return hasRendered;
|
||||
}
|
||||
|
||||
/** @return true if something was rendered, false otherwise */
|
||||
public boolean renderTransparent(LodRenderer renderContext, DhApiRenderParam renderEventParam)
|
||||
{
|
||||
boolean hasRendered = false;
|
||||
|
||||
try
|
||||
{
|
||||
// can throw an IllegalStateException if the GL program was freed before it should've been
|
||||
renderContext.setModelViewMatrixOffset(this.pos, renderEventParam);
|
||||
|
||||
for (GLVertexBuffer vbo : this.vbosTransparent)
|
||||
{
|
||||
if (vbo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vbo.getVertexCount() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hasRendered = true;
|
||||
renderContext.drawVbo(vbo);
|
||||
//LodRenderer.tickLogger.info("Vertex buffer: {}", vbo);
|
||||
}
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
{
|
||||
LOGGER.error("renderContext program doesn't exist for pos: "+this.pos, e);
|
||||
}
|
||||
|
||||
return hasRendered;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -254,28 +322,50 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
// misc methods //
|
||||
//==============//
|
||||
|
||||
// TODO
|
||||
/** can be used when debugging */
|
||||
public boolean hasNonNullVbos() { return false; } //this.vbos != null || this.vbosTransparent != null; }
|
||||
public boolean hasNonNullVbos() { return this.vbos != null || this.vbosTransparent != null; }
|
||||
|
||||
/** can be used when debugging */
|
||||
public int bufferSliceCount()
|
||||
public int vboBufferCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (this.opaqueBufferSlices != null)
|
||||
if (this.vbos != null)
|
||||
{
|
||||
count += this.opaqueBufferSlices.length;
|
||||
count += this.vbos.length;
|
||||
}
|
||||
|
||||
if (this.transparentBufferSlices != null)
|
||||
if (this.vbosTransparent != null)
|
||||
{
|
||||
count += this.transparentBufferSlices.length;
|
||||
count += this.vbosTransparent.length;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public void debugDumpStats(StatsMap statsMap)
|
||||
{
|
||||
statsMap.incStat("RenderBuffers");
|
||||
statsMap.incStat("SimpleRenderBuffers");
|
||||
for (GLVertexBuffer vertexBuffer : vbos)
|
||||
{
|
||||
if (vertexBuffer != null)
|
||||
{
|
||||
statsMap.incStat("VBOs");
|
||||
if (vertexBuffer.getSize() == FULL_SIZED_BUFFER)
|
||||
{
|
||||
statsMap.incStat("FullsizedVBOs");
|
||||
}
|
||||
|
||||
if (vertexBuffer.getSize() == 0)
|
||||
{
|
||||
GLProxy.GL_LOGGER.warn("VBO with size 0");
|
||||
}
|
||||
statsMap.incBytesStat("TotalUsage", vertexBuffer.getSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when object is no longer in use.
|
||||
* Called either after uploadBuffers() returned false (On buffer Upload
|
||||
@@ -287,8 +377,24 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
{
|
||||
this.buffersUploaded = false;
|
||||
|
||||
SharedVbo.OPAQUE.deallocate(this.opaqueBufferSlices);
|
||||
SharedVbo.TRANSPARENT.deallocate(this.transparentBufferSlices);
|
||||
GLProxy.getInstance().queueRunningOnRenderThread(() ->
|
||||
{
|
||||
for (GLVertexBuffer buffer : this.vbos)
|
||||
{
|
||||
if (buffer != null)
|
||||
{
|
||||
buffer.destroyAsync();
|
||||
}
|
||||
}
|
||||
|
||||
for (GLVertexBuffer buffer : this.vbosTransparent)
|
||||
{
|
||||
if (buffer != null)
|
||||
{
|
||||
buffer.destroyAsync();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+30
-21
@@ -82,33 +82,14 @@ public class ColumnRenderBufferBuilder
|
||||
{
|
||||
boolean enableTransparency = Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled;
|
||||
|
||||
//EVENT_LOGGER.trace("RenderRegion start QuadBuild @ " + renderSource.sectionPos);
|
||||
boolean enableSkyLightCulling =
|
||||
Config.Client.Advanced.Graphics.AdvancedGraphics.enableCaveCulling.get()
|
||||
&& (
|
||||
// dimensions with a ceiling will be all caves so we don't want cave culling
|
||||
!clientLevel.getLevelWrapper().hasCeiling()
|
||||
// the end has a lot of overhangs with 0 lighting above the void, which look broken with
|
||||
// the current cave culling logic (this could probably be improved, but just skipping it works best for now)
|
||||
&& !clientLevel.getLevelWrapper().getDimensionType().isTheEnd()
|
||||
// FIXME temporary fix
|
||||
// Cave culling is currently broken for any detail level above 0
|
||||
&& DhSectionPos.getDetailLevel(renderSource.pos) == DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL
|
||||
);
|
||||
|
||||
int skyLightCullingBelow = Config.Client.Advanced.Graphics.AdvancedGraphics.caveCullingHeight.get();
|
||||
// FIXME: Clamp also to the max world height.
|
||||
skyLightCullingBelow = Math.max(skyLightCullingBelow, clientLevel.getMinY());
|
||||
|
||||
|
||||
long builderStartTime = System.currentTimeMillis();
|
||||
|
||||
LodQuadBuilder builder = new LodQuadBuilder(enableSkyLightCulling, (short) (skyLightCullingBelow - clientLevel.getMinY()), enableTransparency, clientLevel.getClientLevelWrapper());
|
||||
LodQuadBuilder builder = new LodQuadBuilder(enableTransparency, clientLevel.getClientLevelWrapper());
|
||||
makeLodRenderData(builder, renderSource, adjData);
|
||||
|
||||
long builderEndTime = System.currentTimeMillis();
|
||||
long buildMs = builderEndTime - builderStartTime;
|
||||
LOGGER.debug("RenderRegion end QuadBuild @ " + renderSource.pos + " took: " + buildMs);
|
||||
//LOGGER.debug("RenderRegion end QuadBuild @ " + renderSource.pos + " took: " + buildMs);
|
||||
|
||||
return builder;
|
||||
}
|
||||
@@ -333,4 +314,32 @@ public class ColumnRenderBufferBuilder
|
||||
quadBuilder.finalizeData();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// vbo interaction //
|
||||
//=================//
|
||||
|
||||
public static GLVertexBuffer[] resizeBuffer(GLVertexBuffer[] vbos, int newSize)
|
||||
{
|
||||
if (vbos.length == newSize)
|
||||
{
|
||||
return vbos;
|
||||
}
|
||||
|
||||
GLVertexBuffer[] newVbos = new GLVertexBuffer[newSize];
|
||||
System.arraycopy(vbos, 0, newVbos, 0, Math.min(vbos.length, newSize));
|
||||
if (newSize < vbos.length)
|
||||
{
|
||||
for (int i = newSize; i < vbos.length; i++)
|
||||
{
|
||||
if (vbos[i] != null)
|
||||
{
|
||||
vbos[i].close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return newVbos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+20
-53
@@ -97,61 +97,28 @@ public class CubicLodTemplate
|
||||
case SHOW_BLOCK_MATERIAL:
|
||||
{
|
||||
|
||||
switch (EDhApiBlockMaterial.getFromIndex(blockMaterialId))
|
||||
color = switch (EDhApiBlockMaterial.getFromIndex(blockMaterialId))
|
||||
{
|
||||
case UNKNOWN:
|
||||
case AIR: // shouldn't normally be rendered, but just in case
|
||||
color = ColorUtil.HOT_PINK;
|
||||
break;
|
||||
|
||||
case LEAVES:
|
||||
color = ColorUtil.DARK_GREEN;
|
||||
break;
|
||||
case STONE:
|
||||
color = ColorUtil.GRAY;
|
||||
break;
|
||||
case WOOD:
|
||||
color = ColorUtil.BROWN;
|
||||
break;
|
||||
case METAL:
|
||||
color = ColorUtil.DARK_GRAY;
|
||||
break;
|
||||
case DIRT:
|
||||
color = ColorUtil.LIGHT_BROWN;
|
||||
break;
|
||||
case LAVA:
|
||||
color = ColorUtil.ORANGE;
|
||||
break;
|
||||
case DEEPSLATE:
|
||||
color = ColorUtil.BLACK;
|
||||
break;
|
||||
case SNOW:
|
||||
color = ColorUtil.WHITE;
|
||||
break;
|
||||
case SAND:
|
||||
color = ColorUtil.TAN;
|
||||
break;
|
||||
case TERRACOTTA:
|
||||
color = ColorUtil.DARK_ORANGE;
|
||||
break;
|
||||
case NETHER_STONE:
|
||||
color = ColorUtil.DARK_RED;
|
||||
break;
|
||||
case WATER:
|
||||
color = ColorUtil.BLUE;
|
||||
break;
|
||||
case GRASS:
|
||||
color = ColorUtil.GREEN;
|
||||
break;
|
||||
case ILLUMINATED:
|
||||
color = ColorUtil.YELLOW;
|
||||
break;
|
||||
|
||||
default:
|
||||
case UNKNOWN, AIR -> // shouldn't normally be rendered, but just in case
|
||||
ColorUtil.HOT_PINK;
|
||||
case LEAVES -> ColorUtil.DARK_GREEN;
|
||||
case STONE -> ColorUtil.GRAY;
|
||||
case WOOD -> ColorUtil.BROWN;
|
||||
case METAL -> ColorUtil.DARK_GRAY;
|
||||
case DIRT -> ColorUtil.LIGHT_BROWN;
|
||||
case LAVA -> ColorUtil.ORANGE;
|
||||
case DEEPSLATE -> ColorUtil.BLACK;
|
||||
case SNOW -> ColorUtil.WHITE;
|
||||
case SAND -> ColorUtil.TAN;
|
||||
case TERRACOTTA -> ColorUtil.DARK_ORANGE;
|
||||
case NETHER_STONE -> ColorUtil.DARK_RED;
|
||||
case WATER -> ColorUtil.BLUE;
|
||||
case GRASS -> ColorUtil.GREEN;
|
||||
case ILLUMINATED -> ColorUtil.YELLOW;
|
||||
default ->
|
||||
// undefined color
|
||||
color = ColorUtil.CYAN;
|
||||
break;
|
||||
}
|
||||
ColorUtil.CYAN;
|
||||
};
|
||||
|
||||
fullBright = true;
|
||||
break;
|
||||
|
||||
+13
-11
@@ -51,7 +51,9 @@ public class LodQuadBuilder
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
|
||||
@Deprecated
|
||||
public final boolean skipQuadsWithZeroSkylight;
|
||||
@Deprecated
|
||||
public final short skyLightCullingBelow;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -123,7 +125,7 @@ public class LodQuadBuilder
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public LodQuadBuilder(boolean enableSkylightCulling, short skyLightCullingBelow, boolean doTransparency, IClientLevelWrapper clientLevelWrapper)
|
||||
public LodQuadBuilder(boolean doTransparency, IClientLevelWrapper clientLevelWrapper)
|
||||
{
|
||||
this.doTransparency = doTransparency;
|
||||
for (int i = 0; i < 6; i++)
|
||||
@@ -132,8 +134,8 @@ public class LodQuadBuilder
|
||||
this.transparentQuads[i] = new ArrayList<>();
|
||||
}
|
||||
|
||||
this.skipQuadsWithZeroSkylight = enableSkylightCulling;
|
||||
this.skyLightCullingBelow = skyLightCullingBelow;
|
||||
this.skipQuadsWithZeroSkylight = false;
|
||||
this.skyLightCullingBelow = 0;
|
||||
this.clientLevelWrapper = clientLevelWrapper;
|
||||
|
||||
this.debugRenderingMode = Config.Client.Advanced.Debugging.debugRendering.get();
|
||||
@@ -166,8 +168,8 @@ public class LodQuadBuilder
|
||||
ArrayList<BufferQuad> quadList = (this.doTransparency && ColorUtil.getAlpha(color) < 255) ? this.transparentQuads[dir.ordinal()] : this.opaqueQuads[dir.ordinal()];
|
||||
if (!quadList.isEmpty() &&
|
||||
(
|
||||
quadList.get(quadList.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|
||||
|| quadList.get(quadList.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
|
||||
quadList.getLast().tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|
||||
|| quadList.getLast().tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
|
||||
)
|
||||
{
|
||||
this.premergeCount++;
|
||||
@@ -194,8 +196,8 @@ public class LodQuadBuilder
|
||||
// attempt to merge this quad with adjacent ones
|
||||
if (!quadList.isEmpty() &&
|
||||
(
|
||||
quadList.get(quadList.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|
||||
|| quadList.get(quadList.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
|
||||
quadList.getLast().tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|
||||
|| quadList.getLast().tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
|
||||
)
|
||||
{
|
||||
this.premergeCount++;
|
||||
@@ -213,8 +215,8 @@ public class LodQuadBuilder
|
||||
ArrayList<BufferQuad> qs = (doTransparency && ColorUtil.getAlpha(color) < 255)
|
||||
? transparentQuads[EDhDirection.DOWN.ordinal()] : opaqueQuads[EDhDirection.DOWN.ordinal()];
|
||||
if (!qs.isEmpty() &&
|
||||
(qs.get(qs.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|
||||
|| qs.get(qs.size() - 1).tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
|
||||
(qs.getLast().tryMerge(quad, BufferMergeDirectionEnum.EastWest)
|
||||
|| qs.getLast().tryMerge(quad, BufferMergeDirectionEnum.NorthSouthOrUpDown))
|
||||
)
|
||||
{
|
||||
premergeCount++;
|
||||
@@ -432,7 +434,7 @@ public class LodQuadBuilder
|
||||
|
||||
public Iterator<ByteBuffer> makeOpaqueVertexBuffers()
|
||||
{
|
||||
return new Iterator<ByteBuffer>()
|
||||
return new Iterator<>()
|
||||
{
|
||||
final ByteBuffer bb = ByteBuffer.allocateDirect(ColumnRenderBuffer.FULL_SIZED_BUFFER)
|
||||
.order(ByteOrder.nativeOrder());
|
||||
@@ -500,7 +502,7 @@ public class LodQuadBuilder
|
||||
|
||||
public Iterator<ByteBuffer> makeTransparentVertexBuffers()
|
||||
{
|
||||
return new Iterator<ByteBuffer>()
|
||||
return new Iterator<>()
|
||||
{
|
||||
final ByteBuffer bb = ByteBuffer.allocateDirect(ColumnRenderBuffer.FULL_SIZED_BUFFER)
|
||||
.order(ByteOrder.nativeOrder());
|
||||
|
||||
-188
@@ -1,188 +0,0 @@
|
||||
package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding;
|
||||
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.coreapi.util.StringUtil;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/** Used to allow multiple {@link ColumnRenderBuffer}'s to be put in a single VBO. */
|
||||
public class SharedVbo
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
public static final SharedVbo OPAQUE = new SharedVbo(2_000_000_000L/*1GB*/, 1024 * 1024/*1MB*/);
|
||||
public static final SharedVbo TRANSPARENT = new SharedVbo(2_000_000_000L/*1GB*/, 1024 * 1024/*1MB*/);
|
||||
|
||||
|
||||
public final int vboId;
|
||||
|
||||
|
||||
private final long bufferTotalByteSize;
|
||||
/** the length of a single chunk of this VBO in bytes. */
|
||||
private final int chunkByteSize;
|
||||
|
||||
private final ConcurrentHashMap<Long, BufferSlice> bufferSliceByStartingIndex = new ConcurrentHashMap<>();
|
||||
private long nextMemoryAddress = 0L;
|
||||
private final Queue<BufferSlice> availableSlices = new ArrayDeque<>();
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public SharedVbo(long totalSize, int chunkByteSize)
|
||||
{
|
||||
LodUtil.assertTrue(GLProxy.getInstance().runningOnRenderThread(), "Buffer Handler has to be created on the render thread.");
|
||||
|
||||
this.bufferTotalByteSize = totalSize;
|
||||
this.chunkByteSize = chunkByteSize;
|
||||
|
||||
// Generate and bind the VBO
|
||||
this.vboId = GL32.glGenBuffers();
|
||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.vboId);
|
||||
GL32.glBufferData(GL32.GL_ARRAY_BUFFER, this.bufferTotalByteSize, GL32.GL_DYNAMIC_DRAW);
|
||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// allocation //
|
||||
//============//
|
||||
|
||||
@Nullable
|
||||
public SharedVbo.BufferSlice allocateSlice()
|
||||
{
|
||||
BufferSlice availableSlice = this.availableSlices.poll();
|
||||
if (availableSlice != null)
|
||||
{
|
||||
return availableSlice;
|
||||
}
|
||||
|
||||
// Find the first free chunk
|
||||
for (long startingIndex = this.nextMemoryAddress; startingIndex < this.bufferTotalByteSize; startingIndex += this.chunkByteSize)
|
||||
{
|
||||
// check if this section is free
|
||||
BufferSlice newSlice = new BufferSlice(startingIndex, this.chunkByteSize);
|
||||
if (this.bufferSliceByStartingIndex.putIfAbsent(startingIndex, newSlice) == null)
|
||||
{
|
||||
this.nextMemoryAddress = startingIndex;
|
||||
return newSlice;
|
||||
}
|
||||
}
|
||||
|
||||
return null; // No free chunk found
|
||||
}
|
||||
public void deallocate(BufferSlice[] slices)
|
||||
{
|
||||
if (slices != null)
|
||||
{
|
||||
for (BufferSlice slice : slices)
|
||||
{
|
||||
if (slice != null)
|
||||
{
|
||||
this.bufferSliceByStartingIndex.remove(slice.startIndex);
|
||||
this.availableSlices.add(slice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void deallocate(BufferSlice slice)
|
||||
{
|
||||
if (slice != null)
|
||||
{
|
||||
this.bufferSliceByStartingIndex.remove(slice.startIndex);
|
||||
this.availableSlices.add(slice);
|
||||
}
|
||||
}
|
||||
public void clear()
|
||||
{
|
||||
this.bufferSliceByStartingIndex.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// buffer handling //
|
||||
//=================//
|
||||
|
||||
public void updateBuffer(BufferSlice chunk, ByteBuffer buffer)
|
||||
{
|
||||
int size = buffer.limit() - buffer.position();
|
||||
if (size > chunk.length)
|
||||
{
|
||||
// if this was fired that means we didn't split up the buffer into the right size
|
||||
// if this isn't stopped the buffer will overwrite an adjacent section and cause incorrect rendering
|
||||
throw new RuntimeException("Programmer error: Uploaded buffer bigger than the allocated area. Allocated: ["+chunk.length+"], buffer: ["+size+"]");
|
||||
}
|
||||
|
||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.vboId);
|
||||
GL32.glBufferSubData(GL32.GL_ARRAY_BUFFER, chunk.startIndex, buffer);
|
||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, 0);
|
||||
chunk.vertexCount = size / LodUtil.LOD_VERTEX_FORMAT.getByteSize();
|
||||
}
|
||||
|
||||
public void bind() { GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.vboId); }
|
||||
public void unbind() { GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, 0); }
|
||||
|
||||
|
||||
|
||||
//=======//
|
||||
// debug //
|
||||
//=======//
|
||||
|
||||
public String getDebugMenuString()
|
||||
{
|
||||
long maxChunkCount = (this.bufferTotalByteSize / this.chunkByteSize);
|
||||
long chunkCount = 0;
|
||||
long allocatedBytes = 0;
|
||||
|
||||
for (BufferSlice slice : this.bufferSliceByStartingIndex.values())
|
||||
{
|
||||
allocatedBytes += slice.length;
|
||||
chunkCount++;
|
||||
}
|
||||
|
||||
return "Slices: ["+F3Screen.NUMBER_FORMAT.format(chunkCount)+"/"+F3Screen.NUMBER_FORMAT.format(maxChunkCount)+"], " +
|
||||
"Mem: ["+StringUtil.convertByteCountToHumanReadableSI(allocatedBytes)+"/"+StringUtil.convertByteCountToHumanReadableSI(this.bufferTotalByteSize)+"]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper classes //
|
||||
//================//
|
||||
|
||||
/** represents a single allocated slice of the parent VBO */
|
||||
public static class BufferSlice
|
||||
{
|
||||
public final long startIndex;
|
||||
public final int length;
|
||||
|
||||
public int vertexCount;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public BufferSlice(long startIndex, int length)
|
||||
{
|
||||
this.startIndex = startIndex;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -199,7 +199,7 @@ public final class ColumnArrayView implements IColumnDataView
|
||||
for (int i = offset; i < end; i++)
|
||||
{
|
||||
long element = a.getLong(i);
|
||||
int elementHash = (int) (element ^ (element >>> 32));
|
||||
int elementHash = Long.hashCode(element);
|
||||
result = 31 * result + elementHash;
|
||||
}
|
||||
return result;
|
||||
|
||||
+108
-71
@@ -20,6 +20,7 @@
|
||||
package com.seibel.distanthorizons.core.dataObjects.transformers;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiBlocksToAvoid;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
@@ -110,9 +111,6 @@ public class FullDataToRenderDataTransformer
|
||||
}
|
||||
|
||||
columnSource.markNotEmpty();
|
||||
|
||||
if (dataDetail == columnSource.getDataDetailLevel())
|
||||
{
|
||||
int baseX = DhSectionPos.getMinCornerBlockX(pos);
|
||||
int baseZ = DhSectionPos.getMinCornerBlockZ(pos);
|
||||
|
||||
@@ -124,60 +122,74 @@ public class FullDataToRenderDataTransformer
|
||||
|
||||
ColumnArrayView columnArrayView = columnSource.getVerticalDataPointView(x, z);
|
||||
LongArrayList dataColumn = fullDataSource.get(x, z);
|
||||
convertColumnData(level, fullDataSource.mapping, baseX + x, baseZ + z, columnArrayView, dataColumn);
|
||||
updateRenderDataViewWithFullDataColumn(level, fullDataSource.mapping, baseX + x, baseZ + z, columnArrayView, dataColumn);
|
||||
}
|
||||
}
|
||||
|
||||
columnSource.fillDebugFlag(0, 0, ColumnRenderSource.SECTION_SIZE, ColumnRenderSource.SECTION_SIZE, ColumnRenderSource.DebugSourceFlag.FULL);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("To be implemented");
|
||||
//FIXME: Implement different size creation of renderData
|
||||
}
|
||||
return columnSource;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
|
||||
/**
|
||||
* Called in loops that may run for an extended period of time. <br>
|
||||
* This is necessary to allow canceling these transformers since running
|
||||
* them after the client has left a given world will throw exceptions.
|
||||
*/
|
||||
private static void throwIfThreadInterrupted() throws InterruptedException
|
||||
/** Updates the given {@link ColumnArrayView} to match the incoming Full data {@link LongArrayList} */
|
||||
public static void updateRenderDataViewWithFullDataColumn(
|
||||
IDhClientLevel level,
|
||||
FullDataPointIdMap fullDataMapping, int blockX, int blockZ,
|
||||
ColumnArrayView columnArrayView,
|
||||
LongArrayList fullDataColumn)
|
||||
{
|
||||
if (Thread.interrupted())
|
||||
if (fullDataColumn == null || fullDataColumn.size() == 0)
|
||||
{
|
||||
throw new InterruptedException(FullDataToRenderDataTransformer.class.getSimpleName() + " task interrupted.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// TODO what does this mean?
|
||||
int dataTotalLength = fullDataColumn.size();
|
||||
if (dataTotalLength > columnArrayView.verticalSize())
|
||||
{
|
||||
ColumnArrayView totalColumnData = new ColumnArrayView(new LongArrayList(new long[dataTotalLength]), dataTotalLength, 0, dataTotalLength);
|
||||
iterateAndConvert(level, fullDataMapping, blockX, blockZ, totalColumnData, fullDataColumn);
|
||||
columnArrayView.changeVerticalSizeFrom(totalColumnData);
|
||||
}
|
||||
else
|
||||
{
|
||||
iterateAndConvert(level, fullDataMapping, blockX, blockZ, columnArrayView, fullDataColumn); //Directly use the arrayView since it fits.
|
||||
}
|
||||
}
|
||||
private static void iterateAndConvert(
|
||||
IDhClientLevel level, FullDataPointIdMap fullDataMapping,
|
||||
int blockX, int blockZ,
|
||||
ColumnArrayView renderColumnData, LongArrayList fullColumnData)
|
||||
{
|
||||
boolean avoidSolidBlocks = (Config.Client.Advanced.Graphics.Quality.blocksToIgnore.get() == EDhApiBlocksToAvoid.NON_COLLIDING);
|
||||
boolean ignoreNonCollidingBlocks = (Config.Client.Advanced.Graphics.Quality.blocksToIgnore.get() == EDhApiBlocksToAvoid.NON_COLLIDING);
|
||||
boolean colorBelowWithAvoidedBlocks = Config.Client.Advanced.Graphics.Quality.tintWithAvoidedBlocks.get();
|
||||
|
||||
HashSet<IBlockStateWrapper> blockStatesToIgnore = WRAPPER_FACTORY.getRendererIgnoredBlocks(level.getLevelWrapper());
|
||||
HashSet<IBlockStateWrapper> caveBlockStatesToIgnore = WRAPPER_FACTORY.getRendererIgnoredCaveBlocks(level.getLevelWrapper());
|
||||
|
||||
boolean caveCullingEnabled =
|
||||
Config.Client.Advanced.Graphics.AdvancedGraphics.enableCaveCulling.get()
|
||||
&& (
|
||||
// dimensions with a ceiling will be all caves so we don't want cave culling
|
||||
!level.getLevelWrapper().hasCeiling()
|
||||
// the end has a lot of overhangs with 0 lighting above the void, which look broken with
|
||||
// the current cave culling logic (this could probably be improved, but just skipping it works best for now)
|
||||
&& !level.getLevelWrapper().getDimensionType().isTheEnd()
|
||||
);
|
||||
|
||||
boolean isVoid = true;
|
||||
|
||||
int colorToApplyToNextBlock = -1;
|
||||
int lastColor = 0;
|
||||
int lastBottom = -10000;
|
||||
|
||||
int skylightToApplyToNextBlock = -1;
|
||||
int blocklightToApplyToNextBlock = -1;
|
||||
int columnOffset = 0;
|
||||
|
||||
IBiomeWrapper biome = null;
|
||||
IBlockStateWrapper block = null;
|
||||
|
||||
|
||||
// goes from the top down
|
||||
for (int i = 0; i < fullColumnData.size(); i++)
|
||||
{
|
||||
@@ -188,23 +200,6 @@ public class FullDataToRenderDataTransformer
|
||||
int blockLight = FullDataPointUtil.getBlockLight(fullData);
|
||||
int skyLight = FullDataPointUtil.getSkyLight(fullData);
|
||||
|
||||
// TODO how should corrupted data be handled?
|
||||
// TODO why is the full data corrupted in the first place? FullDataPointUtil hasn't been changed in a long time, could one of the full data point objects be corrupted?
|
||||
// TODO if either of these happen the ID might also be invalid
|
||||
//if (bottomY + blockHeight > 300)
|
||||
//{
|
||||
// // this data point is too tall, it's probably a monolith
|
||||
// int k = 0;
|
||||
// throw new RuntimeException();
|
||||
//}
|
||||
//if (light > 16 || light < 0)
|
||||
//{
|
||||
// // light is out of range
|
||||
// throw new RuntimeException();
|
||||
//}
|
||||
|
||||
IBiomeWrapper biome;
|
||||
IBlockStateWrapper block;
|
||||
try
|
||||
{
|
||||
biome = fullDataMapping.getBiomeWrapper(id);
|
||||
@@ -229,29 +224,73 @@ public class FullDataToRenderDataTransformer
|
||||
}
|
||||
|
||||
|
||||
if (blockStatesToIgnore.contains(block))
|
||||
//====================//
|
||||
// ignored block and //
|
||||
// cave culling check //
|
||||
//====================//
|
||||
|
||||
boolean ignoreBlock = blockStatesToIgnore.contains(block);
|
||||
boolean caveBlock = caveBlockStatesToIgnore.contains(block);
|
||||
if (caveBlock)
|
||||
{
|
||||
// Don't render: air, barriers, light blocks, etc.
|
||||
if (caveCullingEnabled
|
||||
// assume this data point is underground if it has no sky-light
|
||||
&& skyLight == LodUtil.MIN_MC_LIGHT
|
||||
// cave culling shouldn't happen when at the top of the world
|
||||
&& columnOffset != 0
|
||||
// cave culling can't happen when at the bottom of the world
|
||||
&& columnOffset != fullColumnData.size())
|
||||
{
|
||||
// we need to get the next sky/block lights because
|
||||
// the air block here will always have a light of 0/0 due to only the top of the LOD's light being saved.
|
||||
long nextFullData = fullColumnData.getLong(i+1);
|
||||
int nextSkyLight = FullDataPointUtil.getSkyLight(nextFullData);
|
||||
|
||||
if (nextSkyLight == LodUtil.MIN_MC_LIGHT
|
||||
&& ColorUtil.getAlpha(lastColor) == 255)
|
||||
{
|
||||
// replace the previous block with new bottom
|
||||
long columnData = renderColumnData.get(columnOffset - 1);
|
||||
columnData = RenderDataPointUtil.setYMin(columnData, bottomY);
|
||||
renderColumnData.set(columnOffset - 1, columnData);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// solid block check
|
||||
if (avoidSolidBlocks && !block.isSolid() && !block.isLiquid() && block.getOpacity() != LodUtil.BLOCK_FULLY_OPAQUE)
|
||||
if (ignoreBlock)
|
||||
{
|
||||
// this is a merged block and a cave block, so it should never be rendered
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (ignoreBlock)
|
||||
{
|
||||
// this is an ignored block, but shouldn't be merged like a cave block
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//===================//
|
||||
// solid block check //
|
||||
//===================//
|
||||
|
||||
if (ignoreNonCollidingBlocks && !block.isSolid() && !block.isLiquid() && block.getOpacity() != LodUtil.BLOCK_FULLY_OPAQUE)
|
||||
{
|
||||
if (colorBelowWithAvoidedBlocks)
|
||||
{
|
||||
int tempColor = level.computeBaseColor(new DhBlockPos(blockX, bottomY + level.getMinY(), blockZ), biome, block);
|
||||
if (ColorUtil.getAlpha(tempColor) == 0)
|
||||
// don't transfer the color when alpha is 0
|
||||
if (ColorUtil.getAlpha(tempColor) != 0)
|
||||
{
|
||||
//make sure to not transfer the color when alpha is 0
|
||||
continue;
|
||||
}
|
||||
//mare sure to not trnasfer alpha if for some reason grass is semi transparent
|
||||
// don't transfer alpha if for some reason grass is semi transparent
|
||||
colorToApplyToNextBlock = ColorUtil.setAlpha(tempColor,255);
|
||||
|
||||
skylightToApplyToNextBlock = skyLight;
|
||||
blocklightToApplyToNextBlock = blockLight;
|
||||
}
|
||||
}
|
||||
|
||||
// don't add this block
|
||||
continue;
|
||||
@@ -273,10 +312,10 @@ public class FullDataToRenderDataTransformer
|
||||
blockLight = blocklightToApplyToNextBlock;
|
||||
}
|
||||
|
||||
//check if they share a top-bottom face and if they have same collor
|
||||
//check if they share a top-bottom face and if they have same color
|
||||
if (color == lastColor && bottomY + blockHeight == lastBottom && columnOffset > 0)
|
||||
{
|
||||
//replace the previus block with new bottom
|
||||
//replace the previous block with new bottom
|
||||
long columnData = renderColumnData.get(columnOffset - 1);
|
||||
columnData = RenderDataPointUtil.setYMin(columnData, bottomY);
|
||||
renderColumnData.set(columnOffset - 1, columnData);
|
||||
@@ -301,24 +340,22 @@ public class FullDataToRenderDataTransformer
|
||||
}
|
||||
}
|
||||
|
||||
// TODO what does this mean?
|
||||
public static void convertColumnData(IDhClientLevel level, FullDataPointIdMap fullDataMapping, int blockX, int blockZ, ColumnArrayView columnArrayView, LongArrayList fullDataColumn)
|
||||
{
|
||||
if (fullDataColumn == null || fullDataColumn.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int dataTotalLength = fullDataColumn.size();
|
||||
if (dataTotalLength > columnArrayView.verticalSize())
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
|
||||
/**
|
||||
* Called in loops that may run for an extended period of time. <br>
|
||||
* This is necessary to allow canceling these transformers since running
|
||||
* them after the client has left a given world will throw exceptions.
|
||||
*/
|
||||
private static void throwIfThreadInterrupted() throws InterruptedException
|
||||
{
|
||||
ColumnArrayView totalColumnData = new ColumnArrayView(new LongArrayList(new long[dataTotalLength]), dataTotalLength, 0, dataTotalLength);
|
||||
iterateAndConvert(level, fullDataMapping, blockX, blockZ, totalColumnData, fullDataColumn);
|
||||
columnArrayView.changeVerticalSizeFrom(totalColumnData);
|
||||
}
|
||||
else
|
||||
if (Thread.interrupted())
|
||||
{
|
||||
iterateAndConvert(level, fullDataMapping, blockX, blockZ, columnArrayView, fullDataColumn); //Directly use the arrayView since it fits.
|
||||
throw new InterruptedException(FullDataToRenderDataTransformer.class.getSimpleName() + " task interrupted.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+39
-25
@@ -31,7 +31,6 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.util.FullDataPointUtil;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
@@ -47,8 +46,6 @@ public class LodDataBuilder
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
private static final IBlockStateWrapper AIR = SingletonInjector.INSTANCE.get(IWrapperFactory.class).getAirBlockStateWrapper();
|
||||
/** how many chunks wide the {@link FullDataSourceV2} is. */
|
||||
private static final int NUMB_OF_CHUNKS_WIDE = FullDataSourceV2.WIDTH / LodUtil.CHUNK_WIDTH;
|
||||
|
||||
private static boolean getTopErrorLogged = false;
|
||||
|
||||
@@ -67,12 +64,8 @@ public class LodDataBuilder
|
||||
|
||||
|
||||
|
||||
// get the section position
|
||||
int sectionPosX = chunkWrapper.getChunkPos().x;
|
||||
// negative positions start at -1 so the logic there is slightly different
|
||||
sectionPosX = (sectionPosX < 0) ? ((sectionPosX + 1) / NUMB_OF_CHUNKS_WIDE) - 1 : (sectionPosX / NUMB_OF_CHUNKS_WIDE);
|
||||
int sectionPosZ = chunkWrapper.getChunkPos().z;
|
||||
sectionPosZ = (sectionPosZ < 0) ? ((sectionPosZ + 1) / NUMB_OF_CHUNKS_WIDE) - 1 : (sectionPosZ / NUMB_OF_CHUNKS_WIDE);
|
||||
int sectionPosX = getXOrZSectionPosFromChunkPos(chunkWrapper.getChunkPos().x);
|
||||
int sectionPosZ = getXOrZSectionPosFromChunkPos(chunkWrapper.getChunkPos().z);
|
||||
long pos = DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, sectionPosX, sectionPosZ);
|
||||
|
||||
FullDataSourceV2 dataSource = FullDataSourceV2.createEmpty(pos);
|
||||
@@ -98,30 +91,30 @@ public class LodDataBuilder
|
||||
// -3 -> 1
|
||||
// -4 -> 0 ---
|
||||
// -5 -> 3
|
||||
chunkOffsetX = ((chunkOffsetX) % NUMB_OF_CHUNKS_WIDE);
|
||||
chunkOffsetX = ((chunkOffsetX) % FullDataSourceV2.NUMB_OF_CHUNKS_WIDE);
|
||||
if (chunkOffsetX != 0)
|
||||
{
|
||||
chunkOffsetX += NUMB_OF_CHUNKS_WIDE;
|
||||
chunkOffsetX += FullDataSourceV2.NUMB_OF_CHUNKS_WIDE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkOffsetX %= NUMB_OF_CHUNKS_WIDE;
|
||||
chunkOffsetX %= FullDataSourceV2.NUMB_OF_CHUNKS_WIDE;
|
||||
}
|
||||
chunkOffsetX *= LodUtil.CHUNK_WIDTH;
|
||||
|
||||
int chunkOffsetZ = chunkWrapper.getChunkPos().z;
|
||||
if (chunkWrapper.getChunkPos().z < 0)
|
||||
{
|
||||
chunkOffsetZ = ((chunkOffsetZ) % NUMB_OF_CHUNKS_WIDE);
|
||||
chunkOffsetZ = ((chunkOffsetZ) % FullDataSourceV2.NUMB_OF_CHUNKS_WIDE);
|
||||
if (chunkOffsetZ != 0)
|
||||
{
|
||||
chunkOffsetZ += NUMB_OF_CHUNKS_WIDE;
|
||||
chunkOffsetZ += FullDataSourceV2.NUMB_OF_CHUNKS_WIDE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkOffsetZ %= NUMB_OF_CHUNKS_WIDE;
|
||||
chunkOffsetZ %= FullDataSourceV2.NUMB_OF_CHUNKS_WIDE;
|
||||
}
|
||||
chunkOffsetZ *= LodUtil.CHUNK_WIDTH;
|
||||
|
||||
@@ -302,14 +295,23 @@ public class LodDataBuilder
|
||||
|
||||
|
||||
/** @throws ClassCastException if an API user returns the wrong object type(s) */
|
||||
public static FullDataSourceV2 createFromApiChunkData(DhApiChunk dataPoints) throws ClassCastException, DataCorruptedException
|
||||
public static FullDataSourceV2 createFromApiChunkData(DhApiChunk apiChunk) throws ClassCastException, DataCorruptedException
|
||||
{
|
||||
FullDataSourceV2 accessor = FullDataSourceV2.createEmpty(DhSectionPos.encode(new DhChunkPos(dataPoints.chunkPosX, dataPoints.chunkPosZ)));
|
||||
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
|
||||
// get the section position
|
||||
int sectionPosX = getXOrZSectionPosFromChunkPos(apiChunk.chunkPosX);
|
||||
int sectionPosZ = getXOrZSectionPosFromChunkPos(apiChunk.chunkPosZ);
|
||||
long pos = DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, sectionPosX, sectionPosZ);
|
||||
|
||||
// chunk relative block position in the data source
|
||||
int relSourceBlockX = Math.floorMod(apiChunk.chunkPosX, 4) * LodUtil.CHUNK_WIDTH;
|
||||
int relSourceBlockZ = Math.floorMod(apiChunk.chunkPosZ, 4) * LodUtil.CHUNK_WIDTH;
|
||||
|
||||
FullDataSourceV2 dataSource = FullDataSourceV2.createEmpty(pos);
|
||||
for (int relBlockZ = 0; relBlockZ < LodUtil.CHUNK_WIDTH; relBlockZ++)
|
||||
{
|
||||
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++)
|
||||
for (int relBlockX = 0; relBlockX < LodUtil.CHUNK_WIDTH; relBlockX++)
|
||||
{
|
||||
List<DhApiTerrainDataPoint> columnDataPoints = dataPoints.getDataPoints(relX, relZ);
|
||||
List<DhApiTerrainDataPoint> columnDataPoints = apiChunk.getDataPoints(relBlockX, relBlockZ);
|
||||
|
||||
|
||||
// this null check does 2 nice things at the same time:
|
||||
@@ -323,7 +325,7 @@ public class LodDataBuilder
|
||||
{
|
||||
DhApiTerrainDataPoint dataPoint = columnDataPoints.get(index);
|
||||
|
||||
int id = accessor.mapping.addIfNotPresentAndGetId(
|
||||
int id = dataSource.mapping.addIfNotPresentAndGetId(
|
||||
(IBiomeWrapper) (dataPoint.biomeWrapper),
|
||||
(IBlockStateWrapper) (dataPoint.blockStateWrapper)
|
||||
);
|
||||
@@ -331,7 +333,7 @@ public class LodDataBuilder
|
||||
packedDataPoints.set(index, FullDataPointUtil.encode(
|
||||
id,
|
||||
dataPoint.topYBlockPos - dataPoint.bottomYBlockPos,
|
||||
dataPoint.bottomYBlockPos - dataPoints.topYBlockPos,
|
||||
dataPoint.bottomYBlockPos - apiChunk.bottomYBlockPos,
|
||||
(byte) (dataPoint.blockLightLevel),
|
||||
(byte) (dataPoint.skyLightLevel)
|
||||
));
|
||||
@@ -339,11 +341,14 @@ public class LodDataBuilder
|
||||
|
||||
// TODO add the ability for API users to define a different compression mode
|
||||
// or add a "unkown" compression mode
|
||||
accessor.setSingleColumn(packedDataPoints, relX, relZ, EDhApiWorldGenerationStep.LIGHT, EDhApiWorldCompressionMode.MERGE_SAME_BLOCKS);
|
||||
dataSource.setSingleColumn(
|
||||
packedDataPoints,
|
||||
relBlockX + relSourceBlockX, relBlockZ + relSourceBlockZ,
|
||||
EDhApiWorldGenerationStep.LIGHT, EDhApiWorldCompressionMode.MERGE_SAME_BLOCKS);
|
||||
dataSource.isEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
return accessor;
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
|
||||
@@ -354,4 +359,13 @@ public class LodDataBuilder
|
||||
|
||||
public static boolean canGenerateLodFromChunk(IChunkWrapper chunk) { return chunk != null && chunk.isLightCorrect(); }
|
||||
|
||||
public static int getXOrZSectionPosFromChunkPos(int chunkXOrZPos)
|
||||
{
|
||||
// get the section position
|
||||
int sectionPos = chunkXOrZPos;
|
||||
// negative positions start at -1 so the logic there is slightly different
|
||||
sectionPos = (sectionPos < 0) ? ((sectionPos + 1) / FullDataSourceV2.NUMB_OF_CHUNKS_WIDE) - 1 : (sectionPos / FullDataSourceV2.NUMB_OF_CHUNKS_WIDE);
|
||||
return sectionPos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,9 +98,7 @@ public enum EDhDirection
|
||||
private static final EDhDirection[] VALUES = values();
|
||||
|
||||
private static final Map<String, EDhDirection> BY_NAME = Arrays.stream(VALUES).collect(Collectors.toMap(EDhDirection::getName, (p_199787_0_) ->
|
||||
{
|
||||
return p_199787_0_;
|
||||
}));
|
||||
p_199787_0_));
|
||||
|
||||
// private static final LodDirection[] BY_3D_DATA = Arrays.stream(VALUES).sorted(Comparator.comparingInt((p_199790_0_) ->
|
||||
// {
|
||||
@@ -247,36 +245,26 @@ public enum EDhDirection
|
||||
|
||||
public EDhDirection getClockWise()
|
||||
{
|
||||
switch (this)
|
||||
return switch (this)
|
||||
{
|
||||
case NORTH:
|
||||
return EAST;
|
||||
case SOUTH:
|
||||
return WEST;
|
||||
case WEST:
|
||||
return NORTH;
|
||||
case EAST:
|
||||
return SOUTH;
|
||||
default:
|
||||
throw new IllegalStateException("Unable to get Y-rotated facing of " + this);
|
||||
}
|
||||
case NORTH -> EAST;
|
||||
case SOUTH -> WEST;
|
||||
case WEST -> NORTH;
|
||||
case EAST -> SOUTH;
|
||||
default -> throw new IllegalStateException("Unable to get Y-rotated facing of " + this);
|
||||
};
|
||||
}
|
||||
|
||||
public EDhDirection getCounterClockWise()
|
||||
{
|
||||
switch (this)
|
||||
return switch (this)
|
||||
{
|
||||
case NORTH:
|
||||
return WEST;
|
||||
case SOUTH:
|
||||
return EAST;
|
||||
case WEST:
|
||||
return SOUTH;
|
||||
case EAST:
|
||||
return NORTH;
|
||||
default:
|
||||
throw new IllegalStateException("Unable to get CCW facing of " + this);
|
||||
}
|
||||
case NORTH -> WEST;
|
||||
case SOUTH -> EAST;
|
||||
case WEST -> SOUTH;
|
||||
case EAST -> NORTH;
|
||||
default -> throw new IllegalStateException("Unable to get CCW facing of " + this);
|
||||
};
|
||||
}
|
||||
|
||||
public String getName()
|
||||
@@ -317,16 +305,11 @@ public enum EDhDirection
|
||||
|
||||
public static EDhDirection fromAxisAndDirection(EDhDirection.Axis p_211699_0_, EDhDirection.AxisDirection p_211699_1_)
|
||||
{
|
||||
switch (p_211699_0_)
|
||||
{
|
||||
case X:
|
||||
return p_211699_1_ == EDhDirection.AxisDirection.POSITIVE ? EAST : WEST;
|
||||
case Y:
|
||||
return p_211699_1_ == EDhDirection.AxisDirection.POSITIVE ? UP : DOWN;
|
||||
case Z:
|
||||
default:
|
||||
return p_211699_1_ == EDhDirection.AxisDirection.POSITIVE ? SOUTH : NORTH;
|
||||
}
|
||||
return switch (p_211699_0_) {
|
||||
case X -> p_211699_1_ == AxisDirection.POSITIVE ? EAST : WEST;
|
||||
case Y -> p_211699_1_ == AxisDirection.POSITIVE ? UP : DOWN;
|
||||
default -> p_211699_1_ == AxisDirection.POSITIVE ? SOUTH : NORTH;
|
||||
};
|
||||
}
|
||||
|
||||
// public float toYRot()
|
||||
@@ -436,9 +419,7 @@ public enum EDhDirection
|
||||
private static final EDhDirection.Axis[] VALUES = values();
|
||||
|
||||
private static final Map<String, EDhDirection.Axis> BY_NAME = Arrays.stream(VALUES).collect(Collectors.toMap(EDhDirection.Axis::getName, (p_199785_0_) ->
|
||||
{
|
||||
return p_199785_0_;
|
||||
}));
|
||||
p_199785_0_));
|
||||
private final String name;
|
||||
|
||||
Axis(String name)
|
||||
|
||||
+5
-5
@@ -125,10 +125,10 @@ public class FullDataSourceProviderV2
|
||||
|
||||
// start migrating any legacy data sources present in the background
|
||||
this.migrationThreadPool = ThreadUtil.makeRateLimitedThreadPool(1, MIGRATION_THREAD_NAME_PREFIX +"["+dimensionName+"]", Config.Client.Advanced.MultiThreading.runTimeRatioForUpdatePropagatorThreads.get(), Thread.MIN_PRIORITY, (Semaphore)null);
|
||||
this.migrationThreadPool.execute(() -> this.convertLegacyDataSources());
|
||||
this.migrationThreadPool.execute(this::convertLegacyDataSources);
|
||||
|
||||
this.updateQueueProcessor = ThreadUtil.makeSingleThreadPool("Parent Update Queue ["+dimensionName+"]");
|
||||
this.updateQueueProcessor.execute(() -> this.runUpdateQueue());
|
||||
this.updateQueueProcessor.execute(this::runUpdateQueue);
|
||||
}
|
||||
|
||||
|
||||
@@ -604,12 +604,12 @@ public class FullDataSourceProviderV2
|
||||
public void debugRender(DebugRenderer renderer)
|
||||
{
|
||||
this.lockedPosSet
|
||||
.forEach((pos) -> { renderer.renderBox(new DebugRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)); });
|
||||
.forEach((pos) -> renderer.renderBox(new DebugRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)));
|
||||
|
||||
this.queuedUpdateCountsByPos
|
||||
.forEach((pos, updateCountRef) -> { renderer.renderBox(new DebugRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)); });
|
||||
.forEach((pos, updateCountRef) -> renderer.renderBox(new DebugRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)));
|
||||
this.parentUpdatingPosSet
|
||||
.forEach((pos) -> { renderer.renderBox(new DebugRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)); });
|
||||
.forEach((pos) -> renderer.renderBox(new DebugRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-7
@@ -111,7 +111,7 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
|
||||
// if the generation task was split up into smaller positions, add the on-complete event to them
|
||||
for (CompletableFuture<WorldGenResult> siblingFuture : genTaskResult.childFutures)
|
||||
{
|
||||
siblingFuture.whenComplete((siblingGenTaskResult, siblingEx) -> this.onWorldGenTaskComplete(siblingGenTaskResult, siblingEx));
|
||||
siblingFuture.whenComplete(this::onWorldGenTaskComplete);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
|
||||
|
||||
GenTask genTask = new GenTask(genPos);
|
||||
CompletableFuture<WorldGenResult> worldGenFuture = worldGenQueue.submitGenTask(genPos, (byte) (DhSectionPos.getDetailLevel(genPos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL), genTask);
|
||||
worldGenFuture.whenComplete((genTaskResult, ex) -> this.onWorldGenTaskComplete(genTaskResult, ex));
|
||||
worldGenFuture.whenComplete(this::onWorldGenTaskComplete);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -362,7 +362,7 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
|
||||
super.debugRender(renderer);
|
||||
|
||||
this.delayedFullDataSourceSaveCache.dataSourceByPosition
|
||||
.forEach((pos, dataSource) -> { renderer.renderBox(new DebugRenderer.Box(pos, -32f, 80f, 0.20f, Color.green.darker())); });
|
||||
.forEach((pos, dataSource) -> renderer.renderBox(new DebugRenderer.Box(pos, -32f, 80f, 0.20f, Color.green.darker())));
|
||||
}
|
||||
|
||||
|
||||
@@ -387,10 +387,7 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
|
||||
@Override
|
||||
public Consumer<FullDataSourceV2> getChunkDataConsumer()
|
||||
{
|
||||
return (chunkSizedFullDataSource) ->
|
||||
{
|
||||
GeneratedFullDataSourceProvider.this.delayedFullDataSourceSaveCache.queueDataSourceForUpdateAndSave(chunkSizedFullDataSource);
|
||||
};
|
||||
return GeneratedFullDataSourceProvider.this.delayedFullDataSourceSaveCache::queueDataSourceForUpdateAndSave;
|
||||
}
|
||||
}
|
||||
private void onDataSourceSave(FullDataSourceV2 fullDataSource)
|
||||
|
||||
+30
-33
@@ -41,13 +41,17 @@ import java.util.*;
|
||||
*/
|
||||
public class ClientOnlySaveStructure extends AbstractSaveStructure
|
||||
{
|
||||
final File folder;
|
||||
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
private static final IMinecraftSharedWrapper MC_SHARED = SingletonInjector.INSTANCE.get(IMinecraftSharedWrapper.class);
|
||||
public static final String SERVER_DATA_FOLDER_NAME = "Distant_Horizons_server_data";
|
||||
public static final String REPLAY_SERVER_FOLDER_NAME = "REPLAY";
|
||||
public static final String INVALID_FILE_CHARACTERS_REGEX = "[\\\\/:*?\"<>|]";
|
||||
|
||||
SubDimensionLevelMatcher subDimMatcher = null;
|
||||
final HashMap<ILevelWrapper, File> levelWrapperToFileMap = new HashMap<>();
|
||||
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
private static final IMinecraftSharedWrapper MC_SHARED = SingletonInjector.INSTANCE.get(IMinecraftSharedWrapper.class);
|
||||
|
||||
|
||||
private SubDimensionLevelMatcher subDimMatcher = null;
|
||||
private final File folder;
|
||||
private final HashMap<ILevelWrapper, File> levelWrapperToFileMap = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
@@ -81,9 +85,8 @@ public class ClientOnlySaveStructure extends AbstractSaveStructure
|
||||
return this.levelWrapperToFileMap.computeIfAbsent(levelWrapper, (newLevelWrapper) ->
|
||||
{
|
||||
// Use the server provided key if one was provided
|
||||
if (newLevelWrapper instanceof IServerKeyedClientLevel)
|
||||
if (newLevelWrapper instanceof IServerKeyedClientLevel keyedClientLevel)
|
||||
{
|
||||
IServerKeyedClientLevel keyedClientLevel = (IServerKeyedClientLevel) newLevelWrapper;
|
||||
LOGGER.info("Loading level " + newLevelWrapper.getDimensionType().getDimensionName() + " with key: " + keyedClientLevel.getServerLevelKey());
|
||||
// This world was identified by the server directly, so we can know for sure which folder to use.
|
||||
return new File(getSaveStructureFolderPath() + File.separatorChar + keyedClientLevel.getServerLevelKey());
|
||||
@@ -91,9 +94,8 @@ public class ClientOnlySaveStructure extends AbstractSaveStructure
|
||||
|
||||
|
||||
// use multiverse matching if enabled and in multiplayer (the server should already know where the player is)
|
||||
if (newLevelWrapper instanceof IClientLevelWrapper && Config.Client.Advanced.Multiplayer.multiverseSimilarityRequiredPercent.get() != 0)
|
||||
if (newLevelWrapper instanceof IClientLevelWrapper newClientLevelWrapper && Config.Client.Advanced.Multiplayer.multiverseSimilarityRequiredPercent.get() != 0)
|
||||
{
|
||||
IClientLevelWrapper newClientLevelWrapper = (IClientLevelWrapper) newLevelWrapper;
|
||||
|
||||
// create the matcher if one doesn't exist
|
||||
if (this.subDimMatcher == null || !this.subDimMatcher.isFindingLevel(newClientLevelWrapper))
|
||||
@@ -130,12 +132,12 @@ public class ClientOnlySaveStructure extends AbstractSaveStructure
|
||||
private File getLevelFolderWithoutSimilarityMatching(ILevelWrapper level)
|
||||
{
|
||||
List<File> folders = this.getDhDataFoldersForDimension(level.getDimensionType());
|
||||
if (!folders.isEmpty() && folders.get(0) != null)
|
||||
if (!folders.isEmpty() && folders.getFirst() != null)
|
||||
{
|
||||
// use the first existing sub-dimension
|
||||
String folderName = folders.get(0).getName();
|
||||
String folderName = folders.getFirst().getName();
|
||||
LOGGER.info("Default Sub Dimension set to: [" + LodUtil.shortenString(folderName, 8) + "...]");
|
||||
return folders.get(0);
|
||||
return folders.getFirst();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -237,7 +239,7 @@ public class ClientOnlySaveStructure extends AbstractSaveStructure
|
||||
private static String getSaveStructureFolderPath()
|
||||
{
|
||||
String path = MC_SHARED.getInstallationDirectory().getPath() + File.separatorChar
|
||||
+ "Distant_Horizons_server_data" + File.separatorChar
|
||||
+ SERVER_DATA_FOLDER_NAME + File.separatorChar
|
||||
+ getServerFolderName();
|
||||
return path;
|
||||
}
|
||||
@@ -245,6 +247,14 @@ public class ClientOnlySaveStructure extends AbstractSaveStructure
|
||||
/** Generated from the server the client is currently connected to. */
|
||||
private static String getServerFolderName()
|
||||
{
|
||||
// if connected to a replay we won't have any server info
|
||||
// use the dedicated replay server folder
|
||||
if (MC_CLIENT.connectedToReplay())
|
||||
{
|
||||
return REPLAY_SERVER_FOLDER_NAME;
|
||||
}
|
||||
|
||||
|
||||
// parse the current server's IP
|
||||
ParsedIp parsedIp = new ParsedIp(MC_CLIENT.getCurrentServerIp());
|
||||
String serverIpCleaned = parsedIp.ip.replaceAll(INVALID_FILE_CHARACTERS_REGEX, "");
|
||||
@@ -258,27 +268,14 @@ public class ClientOnlySaveStructure extends AbstractSaveStructure
|
||||
|
||||
|
||||
// generate the folder name
|
||||
String folderName;
|
||||
switch (folderNameMode)
|
||||
String folderName = switch (folderNameMode)
|
||||
{
|
||||
default:
|
||||
case NAME_ONLY:
|
||||
folderName = serverName;
|
||||
break;
|
||||
case IP_ONLY:
|
||||
folderName = serverIpCleaned;
|
||||
break;
|
||||
|
||||
case NAME_IP:
|
||||
folderName = serverName + ", IP " + serverIpCleaned;
|
||||
break;
|
||||
case NAME_IP_PORT:
|
||||
folderName = serverName + ", IP " + serverIpCleaned + (serverPortCleaned.length() != 0 ? ("-" + serverPortCleaned) : "");
|
||||
break;
|
||||
case NAME_IP_PORT_MC_VERSION:
|
||||
folderName = serverName + ", IP " + serverIpCleaned + (serverPortCleaned.length() != 0 ? ("-" + serverPortCleaned) : "") + ", GameVersion " + serverMcVersion;
|
||||
break;
|
||||
}
|
||||
default -> serverName;
|
||||
case IP_ONLY -> serverIpCleaned;
|
||||
case NAME_IP -> serverName + ", IP " + serverIpCleaned;
|
||||
case NAME_IP_PORT -> serverName + ", IP " + serverIpCleaned + (serverPortCleaned.length() != 0 ? ("-" + serverPortCleaned) : "");
|
||||
case NAME_IP_PORT_MC_VERSION -> serverName + ", IP " + serverIpCleaned + (serverPortCleaned.length() != 0 ? ("-" + serverPortCleaned) : "") + ", GameVersion " + serverMcVersion;
|
||||
};
|
||||
|
||||
// PercentEscaper makes the characters all part of the standard alphameric character set
|
||||
// This fixes some issues when the server is named something in other languages
|
||||
|
||||
+2
-2
@@ -190,7 +190,7 @@ public class SubDimensionLevelMatcher implements AutoCloseable
|
||||
}
|
||||
FullDataSourceV2 newChunkSizedFullDataView = FullDataSourceV2.createFromChunk(newlyLoadedChunk);
|
||||
// convert to a data source for easier comparing
|
||||
FullDataSourceV2 newDataSource = FullDataSourceV2.createEmpty(DhSectionPos.encode(this.playerData.playerBlockPos));
|
||||
FullDataSourceV2 newDataSource = FullDataSourceV2.createEmpty(DhSectionPos.encodeContaining(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, this.playerData.playerBlockPos));
|
||||
newDataSource.update(newChunkSizedFullDataView);
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ public class SubDimensionLevelMatcher implements AutoCloseable
|
||||
// get the data source to compare against
|
||||
try (IDhLevel tempLevel = new DhClientLevel(new ClientOnlySaveStructure(), this.currentClientLevel, testLevelFolder, false))
|
||||
{
|
||||
testFullDataSource = tempLevel.getFullDataProvider().getAsync(DhSectionPos.encode(this.playerData.playerBlockPos)).join();
|
||||
testFullDataSource = tempLevel.getFullDataProvider().getAsync(DhSectionPos.encodeContaining(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, this.playerData.playerBlockPos)).join();
|
||||
if (testFullDataSource == null)
|
||||
{
|
||||
continue;
|
||||
|
||||
@@ -109,23 +109,17 @@ public class BatchGenerator implements IDhApiWorldGenerator
|
||||
int chunkPosMinX, int chunkPosMinZ, byte granularity, byte targetDataDetail, EDhApiDistantGeneratorMode generatorMode,
|
||||
ExecutorService worldGeneratorThreadPool, Consumer<Object[]> resultConsumer)
|
||||
{
|
||||
EDhApiWorldGenerationStep targetStep = null;
|
||||
switch (generatorMode)
|
||||
EDhApiWorldGenerationStep targetStep = switch (generatorMode)
|
||||
{
|
||||
case PRE_EXISTING_ONLY: // Only load in existing chunks. Note: this requires the biome generation step in order for biomes to be properly initialized.
|
||||
case PRE_EXISTING_ONLY -> // Only load in existing chunks. Note: this requires the biome generation step in order for biomes to be properly initialized.
|
||||
//case BIOME_ONLY: // No blocks. Require fake height in LodBuilder
|
||||
targetStep = EDhApiWorldGenerationStep.BIOMES;
|
||||
break;
|
||||
EDhApiWorldGenerationStep.BIOMES;
|
||||
//case BIOME_ONLY_SIMULATE_HEIGHT:
|
||||
// targetStep = EDhApiWorldGenerationStep.NOISE; // Stone only. Requires a fake surface
|
||||
// break;
|
||||
case SURFACE:
|
||||
targetStep = EDhApiWorldGenerationStep.SURFACE;
|
||||
break;
|
||||
case FEATURES:
|
||||
targetStep = EDhApiWorldGenerationStep.FEATURES;
|
||||
break;
|
||||
}
|
||||
case SURFACE -> EDhApiWorldGenerationStep.SURFACE;
|
||||
case FEATURES -> EDhApiWorldGenerationStep.FEATURES;
|
||||
};
|
||||
|
||||
int genChunkSize = BitShiftUtil.powerOfTwo(granularity - 4); // minus 4 is equal to dividing by 16 to convert to chunk scale
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ public class DhLightingEngine
|
||||
* Since these objects are always mutated anyway, using a {@link ThreadLocal} will allow us to
|
||||
* only create as many of these {@link DhBlockPos} as necessary.
|
||||
*/
|
||||
private static final ThreadLocal<DhBlockPos> PRIMARY_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new DhBlockPos());
|
||||
private static final ThreadLocal<DhBlockPos> SECONDARY_BLOCK_POS_REF = ThreadLocal.withInitial(() -> new DhBlockPos());
|
||||
private static final ThreadLocal<DhBlockPos> PRIMARY_BLOCK_POS_REF = ThreadLocal.withInitial(DhBlockPos::new);
|
||||
private static final ThreadLocal<DhBlockPos> SECONDARY_BLOCK_POS_REF = ThreadLocal.withInitial(DhBlockPos::new);
|
||||
|
||||
|
||||
|
||||
|
||||
+14
-17
@@ -78,7 +78,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
// TODO this logic isn't great and can cause a limit to how many threads could be used for world generation,
|
||||
// however it won't cause duplicate requests or concurrency issues, so it will be good enough for now.
|
||||
// A good long term fix may be to either:
|
||||
// 1. allow the generator to deal with larger sections (let the generator threads split up larger tasks into smaller one
|
||||
// 1. allow the generator to deal with larger sections (let the generator threads split up larger tasks into smaller ones
|
||||
// 2. batch requests better. instead of sending 4 individual tasks of detail level N, send 1 task of detail level n+1
|
||||
private final ExecutorService queueingThread = ThreadUtil.makeSingleThreadPool("World Gen Queue");
|
||||
private boolean generationQueueRunning = false;
|
||||
@@ -226,6 +226,9 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("queueing exception: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.generationQueueRunning = false;
|
||||
}
|
||||
});
|
||||
@@ -373,7 +376,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
// don't log the shutdown exceptions
|
||||
if (!LodUtil.isInterruptOrReject(exception))
|
||||
{
|
||||
LOGGER.error("Error generating data for section " + taskPos, exception);
|
||||
LOGGER.error("Error generating data for pos: " + DhSectionPos.toString(taskPos), exception);
|
||||
}
|
||||
|
||||
newTaskGroup.group.worldGenTasks.forEach(worldGenTask -> worldGenTask.future.complete(WorldGenResult.CreateFail()));
|
||||
@@ -383,11 +386,11 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
newTaskGroup.group.worldGenTasks.forEach(worldGenTask -> worldGenTask.future.complete(WorldGenResult.CreateSuccess(DhSectionPos.encode(granularity, DhSectionPos.getX(taskPos), DhSectionPos.getZ(taskPos)))));
|
||||
}
|
||||
boolean worked = this.inProgressGenTasksByLodPos.remove(taskPos, newTaskGroup);
|
||||
LodUtil.assertTrue(worked);
|
||||
LodUtil.assertTrue(worked, "Unable to find in progress generator task with position ["+DhSectionPos.toString(taskPos)+"]");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Unexpected error completing world gen task: "+taskPos, e);
|
||||
LOGGER.error("Unexpected error completing world gen task at pos: ["+DhSectionPos.toString(taskPos)+"].", e);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -425,11 +428,9 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
{
|
||||
EDhApiDistantGeneratorMode generatorMode = Config.Client.Advanced.WorldGenerator.distantGeneratorMode.get();
|
||||
EDhApiWorldGeneratorReturnType returnType = this.generator.getReturnType();
|
||||
switch (returnType)
|
||||
return switch (returnType)
|
||||
{
|
||||
case VANILLA_CHUNKS:
|
||||
{
|
||||
return this.generator.generateChunks(
|
||||
case VANILLA_CHUNKS -> this.generator.generateChunks(
|
||||
chunkPosMin.x,
|
||||
chunkPosMin.z,
|
||||
granularity,
|
||||
@@ -452,10 +453,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
case API_CHUNKS:
|
||||
{
|
||||
return this.generator.generateApiChunks(
|
||||
case API_CHUNKS -> this.generator.generateApiChunks(
|
||||
chunkPosMin.x,
|
||||
chunkPosMin.z,
|
||||
granularity,
|
||||
@@ -481,13 +479,12 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
default:
|
||||
default ->
|
||||
{
|
||||
Config.Client.Advanced.WorldGenerator.enableDistantGeneration.set(false);
|
||||
throw new AssertFailureException("Unknown return type: " + returnType);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -613,8 +610,8 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
@Override
|
||||
public void debugRender(DebugRenderer renderer)
|
||||
{
|
||||
this.waitingTasks.keySet().forEach((pos) -> { renderer.renderBox(new DebugRenderer.Box(pos, -32f, 64f, 0.05f, Color.blue)); });
|
||||
this.inProgressGenTasksByLodPos.forEach((pos, t) -> { renderer.renderBox(new DebugRenderer.Box(pos, -32f, 64f, 0.05f, Color.red)); });
|
||||
this.waitingTasks.keySet().forEach((pos) -> renderer.renderBox(new DebugRenderer.Box(pos, -32f, 64f, 0.05f, Color.blue)));
|
||||
this.inProgressGenTasksByLodPos.forEach((pos, t) -> renderer.renderBox(new DebugRenderer.Box(pos, -32f, 64f, 0.05f, Color.red)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,20 +40,14 @@ public class DarkModeDetector
|
||||
|
||||
public static boolean isDarkMode()
|
||||
{
|
||||
switch (EPlatform.get())
|
||||
return switch (EPlatform.get())
|
||||
{
|
||||
case WINDOWS:
|
||||
return isWindowsDarkMode();
|
||||
case MACOS:
|
||||
return isMacOsDarkMode();
|
||||
case LINUX:
|
||||
case WINDOWS -> isWindowsDarkMode();
|
||||
case MACOS -> isMacOsDarkMode();
|
||||
// Most Unix(-like) distros also use a lot of the same things as Linux (like desktop environments and window managers)
|
||||
case BSD:
|
||||
case UNIX:
|
||||
return checkLinuxDark();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case LINUX, BSD, UNIX -> checkLinuxDark();
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
// Needs checking as I dont use Mac
|
||||
|
||||
@@ -131,7 +131,7 @@ public class JarMain
|
||||
|
||||
|
||||
// Selected download
|
||||
AtomicReference<String> downloadID = new AtomicReference<String>("");
|
||||
AtomicReference<String> downloadID = new AtomicReference<>("");
|
||||
|
||||
|
||||
// This is for the panel to show the update description
|
||||
|
||||
@@ -175,17 +175,12 @@ public class JarUtils
|
||||
@Deprecated
|
||||
public static OperatingSystem getOperatingSystem()
|
||||
{ // Get the os and turn it into that enum
|
||||
switch (EPlatform.get())
|
||||
{
|
||||
case WINDOWS:
|
||||
return OperatingSystem.WINDOWS;
|
||||
case LINUX:
|
||||
return OperatingSystem.LINUX;
|
||||
case MACOS:
|
||||
return OperatingSystem.MACOS;
|
||||
default:
|
||||
return OperatingSystem.NONE;
|
||||
}
|
||||
return switch (EPlatform.get()) {
|
||||
case WINDOWS -> OperatingSystem.WINDOWS;
|
||||
case LINUX -> OperatingSystem.LINUX;
|
||||
case MACOS -> OperatingSystem.MACOS;
|
||||
default -> OperatingSystem.NONE;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public class BaseJFrame extends JFrame
|
||||
final BufferedReader br = new BufferedReader(isr)
|
||||
)
|
||||
{
|
||||
List<Object> col = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(br.lines().toArray())));
|
||||
List<Object> col = List.of(br.lines().toArray());
|
||||
for (Object obj : col)
|
||||
{
|
||||
langsToChoose.add(((String) obj).replaceAll("\\.json", ""));
|
||||
@@ -101,7 +101,7 @@ public class BaseJFrame extends JFrame
|
||||
}
|
||||
|
||||
// Creates the box
|
||||
JComboBox<String> languageBox = new JComboBox(new DefaultComboBoxModel(langsToChoose.toArray()));
|
||||
JComboBox<String> languageBox = new JComboBox<>(new DefaultComboBoxModel(langsToChoose.toArray()));
|
||||
languageBox.setSelectedIndex(langsToChoose.indexOf(Locale.getDefault().toString().toLowerCase()));
|
||||
languageBox.addActionListener(e -> {
|
||||
Locale.setDefault(Locale.forLanguageTag(languageBox.getSelectedItem().toString())); // Change lang on update
|
||||
|
||||
@@ -133,7 +133,7 @@ public class GitlabGetter
|
||||
public static void main(String[] args) {
|
||||
GitlabGetter gitlabGetter = new GitlabGetter();
|
||||
|
||||
System.out.println(gitlabGetter.getDownloads(gitlabGetter.projectPipelines.get(0).get("id")));
|
||||
System.out.println(gitlabGetter.getDownloads(gitlabGetter.projectPipelines.getFirst().get("id")));
|
||||
}
|
||||
|
||||
|
||||
|
||||
+7
-7
@@ -72,8 +72,8 @@ public class ModrinthGetter
|
||||
downloadUrl.put(workingID,
|
||||
new URL(
|
||||
((Config)
|
||||
((ArrayList) currentRelease.get("files"))
|
||||
.get(0))
|
||||
((ArrayList<?>) currentRelease.get("files"))
|
||||
.getFirst())
|
||||
.get("url")
|
||||
.toString()
|
||||
));
|
||||
@@ -112,7 +112,7 @@ public class ModrinthGetter
|
||||
{
|
||||
try
|
||||
{
|
||||
return mcVerToReleaseID.get(mcVer).get(0);
|
||||
return mcVerToReleaseID.get(mcVer).getFirst();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -121,17 +121,17 @@ public class ModrinthGetter
|
||||
}
|
||||
public static String getLatestNameForVersion(String mcVer)
|
||||
{
|
||||
return releaseNames.get(mcVerToReleaseID.get(mcVer).get(0));
|
||||
return releaseNames.get(mcVerToReleaseID.get(mcVer).getFirst());
|
||||
}
|
||||
public static URL getLatestDownloadForVersion(String mcVer)
|
||||
{
|
||||
return downloadUrl.get(mcVerToReleaseID.get(mcVer).get(0));
|
||||
return downloadUrl.get(mcVerToReleaseID.get(mcVer).getFirst());
|
||||
}
|
||||
public static String getLatestShaForVersion(String mcVer)
|
||||
{
|
||||
return (((ArrayList<Config>) idToJson.get(
|
||||
mcVerToReleaseID.get(mcVer).get(0)
|
||||
).get("files")).get(0).get("hashes.sha1")
|
||||
mcVerToReleaseID.get(mcVer).getFirst()
|
||||
).get("files")).getFirst().get("hashes.sha1")
|
||||
.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ public class SelfUpdater
|
||||
{
|
||||
if (GitlabGetter.INSTANCE.projectPipelines.size() == 0)
|
||||
return false;
|
||||
com.electronwill.nightconfig.core.Config pipeline = GitlabGetter.INSTANCE.projectPipelines.get(0);
|
||||
com.electronwill.nightconfig.core.Config pipeline = GitlabGetter.INSTANCE.projectPipelines.getFirst();
|
||||
|
||||
if (!pipeline.get("ref").equals(ModJarInfo.Git_Branch))
|
||||
{
|
||||
@@ -186,16 +186,13 @@ public class SelfUpdater
|
||||
}
|
||||
public static boolean updateMod(String minecraftVersion, File file)
|
||||
{
|
||||
boolean returnValue = false;
|
||||
switch (Config.Client.Advanced.AutoUpdater.updateBranch.get())
|
||||
boolean returnValue = switch (Config.Client.Advanced.AutoUpdater.updateBranch.get())
|
||||
{
|
||||
case STABLE:
|
||||
returnValue = updateStableMod(minecraftVersion, file);
|
||||
break;
|
||||
case NIGHTLY:
|
||||
returnValue = updateNightlyMod(minecraftVersion, file);
|
||||
break;
|
||||
case STABLE -> updateStableMod(minecraftVersion, file);
|
||||
case NIGHTLY -> updateNightlyMod(minecraftVersion, file);
|
||||
default -> false;
|
||||
};
|
||||
;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@@ -253,7 +250,7 @@ public class SelfUpdater
|
||||
|
||||
File mergedZip = file.getParentFile().toPath().resolve("merged.zip").toFile();
|
||||
|
||||
WebDownloader.downloadAsFile(GitlabGetter.INSTANCE.getDownloads(GitlabGetter.INSTANCE.projectPipelines.get(0).get("id")).get(minecraftVersion), mergedZip);
|
||||
WebDownloader.downloadAsFile(GitlabGetter.INSTANCE.getDownloads(GitlabGetter.INSTANCE.projectPipelines.getFirst().get("id")).get(minecraftVersion), mergedZip);
|
||||
|
||||
ZipInputStream zis = new ZipInputStream(new FileInputStream(mergedZip));
|
||||
ZipEntry zipEntry = zis.getNextEntry();
|
||||
@@ -301,7 +298,7 @@ public class SelfUpdater
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Failed to update " + ModInfo.READABLE_NAME + " to version " + GitlabGetter.INSTANCE.projectPipelines.get(0).get("sha"));
|
||||
LOGGER.warn("Failed to update " + ModInfo.READABLE_NAME + " to version " + GitlabGetter.INSTANCE.projectPipelines.getFirst().get("sha"));
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class ConfigBasedLogger
|
||||
|
||||
|
||||
public static final List<WeakReference<ConfigBasedLogger>> loggers
|
||||
= Collections.synchronizedList(new LinkedList<WeakReference<ConfigBasedLogger>>());
|
||||
= Collections.synchronizedList(new LinkedList<>());
|
||||
|
||||
public static synchronized void updateAll()
|
||||
{
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public class ConfigBasedSpamLogger
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
|
||||
public static final List<WeakReference<ConfigBasedSpamLogger>> loggers
|
||||
= Collections.synchronizedList(new LinkedList<WeakReference<ConfigBasedSpamLogger>>());
|
||||
= Collections.synchronizedList(new LinkedList<>());
|
||||
|
||||
public static synchronized void updateAll(boolean flush)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ public class SpamReducedLogger
|
||||
private static final Logger LOGGER = LogManager.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
|
||||
|
||||
public static final List<WeakReference<SpamReducedLogger>> loggers
|
||||
= Collections.synchronizedList(new LinkedList<WeakReference<SpamReducedLogger>>());
|
||||
= Collections.synchronizedList(new LinkedList<>());
|
||||
|
||||
public static synchronized void flushAll()
|
||||
{
|
||||
@@ -53,7 +53,7 @@ public class SpamReducedLogger
|
||||
public SpamReducedLogger(int maxLogPerSec)
|
||||
{
|
||||
maxLogCount = maxLogPerSec;
|
||||
loggers.add(new WeakReference<SpamReducedLogger>(this));
|
||||
loggers.add(new WeakReference<>(this));
|
||||
}
|
||||
|
||||
public void reset()
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
package com.seibel.distanthorizons.core.logging.f3;
|
||||
|
||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.SharedVbo;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.render.RenderBufferHandler;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
|
||||
@@ -112,11 +111,6 @@ public class F3Screen
|
||||
messageList.add(genericRenderer.getVboRenderDebugMenuString());
|
||||
}
|
||||
}
|
||||
messageList.add("");
|
||||
// GPU memory
|
||||
messageList.add("GPU Opaque " + SharedVbo.OPAQUE.getDebugMenuString());
|
||||
messageList.add("GPU Transp " + SharedVbo.TRANSPARENT.getDebugMenuString());
|
||||
messageList.add("");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -85,9 +85,8 @@ public class DhBlockPos2D
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj instanceof DhBlockPos2D)
|
||||
if (obj instanceof DhBlockPos2D other)
|
||||
{
|
||||
DhBlockPos2D other = (DhBlockPos2D) obj;
|
||||
return this.x == other.x && this.z == other.z;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.pos;
|
||||
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
|
||||
@@ -101,21 +102,32 @@ public class DhSectionPos
|
||||
return data;
|
||||
}
|
||||
|
||||
public static long encode(DhBlockPos pos) { return encodeBlockPos(pos.x, pos.z); }
|
||||
public static long encode(DhBlockPos2D pos) { return encodeBlockPos(pos.x, pos.z); }
|
||||
public static long encodeBlockPos(int blockX, int blockZ)
|
||||
/** Returns the section pos at the requested detail level containing the given BlockPos */
|
||||
public static long encodeContaining(byte outputSectionDetailLevel, DhBlockPos pos)
|
||||
{
|
||||
long pos = encode(LodUtil.BLOCK_DETAIL_LEVEL, blockX, blockZ);
|
||||
pos = convertToDetailLevel(pos, DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
|
||||
return pos;
|
||||
int sectionPosX = getXOrZSectionPosFromChunkOrBlockPos(pos.x, false);
|
||||
int sectionPosZ = getXOrZSectionPosFromChunkOrBlockPos(pos.z, false);
|
||||
long blockPos = DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, sectionPosX, sectionPosZ);
|
||||
return convertToDetailLevel(blockPos, outputSectionDetailLevel);
|
||||
}
|
||||
|
||||
public static long encode(DhChunkPos pos) { return encodeChunkPos(pos.x, pos.z); }
|
||||
public static long encodeChunkPos(int chunkX, int chunkZ)
|
||||
/** Returns the section pos at the requested detail level containing the given ChunkPos */
|
||||
public static long encodeContaining(byte outputSectionDetailLevel, DhChunkPos pos)
|
||||
{
|
||||
long pos = encode(LodUtil.CHUNK_DETAIL_LEVEL, chunkX, chunkZ);
|
||||
pos = convertToDetailLevel(pos, DhSectionPos.SECTION_CHUNK_DETAIL_LEVEL);
|
||||
return pos;
|
||||
int sectionPosX = getXOrZSectionPosFromChunkOrBlockPos(pos.x, true);
|
||||
int sectionPosZ = getXOrZSectionPosFromChunkOrBlockPos(pos.z, true);
|
||||
long blockPos = DhSectionPos.encode(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, sectionPosX, sectionPosZ);
|
||||
return convertToDetailLevel(blockPos, outputSectionDetailLevel);
|
||||
}
|
||||
private static int getXOrZSectionPosFromChunkOrBlockPos(int chunkXOrZPos, boolean isChunkPos)
|
||||
{
|
||||
int sectionPos = chunkXOrZPos;
|
||||
int fullDataSourceWidth = isChunkPos ? FullDataSourceV2.NUMB_OF_CHUNKS_WIDE : (FullDataSourceV2.NUMB_OF_CHUNKS_WIDE * LodUtil.CHUNK_WIDTH);
|
||||
|
||||
// negative positions start at -1 so the logic there is slightly different
|
||||
sectionPos = (sectionPos < 0)
|
||||
? ((sectionPos + 1) / fullDataSourceWidth) - 1
|
||||
: (sectionPos / fullDataSourceWidth);
|
||||
return sectionPos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -80,9 +80,8 @@ public class Pos2D
|
||||
{
|
||||
if (otherObj == this)
|
||||
return true;
|
||||
if (otherObj instanceof Pos2D)
|
||||
if (otherObj instanceof Pos2D otherPos)
|
||||
{
|
||||
Pos2D otherPos = (Pos2D) otherObj;
|
||||
return this.x == otherPos.x && this.y == otherPos.y;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.seibel.distanthorizons.core.pos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
|
||||
import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.quadTree.QuadNode;
|
||||
@@ -646,7 +647,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
||||
}
|
||||
else if (renderSection.renderBuffer.hasNonNullVbos())
|
||||
{
|
||||
if (renderSection.renderBuffer.bufferSliceCount() != 0)
|
||||
if (renderSection.renderBuffer.vboBufferCount() != 0)
|
||||
{
|
||||
color = Color.GREEN;
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Unable to get render source " + this.pos + ", error: " + e.getMessage(), e);
|
||||
LOGGER.warn("Unable to get render source " + DhSectionPos.toString(this.pos) + ", error: " + e.getMessage(), e);
|
||||
this.renderSourceLoadingRefFuture = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
+10
-13
@@ -25,13 +25,11 @@ import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadow
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.ColumnRenderBuffer;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.SharedVbo;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhLodPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.Pos2D;
|
||||
@@ -50,7 +48,9 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.ListIterator;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
@@ -348,11 +348,7 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
// TODO why can these sometimes be null when teleporting between multiverses
|
||||
if (this.loadedNearToFarBuffers != null)
|
||||
{
|
||||
renderContext.setModelViewMatrixOffset(DhBlockPos.ZERO, renderEventParam);
|
||||
|
||||
ArrayList<SharedVbo.BufferSlice> sliceList = new ArrayList<>();
|
||||
this.loadedNearToFarBuffers.forEach(loadedBuffer -> sliceList.addAll(Arrays.asList(loadedBuffer.buffer.opaqueBufferSlices)));
|
||||
renderContext.drawSharedVbo(SharedVbo.OPAQUE, sliceList.toArray(new SharedVbo.BufferSlice[0]));
|
||||
this.loadedNearToFarBuffers.forEach(loadedBuffer -> loadedBuffer.buffer.renderOpaque(renderContext, renderEventParam));
|
||||
}
|
||||
}
|
||||
public void renderTransparent(LodRenderer renderContext, DhApiRenderParam renderEventParam)
|
||||
@@ -360,11 +356,12 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
// TODO why can these sometimes be null when teleporting between multiverses
|
||||
if (this.loadedNearToFarBuffers != null)
|
||||
{
|
||||
renderContext.setModelViewMatrixOffset(DhBlockPos.ZERO, renderEventParam);
|
||||
|
||||
ArrayList<SharedVbo.BufferSlice> sliceList = new ArrayList<>();
|
||||
this.loadedNearToFarBuffers.forEach(loadedBuffer -> sliceList.addAll(Arrays.asList(loadedBuffer.buffer.transparentBufferSlices)));
|
||||
renderContext.drawSharedVbo(SharedVbo.TRANSPARENT, sliceList.toArray(new SharedVbo.BufferSlice[0]));
|
||||
ListIterator<LoadedRenderBuffer> iter = this.loadedNearToFarBuffers.listIterator(this.loadedNearToFarBuffers.size());
|
||||
while (iter.hasPrevious())
|
||||
{
|
||||
LoadedRenderBuffer loadedBuffer = iter.previous();
|
||||
loadedBuffer.buffer.renderTransparent(renderContext, renderEventParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,15 +179,19 @@ public class LodFogConfig
|
||||
|
||||
if (farFogSetting == null)
|
||||
{
|
||||
str.append("\n" +
|
||||
"float getFarFogThickness(float dist) { return 0.0; } \n" +
|
||||
"float getHeightFogThickness(float dist) { return 0.0; } \n" +
|
||||
"float calculateFarFogDepth(float horizontal, float dist, float uNearFogStart) { return 0.0; } \n" +
|
||||
"float calculateHeightFogDepth(float vertical, float realY) { return 0.0; } \n" +
|
||||
"float mixFogThickness(float near, float far, float height) \n" +
|
||||
"{ \n" +
|
||||
" return 0.0; \n" +
|
||||
"} \n\n");
|
||||
str.append("""
|
||||
|
||||
float getFarFogThickness(float dist) { return 0.0; }
|
||||
float getHeightFogThickness(float dist) { return 0.0; }
|
||||
float calculateFarFogDepth(float horizontal, float dist, float uNearFogStart) { return 0.0; }
|
||||
float calculateHeightFogDepth(float vertical, float realY) { return 0.0; }
|
||||
float mixFogThickness(float near, float far, float height)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
""");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -269,18 +273,13 @@ public class LodFogConfig
|
||||
|
||||
private static String getFarFogMethod(EDhApiFogFalloff fogType)
|
||||
{
|
||||
switch (fogType)
|
||||
return switch (fogType)
|
||||
{
|
||||
case LINEAR:
|
||||
return "return linearFog(dist, farFogStart, farFogLength, farFogMin, farFogRange);\n";
|
||||
case EXPONENTIAL:
|
||||
return "return exponentialFog(dist, farFogStart, farFogLength, farFogMin, farFogRange, farFogDensity);\n";
|
||||
case EXPONENTIAL_SQUARED:
|
||||
return "return exponentialSquaredFog(dist, farFogStart, farFogLength, farFogMin, farFogRange, farFogDensity);\n";
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("FogType [" + fogType + "] not implemented for [getFarFogMethod].");
|
||||
}
|
||||
case LINEAR -> "return linearFog(dist, farFogStart, farFogLength, farFogMin, farFogRange);\n";
|
||||
case EXPONENTIAL -> "return exponentialFog(dist, farFogStart, farFogLength, farFogMin, farFogRange, farFogDensity);\n";
|
||||
case EXPONENTIAL_SQUARED -> "return exponentialSquaredFog(dist, farFogStart, farFogLength, farFogMin, farFogRange, farFogDensity);\n";
|
||||
default -> throw new IllegalArgumentException("FogType [" + fogType + "] not implemented for [getFarFogMethod].");
|
||||
};
|
||||
}
|
||||
|
||||
private static String getHeightDepthMethod(EDhApiHeightFogMode heightMode, float heightFogHeight)
|
||||
@@ -317,18 +316,13 @@ public class LodFogConfig
|
||||
*/
|
||||
private static String getHeightFogMethod(EDhApiFogFalloff fogType)
|
||||
{
|
||||
switch (fogType)
|
||||
return switch (fogType)
|
||||
{
|
||||
case LINEAR:
|
||||
return " return linearFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange);\n";
|
||||
case EXPONENTIAL:
|
||||
return " return exponentialFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange, heightFogDensity);\n";
|
||||
case EXPONENTIAL_SQUARED:
|
||||
return " return exponentialSquaredFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange, heightFogDensity);\n";
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("FogType [" + fogType + "] not implemented for [getHeightFogMethod].");
|
||||
}
|
||||
case LINEAR -> " return linearFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange);\n";
|
||||
case EXPONENTIAL -> " return exponentialFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange, heightFogDensity);\n";
|
||||
case EXPONENTIAL_SQUARED -> " return exponentialSquaredFog(dist, heightFogStart, heightFogLength, heightFogMin, heightFogRange, heightFogDensity);\n";
|
||||
default -> throw new IllegalArgumentException("FogType [" + fogType + "] not implemented for [getHeightFogMethod].");
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,213 +27,109 @@ public class GLEnums
|
||||
|
||||
public static String getString(int glEnum)
|
||||
{
|
||||
// blend stuff
|
||||
switch (glEnum)
|
||||
return switch (glEnum)
|
||||
{
|
||||
case GL_ZERO:
|
||||
return "GL_ZERO";
|
||||
case GL_ONE:
|
||||
return "GL_ONE";
|
||||
case GL_SRC_COLOR:
|
||||
return "GL_SRC_COLOR";
|
||||
case GL_ONE_MINUS_SRC_COLOR:
|
||||
return "GL_ONE_MINUS_SRC_COLOR";
|
||||
case GL_DST_COLOR:
|
||||
return "GL_DST_COLOR";
|
||||
case GL_ONE_MINUS_DST_COLOR:
|
||||
return "GL_ONE_MINUS_DST_COLOR";
|
||||
case GL_SRC_ALPHA:
|
||||
return "GL_SRC_ALPHA";
|
||||
case GL_ONE_MINUS_SRC_ALPHA:
|
||||
return "GL_ONE_MINUS_SRC_ALPHA";
|
||||
case GL_DST_ALPHA:
|
||||
return "GL_DST_ALPHA";
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
return "GL_ONE_MINUS_DST_ALPHA";
|
||||
case GL_CONSTANT_COLOR:
|
||||
return "GL_CONSTANT_COLOR";
|
||||
case GL_ONE_MINUS_CONSTANT_COLOR:
|
||||
return "GL_ONE_MINUS_CONSTANT_COLOR";
|
||||
case GL_CONSTANT_ALPHA:
|
||||
return "GL_CONSTANT_ALPHA";
|
||||
case GL_ONE_MINUS_CONSTANT_ALPHA:
|
||||
return "GL_ONE_MINUS_CONSTANT_ALPHA";
|
||||
default:
|
||||
}
|
||||
// Zero
|
||||
case GL_ZERO -> "GL_ZERO";
|
||||
|
||||
// blend stuff
|
||||
case GL_ONE -> "GL_ONE";
|
||||
case GL_SRC_COLOR -> "GL_SRC_COLOR";
|
||||
case GL_ONE_MINUS_SRC_COLOR -> "GL_ONE_MINUS_SRC_COLOR";
|
||||
case GL_DST_COLOR -> "GL_DST_COLOR";
|
||||
case GL_ONE_MINUS_DST_COLOR -> "GL_ONE_MINUS_DST_COLOR";
|
||||
case GL_SRC_ALPHA -> "GL_SRC_ALPHA";
|
||||
case GL_ONE_MINUS_SRC_ALPHA -> "GL_ONE_MINUS_SRC_ALPHA";
|
||||
case GL_DST_ALPHA -> "GL_DST_ALPHA";
|
||||
case GL_ONE_MINUS_DST_ALPHA -> "GL_ONE_MINUS_DST_ALPHA";
|
||||
case GL_CONSTANT_COLOR -> "GL_CONSTANT_COLOR";
|
||||
case GL_ONE_MINUS_CONSTANT_COLOR -> "GL_ONE_MINUS_CONSTANT_COLOR";
|
||||
case GL_CONSTANT_ALPHA -> "GL_CONSTANT_ALPHA";
|
||||
case GL_ONE_MINUS_CONSTANT_ALPHA -> "GL_ONE_MINUS_CONSTANT_ALPHA";
|
||||
|
||||
// shader stuff
|
||||
switch (glEnum)
|
||||
{
|
||||
case GL_VERTEX_SHADER:
|
||||
return "GL_VERTEX_SHADER";
|
||||
case GL_GEOMETRY_SHADER:
|
||||
return "GL_GEOMETRY_SHADER";
|
||||
case GL_FRAGMENT_SHADER:
|
||||
return "GL_FRAGMENT_SHADER";
|
||||
default:
|
||||
}
|
||||
case GL_VERTEX_SHADER -> "GL_VERTEX_SHADER";
|
||||
case GL_GEOMETRY_SHADER -> "GL_GEOMETRY_SHADER";
|
||||
case GL_FRAGMENT_SHADER -> "GL_FRAGMENT_SHADER";
|
||||
|
||||
// stencil stuff
|
||||
switch (glEnum)
|
||||
{
|
||||
case GL_KEEP:
|
||||
return "GL_KEEP";
|
||||
case GL_ZERO:
|
||||
return "GL_ZERO";
|
||||
case GL_REPLACE:
|
||||
return "GL_REPLACE";
|
||||
case GL_INCR:
|
||||
return "GL_INCR";
|
||||
case GL_DECR:
|
||||
return "GL_DECR";
|
||||
case GL_INVERT:
|
||||
return "GL_INVERT";
|
||||
case GL_INCR_WRAP:
|
||||
return "GL_INCR_WRAP";
|
||||
case GL_DECR_WRAP:
|
||||
return "GL_DECR_WRAP";
|
||||
default:
|
||||
}
|
||||
case GL_KEEP -> "GL_KEEP";
|
||||
case GL_REPLACE -> "GL_REPLACE";
|
||||
case GL_INCR -> "GL_INCR";
|
||||
case GL_DECR -> "GL_DECR";
|
||||
case GL_INVERT -> "GL_INVERT";
|
||||
case GL_INCR_WRAP -> "GL_INCR_WRAP";
|
||||
case GL_DECR_WRAP -> "GL_DECR_WRAP";
|
||||
|
||||
// depth stuff
|
||||
switch (glEnum)
|
||||
{
|
||||
case GL_NEVER:
|
||||
return "GL_NEVER";
|
||||
case GL_LESS:
|
||||
return "GL_LESS";
|
||||
case GL_EQUAL:
|
||||
return "GL_EQUAL";
|
||||
case GL_LEQUAL:
|
||||
return "GL_LEQUAL";
|
||||
case GL_GREATER:
|
||||
return "GL_GREATER";
|
||||
case GL_NOTEQUAL:
|
||||
return "GL_NOTEQUAL";
|
||||
case GL_GEQUAL:
|
||||
return "GL_GEQUAL";
|
||||
case GL_ALWAYS:
|
||||
return "GL_ALWAYS";
|
||||
default:
|
||||
}
|
||||
case GL_NEVER -> "GL_NEVER";
|
||||
case GL_LESS -> "GL_LESS";
|
||||
case GL_EQUAL -> "GL_EQUAL";
|
||||
case GL_LEQUAL -> "GL_LEQUAL";
|
||||
case GL_GREATER -> "GL_GREATER";
|
||||
case GL_NOTEQUAL -> "GL_NOTEQUAL";
|
||||
case GL_GEQUAL -> "GL_GEQUAL";
|
||||
case GL_ALWAYS -> "GL_ALWAYS";
|
||||
|
||||
// Texture binding points
|
||||
switch (glEnum)
|
||||
{
|
||||
case GL_TEXTURE0:
|
||||
return "GL_TEXTURE0";
|
||||
case GL_TEXTURE1:
|
||||
return "GL_TEXTURE1";
|
||||
case GL_TEXTURE2:
|
||||
return "GL_TEXTURE2";
|
||||
case GL_TEXTURE3:
|
||||
return "GL_TEXTURE3";
|
||||
case GL_TEXTURE4:
|
||||
return "GL_TEXTURE4";
|
||||
case GL_TEXTURE5:
|
||||
return "GL_TEXTURE5";
|
||||
case GL_TEXTURE6:
|
||||
return "GL_TEXTURE6";
|
||||
case GL_TEXTURE7:
|
||||
return "GL_TEXTURE7";
|
||||
case GL_TEXTURE8:
|
||||
return "GL_TEXTURE8";
|
||||
case GL_TEXTURE9:
|
||||
return "GL_TEXTURE9";
|
||||
case GL_TEXTURE10:
|
||||
return "GL_TEXTURE10";
|
||||
case GL_TEXTURE11:
|
||||
return "GL_TEXTURE11";
|
||||
case GL_TEXTURE12:
|
||||
return "GL_TEXTURE12";
|
||||
case GL_TEXTURE13:
|
||||
return "GL_TEXTURE13";
|
||||
case GL_TEXTURE14:
|
||||
return "GL_TEXTURE14";
|
||||
case GL_TEXTURE15:
|
||||
return "GL_TEXTURE15";
|
||||
case GL_TEXTURE16:
|
||||
return "GL_TEXTURE16";
|
||||
case GL_TEXTURE17:
|
||||
return "GL_TEXTURE17";
|
||||
case GL_TEXTURE18:
|
||||
return "GL_TEXTURE18";
|
||||
case GL_TEXTURE19:
|
||||
return "GL_TEXTURE19";
|
||||
case GL_TEXTURE20:
|
||||
return "GL_TEXTURE20";
|
||||
case GL_TEXTURE21:
|
||||
return "GL_TEXTURE21";
|
||||
case GL_TEXTURE22:
|
||||
return "GL_TEXTURE22";
|
||||
case GL_TEXTURE23:
|
||||
return "GL_TEXTURE23";
|
||||
case GL_TEXTURE24:
|
||||
return "GL_TEXTURE24";
|
||||
case GL_TEXTURE25:
|
||||
return "GL_TEXTURE25";
|
||||
case GL_TEXTURE26:
|
||||
return "GL_TEXTURE26";
|
||||
case GL_TEXTURE27:
|
||||
return "GL_TEXTURE27";
|
||||
case GL_TEXTURE28:
|
||||
return "GL_TEXTURE28";
|
||||
case GL_TEXTURE29:
|
||||
return "GL_TEXTURE29";
|
||||
case GL_TEXTURE30:
|
||||
return "GL_TEXTURE30";
|
||||
case GL_TEXTURE31:
|
||||
return "GL_TEXTURE31";
|
||||
default:
|
||||
}
|
||||
case GL_TEXTURE0 -> "GL_TEXTURE0";
|
||||
case GL_TEXTURE1 -> "GL_TEXTURE1";
|
||||
case GL_TEXTURE2 -> "GL_TEXTURE2";
|
||||
case GL_TEXTURE3 -> "GL_TEXTURE3";
|
||||
case GL_TEXTURE4 -> "GL_TEXTURE4";
|
||||
case GL_TEXTURE5 -> "GL_TEXTURE5";
|
||||
case GL_TEXTURE6 -> "GL_TEXTURE6";
|
||||
case GL_TEXTURE7 -> "GL_TEXTURE7";
|
||||
case GL_TEXTURE8 -> "GL_TEXTURE8";
|
||||
case GL_TEXTURE9 -> "GL_TEXTURE9";
|
||||
case GL_TEXTURE10 -> "GL_TEXTURE10";
|
||||
case GL_TEXTURE11 -> "GL_TEXTURE11";
|
||||
case GL_TEXTURE12 -> "GL_TEXTURE12";
|
||||
case GL_TEXTURE13 -> "GL_TEXTURE13";
|
||||
case GL_TEXTURE14 -> "GL_TEXTURE14";
|
||||
case GL_TEXTURE15 -> "GL_TEXTURE15";
|
||||
case GL_TEXTURE16 -> "GL_TEXTURE16";
|
||||
case GL_TEXTURE17 -> "GL_TEXTURE17";
|
||||
case GL_TEXTURE18 -> "GL_TEXTURE18";
|
||||
case GL_TEXTURE19 -> "GL_TEXTURE19";
|
||||
case GL_TEXTURE20 -> "GL_TEXTURE20";
|
||||
case GL_TEXTURE21 -> "GL_TEXTURE21";
|
||||
case GL_TEXTURE22 -> "GL_TEXTURE22";
|
||||
case GL_TEXTURE23 -> "GL_TEXTURE23";
|
||||
case GL_TEXTURE24 -> "GL_TEXTURE24";
|
||||
case GL_TEXTURE25 -> "GL_TEXTURE25";
|
||||
case GL_TEXTURE26 -> "GL_TEXTURE26";
|
||||
case GL_TEXTURE27 -> "GL_TEXTURE27";
|
||||
case GL_TEXTURE28 -> "GL_TEXTURE28";
|
||||
case GL_TEXTURE29 -> "GL_TEXTURE29";
|
||||
case GL_TEXTURE30 -> "GL_TEXTURE30";
|
||||
case GL_TEXTURE31 -> "GL_TEXTURE31";
|
||||
|
||||
|
||||
// Polygon modes
|
||||
switch (glEnum)
|
||||
{
|
||||
case GL_POINT:
|
||||
return "GL_POINT";
|
||||
case GL_LINE:
|
||||
return "GL_LINE";
|
||||
case GL_FILL:
|
||||
return "GL_FILL";
|
||||
default:
|
||||
}
|
||||
case GL_POINT -> "GL_POINT";
|
||||
case GL_LINE -> "GL_LINE";
|
||||
case GL_FILL -> "GL_FILL";
|
||||
|
||||
// Culling modes
|
||||
switch (glEnum)
|
||||
{
|
||||
case GL_FRONT:
|
||||
return "GL_FRONT";
|
||||
case GL_BACK:
|
||||
return "GL_BACK";
|
||||
case GL_FRONT_AND_BACK:
|
||||
return "GL_FRONT_AND_BACK";
|
||||
default:
|
||||
}
|
||||
|
||||
return "GL_UNKNOWN(" + glEnum + ")";
|
||||
case GL_FRONT -> "GL_FRONT";
|
||||
case GL_BACK -> "GL_BACK";
|
||||
case GL_FRONT_AND_BACK -> "GL_FRONT_AND_BACK";
|
||||
default -> "GL_UNKNOWN(" + glEnum + ")";
|
||||
};
|
||||
}
|
||||
|
||||
public static int getTypeSize(int glTypeEnum)
|
||||
{
|
||||
switch (glTypeEnum)
|
||||
return switch (glTypeEnum)
|
||||
{
|
||||
case GL_BYTE:
|
||||
case GL_UNSIGNED_BYTE:
|
||||
return 1;
|
||||
case GL_SHORT:
|
||||
case GL_UNSIGNED_SHORT:
|
||||
return 2;
|
||||
case GL_INT:
|
||||
case GL_UNSIGNED_INT:
|
||||
return 4;
|
||||
case GL_FLOAT:
|
||||
return 4;
|
||||
case GL_DOUBLE:
|
||||
return 8;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown type enum: " + getString(glTypeEnum));
|
||||
}
|
||||
case GL_BYTE, GL_UNSIGNED_BYTE -> 1;
|
||||
case GL_SHORT, GL_UNSIGNED_SHORT -> 2;
|
||||
case GL_INT, GL_UNSIGNED_INT -> 4;
|
||||
case GL_FLOAT -> 4;
|
||||
case GL_DOUBLE -> 8;
|
||||
default -> throw new IllegalArgumentException("Unknown type enum: " + getString(glTypeEnum));
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -70,7 +70,7 @@ public class GLBuffer implements AutoCloseable
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
static { CLEANUP_THREAD.execute(() -> runPhantomReferenceCleanupLoop()); }
|
||||
static { CLEANUP_THREAD.execute(GLBuffer::runPhantomReferenceCleanupLoop); }
|
||||
|
||||
public GLBuffer(boolean isBufferStorage) { this.create(isBufferStorage); }
|
||||
|
||||
|
||||
+31
-61
@@ -4,6 +4,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL30C;
|
||||
import org.lwjgl.opengl.GL43C;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public enum EDhDepthBufferFormat
|
||||
{
|
||||
DEPTH(false),
|
||||
@@ -26,87 +28,55 @@ public enum EDhDepthBufferFormat
|
||||
@Nullable
|
||||
public static EDhDepthBufferFormat fromGlEnum(int glenum)
|
||||
{
|
||||
switch (glenum)
|
||||
return switch (glenum)
|
||||
{
|
||||
case GL30C.GL_DEPTH_COMPONENT:
|
||||
return EDhDepthBufferFormat.DEPTH;
|
||||
case GL30C.GL_DEPTH_COMPONENT16:
|
||||
return EDhDepthBufferFormat.DEPTH16;
|
||||
case GL30C.GL_DEPTH_COMPONENT24:
|
||||
return EDhDepthBufferFormat.DEPTH24;
|
||||
case GL30C.GL_DEPTH_COMPONENT32:
|
||||
return EDhDepthBufferFormat.DEPTH32;
|
||||
case GL30C.GL_DEPTH_COMPONENT32F:
|
||||
return EDhDepthBufferFormat.DEPTH32F;
|
||||
case GL30C.GL_DEPTH_STENCIL:
|
||||
return EDhDepthBufferFormat.DEPTH_STENCIL;
|
||||
case GL30C.GL_DEPTH24_STENCIL8:
|
||||
return EDhDepthBufferFormat.DEPTH24_STENCIL8;
|
||||
case GL30C.GL_DEPTH32F_STENCIL8:
|
||||
return EDhDepthBufferFormat.DEPTH32F_STENCIL8;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
case GL30C.GL_DEPTH_COMPONENT -> EDhDepthBufferFormat.DEPTH;
|
||||
case GL30C.GL_DEPTH_COMPONENT16 -> EDhDepthBufferFormat.DEPTH16;
|
||||
case GL30C.GL_DEPTH_COMPONENT24 -> EDhDepthBufferFormat.DEPTH24;
|
||||
case GL30C.GL_DEPTH_COMPONENT32 -> EDhDepthBufferFormat.DEPTH32;
|
||||
case GL30C.GL_DEPTH_COMPONENT32F -> EDhDepthBufferFormat.DEPTH32F;
|
||||
case GL30C.GL_DEPTH_STENCIL -> EDhDepthBufferFormat.DEPTH_STENCIL;
|
||||
case GL30C.GL_DEPTH24_STENCIL8 -> EDhDepthBufferFormat.DEPTH24_STENCIL8;
|
||||
case GL30C.GL_DEPTH32F_STENCIL8 -> EDhDepthBufferFormat.DEPTH32F_STENCIL8;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
public static EDhDepthBufferFormat fromGlEnumOrDefault(int glenum)
|
||||
{
|
||||
EDhDepthBufferFormat format = fromGlEnum(glenum);
|
||||
if (format == null)
|
||||
{
|
||||
// yolo, just assume it's GL_DEPTH_COMPONENT
|
||||
return EDhDepthBufferFormat.DEPTH;
|
||||
}
|
||||
return format;
|
||||
return Objects.requireNonNullElse(format, EDhDepthBufferFormat.DEPTH);
|
||||
}
|
||||
|
||||
public int getGlInternalFormat()
|
||||
{
|
||||
switch (this)
|
||||
return switch (this)
|
||||
{
|
||||
case DEPTH:
|
||||
return GL30C.GL_DEPTH_COMPONENT;
|
||||
case DEPTH16:
|
||||
return GL30C.GL_DEPTH_COMPONENT16;
|
||||
case DEPTH24:
|
||||
return GL30C.GL_DEPTH_COMPONENT24;
|
||||
case DEPTH32:
|
||||
return GL30C.GL_DEPTH_COMPONENT32;
|
||||
case DEPTH32F:
|
||||
return GL30C.GL_DEPTH_COMPONENT32F;
|
||||
case DEPTH_STENCIL:
|
||||
return GL30C.GL_DEPTH_STENCIL;
|
||||
case DEPTH24_STENCIL8:
|
||||
return GL30C.GL_DEPTH24_STENCIL8;
|
||||
case DEPTH32F_STENCIL8:
|
||||
return GL30C.GL_DEPTH32F_STENCIL8;
|
||||
}
|
||||
case DEPTH -> GL30C.GL_DEPTH_COMPONENT;
|
||||
case DEPTH16 -> GL30C.GL_DEPTH_COMPONENT16;
|
||||
case DEPTH24 -> GL30C.GL_DEPTH_COMPONENT24;
|
||||
case DEPTH32 -> GL30C.GL_DEPTH_COMPONENT32;
|
||||
case DEPTH32F -> GL30C.GL_DEPTH_COMPONENT32F;
|
||||
case DEPTH_STENCIL -> GL30C.GL_DEPTH_STENCIL;
|
||||
case DEPTH24_STENCIL8 -> GL30C.GL_DEPTH24_STENCIL8;
|
||||
case DEPTH32F_STENCIL8 -> GL30C.GL_DEPTH32F_STENCIL8;
|
||||
};
|
||||
|
||||
throw new AssertionError("unreachable");
|
||||
}
|
||||
|
||||
public int getGlType() { return isCombinedStencil() ? GL30C.GL_DEPTH_STENCIL : GL30C.GL_DEPTH_COMPONENT; }
|
||||
|
||||
public int getGlFormat()
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case DEPTH:
|
||||
case DEPTH16:
|
||||
return GL43C.GL_UNSIGNED_SHORT;
|
||||
case DEPTH24:
|
||||
case DEPTH32:
|
||||
return GL43C.GL_UNSIGNED_INT;
|
||||
case DEPTH32F:
|
||||
return GL30C.GL_FLOAT;
|
||||
case DEPTH_STENCIL:
|
||||
case DEPTH24_STENCIL8:
|
||||
return GL30C.GL_UNSIGNED_INT_24_8;
|
||||
case DEPTH32F_STENCIL8:
|
||||
return GL30C.GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
|
||||
}
|
||||
return switch (this) {
|
||||
case DEPTH, DEPTH16 -> GL43C.GL_UNSIGNED_SHORT;
|
||||
case DEPTH24, DEPTH32 -> GL43C.GL_UNSIGNED_INT;
|
||||
case DEPTH32F -> GL30C.GL_FLOAT;
|
||||
case DEPTH_STENCIL, DEPTH24_STENCIL8 -> GL30C.GL_UNSIGNED_INT_24_8;
|
||||
case DEPTH32F_STENCIL8 -> GL30C.GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
|
||||
};
|
||||
|
||||
throw new AssertionError("unreachable");
|
||||
}
|
||||
|
||||
public boolean isCombinedStencil() { return combinedStencil; }
|
||||
|
||||
+16
-45
@@ -25,7 +25,6 @@ import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShader
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.SharedVbo;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.ColumnRenderBuffer;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
@@ -36,11 +35,11 @@ import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
||||
import com.seibel.distanthorizons.core.render.RenderBufferHandler;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.buffer.QuadElementBuffer;
|
||||
import com.seibel.distanthorizons.core.render.glObject.texture.*;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.shaders.*;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||
@@ -55,13 +54,10 @@ import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.IntBuffer;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@@ -305,11 +301,8 @@ public class LodRenderer
|
||||
// terrain
|
||||
profiler.popPush("LOD Opaque");
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam);
|
||||
|
||||
this.bufferHandler.renderOpaque(this, renderEventParam);
|
||||
|
||||
|
||||
|
||||
// custom objects with SSAO
|
||||
if (Config.Client.Advanced.Graphics.GenericRendering.enableRendering.get())
|
||||
{
|
||||
@@ -473,7 +466,6 @@ public class LodRenderer
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam);
|
||||
|
||||
this.bufferHandler.renderTransparent(this, renderEventParam);
|
||||
GL32.glDepthMask(true); // Apparently the depth mask state is stored in the FBO, so glState fails to restore it...
|
||||
|
||||
@@ -493,18 +485,17 @@ public class LodRenderer
|
||||
shaderProgram = shaderProgramOverride;
|
||||
}
|
||||
|
||||
if (!GL32.glIsProgram(shaderProgram.getId()))
|
||||
{
|
||||
throw new IllegalStateException("No GL program exists with the ID: [" + shaderProgram.getId() + "]. This either means a shader program was freed while it was still in use or was never created.");
|
||||
}
|
||||
|
||||
shaderProgram.bind();
|
||||
shaderProgram.setModelOffsetPos(modelPos);
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos));
|
||||
}
|
||||
|
||||
public void drawSharedVbo(SharedVbo sharedVbo, SharedVbo.BufferSlice[] slices)
|
||||
public void drawVbo(GLVertexBuffer vbo)
|
||||
{
|
||||
//// can be uncommented to add additional debug validation to prevent crashes if invalid buffers are being created
|
||||
//// shouldn't be used in production due to the performance hit
|
||||
//if (GL32.glIsBuffer(vbo.getId()))
|
||||
{
|
||||
IDhApiShaderProgram shaderProgram = this.lodRenderProgram;
|
||||
IDhApiShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class);
|
||||
@@ -514,37 +505,17 @@ public class LodRenderer
|
||||
}
|
||||
|
||||
|
||||
sharedVbo.bind();
|
||||
shaderProgram.bindVertexBuffer(sharedVbo.vboId);
|
||||
|
||||
IntArrayList countList = new IntArrayList();
|
||||
IntArrayList baseVertexList = new IntArrayList();
|
||||
for (int i = 0; i < slices.length; i++)
|
||||
{
|
||||
SharedVbo.BufferSlice slice = slices[i];
|
||||
if (slice != null && slice.vertexCount != 0)
|
||||
{
|
||||
countList.add((slice.vertexCount / 4) * 6); // 4 vertices per quad, 6 indices per quad
|
||||
baseVertexList.add((int)slice.startIndex / LodUtil.LOD_VERTEX_FORMAT.getByteSize());
|
||||
vbo.bind();
|
||||
shaderProgram.bindVertexBuffer(vbo.getId());
|
||||
GL32.glDrawElements(GL32.GL_TRIANGLES, (vbo.getVertexCount() / 4) * 6, // TODO what does the 4 and 6 here represent?
|
||||
this.quadIBO.getType(), 0);
|
||||
vbo.unbind();
|
||||
}
|
||||
}
|
||||
|
||||
int[] counts = countList.toIntArray();
|
||||
PointerBuffer iboIndicies = PointerBuffer.allocateDirect(counts.length);
|
||||
for (int i = 0; i < counts.length; i++)
|
||||
{
|
||||
iboIndicies.put(0L);
|
||||
}
|
||||
iboIndicies.rewind();
|
||||
int[] baseVertecies = baseVertexList.toIntArray();
|
||||
|
||||
|
||||
if (counts.length != 0)
|
||||
{
|
||||
GL32.glMultiDrawElementsBaseVertex(GL32.GL_TRIANGLES, counts, this.quadIBO.getType(), iboIndicies, baseVertecies);
|
||||
}
|
||||
|
||||
sharedVbo.unbind();
|
||||
//else
|
||||
//{
|
||||
// // will spam the log if uncommented, but helpful for validation
|
||||
// //LOGGER.warn("Unable to draw VBO: "+vbo.getId());
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-4
@@ -308,8 +308,8 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
|
||||
{
|
||||
blockPos.y = 140f;
|
||||
|
||||
Color newColor = (massRelativePosBoxGroup.get(0).color == Color.RED) ? Color.RED.darker() : Color.RED;
|
||||
massRelativePosBoxGroup.forEach((box) -> { box.color = newColor; });
|
||||
Color newColor = (massRelativePosBoxGroup.getFirst().color == Color.RED) ? Color.RED.darker() : Color.RED;
|
||||
massRelativePosBoxGroup.forEach((box) -> box.color = newColor);
|
||||
massRelativePosBoxGroup.triggerBoxChange();
|
||||
}
|
||||
|
||||
@@ -327,11 +327,10 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
|
||||
@Override
|
||||
public void add(IDhApiRenderableBoxGroup iBoxGroup) throws IllegalArgumentException
|
||||
{
|
||||
if (!(iBoxGroup instanceof RenderableBoxGroup))
|
||||
if (!(iBoxGroup instanceof RenderableBoxGroup boxGroup))
|
||||
{
|
||||
throw new IllegalArgumentException("Box group must be of type ["+ RenderableBoxGroup.class.getSimpleName()+"], type received: ["+(iBoxGroup != null ? iBoxGroup.getClass() : "NULL")+"].");
|
||||
}
|
||||
RenderableBoxGroup boxGroup = (RenderableBoxGroup) iBoxGroup;
|
||||
|
||||
|
||||
long id = boxGroup.getId();
|
||||
|
||||
@@ -289,7 +289,7 @@ public abstract class AbstractDhRepo<TKey, TDTO extends IBaseDTO<TKey>> implemen
|
||||
try
|
||||
{
|
||||
List<Map<String, Object>> objectList = this.query(sql);
|
||||
return !objectList.isEmpty() ? objectList.get(0) : null;
|
||||
return !objectList.isEmpty() ? objectList.getFirst() : null;
|
||||
}
|
||||
catch (DbConnectionClosedException e)
|
||||
{
|
||||
@@ -512,7 +512,7 @@ public abstract class AbstractDhRepo<TKey, TDTO extends IBaseDTO<TKey>> implemen
|
||||
for (int columnIndex = 1; columnIndex <= resultColumnCount; columnIndex++) // column indices start at 1
|
||||
{
|
||||
String columnName = resultMetaData.getColumnName(columnIndex);
|
||||
if (columnName == null || columnName.equals(""))
|
||||
if (columnName == null || columnName.isEmpty())
|
||||
{
|
||||
throw new RuntimeException("SQL result set is missing a column name for column ["+resultMetaData.getTableName(columnIndex)+"."+columnIndex+"].");
|
||||
}
|
||||
@@ -521,22 +521,13 @@ public abstract class AbstractDhRepo<TKey, TDTO extends IBaseDTO<TKey>> implemen
|
||||
// some values need explicit conversion
|
||||
// Example: Long values that are within the bounds of an int would automatically be incorrectly returned as "Integer" objects
|
||||
String columnType = resultMetaData.getColumnTypeName(columnIndex).toUpperCase();
|
||||
Object columnValue;
|
||||
switch (columnType)
|
||||
Object columnValue = switch (columnType)
|
||||
{
|
||||
case "BIGINT":
|
||||
columnValue = resultSet.getLong(columnIndex);
|
||||
break;
|
||||
case "SMALLINT":
|
||||
columnValue = resultSet.getShort(columnIndex);
|
||||
break;
|
||||
case "TINYINT":
|
||||
columnValue = resultSet.getByte(columnIndex);
|
||||
break;
|
||||
default:
|
||||
columnValue = resultSet.getObject(columnIndex);
|
||||
break;
|
||||
}
|
||||
case "BIGINT" -> resultSet.getLong(columnIndex);
|
||||
case "SMALLINT" -> resultSet.getShort(columnIndex);
|
||||
case "TINYINT" -> resultSet.getByte(columnIndex);
|
||||
default -> resultSet.getObject(columnIndex);
|
||||
};
|
||||
|
||||
|
||||
object.put(columnName, columnValue);
|
||||
|
||||
@@ -179,21 +179,15 @@ public class ColorUtil
|
||||
float q = v * (1f - s * f);
|
||||
float t = v * (1f - s * (1f - f));
|
||||
|
||||
switch (i)
|
||||
return switch (i)
|
||||
{
|
||||
case 0:
|
||||
return ColorUtil.rgbToInt(a, v, t, p);
|
||||
case 1:
|
||||
return ColorUtil.rgbToInt(a, q, v, p);
|
||||
case 2:
|
||||
return ColorUtil.rgbToInt(a, p, v, t);
|
||||
case 3:
|
||||
return ColorUtil.rgbToInt(a, p, q, v);
|
||||
case 4:
|
||||
return ColorUtil.rgbToInt(a, t, p, v);
|
||||
default:
|
||||
return ColorUtil.rgbToInt(a, v, p, q); // case 5
|
||||
}
|
||||
case 0 -> ColorUtil.rgbToInt(a, v, t, p);
|
||||
case 1 -> ColorUtil.rgbToInt(a, q, v, p);
|
||||
case 2 -> ColorUtil.rgbToInt(a, p, v, t);
|
||||
case 3 -> ColorUtil.rgbToInt(a, p, q, v);
|
||||
case 4 -> ColorUtil.rgbToInt(a, t, p, v);
|
||||
default -> ColorUtil.rgbToInt(a, v, p, q); // case 5
|
||||
};
|
||||
}
|
||||
|
||||
/** Returns the hex value for the Alpha, Red, Green, and Blue channels. */
|
||||
|
||||
@@ -233,7 +233,7 @@ public class LodUtil
|
||||
|
||||
Iterator<DhChunkPos> posIter = MC_RENDER.getVanillaRenderedChunks().iterator();
|
||||
|
||||
return new EdgeDistanceBooleanGrid(new Iterator<Pos2D>()
|
||||
return new EdgeDistanceBooleanGrid(new Iterator<>()
|
||||
{
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
|
||||
+6
-14
@@ -453,17 +453,13 @@ public class RenderDataPointReducingList
|
||||
size,
|
||||
// comparator
|
||||
(int index1, int index2) ->
|
||||
{
|
||||
return Integer.compare(
|
||||
Integer.compare(
|
||||
this.getSize(this.getSortingIndex(index1)),
|
||||
this.getSize(this.getSortingIndex(index2))
|
||||
);
|
||||
},
|
||||
),
|
||||
// swapper
|
||||
(int index1, int index2) ->
|
||||
{
|
||||
ShortArrays.swap(array, index1, index2);
|
||||
}
|
||||
ShortArrays.swap(array, index1, index2)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -480,17 +476,13 @@ public class RenderDataPointReducingList
|
||||
size,
|
||||
// comparator
|
||||
(int index1, int index2) ->
|
||||
{
|
||||
return Integer.compare(
|
||||
Integer.compare(
|
||||
this.getMinY(this.getSortingIndex(index1)),
|
||||
this.getMinY(this.getSortingIndex(index2))
|
||||
);
|
||||
},
|
||||
),
|
||||
// swapper
|
||||
(int index1, int index2) ->
|
||||
{
|
||||
ShortArrays.swap(array, index1, index2);
|
||||
}
|
||||
ShortArrays.swap(array, index1, index2)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -245,8 +245,8 @@ public class RenderDataPointUtil
|
||||
" Y-:" + getYMin(dataPoint) +
|
||||
" argb:" + getAlpha(dataPoint) + " " +
|
||||
getRed(dataPoint) + " " +
|
||||
getBlue(dataPoint) + " " +
|
||||
getGreen(dataPoint) +
|
||||
getGreen(dataPoint) + " " +
|
||||
getBlue(dataPoint) +
|
||||
" BL:" + getLightBlock(dataPoint) +
|
||||
" SL:" + getLightSky(dataPoint) +
|
||||
" BID:" + getBlockMaterialId(dataPoint);
|
||||
|
||||
@@ -72,7 +72,7 @@ public class ThreadUtil
|
||||
|
||||
RateLimitedThreadPoolExecutor executor = makeRateLimitedThreadPool(poolSize, runTimeRatioConfigEntry.get(), threadFactory, activeThreadCountSemaphore);
|
||||
|
||||
ConfigChangeListener<Double> changeListener = new ConfigChangeListener<>(runTimeRatioConfigEntry, (newRunTimeRatio) -> { executor.runTimeRatio = newRunTimeRatio; });
|
||||
ConfigChangeListener<Double> changeListener = new ConfigChangeListener<>(runTimeRatioConfigEntry, (newRunTimeRatio) -> executor.runTimeRatio = newRunTimeRatio);
|
||||
THREAD_CHANGE_LISTENERS_BY_THREAD_NAME.put(threadFactory.threadName, changeListener);
|
||||
|
||||
return executor;
|
||||
@@ -102,7 +102,7 @@ public class ThreadUtil
|
||||
// ThreadPoolExecutor vs the more generic ExecutorService
|
||||
return new ThreadPoolExecutor(/*corePoolSize*/ poolSize, /*maxPoolSize*/ poolSize,
|
||||
0L, TimeUnit.MILLISECONDS,
|
||||
new LinkedBlockingQueue<Runnable>(),
|
||||
new LinkedBlockingQueue<>(),
|
||||
new DhThreadFactory(name, priority));
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -70,7 +70,7 @@ public class EdgeDistanceBooleanGrid extends PosArrayGridList<BoolType>
|
||||
{
|
||||
if (edgeCache != null) return;
|
||||
|
||||
edgeCache = new ArrayGridList<Integer>(gridSize, (ox, oy) -> {
|
||||
edgeCache = new ArrayGridList<>(gridSize, (ox, oy) -> {
|
||||
BoolType b = get(ox + getOffsetX(), oy + getOffsetY());
|
||||
return b == null ? -1 : 0;
|
||||
});
|
||||
@@ -79,9 +79,7 @@ public class EdgeDistanceBooleanGrid extends PosArrayGridList<BoolType>
|
||||
while (!isDone[0])
|
||||
{
|
||||
isDone[0] = true;
|
||||
edgeCache.forEachPos((ox, oy) -> {
|
||||
isDone[0] &= updatePos(edgeCache, ox, oy);
|
||||
});
|
||||
edgeCache.forEachPos((ox, oy) -> isDone[0] &= updatePos(edgeCache, ox, oy));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -50,7 +50,7 @@ public class DummyRunExecutorService implements ExecutorService
|
||||
public List<Runnable> shutdownNow()
|
||||
{
|
||||
shutdownCalled = true;
|
||||
return new ArrayList<Runnable>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,7 +116,7 @@ public class DummyRunExecutorService implements ExecutorService
|
||||
@Override
|
||||
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
|
||||
{
|
||||
List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
|
||||
List<Future<T>> futures = new ArrayList<>(tasks.size());
|
||||
for (Callable<T> t : tasks)
|
||||
{
|
||||
futures.add(submit(t));
|
||||
|
||||
@@ -48,9 +48,9 @@ public class EventTimer
|
||||
public void nextEvent(String name)
|
||||
{
|
||||
long timeNs = System.nanoTime();
|
||||
if (lastEventNs != -1 && !events.isEmpty() && events.get(events.size() - 1).timeNs == -1)
|
||||
if (lastEventNs != -1 && !events.isEmpty() && events.getLast().timeNs == -1)
|
||||
{
|
||||
events.get(events.size() - 1).timeNs = timeNs - lastEventNs;
|
||||
events.getLast().timeNs = timeNs - lastEventNs;
|
||||
}
|
||||
lastEventNs = timeNs;
|
||||
events.add(new Event(name));
|
||||
@@ -59,9 +59,9 @@ public class EventTimer
|
||||
public void complete()
|
||||
{
|
||||
long timeNs = System.nanoTime();
|
||||
if (lastEventNs != -1 && !events.isEmpty() && events.get(events.size() - 1).timeNs == -1)
|
||||
if (lastEventNs != -1 && !events.isEmpty() && events.getLast().timeNs == -1)
|
||||
{
|
||||
events.get(events.size() - 1).timeNs = timeNs - lastEventNs;
|
||||
events.getLast().timeNs = timeNs - lastEventNs;
|
||||
}
|
||||
lastEventNs = -1;
|
||||
}
|
||||
|
||||
@@ -61,13 +61,13 @@ public class SortedArraySet<E> implements SortedSet<E>
|
||||
@Override
|
||||
public E first()
|
||||
{
|
||||
return list.get(0);
|
||||
return list.getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E last()
|
||||
{
|
||||
return list.get(list.size() - 1);
|
||||
return list.getLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,8 +25,8 @@ import java.util.TreeMap;
|
||||
|
||||
public class StatsMap
|
||||
{
|
||||
final TreeMap<String, Long> longMap = new TreeMap<String, Long>();
|
||||
final TreeMap<String, UnitBytes> bytesMap = new TreeMap<String, UnitBytes>();
|
||||
final TreeMap<String, Long> longMap = new TreeMap<>();
|
||||
final TreeMap<String, UnitBytes> bytesMap = new TreeMap<>();
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
+7
-11
@@ -53,19 +53,15 @@ public class DhDataInputStream extends DataInputStream
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (compressionMode)
|
||||
return switch (compressionMode)
|
||||
{
|
||||
case UNCOMPRESSED:
|
||||
return stream;
|
||||
case LZ4:
|
||||
return new LZ4FrameInputStream(stream);
|
||||
case LZMA2:
|
||||
case UNCOMPRESSED -> stream;
|
||||
case LZ4 -> new LZ4FrameInputStream(stream);
|
||||
case LZMA2 ->
|
||||
// Note: all LZMA/XZ compressors can be decompressed using this same InputStream
|
||||
return new XZInputStream(stream);
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("No compressor defined for [" + compressionMode + "]");
|
||||
}
|
||||
new XZInputStream(stream);
|
||||
default -> throw new IllegalArgumentException("No compressor defined for [" + compressionMode + "]");
|
||||
};
|
||||
}
|
||||
catch (Error e)
|
||||
{
|
||||
|
||||
+2
-2
@@ -58,7 +58,7 @@ public class LzmaArrayCache extends ArrayCache
|
||||
return new byte[size];
|
||||
}
|
||||
|
||||
byte[] array = cacheList.remove(cacheList.size()-1);
|
||||
byte[] array = cacheList.removeLast();
|
||||
if (array == null)
|
||||
{
|
||||
return new byte[size];
|
||||
@@ -102,7 +102,7 @@ public class LzmaArrayCache extends ArrayCache
|
||||
return new int[size];
|
||||
}
|
||||
|
||||
int[] array = cacheList.remove(cacheList.size()-1);
|
||||
int[] array = cacheList.removeLast();
|
||||
if (array == null)
|
||||
{
|
||||
return new int[size];
|
||||
|
||||
+7
-13
@@ -124,20 +124,14 @@ public class QuadNode<T>
|
||||
*/
|
||||
public QuadNode<T> getChildByIndex(int child0to3) throws IllegalArgumentException
|
||||
{
|
||||
switch (child0to3)
|
||||
return switch (child0to3)
|
||||
{
|
||||
case 0:
|
||||
return nwChild;
|
||||
case 1:
|
||||
return swChild;
|
||||
case 2:
|
||||
return neChild;
|
||||
case 3:
|
||||
return seChild;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("child0to3 must be between 0 and 3");
|
||||
}
|
||||
case 0 -> nwChild;
|
||||
case 1 -> swChild;
|
||||
case 2 -> neChild;
|
||||
case 3 -> seChild;
|
||||
default -> throw new IllegalArgumentException("child0to3 must be between 0 and 3");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -141,7 +141,7 @@ public class QuadTree<T>
|
||||
return null;
|
||||
}
|
||||
|
||||
topQuadNode = new QuadNode<T>(rootPos, this.treeMaxDetailLevel);
|
||||
topQuadNode = new QuadNode<>(rootPos, this.treeMaxDetailLevel);
|
||||
boolean successfullyAdded = this.topRingList.set(ringListPosX, ringListPosZ, topQuadNode);
|
||||
if (!successfullyAdded)
|
||||
{
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class ConfigThreadPool
|
||||
|
||||
this.threadCountConfig = threadCountConfig;
|
||||
this.threadCountConfigListener = new ConfigChangeListener<>(threadCountConfig,
|
||||
(threadCount) -> { this.setThreadPoolSize(threadCount); });
|
||||
this::setThreadPoolSize);
|
||||
this.runTimeRatioConfig = runTimeRatioConfig;
|
||||
|
||||
this.setThreadPoolSize(threadCountConfig.get());
|
||||
|
||||
@@ -19,26 +19,18 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.world;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.level.DhClientLevel;
|
||||
import com.seibel.distanthorizons.core.network.NetworkClient;
|
||||
import com.seibel.distanthorizons.core.network.messages.*;
|
||||
import com.seibel.distanthorizons.core.network.messages.PlayerUUIDMessage;
|
||||
import com.seibel.distanthorizons.core.network.messages.RemotePlayerConfigMessage;
|
||||
import com.seibel.distanthorizons.core.network.objects.RemotePlayer;
|
||||
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.EventLoop;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user