Compare commits
135 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e6eb4c096 | |||
| 618707533b | |||
| 2d7e2e2444 | |||
| 4f2b8e6d8d | |||
| 7165c086e4 | |||
| fa22a4f27b | |||
| 9c0f5865f6 | |||
| 1d0cb048cd | |||
| 641d399a8e | |||
| 32861e757d | |||
| 634738a1fc | |||
| 859cbb6161 | |||
| 6c960a81c0 | |||
| 1695c41ef2 | |||
| 8eabc6ad4c | |||
| a153ca1fe1 | |||
| cab9f7c830 | |||
| 6bb832a488 | |||
| e7dda9590a | |||
| 0483edd2f3 | |||
| 122ef4dce0 | |||
| e9d254f8c4 | |||
| 17aa85ad24 | |||
| 8e1dfd688e | |||
| 691d5caded | |||
| 31c089f82f | |||
| 8eceeb0226 | |||
| c178afa4b9 | |||
| 116df0d999 | |||
| ef3cd4b43d | |||
| 4b27f39a04 | |||
| 53a2bf1748 | |||
| edec8bc0a2 | |||
| 066b23c785 | |||
| 1f74f19cd9 | |||
| 232c727b4f | |||
| cd5da82d0c | |||
| b762c0561d | |||
| f144a9ebc1 | |||
| 29ef95387c | |||
| 0d79a856b2 | |||
| bd5054e762 | |||
| 63dea2515e | |||
| baa89edd03 | |||
| c45f9f442f | |||
| 9e13b27197 | |||
| 3c173685ea | |||
| 8eb70cbaed | |||
| 22167081f0 | |||
| 23d07aa92d | |||
| 578a9f9309 | |||
| bacdfa96e3 | |||
| c73c3f8490 | |||
| f4a8bfeb0a | |||
| 197e6e8178 | |||
| c2c8bf8613 | |||
| fce703579f | |||
| e98f17f63b | |||
| 120dddf844 | |||
| ca711bbc72 | |||
| cc4cb10307 | |||
| 88db5c9594 | |||
| 81bfa9a02b | |||
| ae72e627c5 | |||
| 131b2835e5 | |||
| 5b905a9ab3 | |||
| e90c7cd8a0 | |||
| 3b4a0ff4bc | |||
| 55cb4595bd | |||
| e91afc17a3 | |||
| 6a398e6514 | |||
| 51de347bdd | |||
| 72d6cb9697 | |||
| 4a025de9d6 | |||
| 6c8060fa87 | |||
| 0c0987b66b | |||
| 5a71e4015c | |||
| f68edcbfea | |||
| aefa0d6797 | |||
| 305a6bb459 | |||
| 28c8614550 | |||
| f282d78fb9 | |||
| 7f8b5579c5 | |||
| db786290e8 | |||
| 2c71d97c15 | |||
| bf1361c7c3 | |||
| f2bba7f3df | |||
| 62e5183c54 | |||
| c1a90c9350 | |||
| 0d0826f319 | |||
| 6bfa3a422e | |||
| 352abc40e6 | |||
| 58d26dedd6 | |||
| 321afa2a9e | |||
| 71ffbfb7b9 | |||
| 2ab7949ce5 | |||
| 28e1eaae77 | |||
| 30dda058fe | |||
| 0d16c037f5 | |||
| 7f50de17c0 | |||
| 67819b30eb | |||
| ad38722304 | |||
| 4da48c4c55 | |||
| 6542e9e889 | |||
| 2f7e3d43d1 | |||
| edaafb5cf0 | |||
| 81d1ed419e | |||
| 385e3dc964 | |||
| 9592cd80f3 | |||
| 7b153a8aad | |||
| 54c2213eb6 | |||
| 1274a8e097 | |||
| bd1d0063e5 | |||
| af9b55ad6c | |||
| 97b86d69c4 | |||
| c6b4eacf03 | |||
| e011ce3ee0 | |||
| 1dd6359c89 | |||
| e41abdd176 | |||
| b7a5bfd274 | |||
| c3abfb123d | |||
| 76f28e648c | |||
| f49a79b54a | |||
| 3cf385c2a2 | |||
| 8c91a84795 | |||
| 4af63758f2 | |||
| 969b02dc18 | |||
| 2111ad64c4 | |||
| e02deb2fb0 | |||
| 410e34b147 | |||
| 9cebd7ee54 | |||
| cfec32746d | |||
| fabe5d77ea | |||
| c67712d973 | |||
| 7e45a98e8f |
Binary file not shown.
+1
-1
@@ -3,7 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
plugins {
|
||||
id "java"
|
||||
|
||||
id "com.github.johnrengelman.shadow" version '7.1.2' apply false
|
||||
id "com.github.johnrengelman.shadow" version '8.1.1' apply false
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@ import com.seibel.distanthorizons.api.interfaces.events.IDhApiEventInjector;
|
||||
import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.worldGenerator.IDhApiWorldGeneratorOverrideRegister;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderProxy;
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||
import com.seibel.distanthorizons.api.methods.override.DhApiWorldGeneratorOverrideRegister;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
@@ -123,10 +125,16 @@ public class DhApi
|
||||
|
||||
/**
|
||||
* Used to create wrappers for Minecraft objects needed by other Distant Horizons API methods.
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public static IDhApiWrapperFactory wrapperFactory = null;
|
||||
|
||||
/**
|
||||
* Used to create custom renderable objects. <br>
|
||||
* These objects can be added to the renderer in {@link IDhApiLevelWrapper}
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public static IDhApiCustomRenderObjectFactory customRenderObjectFactory = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -198,7 +206,7 @@ public class DhApi
|
||||
|
||||
/**
|
||||
* Returns true if the thread this method was called from is owned by Distant Horizons.
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public static boolean isDhThread() { return Thread.currentThread().getName().startsWith(ModInfo.THREAD_NAME_PREFIX); }
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
* NONE, <br>
|
||||
* NON_COLLIDING, <br>
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiBlocksToAvoid
|
||||
|
||||
+1
-2
@@ -22,14 +22,13 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
/**
|
||||
* UNCOMPRESSED <br>
|
||||
* LZ4 <br>
|
||||
* ZSTD <br>
|
||||
* XZ <br><br>
|
||||
*
|
||||
* Note: speed and compression ratios are examples
|
||||
* and should only be used for estimated comparisons.
|
||||
*
|
||||
* @version 2024-3-16
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiDataCompressionMode
|
||||
{
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
package com.seibel.distanthorizons.api.enums.config;
|
||||
|
||||
/**
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiGLErrorHandlingMode
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
package com.seibel.distanthorizons.api.enums.config;
|
||||
|
||||
/**
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiGlProfileMode
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
* @author Leetom
|
||||
* @author James Seibel
|
||||
* @version 2024-4-6
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiGpuUploadMethod
|
||||
{
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
* FADE_TO_DIRT <br>
|
||||
* AS_DIRT <br>
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-7
|
||||
*/
|
||||
public enum EDhApiGrassSideRendering
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
* HIGH <br>
|
||||
* UNLIMITED <br>
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiHorizontalQuality
|
||||
|
||||
@@ -24,7 +24,7 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
* ENABLED <br>
|
||||
* DISABLED <br>
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiLodShading
|
||||
|
||||
@@ -22,7 +22,7 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
/**
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiLoggerMode
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
||||
*
|
||||
* @author James Seibel
|
||||
* @author Leonardo Amato
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiMaxHorizontalResolution
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
* Determines how the multiplayer folders should be named.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiServerFolderNameMode
|
||||
|
||||
+30
-3
@@ -1,14 +1,41 @@
|
||||
package com.seibel.distanthorizons.api.enums.config;
|
||||
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
|
||||
/**
|
||||
* AUTO, <br>
|
||||
* STABLE, <br>
|
||||
* NIGHTLY, <br><br>
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @version 2024-4-6
|
||||
* @since API 2.1.0
|
||||
* @version 2024-6-8
|
||||
*/
|
||||
public enum EDhApiUpdateBranch
|
||||
{
|
||||
AUTO,
|
||||
STABLE,
|
||||
NIGHTLY
|
||||
NIGHTLY;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* If the updateBranch value is {@link EDhApiUpdateBranch#AUTO}
|
||||
* this method will convert it either to {@link EDhApiUpdateBranch#STABLE} or {@link EDhApiUpdateBranch#NIGHTLY}
|
||||
* based on this jar's state. <Br><br>
|
||||
*
|
||||
* If updateBranch is {@link EDhApiUpdateBranch#STABLE} or {@link EDhApiUpdateBranch#NIGHTLY}
|
||||
* it just returns.
|
||||
*/
|
||||
public static EDhApiUpdateBranch convertAutoToStableOrNightly(EDhApiUpdateBranch updateBranch)
|
||||
{
|
||||
if (updateBranch != EDhApiUpdateBranch.AUTO)
|
||||
{
|
||||
return updateBranch;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ModInfo.IS_DEV_BUILD ? EDhApiUpdateBranch.NIGHTLY : EDhApiUpdateBranch.STABLE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
* the vanilla Minecraft terrain.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
@Deprecated // not currently in use, if the config this enum represents is re-implemented, the deprecated flag can be removed
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
||||
*
|
||||
* @author Leonardo Amato
|
||||
* @version 2024-4-6
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiVerticalQuality
|
||||
{
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ package com.seibel.distanthorizons.api.enums.config;
|
||||
* VISUALLY_EQUAL <br><br>
|
||||
*
|
||||
* @version 2024-3-27
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiWorldCompressionMode
|
||||
{
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui
|
||||
* HIGH, <br>
|
||||
* EXTREME, <br>
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiQualityPreset
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui
|
||||
* BALANCED, <br>
|
||||
* AGGRESSIVE, <br>
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiThreadPreset
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.seibel.distanthorizons.api.enums.rendering;
|
||||
|
||||
/**
|
||||
* contains the indices used by shaders to determine
|
||||
* how different block types should be rendered. <br><br>
|
||||
*
|
||||
* UNKNOWN, <br>
|
||||
* LEAVES, <br>
|
||||
* STONE, <br>
|
||||
* WOOD, <br>
|
||||
* METAL, <br>
|
||||
* DIRT, <br>
|
||||
* LAVA, <br>
|
||||
* DEEPSLATE, <br>
|
||||
* SNOW, <br>
|
||||
* SAND, <br>
|
||||
* TERRACOTTA, <br>
|
||||
* NETHER_STONE, <br>
|
||||
* WATER, <br>
|
||||
* GRASS, <br>
|
||||
* AIR, <br>
|
||||
* ILLUMINATED, <br>
|
||||
*
|
||||
* @author James Seibel
|
||||
* @since API 3.0.0
|
||||
* @version 2024-7-11
|
||||
*/
|
||||
public enum EDhApiBlockMaterial
|
||||
{
|
||||
UNKNOWN(0),
|
||||
LEAVES(1),
|
||||
STONE(2),
|
||||
WOOD(3),
|
||||
METAL(4),
|
||||
DIRT(5),
|
||||
LAVA(6),
|
||||
DEEPSLATE(7),
|
||||
SNOW(8),
|
||||
SAND(9),
|
||||
TERRACOTTA(10),
|
||||
NETHER_STONE(11),
|
||||
WATER(12),
|
||||
GRASS(13),
|
||||
/** shouldn't normally be needed, but just in case */
|
||||
AIR(14),
|
||||
ILLUMINATED(15); // Max value
|
||||
|
||||
|
||||
|
||||
public final byte index;
|
||||
|
||||
EDhApiBlockMaterial(int index) { this.index = (byte)index;}
|
||||
|
||||
public static EDhApiBlockMaterial getFromIndex(int index)
|
||||
{
|
||||
for(EDhApiBlockMaterial material : EDhApiBlockMaterial.values())
|
||||
{
|
||||
if (material.index == index)
|
||||
{
|
||||
return material;
|
||||
}
|
||||
}
|
||||
|
||||
return EDhApiBlockMaterial.UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -29,7 +29,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
* @author Leetom
|
||||
* @author James Seibel
|
||||
* @version 2024-4-6
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiDebugRendering
|
||||
{
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-4-6
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiFogColorMode
|
||||
{
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
* FOG_DISABLED <br>
|
||||
*
|
||||
* @author James Seibel
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2022-6-2
|
||||
*/
|
||||
public enum EDhApiFogDrawMode
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
*
|
||||
* @author Leetom
|
||||
* @version 2022-6-30
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiFogFalloff
|
||||
{
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
*
|
||||
* @author Leetom
|
||||
* @version 2024-4-6
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiHeightFogMixMode
|
||||
{
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
*
|
||||
* @author Leetom
|
||||
* @version 2024-4-6
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiHeightFogMode
|
||||
{
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-30
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiRenderPass
|
||||
{
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
* Debug <br>
|
||||
* Disabled <br>
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiRendererMode
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ package com.seibel.distanthorizons.api.enums.rendering;
|
||||
* FAKE, <br>
|
||||
* COMPLETE, <br>
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @version 2024-4-6
|
||||
*/
|
||||
public enum EDhApiTransparency
|
||||
|
||||
+3
-3
@@ -31,7 +31,7 @@ import java.util.function.Consumer;
|
||||
*
|
||||
* @author Builderb0y, James Seibel
|
||||
* @version 2023-12-21
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public enum EDhApiWorldGeneratorReturnType
|
||||
{
|
||||
@@ -40,7 +40,7 @@ public enum EDhApiWorldGeneratorReturnType
|
||||
* {@link IDhApiWorldGenerator#generateChunks(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer)}
|
||||
* will be used when generating terrain.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
VANILLA_CHUNKS,
|
||||
|
||||
@@ -49,7 +49,7 @@ public enum EDhApiWorldGeneratorReturnType
|
||||
* {@link IDhApiWorldGenerator#generateApiChunks(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer)}
|
||||
* will be used when generating terrain.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
API_CHUNKS;
|
||||
|
||||
|
||||
+12
-3
@@ -30,12 +30,21 @@ import com.seibel.distanthorizons.api.interfaces.IDhApiUnsafeWrapper;
|
||||
*/
|
||||
public interface IDhApiBlockStateWrapper extends IDhApiUnsafeWrapper
|
||||
{
|
||||
/** @since API 1.0.0 */
|
||||
boolean isAir();
|
||||
|
||||
/** @since API 1.0.0 */
|
||||
boolean isSolid();
|
||||
/** @since API 1.0.0 */
|
||||
boolean isLiquid();
|
||||
|
||||
// TODO:
|
||||
// boolean hasNoCollision();
|
||||
// boolean noFaceIsFullFace();
|
||||
/**
|
||||
* Returns the full serialized form of the given block
|
||||
* as defined by DH's serialization methods.
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
String getSerialString();
|
||||
/** @since API 3.0.0 */
|
||||
byte getMaterialId();
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -47,7 +47,7 @@ public interface IDhApiConfigValue<T>
|
||||
* Returns the value of the config if it was set by the API.
|
||||
* Returns null if the config hasn't been set by the API.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
T getApiValue();
|
||||
|
||||
@@ -68,7 +68,7 @@ public interface IDhApiConfigValue<T>
|
||||
* use the value set in the config menu.
|
||||
*
|
||||
* @return true if the value was set, false otherwise.
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
boolean clearValue();
|
||||
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.api.interfaces.config.client;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.config.IDhApiConfigGroup;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.IDhApiConfigValue;
|
||||
|
||||
/**
|
||||
* Distant Horizons' generic rendering configuration. <br><br>
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-11
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public interface IDhApiGenericRenderingConfig extends IDhApiConfigGroup
|
||||
{
|
||||
/**
|
||||
* If enabled DH will render generic objects into its terrain pass. <br>
|
||||
* This includes: clouds, beacons, and API added objects.
|
||||
*/
|
||||
IDhApiConfigValue<Boolean> renderingEnabled();
|
||||
|
||||
/** If enabled DH will render beacon beams. */
|
||||
IDhApiConfigValue<Boolean> beaconRenderingEnabled();
|
||||
|
||||
/** If enabled DH will render clouds. */
|
||||
IDhApiConfigValue<Boolean> cloudRenderingEnabled();
|
||||
|
||||
}
|
||||
-9
@@ -36,13 +36,4 @@ 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();
|
||||
|
||||
}
|
||||
|
||||
+5
-4
@@ -41,6 +41,7 @@ public interface IDhApiGraphicsConfig extends IDhApiConfigGroup
|
||||
IDhApiFogConfig fog();
|
||||
IDhApiAmbientOcclusionConfig ambientOcclusion();
|
||||
IDhApiNoiseTextureConfig noiseTexture();
|
||||
IDhApiGenericRenderingConfig genericRendering();
|
||||
|
||||
|
||||
|
||||
@@ -121,7 +122,7 @@ public interface IDhApiGraphicsConfig extends IDhApiConfigGroup
|
||||
* Setting this to 0 will reduce/prevent holes in the world due to clipping to close to the camera
|
||||
* but may cause overdraw issues with transparent or non-full blocks.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
IDhApiConfigValue<Double> overdrawPreventionRadius();
|
||||
|
||||
@@ -158,7 +159,7 @@ public interface IDhApiGraphicsConfig extends IDhApiConfigGroup
|
||||
/**
|
||||
* Determines how LODs should be shaded.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
IDhApiConfigValue<EDhApiLodShading> lodShading();
|
||||
|
||||
@@ -171,7 +172,7 @@ public interface IDhApiGraphicsConfig extends IDhApiConfigGroup
|
||||
* start/stop rendering incorrectly based on the camera direction,
|
||||
* but will also reduce FPS.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @see IDhApiGraphicsConfig#disableShadowFrustumCulling()
|
||||
*/
|
||||
IDhApiConfigValue<Boolean> disableFrustumCulling();
|
||||
@@ -183,7 +184,7 @@ public interface IDhApiGraphicsConfig extends IDhApiConfigGroup
|
||||
*
|
||||
* Disable this if shadows render incorrectly.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
* @see IDhApiGraphicsConfig#disableFrustumCulling()
|
||||
*/
|
||||
IDhApiConfigValue<Boolean> disableShadowFrustumCulling();
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.seibel.distanthorizons.api.interfaces.data;
|
||||
|
||||
/**
|
||||
* Can be used to drastically speed up repeat read operations in {@link IDhApiTerrainDataRepo}.
|
||||
*
|
||||
* @see IDhApiTerrainDataRepo
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-14
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public interface IDhApiTerrainDataCache
|
||||
{
|
||||
/**
|
||||
* Removes any data that's currently stored in this cache.
|
||||
* This cane be done to free up memory or invalidate
|
||||
* the cache so fresh data can be pulled in.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
}
|
||||
+69
-12
@@ -29,6 +29,8 @@ import com.seibel.distanthorizons.api.objects.data.DhApiTerrainDataPoint;
|
||||
/**
|
||||
* Used to interface with Distant Horizons' terrain data.
|
||||
*
|
||||
* @see IDhApiTerrainDataCache
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2023-6-22
|
||||
* @since API 1.0.0
|
||||
@@ -40,29 +42,50 @@ public interface IDhApiTerrainDataRepo
|
||||
// getters //
|
||||
//=========//
|
||||
|
||||
/** Returns the terrain datapoint at the given block position, at/or containing the given Y position. */
|
||||
DhApiResult<DhApiTerrainDataPoint> getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ);
|
||||
/** Returns every datapoint in the column located at the given block X and Z position top to bottom. */
|
||||
DhApiResult<DhApiTerrainDataPoint[]> getColumnDataAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosZ);
|
||||
/** @see IDhApiTerrainDataRepo#getSingleDataPointAtBlockPos(IDhApiLevelWrapper, int, int, int, IDhApiTerrainDataCache) */
|
||||
default DhApiResult<DhApiTerrainDataPoint> getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ) { return this.getSingleDataPointAtBlockPos(levelWrapper, blockPosX, blockPosY, blockPosZ, null); }
|
||||
/**
|
||||
* Returns the terrain datapoint at the given block position, at/or containing the given Y position.
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
DhApiResult<DhApiTerrainDataPoint> getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ, IDhApiTerrainDataCache dataCache);
|
||||
|
||||
/** @see IDhApiTerrainDataRepo#getColumnDataAtBlockPos(IDhApiLevelWrapper, int, int, IDhApiTerrainDataCache) */
|
||||
default DhApiResult<DhApiTerrainDataPoint[]> getColumnDataAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosZ) { return this.getColumnDataAtBlockPos(levelWrapper, blockPosX, blockPosZ, null); }
|
||||
/**
|
||||
* Returns every datapoint in the column located at the given block X and Z position top to bottom.
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
DhApiResult<DhApiTerrainDataPoint[]> getColumnDataAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosZ, IDhApiTerrainDataCache dataCache);
|
||||
|
||||
/** @see IDhApiTerrainDataRepo#getAllTerrainDataAtChunkPos(IDhApiLevelWrapper, int, int, IDhApiTerrainDataCache) */
|
||||
default DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ) { return this.getAllTerrainDataAtChunkPos(levelWrapper, chunkPosX, chunkPosZ, null); }
|
||||
/**
|
||||
* Returns every datapoint in the given chunk's X and Z position. <br><br>
|
||||
*
|
||||
* The returned array is ordered: [relativeBlockX][relativeBlockZ][columnIndex] <br>
|
||||
* RelativeBlockX/Z are relative to the block position closest to negative infinity in the chunk's position. <br>
|
||||
* The column data is ordered from top to bottom. Note: each column may have a different number of values. <br>
|
||||
*
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ);
|
||||
DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ, IDhApiTerrainDataCache dataCache);
|
||||
|
||||
/** @see IDhApiTerrainDataRepo#getAllTerrainDataAtRegionPos(IDhApiLevelWrapper, int, int, IDhApiTerrainDataCache) */
|
||||
default DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ) { return this.getAllTerrainDataAtRegionPos(levelWrapper, regionPosX, regionPosZ, null); }
|
||||
/**
|
||||
* Returns every datapoint in the given region's X and Z position. <br><br>
|
||||
*
|
||||
* The returned array is ordered: [relativeBlockX][relativeBlockZ][columnIndex] <br>
|
||||
* RelativeBlockX/Z are relative to the block position closest to negative infinity in the region's position. <br>
|
||||
* The column data is ordered from top to bottom. Note: each column may have a different number of values. <br>
|
||||
*
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ);
|
||||
DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ, IDhApiTerrainDataCache dataCache);
|
||||
|
||||
/** @see IDhApiTerrainDataRepo#getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper, byte, int, int, IDhApiTerrainDataCache) */
|
||||
default DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtRegionPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ) { return this.getAllTerrainDataAtDetailLevelAndPos(levelWrapper, detailLevel, posX, posZ, null); }
|
||||
/**
|
||||
* Returns every datapoint in the column located at the given detail level and X/Z position. <br>
|
||||
* This can be used to return terrain data for non-standard sizes (IE 2x2 blocks or 2x2 chunks).
|
||||
@@ -71,20 +94,42 @@ public interface IDhApiTerrainDataRepo
|
||||
* Every increase doubles the width of the returned area. <br>
|
||||
* Example values: 0 = block, 1 = 2x2 blocks, 2 = 4x4 blocks, ... 4 = chunk (16x16 blocks), ... 9 = region (512x512 blocks) <br>
|
||||
* See {@link EDhApiDetailLevel} for more information.
|
||||
*
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ);
|
||||
DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ, IDhApiTerrainDataCache dataCache);
|
||||
|
||||
|
||||
|
||||
/** @see IDhApiTerrainDataRepo#raycast(IDhApiLevelWrapper, double, double, double, float, float, float, int, IDhApiTerrainDataCache) */
|
||||
default DhApiResult<DhApiRaycastResult> raycast(
|
||||
IDhApiLevelWrapper levelWrapper,
|
||||
double rayOriginX, double rayOriginY, double rayOriginZ,
|
||||
float rayDirectionX, float rayDirectionY, float rayDirectionZ,
|
||||
int maxRayBlockLength)
|
||||
{
|
||||
return this.raycast(
|
||||
levelWrapper,
|
||||
rayOriginX, rayOriginY, rayOriginZ,
|
||||
rayDirectionX, rayDirectionY, rayDirectionZ,
|
||||
maxRayBlockLength,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the datapoint and position of the LOD
|
||||
* at the end of the given ray. <br><br>
|
||||
*
|
||||
* Will return "success" with a null datapoint if the ray reaches the max length without finding any data.
|
||||
*
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
DhApiResult<DhApiRaycastResult> raycast(
|
||||
IDhApiLevelWrapper levelWrapper,
|
||||
double rayOriginX, double rayOriginY, double rayOriginZ,
|
||||
float rayDirectionX, float rayDirectionY, float rayDirectionZ,
|
||||
int maxRayBlockLength);
|
||||
int maxRayBlockLength,
|
||||
IDhApiTerrainDataCache dataCache);
|
||||
|
||||
|
||||
|
||||
@@ -98,15 +143,27 @@ public interface IDhApiTerrainDataRepo
|
||||
* Notes: <br>
|
||||
* - Only works if the given {@link IDhApiLevelWrapper} points to a loaded level. <br>
|
||||
* - If the player travels to this chunk, or the chunk is updated in some other way; your data will be replaced
|
||||
* by whatever the current chunk is. <br>
|
||||
* - This method may not update the LOD data immediately. Any other chunks have
|
||||
* been queued to update, they will be handled first.
|
||||
* by whatever the current chunk is. <br>
|
||||
* - This method may not update the LOD data immediately. Any other chunks that have
|
||||
* been queued to update will be handled first.
|
||||
*
|
||||
* @param levelWrapper the level wrapper that the chunk should be saved to.
|
||||
* @param chunkObjectArray see {@link IDhApiWorldGenerator#generateChunks} for what objects are expected.
|
||||
* @throws ClassCastException if chunkObjectArray doesn't contain the right objects.
|
||||
* The exception will contain the expected object(s).
|
||||
*/
|
||||
public DhApiResult<Void> overwriteChunkDataAsync(IDhApiLevelWrapper levelWrapper, Object[] chunkObjectArray) throws ClassCastException;
|
||||
DhApiResult<Void> overwriteChunkDataAsync(IDhApiLevelWrapper levelWrapper, Object[] chunkObjectArray) throws ClassCastException;
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// helpers //
|
||||
//=========//
|
||||
|
||||
/**
|
||||
* @return a {@link IDhApiTerrainDataCache} backed by {@link java.lang.ref.SoftReference}'s.
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
IDhApiTerrainDataCache getSoftCache();
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -31,7 +31,7 @@ import java.io.IOException;
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2023-12-16
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public interface IDhApiWrapperFactory
|
||||
{
|
||||
@@ -50,7 +50,7 @@ public interface IDhApiWrapperFactory
|
||||
* @throws ClassCastException if any of the given parameters is of the wrong type.
|
||||
* If thrown the error message will contain the list of expected object types in order.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
IDhApiBiomeWrapper getBiomeWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper) throws ClassCastException;
|
||||
|
||||
@@ -67,13 +67,13 @@ public interface IDhApiWrapperFactory
|
||||
* @throws ClassCastException if any of the given parameters is of the wrong type.
|
||||
* If thrown the error message will contain the list of expected object types in order.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
IDhApiBlockStateWrapper getBlockStateWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper) throws ClassCastException;
|
||||
|
||||
/**
|
||||
* Returns the {@link IDhApiBlockStateWrapper} representing air.
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
IDhApiBlockStateWrapper getAirBlockStateWrapper();
|
||||
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ package com.seibel.distanthorizons.api.interfaces.override.rendering;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.EDhApiDetailLevel;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
|
||||
|
||||
/**
|
||||
* Used to determine if a LOD should be rendered or is outside the
|
||||
@@ -29,7 +29,7 @@ import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-2-6
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public interface IDhApiCullingFrustum extends IDhApiOverrideable
|
||||
{
|
||||
@@ -41,7 +41,7 @@ public interface IDhApiCullingFrustum extends IDhApiOverrideable
|
||||
* @param worldMaxBlockY the highest block position this level allows.
|
||||
* @param worldViewProjection the projection matrix used in this render pass.
|
||||
*/
|
||||
void update(int worldMinBlockY, int worldMaxBlockY, Mat4f worldViewProjection);
|
||||
void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f worldViewProjection);
|
||||
|
||||
/**
|
||||
* returns true if the LOD bounds intersect this frustum
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 2024-1-24
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public interface IDhApiFramebuffer extends IDhApiOverrideable
|
||||
{
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.api.interfaces.override.rendering;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
|
||||
|
||||
/**
|
||||
* @see IDhApiShaderProgram
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-11
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public interface IDhApiGenericObjectShaderProgram extends IDhApiOverrideable
|
||||
{
|
||||
|
||||
/**
|
||||
* If this method is called that means this program has the highest priority as defined by {@link IDhApiOverrideable#getPriority()}
|
||||
* and gets to decide if it wants to be used to render this frame or not. <br><br>
|
||||
*
|
||||
* If this method returns true then this program will be used for this frame. <br>
|
||||
* If this returns false then the default DH {@link IDhApiGenericObjectShaderProgram} will be used instead.
|
||||
*/
|
||||
boolean overrideThisFrame();
|
||||
|
||||
/** @return the OpenGL ID for this shader program */
|
||||
int getId();
|
||||
|
||||
/** Free any OpenGL objects owned by this program. */
|
||||
void free();
|
||||
|
||||
/** Runs any necessary binding this program needs so rendering can be done. */
|
||||
void bind(DhApiRenderParam renderEventParam);
|
||||
/** Runs any necessary unbinding this program needs so rendering can be done by another program. */
|
||||
void unbind();
|
||||
|
||||
/** Binds the given Vertex Buffer Object to this shader program for rendering. */
|
||||
void bindVertexBuffer(int vbo);
|
||||
|
||||
|
||||
/** sets up the necessary uniforms for rendering */
|
||||
void fillIndirectUniformData(
|
||||
DhApiRenderParam renderParameters,
|
||||
DhApiRenderableBoxGroupShading shading, IDhApiRenderableBoxGroup boxGroup,
|
||||
DhApiVec3d camPos);
|
||||
|
||||
/** sets up the necessary uniforms for rendering */
|
||||
void fillSharedDirectUniformData(
|
||||
DhApiRenderParam renderParameters,
|
||||
DhApiRenderableBoxGroupShading shading, IDhApiRenderableBoxGroup boxGroup,
|
||||
DhApiVec3d camPos);
|
||||
void fillDirectUniformData(
|
||||
DhApiRenderParam renderParameters,
|
||||
IDhApiRenderableBoxGroup boxGroup, DhApiRenderableBox box,
|
||||
DhApiVec3d camPos);
|
||||
|
||||
|
||||
}
|
||||
+5
-4
@@ -21,13 +21,14 @@ package com.seibel.distanthorizons.api.interfaces.override.rendering;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
|
||||
/**
|
||||
* @see IDhApiGenericObjectShaderProgram
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-24
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public interface IDhApiShaderProgram extends IDhApiOverrideable
|
||||
{
|
||||
@@ -57,7 +58,7 @@ public interface IDhApiShaderProgram extends IDhApiOverrideable
|
||||
void fillUniformData(DhApiRenderParam renderParameters);
|
||||
|
||||
/** sets the vec3 that all DH verticies should be offset by when rendering */
|
||||
void setModelOffsetPos(Vec3f modelPos);
|
||||
void setModelOffsetPos(DhApiVec3f modelPos);
|
||||
|
||||
/** Binds the given Vertex Buffer Object to this shader program for rendering. */
|
||||
void bindVertexBuffer(int vbo);
|
||||
|
||||
+1
-5
@@ -19,10 +19,6 @@
|
||||
|
||||
package com.seibel.distanthorizons.api.interfaces.override.rendering;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.EDhApiDetailLevel;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
|
||||
/**
|
||||
* The culling frustum used during Distant Horizons' shadow pass
|
||||
* if another mod has enabled Distant Horizons' shadow
|
||||
@@ -35,7 +31,7 @@ import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-2-10
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public interface IDhApiShadowCullingFrustum extends IDhApiCullingFrustum
|
||||
{
|
||||
|
||||
+2
-2
@@ -168,7 +168,7 @@ public interface IDhApiWorldGenerator extends Closeable, IDhApiOverrideable
|
||||
*
|
||||
* @return a future that should run on the worldGeneratorThreadPool and complete once the given generation task has completed.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
default CompletableFuture<Void> generateApiChunks(
|
||||
int chunkPosMinX,
|
||||
@@ -189,7 +189,7 @@ public interface IDhApiWorldGenerator extends Closeable, IDhApiOverrideable
|
||||
* which means that {@link #generateChunks(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer)}
|
||||
* will be invoked whenever Distant Horizons wants to generate terrain with this world generator.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
default EDhApiWorldGeneratorReturnType getReturnType() { return EDhApiWorldGeneratorReturnType.VANILLA_CHUNKS; }
|
||||
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.seibel.distanthorizons.api.interfaces.render;
|
||||
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles creating
|
||||
* {@link IDhApiRenderableBoxGroup} objects,
|
||||
* which can be added via a {@link IDhApiCustomRenderRegister}.
|
||||
*
|
||||
* @see IDhApiCustomRenderRegister
|
||||
* @see IDhApiRenderableBoxGroup
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-3
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public interface IDhApiCustomRenderObjectFactory
|
||||
{
|
||||
/**
|
||||
* Creates a {@link IDhApiRenderableBoxGroup} from for the given {@link DhApiRenderableBox}
|
||||
* where the box is positioned relative to the level's origin.
|
||||
*
|
||||
* @param resourceLocation A colon separated Resource Location string, similar to vanilla Minecraft, for example: "DistantHorizons:Clouds"
|
||||
*
|
||||
* @see DhApiRenderableBox
|
||||
* @see IDhApiRenderableBoxGroup#getResourceLocationNamespace()
|
||||
* @see IDhApiRenderableBoxGroup#getResourceLocationPath()
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>resourceLocation</code> is null, isn't separated by a colon, or has multiple colons.
|
||||
*/
|
||||
IDhApiRenderableBoxGroup createForSingleBox(String resourceLocation, DhApiRenderableBox cube) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Creates a {@link IDhApiRenderableBoxGroup} from the given list of {@link DhApiRenderableBox} where each
|
||||
* one is positioned relative to given <code>originBlockPos</code>, which in turn is relative to the level's origin.
|
||||
*
|
||||
* @param resourceLocation A colon separated Resource Location string, similar to vanilla Minecraft, for example: "DistantHorizons:Clouds"
|
||||
* @param originBlockPos The starting position for this {@link IDhApiRenderableBoxGroup}, can be changed during runtime.
|
||||
*
|
||||
*
|
||||
* @see DhApiRenderableBox
|
||||
* @see IDhApiRenderableBoxGroup#getResourceLocationNamespace()
|
||||
* @see IDhApiRenderableBoxGroup#getResourceLocationPath()
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>resourceLocation</code> is null, isn't separated by a colon, or has multiple colons.
|
||||
*/
|
||||
IDhApiRenderableBoxGroup createRelativePositionedGroup(String resourceLocation, DhApiVec3d originBlockPos, List<DhApiRenderableBox> cubeList);
|
||||
|
||||
/**
|
||||
* Creates a {@link IDhApiRenderableBoxGroup} from the given list of {@link DhApiRenderableBox} where each
|
||||
* one is positioned relative to the level's origin.
|
||||
*
|
||||
* @param resourceLocation A colon separated Resource Location string, similar to vanilla Minecraft, for example: "DistantHorizons:Clouds"
|
||||
*
|
||||
* @see DhApiRenderableBox
|
||||
* @see IDhApiRenderableBoxGroup#getResourceLocationNamespace()
|
||||
* @see IDhApiRenderableBoxGroup#getResourceLocationPath()
|
||||
*
|
||||
* @throws IllegalArgumentException if <code>resourceLocation</code> is null, isn't separated by a colon, or has multiple colons.
|
||||
*/
|
||||
IDhApiRenderableBoxGroup createAbsolutePositionedGroup(String resourceLocation, List<DhApiRenderableBox> cubeList);
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.seibel.distanthorizons.api.interfaces.render;
|
||||
|
||||
import com.seibel.distanthorizons.api.DhApi;
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiWorldProxy;
|
||||
|
||||
/**
|
||||
* Handles adding and removing
|
||||
* {@link IDhApiRenderableBoxGroup} objects,
|
||||
* from DH's renderer. <br><br>
|
||||
*
|
||||
* Can be accessed in
|
||||
* {@link DhApi.Delayed#worldProxy} -> {@link IDhApiLevelWrapper}.
|
||||
*
|
||||
* @see IDhApiCustomRenderObjectFactory
|
||||
* @see IDhApiRenderableBoxGroup
|
||||
* @see IDhApiWorldProxy
|
||||
* @see IDhApiLevelWrapper
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-3
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public interface IDhApiCustomRenderRegister
|
||||
{
|
||||
void add(IDhApiRenderableBoxGroup cubeGroup) throws IllegalArgumentException;
|
||||
|
||||
IDhApiRenderableBoxGroup remove(long id);
|
||||
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package com.seibel.distanthorizons.api.interfaces.render;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3i;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A list of {@link DhApiRenderableBox}'s that
|
||||
* can be rendered to DH's terrain pass.
|
||||
*
|
||||
* @see DhApiRenderableBox
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-6-30
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public interface IDhApiRenderableBoxGroup extends List<DhApiRenderableBox>
|
||||
{
|
||||
/**
|
||||
* A unique numerical ID used by DH during rendering.
|
||||
* This can also be used to bind/unbind specific {@link IDhApiRenderableBoxGroup}'s from the renderer.
|
||||
* @return the ID for this specific group
|
||||
*/
|
||||
long getId();
|
||||
|
||||
/**
|
||||
* Used to determine which mods have added what to the DH renderer.
|
||||
* This can be used both by the F3 pie chart so you as a mod developer can profile your code
|
||||
* or by shader developers who want to render your objects differently. <br><br>
|
||||
*
|
||||
* Should be used the same as a vanilla Minecraft ResourceLocation.
|
||||
* For example if your mod named "Heavy Thunder" adds additional clouds named "Storm Front",
|
||||
* your Resource Location would be something like "HeavyThunder:StormFront"
|
||||
* and this method would return "HeavyThunder".
|
||||
*/
|
||||
String getResourceLocationNamespace();
|
||||
/**
|
||||
* Used to determine what type of object mods have added what to the DH renderer.
|
||||
* This can be used both by the F3 pie chart so you as a mod developer can profile your code
|
||||
* or by shader developers who want to render your objects differently. <br><br>
|
||||
*
|
||||
* Should be used the same as a vanilla Minecraft ResourceLocation.
|
||||
* For example if your mod named "Heavy Thunder" adds additional clouds named "Storm Front",
|
||||
* your Resource Location would be something like "HeavyThunder:StormFront"
|
||||
* and this method would return "StormFront".
|
||||
*/
|
||||
String getResourceLocationPath();
|
||||
|
||||
/** Sets whether this group should render or not. */
|
||||
void setActive(boolean active);
|
||||
/** @return if active this group will render. */
|
||||
boolean isActive();
|
||||
|
||||
/** Sets whether this group should render with Screen Space Ambient Occlusioning. */
|
||||
void setSsaoEnabled(boolean ssaoEnabled);
|
||||
/** @return if active this group will render with Screen Space Ambient Occlusioning. */
|
||||
boolean isSsaoEnabled();
|
||||
|
||||
/** Sets where this group will render in the level. */
|
||||
void setOriginBlockPos(DhApiVec3d pos);
|
||||
/** @return the block position in the level that all {@see DhApiRenderableBox} will render relative to. */
|
||||
DhApiVec3d getOriginBlockPos();
|
||||
|
||||
/**
|
||||
* Called right before this group is rendered. <br>
|
||||
* This is a good place to change the origin or notify of any box changes.
|
||||
*/
|
||||
void setPreRenderFunc(Consumer<DhApiRenderParam> renderEventParam);
|
||||
void setPostRenderFunc(Consumer<DhApiRenderParam> renderEventParam); // TODO name?
|
||||
|
||||
/**
|
||||
* If a cube's color, position, or other property is changed this method
|
||||
* must be called for those changes to render. <br><br>
|
||||
*
|
||||
* Note: changing the group's position via {@link #setOriginBlockPos} doesn't
|
||||
* require calling this method.
|
||||
*/
|
||||
void triggerBoxChange();
|
||||
|
||||
/** Only accepts values between 0 and 15 */
|
||||
void setSkyLight(int skyLight);
|
||||
int getSkyLight();
|
||||
|
||||
/** Only accepts values between 0 and 15 */
|
||||
void setBlockLight(int blockLight);
|
||||
int getBlockLight();
|
||||
|
||||
void setShading(DhApiRenderableBoxGroupShading shading);
|
||||
DhApiRenderableBoxGroupShading getShading();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.seibel.distanthorizons.api.interfaces.util;
|
||||
|
||||
/**
|
||||
* Used for objects that need deep clones. <br>
|
||||
* Replacement for {@link Cloneable}.
|
||||
*
|
||||
* @see Cloneable
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-12
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public interface IDhApiCopyable
|
||||
{
|
||||
/** Returns a deep clone of all parameters whenever possible. */
|
||||
IDhApiCopyable copy();
|
||||
|
||||
}
|
||||
+8
-1
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.api.interfaces.world;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.IDhApiUnsafeWrapper;
|
||||
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||
|
||||
/**
|
||||
* Can be either a Server or Client level.<br>
|
||||
@@ -41,7 +42,7 @@ public interface IDhApiLevelWrapper extends IDhApiUnsafeWrapper
|
||||
boolean hasSkyLight();
|
||||
|
||||
/** Returns the max block height of the level(?) */
|
||||
int getHeight();
|
||||
int getMaxHeight();
|
||||
|
||||
/**
|
||||
* Returns the lowest possible block position for the level. <br>
|
||||
@@ -49,4 +50,10 @@ public interface IDhApiLevelWrapper extends IDhApiUnsafeWrapper
|
||||
*/
|
||||
default int getMinHeight() { return 0; }
|
||||
|
||||
/**
|
||||
* Will return null if called on the server,
|
||||
* or if called before the renderer has been set up.
|
||||
*/
|
||||
IDhApiCustomRenderRegister getRenderRegister();
|
||||
|
||||
}
|
||||
|
||||
+9
-6
@@ -26,17 +26,20 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
|
||||
/**
|
||||
* Fired after Distant Horizons finishes rendering a frame. <br>
|
||||
* At this point DH will have also finished cleaning up any modifications it
|
||||
* did to the OpenGL state, so the state should be back to Minecraft's defaults.
|
||||
* did to the OpenGL state, so the state should be back to Minecraft's defaults. <br><br>
|
||||
*
|
||||
* Note: as of API v 3.0.0 no {@link DhApiRenderParam} is included in this event
|
||||
* because the specific parameters may change
|
||||
* depending on whether deferred rendering is enabled or not.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-31
|
||||
* @see DhApiRenderParam
|
||||
* @version 2024-7-14
|
||||
* @since API 1.0.0
|
||||
*/
|
||||
public abstract class DhApiAfterRenderEvent implements IDhApiEvent<DhApiRenderParam>
|
||||
public abstract class DhApiAfterRenderEvent implements IDhApiEvent<Void>
|
||||
{
|
||||
/** Fired after Distant Horizons finishes rendering fake chunks. */
|
||||
public abstract void afterRender(DhApiEventParam<DhApiRenderParam> event);
|
||||
public abstract void afterRender(DhApiEventParam<Void> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
@@ -44,6 +47,6 @@ public abstract class DhApiAfterRenderEvent implements IDhApiEvent<DhApiRenderPa
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiEventParam<DhApiRenderParam> event) { this.afterRender(event); }
|
||||
public final void fireEvent(DhApiEventParam<Void> event) { this.afterRender(event); }
|
||||
|
||||
}
|
||||
+1
-1
@@ -31,7 +31,7 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-31
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public abstract class DhApiBeforeApplyShaderRenderEvent implements IDhApiCancelableEvent<DhApiRenderParam>
|
||||
{
|
||||
|
||||
+15
-5
@@ -20,9 +20,10 @@
|
||||
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
|
||||
/**
|
||||
* Called before Distant Horizons starts rendering a buffer. <br>
|
||||
@@ -30,7 +31,7 @@ import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2023-1-31
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*
|
||||
* @see DhApiBeforeRenderEvent
|
||||
*/
|
||||
@@ -52,20 +53,29 @@ public abstract class DhApiBeforeBufferRenderEvent implements IDhApiEvent<DhApiB
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam extends DhApiRenderParam
|
||||
public static class EventParam extends DhApiRenderParam implements IDhApiEventParam
|
||||
{
|
||||
/**
|
||||
* Measured in blocks.
|
||||
* Should be applied to the model view matrix to move the buffer into its proper place.
|
||||
*/
|
||||
public final Vec3f modelPos;
|
||||
public final DhApiVec3f modelPos;
|
||||
|
||||
|
||||
public EventParam(DhApiRenderParam parent, Vec3f modelPos)
|
||||
public EventParam(DhApiRenderParam parent, DhApiVec3f modelPos)
|
||||
{
|
||||
super(parent);
|
||||
this.modelPos = modelPos;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EventParam copy()
|
||||
{
|
||||
return new EventParam(
|
||||
this, this.modelPos.copy()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -29,7 +29,7 @@ import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderProxy;
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-22
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public abstract class DhApiBeforeDeferredRenderEvent extends DhApiBeforeRenderEvent
|
||||
{
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiCancelableEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
|
||||
/**
|
||||
* Called before Distant Horizons starts rendering a generic object. <br>
|
||||
* Canceling this event will prevent the triggering {@link IDhApiRenderableBoxGroup} from rendering this frame.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-11
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public abstract class DhApiBeforeGenericObjectRenderEvent implements IDhApiCancelableEvent<DhApiBeforeGenericObjectRenderEvent.EventParam>
|
||||
{
|
||||
/** Fired before Distant Horizons renders a generic object. */
|
||||
public abstract void beforeRender(DhApiCancelableEventParam<EventParam> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiCancelableEventParam<EventParam> input) { this.beforeRender(input); }
|
||||
|
||||
|
||||
//==================//
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam extends DhApiRenderParam implements IDhApiEventParam
|
||||
{
|
||||
public final long boxGroupId;
|
||||
public final String resourceLocationNamespace;
|
||||
public final String resourceLocationPath;
|
||||
|
||||
|
||||
public EventParam(
|
||||
DhApiRenderParam renderParam,
|
||||
IDhApiRenderableBoxGroup boxGroup
|
||||
)
|
||||
{
|
||||
super(renderParam);
|
||||
|
||||
this.boxGroupId = boxGroup.getId();
|
||||
this.resourceLocationNamespace = boxGroup.getResourceLocationNamespace();
|
||||
this.resourceLocationPath = boxGroup.getResourceLocationPath();
|
||||
}
|
||||
public EventParam(
|
||||
DhApiRenderParam renderParam,
|
||||
long boxGroupId, String resourceLocationNamespace, String resourceLocationPath
|
||||
)
|
||||
{
|
||||
super(renderParam);
|
||||
|
||||
this.boxGroupId = boxGroupId;
|
||||
this.resourceLocationNamespace = resourceLocationNamespace;
|
||||
this.resourceLocationPath = resourceLocationPath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public EventParam copy()
|
||||
{
|
||||
return new EventParam(
|
||||
this,
|
||||
this.boxGroupId, this.resourceLocationNamespace, this.resourceLocationPath
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
|
||||
/**
|
||||
* Called before Distant Horizons starts the cleanup process done after rendering generic objects. <br>
|
||||
* This is called after all generic objects have finished rendering.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-13
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public abstract class DhApiBeforeGenericRenderCleanupEvent implements IDhApiEvent<DhApiRenderParam>
|
||||
{
|
||||
/** Fired before Distant Horizons starts the cleanup process once rendering has finished. */
|
||||
public abstract void beforeCleanup(DhApiEventParam<DhApiRenderParam> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiEventParam<DhApiRenderParam> event) { this.beforeCleanup(event); }
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
|
||||
/**
|
||||
* Called before Distant Horizons has started setting up OpenGL objects for rendering generic objects. <br>
|
||||
* If you want to modify already bound DH OpenGL objects try using {@link DhApiBeforeGenericObjectRenderEvent}.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-12
|
||||
* @since API 3.0.0
|
||||
*
|
||||
* @see DhApiBeforeGenericObjectRenderEvent
|
||||
*/
|
||||
public abstract class DhApiBeforeGenericRenderSetupEvent implements IDhApiEvent<DhApiRenderParam>
|
||||
{
|
||||
/** Fired before Distant Horizons has started setting up OpenGL objects for rendering generic objects. */
|
||||
public abstract void beforeSetup(DhApiEventParam<DhApiRenderParam> input);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiEventParam<DhApiRenderParam> input) { this.beforeSetup(input); }
|
||||
|
||||
|
||||
}
|
||||
+2
-2
@@ -29,11 +29,11 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-31
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public abstract class DhApiBeforeRenderCleanupEvent implements IDhApiEvent<DhApiRenderParam>
|
||||
{
|
||||
/** Fired before Distant Horizons renders LODs. */
|
||||
/** Fired before Distant Horizons starts the cleanup process once rendering has finished. */
|
||||
public abstract void beforeCleanup(DhApiEventParam<DhApiRenderParam> event);
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2023-1-31
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*
|
||||
* @see DhApiBeforeRenderEvent
|
||||
*/
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-31
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*
|
||||
* @see DhApiBeforeRenderPassEvent
|
||||
*/
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-31
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public abstract class DhApiBeforeTextureClearEvent implements IDhApiCancelableEvent<DhApiRenderParam>
|
||||
{
|
||||
|
||||
+11
-1
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.api.methods.events.abstractEvents;
|
||||
import com.seibel.distanthorizons.api.interfaces.data.IDhApiTerrainDataRepo;
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
|
||||
/**
|
||||
@@ -53,7 +54,7 @@ public abstract class DhApiChunkModifiedEvent implements IDhApiEvent<DhApiChunkM
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam
|
||||
public static class EventParam implements IDhApiEventParam
|
||||
{
|
||||
/** The saved level. */
|
||||
public final IDhApiLevelWrapper levelWrapper;
|
||||
@@ -71,6 +72,15 @@ public abstract class DhApiChunkModifiedEvent implements IDhApiEvent<DhApiChunkM
|
||||
this.chunkZ = chunkZ;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EventParam copy()
|
||||
{
|
||||
return new EventParam(
|
||||
this.levelWrapper,
|
||||
this.chunkX, this.chunkZ
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+13
-2
@@ -20,6 +20,7 @@
|
||||
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
|
||||
/**
|
||||
@@ -28,7 +29,7 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-3-2
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*/
|
||||
public abstract class DhApiColorDepthTextureCreatedEvent implements IDhApiEvent<DhApiColorDepthTextureCreatedEvent.EventParam>
|
||||
{
|
||||
@@ -48,7 +49,7 @@ public abstract class DhApiColorDepthTextureCreatedEvent implements IDhApiEvent<
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam
|
||||
public static class EventParam implements IDhApiEventParam
|
||||
{
|
||||
/** Measured in pixels */
|
||||
public final int previousWidth;
|
||||
@@ -72,6 +73,16 @@ public abstract class DhApiColorDepthTextureCreatedEvent implements IDhApiEvent<
|
||||
this.newHeight = newHeight;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EventParam copy()
|
||||
{
|
||||
return new EventParam(
|
||||
this.previousWidth, this.previousHeight,
|
||||
this.newWidth, this.newHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+5
-1
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
|
||||
/**
|
||||
@@ -49,13 +50,16 @@ public abstract class DhApiLevelLoadEvent implements IDhApiEvent<DhApiLevelLoadE
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam
|
||||
public static class EventParam implements IDhApiEventParam
|
||||
{
|
||||
/** The newly loaded level. */
|
||||
public final IDhApiLevelWrapper levelWrapper;
|
||||
|
||||
public EventParam(IDhApiLevelWrapper newLevelWrapper) { this.levelWrapper = newLevelWrapper; }
|
||||
|
||||
|
||||
@Override
|
||||
public EventParam copy() { return new EventParam(this.levelWrapper); }
|
||||
}
|
||||
|
||||
}
|
||||
+5
-2
@@ -19,9 +19,9 @@
|
||||
|
||||
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.DhApi;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
|
||||
/**
|
||||
@@ -49,13 +49,16 @@ public abstract class DhApiLevelUnloadEvent implements IDhApiEvent<DhApiLevelUnl
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam
|
||||
public static class EventParam implements IDhApiEventParam
|
||||
{
|
||||
/** The recently unloaded level. */
|
||||
public final IDhApiLevelWrapper levelWrapper;
|
||||
|
||||
public EventParam(IDhApiLevelWrapper newLevelWrapper) { this.levelWrapper = newLevelWrapper; }
|
||||
|
||||
|
||||
@Override
|
||||
public EventParam copy() { return new EventParam(this.levelWrapper); }
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.seibel.distanthorizons.api.methods.events.interfaces;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.util.IDhApiCopyable;
|
||||
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 2024-7-12
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public interface IDhApiEventParam extends IDhApiCopyable
|
||||
{
|
||||
|
||||
}
|
||||
+29
-19
@@ -20,7 +20,8 @@
|
||||
package com.seibel.distanthorizons.api.methods.events.sharedParameterObjects;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
|
||||
|
||||
/**
|
||||
* Contains information relevant to Distant Horizons and Minecraft rendering.
|
||||
@@ -29,7 +30,7 @@ import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
* @version 2024-1-31
|
||||
* @since API 1.0.0
|
||||
*/
|
||||
public class DhApiRenderParam
|
||||
public class DhApiRenderParam implements IDhApiEventParam
|
||||
{
|
||||
/** Indicates what render pass DH is currently rendering */
|
||||
public final EDhApiRenderPass renderPass;
|
||||
@@ -49,18 +50,15 @@ public class DhApiRenderParam
|
||||
public final float farClipPlane;
|
||||
|
||||
/** The projection matrix Minecraft is using to render this frame. */
|
||||
public final Mat4f mcProjectionMatrix;
|
||||
public final DhApiMat4f mcProjectionMatrix;
|
||||
/** The model view matrix Minecraft is using to render this frame. */
|
||||
public final Mat4f mcModelViewMatrix;
|
||||
public final DhApiMat4f mcModelViewMatrix;
|
||||
|
||||
/** The projection matrix Distant Horizons is using to render this frame. */
|
||||
public final Mat4f dhProjectionMatrix;
|
||||
public final DhApiMat4f dhProjectionMatrix;
|
||||
/** The model view matrix Distant Horizons is using to render this frame. */
|
||||
public final Mat4f dhModelViewMatrix;
|
||||
public final DhApiMat4f dhModelViewMatrix;
|
||||
|
||||
public final int lightmapBindingIndex = 0;
|
||||
|
||||
// TODO why is this here? wouldn't it make more sense to have this built into the vertex buffer data?
|
||||
public final int worldYOffset;
|
||||
|
||||
|
||||
@@ -69,24 +67,24 @@ public class DhApiRenderParam
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
|
||||
public DhApiRenderParam(DhApiRenderParam parent)
|
||||
{
|
||||
this(
|
||||
parent.renderPass,
|
||||
parent.partialTicks,
|
||||
parent.nearClipPlane, parent.farClipPlane,
|
||||
parent.mcProjectionMatrix, parent.mcModelViewMatrix,
|
||||
parent.dhProjectionMatrix, parent.dhModelViewMatrix,
|
||||
parent.worldYOffset
|
||||
);
|
||||
parent.renderPass,
|
||||
parent.partialTicks,
|
||||
parent.nearClipPlane, parent.farClipPlane,
|
||||
parent.mcProjectionMatrix.copy(), parent.mcModelViewMatrix.copy(),
|
||||
parent.dhProjectionMatrix.copy(), parent.dhModelViewMatrix.copy(),
|
||||
parent.worldYOffset
|
||||
);
|
||||
}
|
||||
|
||||
public DhApiRenderParam(
|
||||
EDhApiRenderPass renderPass,
|
||||
float newPartialTicks,
|
||||
float nearClipPlane, float farClipPlane,
|
||||
Mat4f newMcProjectionMatrix, Mat4f newMcModelViewMatrix,
|
||||
Mat4f newDhProjectionMatrix, Mat4f newDhModelViewMatrix,
|
||||
DhApiMat4f newMcProjectionMatrix, DhApiMat4f newMcModelViewMatrix,
|
||||
DhApiMat4f newDhProjectionMatrix, DhApiMat4f newDhModelViewMatrix,
|
||||
int worldYOffset
|
||||
)
|
||||
{
|
||||
@@ -107,4 +105,16 @@ public class DhApiRenderParam
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
|
||||
@Override
|
||||
public DhApiRenderParam copy()
|
||||
{
|
||||
return new DhApiRenderParam(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.List;
|
||||
*
|
||||
* @author Builderb0y, James Seibel
|
||||
* @version 2023-12-21
|
||||
* @since API 1.1.0
|
||||
* @since API 2.0.0
|
||||
*
|
||||
* @see IDhApiWrapperFactory
|
||||
* @see DhApiTerrainDataPoint
|
||||
|
||||
+1
-2
@@ -20,7 +20,6 @@
|
||||
package com.seibel.distanthorizons.api.objects.data;
|
||||
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3i;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3i;
|
||||
|
||||
/**
|
||||
* Holds a single datapoint of terrain data
|
||||
@@ -47,7 +46,7 @@ public class DhApiRaycastResult
|
||||
|
||||
|
||||
|
||||
public DhApiRaycastResult(DhApiTerrainDataPoint dataPoint, Vec3i blockPos)
|
||||
public DhApiRaycastResult(DhApiTerrainDataPoint dataPoint, DhApiVec3i blockPos)
|
||||
{
|
||||
this.dataPoint = dataPoint;
|
||||
this.pos = blockPos;
|
||||
|
||||
+126
-360
@@ -17,46 +17,55 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.coreapi.util.math;
|
||||
package com.seibel.distanthorizons.api.objects.math;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import com.seibel.distanthorizons.api.interfaces.util.IDhApiCopyable;
|
||||
|
||||
/**
|
||||
* An (almost) exact copy of Minecraft's 1.16.5
|
||||
* implementation of a 4x4 float matrix.
|
||||
* implementation of a 4x4 float matrix. <br><br>
|
||||
*
|
||||
* <code>
|
||||
* m00, m10, m20, m30, <br>
|
||||
* m01, m11, m21, m31, <br>
|
||||
* m02, m12, m22, m32, <br>
|
||||
* m03, m13, m23, m33 <br>
|
||||
* </code>
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 11-11-2021
|
||||
* @version 2024-6-30
|
||||
*/
|
||||
public class Mat4f
|
||||
public class DhApiMat4f implements IDhApiCopyable
|
||||
{
|
||||
private float m00;
|
||||
private float m01;
|
||||
private float m02;
|
||||
private float m03;
|
||||
private float m10;
|
||||
private float m11;
|
||||
private float m12;
|
||||
private float m13;
|
||||
private float m20;
|
||||
private float m21;
|
||||
private float m22;
|
||||
private float m23;
|
||||
private float m30;
|
||||
private float m31;
|
||||
private float m32;
|
||||
private float m33;
|
||||
public float m00;
|
||||
public float m01;
|
||||
public float m02;
|
||||
public float m03;
|
||||
|
||||
public float m10;
|
||||
public float m11;
|
||||
public float m12;
|
||||
public float m13;
|
||||
|
||||
public float m20;
|
||||
public float m21;
|
||||
public float m22;
|
||||
public float m23;
|
||||
|
||||
public float m30;
|
||||
public float m31;
|
||||
public float m32;
|
||||
public float m33;
|
||||
|
||||
|
||||
public Mat4f()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Mat4f(Mat4f sourceMatrix)
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public DhApiMat4f() { /* all values are 0 */ }
|
||||
|
||||
public DhApiMat4f(DhApiMat4f sourceMatrix)
|
||||
{
|
||||
this.m00 = sourceMatrix.m00;
|
||||
this.m01 = sourceMatrix.m01;
|
||||
@@ -76,163 +85,36 @@ public class Mat4f
|
||||
this.m33 = sourceMatrix.m33;
|
||||
}
|
||||
|
||||
public Mat4f(Matrix4fc sourceMatrix) { this(convertJomlMatrixToArray(sourceMatrix)); }
|
||||
private static float[] convertJomlMatrixToArray(Matrix4fc sourceMatrix)
|
||||
/** Expects the values of the input array to be in row major order (AKA rows then columns) */
|
||||
public DhApiMat4f(float[] values)
|
||||
{
|
||||
FloatBuffer buffer = FloatBuffer.allocate(16);
|
||||
m00 = values[0];
|
||||
m01 = values[1];
|
||||
m02 = values[2];
|
||||
m03 = values[3];
|
||||
|
||||
buffer.put(bufferIndex(0, 0), sourceMatrix.m00());
|
||||
buffer.put(bufferIndex(0, 1), sourceMatrix.m01());
|
||||
buffer.put(bufferIndex(0, 2), sourceMatrix.m02());
|
||||
buffer.put(bufferIndex(0, 3), sourceMatrix.m03());
|
||||
buffer.put(bufferIndex(1, 0), sourceMatrix.m10());
|
||||
buffer.put(bufferIndex(1, 1), sourceMatrix.m11());
|
||||
buffer.put(bufferIndex(1, 2), sourceMatrix.m12());
|
||||
buffer.put(bufferIndex(1, 3), sourceMatrix.m13());
|
||||
buffer.put(bufferIndex(2, 0), sourceMatrix.m20());
|
||||
buffer.put(bufferIndex(2, 1), sourceMatrix.m21());
|
||||
buffer.put(bufferIndex(2, 2), sourceMatrix.m22());
|
||||
buffer.put(bufferIndex(2, 3), sourceMatrix.m23());
|
||||
buffer.put(bufferIndex(3, 0), sourceMatrix.m30());
|
||||
buffer.put(bufferIndex(3, 1), sourceMatrix.m31());
|
||||
buffer.put(bufferIndex(3, 2), sourceMatrix.m32());
|
||||
buffer.put(bufferIndex(3, 3), sourceMatrix.m33());
|
||||
m10 = values[4];
|
||||
m11 = values[5];
|
||||
m12 = values[6];
|
||||
m13 = values[7];
|
||||
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
/* Quaternions are not currently needed/implemented
|
||||
public Matrix4float(Quaternion p_i48104_1_)
|
||||
{
|
||||
float f = p_i48104_1_.i();
|
||||
float f1 = p_i48104_1_.j();
|
||||
float f2 = p_i48104_1_.k();
|
||||
float f3 = p_i48104_1_.r();
|
||||
float f4 = 2.0F * f * f;
|
||||
float f5 = 2.0F * f1 * f1;
|
||||
float f6 = 2.0F * f2 * f2;
|
||||
this.m00 = 1.0F - f5 - f6;
|
||||
this.m11 = 1.0F - f6 - f4;
|
||||
this.m22 = 1.0F - f4 - f5;
|
||||
this.m33 = 1.0F;
|
||||
float f7 = f * f1;
|
||||
float f8 = f1 * f2;
|
||||
float f9 = f2 * f;
|
||||
float f10 = f * f3;
|
||||
float f11 = f1 * f3;
|
||||
float f12 = f2 * f3;
|
||||
this.m10 = 2.0F * (f7 + f12);
|
||||
this.m01 = 2.0F * (f7 - f12);
|
||||
this.m20 = 2.0F * (f9 - f11);
|
||||
this.m02 = 2.0F * (f9 + f11);
|
||||
this.m21 = 2.0F * (f8 + f10);
|
||||
this.m12 = 2.0F * (f8 - f10);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obj != null && this.getClass() == obj.getClass())
|
||||
{
|
||||
Mat4f otherMatrix = (Mat4f) obj;
|
||||
return Float.compare(otherMatrix.m00, this.m00) == 0
|
||||
&& Float.compare(otherMatrix.m01, this.m01) == 0
|
||||
&& Float.compare(otherMatrix.m02, this.m02) == 0
|
||||
&& Float.compare(otherMatrix.m03, this.m03) == 0
|
||||
&& Float.compare(otherMatrix.m10, this.m10) == 0
|
||||
&& Float.compare(otherMatrix.m11, this.m11) == 0
|
||||
&& Float.compare(otherMatrix.m12, this.m12) == 0
|
||||
&& Float.compare(otherMatrix.m13, this.m13) == 0
|
||||
&& Float.compare(otherMatrix.m20, this.m20) == 0
|
||||
&& Float.compare(otherMatrix.m21, this.m21) == 0
|
||||
&& Float.compare(otherMatrix.m22, this.m22) == 0
|
||||
&& Float.compare(otherMatrix.m23, this.m23) == 0
|
||||
&& Float.compare(otherMatrix.m30, this.m30) == 0
|
||||
&& Float.compare(otherMatrix.m31, this.m31) == 0
|
||||
&& Float.compare(otherMatrix.m32, this.m32) == 0
|
||||
&& Float.compare(otherMatrix.m33, this.m33) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int i = this.m00 != 0.0F ? Float.floatToIntBits(this.m00) : 0;
|
||||
i = 31 * i + (this.m01 != 0.0F ? Float.floatToIntBits(this.m01) : 0);
|
||||
i = 31 * i + (this.m02 != 0.0F ? Float.floatToIntBits(this.m02) : 0);
|
||||
i = 31 * i + (this.m03 != 0.0F ? Float.floatToIntBits(this.m03) : 0);
|
||||
i = 31 * i + (this.m10 != 0.0F ? Float.floatToIntBits(this.m10) : 0);
|
||||
i = 31 * i + (this.m11 != 0.0F ? Float.floatToIntBits(this.m11) : 0);
|
||||
i = 31 * i + (this.m12 != 0.0F ? Float.floatToIntBits(this.m12) : 0);
|
||||
i = 31 * i + (this.m13 != 0.0F ? Float.floatToIntBits(this.m13) : 0);
|
||||
i = 31 * i + (this.m20 != 0.0F ? Float.floatToIntBits(this.m20) : 0);
|
||||
i = 31 * i + (this.m21 != 0.0F ? Float.floatToIntBits(this.m21) : 0);
|
||||
i = 31 * i + (this.m22 != 0.0F ? Float.floatToIntBits(this.m22) : 0);
|
||||
i = 31 * i + (this.m23 != 0.0F ? Float.floatToIntBits(this.m23) : 0);
|
||||
i = 31 * i + (this.m30 != 0.0F ? Float.floatToIntBits(this.m30) : 0);
|
||||
i = 31 * i + (this.m31 != 0.0F ? Float.floatToIntBits(this.m31) : 0);
|
||||
i = 31 * i + (this.m32 != 0.0F ? Float.floatToIntBits(this.m32) : 0);
|
||||
return 31 * i + (this.m33 != 0.0F ? Float.floatToIntBits(this.m33) : 0);
|
||||
m20 = values[8];
|
||||
m21 = values[9];
|
||||
m22 = values[10];
|
||||
m23 = values[11];
|
||||
|
||||
m30 = values[12];
|
||||
m31 = values[13];
|
||||
m32 = values[14];
|
||||
m33 = values[15];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Matrix4f:\n" +
|
||||
this.m00 + " " + this.m01 + " " + this.m02 + " " + this.m03 + "\n" +
|
||||
this.m10 + " " + this.m11 + " " + this.m12 + " " + this.m13 + "\n" +
|
||||
this.m20 + " " + this.m21 + " " + this.m22 + " " + this.m23 + "\n" +
|
||||
this.m30 + " " + this.m31 + " " + this.m32 + " " + this.m33 + "\n";
|
||||
}
|
||||
|
||||
|
||||
public void store(FloatBuffer floatBuffer)
|
||||
{
|
||||
floatBuffer.put(bufferIndex(0, 0), this.m00);
|
||||
floatBuffer.put(bufferIndex(0, 1), this.m01);
|
||||
floatBuffer.put(bufferIndex(0, 2), this.m02);
|
||||
floatBuffer.put(bufferIndex(0, 3), this.m03);
|
||||
floatBuffer.put(bufferIndex(1, 0), this.m10);
|
||||
floatBuffer.put(bufferIndex(1, 1), this.m11);
|
||||
floatBuffer.put(bufferIndex(1, 2), this.m12);
|
||||
floatBuffer.put(bufferIndex(1, 3), this.m13);
|
||||
floatBuffer.put(bufferIndex(2, 0), this.m20);
|
||||
floatBuffer.put(bufferIndex(2, 1), this.m21);
|
||||
floatBuffer.put(bufferIndex(2, 2), this.m22);
|
||||
floatBuffer.put(bufferIndex(2, 3), this.m23);
|
||||
floatBuffer.put(bufferIndex(3, 0), this.m30);
|
||||
floatBuffer.put(bufferIndex(3, 1), this.m31);
|
||||
floatBuffer.put(bufferIndex(3, 2), this.m32);
|
||||
floatBuffer.put(bufferIndex(3, 3), this.m33);
|
||||
}
|
||||
|
||||
public Matrix4f createJomlMatrix()
|
||||
{
|
||||
return new Matrix4f(
|
||||
this.m00, this.m10, this.m20, this.m30,
|
||||
this.m01, this.m11, this.m21, this.m31,
|
||||
this.m02, this.m12, this.m22, this.m32,
|
||||
this.m03, this.m13, this.m23, this.m33
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private static int bufferIndex(int xIndex, int zIndex)
|
||||
{
|
||||
return (zIndex * 4) + xIndex;
|
||||
}
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
public void setIdentity()
|
||||
{
|
||||
@@ -341,7 +223,7 @@ public class Mat4f
|
||||
}
|
||||
}
|
||||
|
||||
public void multiply(Mat4f multMatrix)
|
||||
public void multiply(DhApiMat4f multMatrix)
|
||||
{
|
||||
float f = this.m00 * multMatrix.m00 + this.m01 * multMatrix.m10 + this.m02 * multMatrix.m20 + this.m03 * multMatrix.m30;
|
||||
float f1 = this.m00 * multMatrix.m01 + this.m01 * multMatrix.m11 + this.m02 * multMatrix.m21 + this.m03 * multMatrix.m31;
|
||||
@@ -377,13 +259,6 @@ public class Mat4f
|
||||
this.m33 = f15;
|
||||
}
|
||||
|
||||
/* Quaternions aren't currently needed/implemented
|
||||
public void multiply(Quaternion p_226596_1_)
|
||||
{
|
||||
this.multiply(new Matrix4f(p_226596_1_));
|
||||
}
|
||||
*/
|
||||
|
||||
public void multiply(float scalar)
|
||||
{
|
||||
this.m00 *= scalar;
|
||||
@@ -404,81 +279,6 @@ public class Mat4f
|
||||
this.m33 *= scalar;
|
||||
}
|
||||
|
||||
public static Mat4f perspective(double fov, float widthHeightRatio, float nearClipPlane, float farClipPlane)
|
||||
{
|
||||
float f = (float) (1.0D / Math.tan(fov * ((float) Math.PI / 180F) / 2.0D));
|
||||
Mat4f matrix = new Mat4f();
|
||||
matrix.m00 = f / widthHeightRatio;
|
||||
matrix.m11 = f;
|
||||
matrix.m22 = (farClipPlane + nearClipPlane) / (nearClipPlane - farClipPlane);
|
||||
matrix.m32 = -1.0F;
|
||||
matrix.m23 = 2.0F * farClipPlane * nearClipPlane / (nearClipPlane - farClipPlane);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
|
||||
/* not currently needed/implemented
|
||||
* Also the parameter names should be double checked as they may be incorrect
|
||||
public static Matrix4Float orthographic(float left, float right, float top, float bottom)
|
||||
{
|
||||
Matrix4Float matrix4f = new Matrix4Float();
|
||||
matrix4f.m00 = 2.0F / left;
|
||||
matrix4f.m11 = 2.0F / right;
|
||||
float f = bottom - top;
|
||||
matrix4f.m22 = -2.0F / f;
|
||||
matrix4f.m33 = 1.0F;
|
||||
matrix4f.m03 = -1.0F;
|
||||
matrix4f.m13 = -1.0F;
|
||||
matrix4f.m23 = -(bottom + top) / f;
|
||||
return matrix4f;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* TODO: what kind of translation is this?
|
||||
* and how is this different from "multiplyTranslationMatrix"?
|
||||
* Answer: This is faster and direct (but only if this is pure translation matrix without rotate)
|
||||
*/
|
||||
public void translate(Vec3f vec)
|
||||
{
|
||||
this.m03 += vec.x;
|
||||
this.m13 += vec.y;
|
||||
this.m23 += vec.z;
|
||||
}
|
||||
|
||||
/** originally "translate" from Minecraft's MatrixStack */
|
||||
public void multiplyTranslationMatrix(double x, double y, double z)
|
||||
{
|
||||
multiply(createTranslateMatrix((float) x, (float) y, (float) z));
|
||||
}
|
||||
|
||||
public Mat4f copy()
|
||||
{
|
||||
return new Mat4f(this);
|
||||
}
|
||||
|
||||
public static Mat4f createScaleMatrix(float x, float y, float z)
|
||||
{
|
||||
Mat4f matrix = new Mat4f();
|
||||
matrix.m00 = x;
|
||||
matrix.m11 = y;
|
||||
matrix.m22 = z;
|
||||
matrix.m33 = 1.0F;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public static Mat4f createTranslateMatrix(float x, float y, float z)
|
||||
{
|
||||
Mat4f matrix = new Mat4f();
|
||||
matrix.m00 = 1.0F;
|
||||
matrix.m11 = 1.0F;
|
||||
matrix.m22 = 1.0F;
|
||||
matrix.m33 = 1.0F;
|
||||
matrix.m03 = x;
|
||||
matrix.m13 = y;
|
||||
matrix.m23 = z;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -487,6 +287,8 @@ public class Mat4f
|
||||
// methods //
|
||||
//==================//
|
||||
|
||||
private static int getArrayIndex(int xIndex, int zIndex) { return (zIndex * 4) + xIndex; }
|
||||
|
||||
/** Returns the values of this matrix in row major order (AKA rows then columns) */
|
||||
public float[] getValuesAsArray()
|
||||
{
|
||||
@@ -513,113 +315,77 @@ public class Mat4f
|
||||
};
|
||||
}
|
||||
|
||||
public Vec3f asNonNormalizedLookForwardVector()
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
return new Vec3f(this.m02, this.m12, this.m22);
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obj != null && this.getClass() == obj.getClass())
|
||||
{
|
||||
DhApiMat4f otherMatrix = (DhApiMat4f) obj;
|
||||
return Float.compare(otherMatrix.m00, this.m00) == 0
|
||||
&& Float.compare(otherMatrix.m01, this.m01) == 0
|
||||
&& Float.compare(otherMatrix.m02, this.m02) == 0
|
||||
&& Float.compare(otherMatrix.m03, this.m03) == 0
|
||||
&& Float.compare(otherMatrix.m10, this.m10) == 0
|
||||
&& Float.compare(otherMatrix.m11, this.m11) == 0
|
||||
&& Float.compare(otherMatrix.m12, this.m12) == 0
|
||||
&& Float.compare(otherMatrix.m13, this.m13) == 0
|
||||
&& Float.compare(otherMatrix.m20, this.m20) == 0
|
||||
&& Float.compare(otherMatrix.m21, this.m21) == 0
|
||||
&& Float.compare(otherMatrix.m22, this.m22) == 0
|
||||
&& Float.compare(otherMatrix.m23, this.m23) == 0
|
||||
&& Float.compare(otherMatrix.m30, this.m30) == 0
|
||||
&& Float.compare(otherMatrix.m31, this.m31) == 0
|
||||
&& Float.compare(otherMatrix.m32, this.m32) == 0
|
||||
&& Float.compare(otherMatrix.m33, this.m33) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//===============//
|
||||
// Forge methods //
|
||||
//===============//
|
||||
|
||||
public Mat4f(float[] values)
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
m00 = values[0];
|
||||
m01 = values[1];
|
||||
m02 = values[2];
|
||||
m03 = values[3];
|
||||
m10 = values[4];
|
||||
m11 = values[5];
|
||||
m12 = values[6];
|
||||
m13 = values[7];
|
||||
m20 = values[8];
|
||||
m21 = values[9];
|
||||
m22 = values[10];
|
||||
m23 = values[11];
|
||||
m30 = values[12];
|
||||
m31 = values[13];
|
||||
m32 = values[14];
|
||||
m33 = values[15];
|
||||
int i = this.m00 != 0.0F ? Float.floatToIntBits(this.m00) : 0;
|
||||
i = 31 * i + (this.m01 != 0.0F ? Float.floatToIntBits(this.m01) : 0);
|
||||
i = 31 * i + (this.m02 != 0.0F ? Float.floatToIntBits(this.m02) : 0);
|
||||
i = 31 * i + (this.m03 != 0.0F ? Float.floatToIntBits(this.m03) : 0);
|
||||
i = 31 * i + (this.m10 != 0.0F ? Float.floatToIntBits(this.m10) : 0);
|
||||
i = 31 * i + (this.m11 != 0.0F ? Float.floatToIntBits(this.m11) : 0);
|
||||
i = 31 * i + (this.m12 != 0.0F ? Float.floatToIntBits(this.m12) : 0);
|
||||
i = 31 * i + (this.m13 != 0.0F ? Float.floatToIntBits(this.m13) : 0);
|
||||
i = 31 * i + (this.m20 != 0.0F ? Float.floatToIntBits(this.m20) : 0);
|
||||
i = 31 * i + (this.m21 != 0.0F ? Float.floatToIntBits(this.m21) : 0);
|
||||
i = 31 * i + (this.m22 != 0.0F ? Float.floatToIntBits(this.m22) : 0);
|
||||
i = 31 * i + (this.m23 != 0.0F ? Float.floatToIntBits(this.m23) : 0);
|
||||
i = 31 * i + (this.m30 != 0.0F ? Float.floatToIntBits(this.m30) : 0);
|
||||
i = 31 * i + (this.m31 != 0.0F ? Float.floatToIntBits(this.m31) : 0);
|
||||
i = 31 * i + (this.m32 != 0.0F ? Float.floatToIntBits(this.m32) : 0);
|
||||
return 31 * i + (this.m33 != 0.0F ? Float.floatToIntBits(this.m33) : 0);
|
||||
}
|
||||
|
||||
public Mat4f(FloatBuffer buffer)
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
this(buffer.array());
|
||||
return "Matrix4f:\n" +
|
||||
this.m00 + " " + this.m01 + " " + this.m02 + " " + this.m03 + "\n" +
|
||||
this.m10 + " " + this.m11 + " " + this.m12 + " " + this.m13 + "\n" +
|
||||
this.m20 + " " + this.m21 + " " + this.m22 + " " + this.m23 + "\n" +
|
||||
this.m30 + " " + this.m31 + " " + this.m32 + " " + this.m33 + "\n";
|
||||
}
|
||||
|
||||
public void set(Mat4f mat)
|
||||
{
|
||||
this.m00 = mat.m00;
|
||||
this.m01 = mat.m01;
|
||||
this.m02 = mat.m02;
|
||||
this.m03 = mat.m03;
|
||||
this.m10 = mat.m10;
|
||||
this.m11 = mat.m11;
|
||||
this.m12 = mat.m12;
|
||||
this.m13 = mat.m13;
|
||||
this.m20 = mat.m20;
|
||||
this.m21 = mat.m21;
|
||||
this.m22 = mat.m22;
|
||||
this.m23 = mat.m23;
|
||||
this.m30 = mat.m30;
|
||||
this.m31 = mat.m31;
|
||||
this.m32 = mat.m32;
|
||||
this.m33 = mat.m33;
|
||||
}
|
||||
|
||||
public void add(Mat4f other)
|
||||
{
|
||||
m00 += other.m00;
|
||||
m01 += other.m01;
|
||||
m02 += other.m02;
|
||||
m03 += other.m03;
|
||||
m10 += other.m10;
|
||||
m11 += other.m11;
|
||||
m12 += other.m12;
|
||||
m13 += other.m13;
|
||||
m20 += other.m20;
|
||||
m21 += other.m21;
|
||||
m22 += other.m22;
|
||||
m23 += other.m23;
|
||||
m30 += other.m30;
|
||||
m31 += other.m31;
|
||||
m32 += other.m32;
|
||||
m33 += other.m33;
|
||||
}
|
||||
|
||||
public void multiplyBackward(Mat4f other)
|
||||
{
|
||||
Mat4f copy = other.copy();
|
||||
copy.multiply(this);
|
||||
this.set(copy);
|
||||
}
|
||||
|
||||
public void setTranslation(float x, float y, float z)
|
||||
{
|
||||
this.m00 = 1.0F;
|
||||
this.m11 = 1.0F;
|
||||
this.m22 = 1.0F;
|
||||
this.m33 = 1.0F;
|
||||
this.m03 = x;
|
||||
this.m13 = y;
|
||||
this.m23 = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the values that store the clipping planes.
|
||||
* Formula for calculating matrix values is the same that OpenGL uses when making matrices.
|
||||
*
|
||||
* @param nearClip New near clipping plane value.
|
||||
* @param farClip New far clipping plane value.
|
||||
*/
|
||||
public void setClipPlanes(float nearClip, float farClip)
|
||||
{
|
||||
//convert to matrix values, formula copied from a textbook / openGL specification.
|
||||
float matNearClip = -((farClip + nearClip) / (farClip - nearClip));
|
||||
float matFarClip = -((2 * farClip * nearClip) / (farClip - nearClip));
|
||||
//set new values for the clip planes.
|
||||
this.m22 = matNearClip;
|
||||
this.m23 = matFarClip;
|
||||
}
|
||||
@Override
|
||||
public DhApiMat4f copy() { return new DhApiMat4f(this); }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.api.objects.math;
|
||||
|
||||
/**
|
||||
* Often used to store block positions or any other
|
||||
* position in 3D space.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-9
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public class DhApiVec3d
|
||||
{
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
|
||||
|
||||
|
||||
/** creates a Vec3 at (0,0,0) */
|
||||
public DhApiVec3d()
|
||||
{
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
}
|
||||
|
||||
public DhApiVec3d(double x, double y, double z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obj != null && this.getClass() == obj.getClass())
|
||||
{
|
||||
DhApiVec3d Vec3d = (DhApiVec3d) obj;
|
||||
if (Double.compare(Vec3d.x, this.x) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (Double.compare(Vec3d.y, this.y) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Double.compare(Vec3d.z, this.z) == 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
long i = Double.doubleToLongBits(this.x);
|
||||
i = 31 * i + Double.doubleToLongBits(this.y);
|
||||
i = 31 * i + Double.doubleToLongBits(this.z);
|
||||
return Long.hashCode(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return "[" + this.x + ", " + this.y + ", " + this.z + "]"; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.api.objects.math;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.util.IDhApiCopyable;
|
||||
|
||||
/**
|
||||
* Often used to store block positions or any other
|
||||
* position in 3D space.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-6-3
|
||||
* @since API 2.2.0
|
||||
*/
|
||||
public class DhApiVec3f implements IDhApiCopyable
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
|
||||
|
||||
|
||||
/** creates a Vec3 at (0,0,0) */
|
||||
public DhApiVec3f()
|
||||
{
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
}
|
||||
|
||||
public DhApiVec3f(float x, float y, float z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obj != null && this.getClass() == obj.getClass())
|
||||
{
|
||||
DhApiVec3f Vec3f = (DhApiVec3f) obj;
|
||||
if (Float.compare(Vec3f.x, this.x) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (Float.compare(Vec3f.y, this.y) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Float.compare(Vec3f.z, this.z) == 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int i = Float.floatToIntBits(this.x);
|
||||
i = 31 * i + Float.floatToIntBits(this.y);
|
||||
return 31 * i + Float.floatToIntBits(this.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return "[" + this.x + ", " + this.y + ", " + this.z + "]"; }
|
||||
|
||||
@Override
|
||||
public DhApiVec3f copy() { return new DhApiVec3f(this.x, this.y, this.z); }
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.seibel.distanthorizons.api.objects.render;
|
||||
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @see IDhApiRenderableBoxGroup
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-6-30
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public class DhApiRenderableBox
|
||||
{
|
||||
/** the position closest to (-inf,-inf) */
|
||||
public DhApiVec3d minPos;
|
||||
/** the position closest to (+inf,+inf) */
|
||||
public DhApiVec3d maxPos;
|
||||
|
||||
public Color color;
|
||||
public byte material;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public DhApiRenderableBox(DhApiVec3d minPos, float width, Color color, EDhApiBlockMaterial material)
|
||||
{
|
||||
this(minPos, new DhApiVec3d(
|
||||
minPos.x + width,
|
||||
minPos.y + width,
|
||||
minPos.z + width
|
||||
), color, material);
|
||||
}
|
||||
|
||||
public DhApiRenderableBox(DhApiVec3d minPos, DhApiVec3d maxPos, Color color, EDhApiBlockMaterial material)
|
||||
{
|
||||
this.minPos = minPos;
|
||||
this.maxPos = maxPos;
|
||||
this.color = color;
|
||||
this.material = material.index;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package com.seibel.distanthorizons.api.objects.render;
|
||||
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @see IDhApiRenderableBoxGroup
|
||||
*
|
||||
* Shading values are multiplied against the color for each direction,
|
||||
* for example: <br>
|
||||
* A shading value of 1.0 indicates the color is unchanged. <br>
|
||||
* A shading value of 0.0 changes the color to black. <br>
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-7-7
|
||||
* @since API 3.0.0
|
||||
*/
|
||||
public class DhApiRenderableBoxGroupShading
|
||||
{
|
||||
/** negative X */
|
||||
public float north = 1.0f;
|
||||
/** positive X */
|
||||
public float south = 1.0f;
|
||||
|
||||
/** positive X */
|
||||
public float east = 1.0f;
|
||||
/** negative X */
|
||||
public float west = 1.0f;
|
||||
|
||||
/** positive Y */
|
||||
public float top = 1.0f;
|
||||
/** negative Y */
|
||||
public float bottom = 1.0f;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public static DhApiRenderableBoxGroupShading getDefaultShaded()
|
||||
{
|
||||
DhApiRenderableBoxGroupShading shading = new DhApiRenderableBoxGroupShading();
|
||||
shading.setDefaultShaded();
|
||||
return shading;
|
||||
}
|
||||
|
||||
public static DhApiRenderableBoxGroupShading getUnshaded()
|
||||
{
|
||||
DhApiRenderableBoxGroupShading shading = new DhApiRenderableBoxGroupShading();
|
||||
shading.setUnshaded();
|
||||
return shading;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
/**
|
||||
* Directions will have different brightness similar to Minecraft blocks. <br>
|
||||
* This is a good default for un-lit objects.
|
||||
*/
|
||||
public void setDefaultShaded()
|
||||
{
|
||||
this.north = 0.8f;
|
||||
this.south = 0.8f;
|
||||
this.east = 0.6f;
|
||||
this.west = 0.6f;
|
||||
this.top = 1.0f;
|
||||
this.bottom = 0.5f;
|
||||
}
|
||||
|
||||
/**
|
||||
* All directions render with the same brightness. <br>
|
||||
* This is best used for glowing objects like beacons.
|
||||
*/
|
||||
public void setUnshaded()
|
||||
{
|
||||
this.north = 1.0f;
|
||||
this.south = 1.0f;
|
||||
this.east = 1.0f;
|
||||
this.west = 1.0f;
|
||||
this.top = 1.0f;
|
||||
this.bottom = 1.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+21
-1
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.coreapi.DependencyInjection;
|
||||
import com.seibel.distanthorizons.api.interfaces.events.IDhApiEventInjector;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiCancelableEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiOneTimeEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
@@ -140,7 +141,26 @@ public class ApiEventInjector extends DependencyInjector<IDhApiEvent> implements
|
||||
// fire each event and record if any of them
|
||||
// request to cancel the event.
|
||||
|
||||
DhApiEventParam<T> eventParam = createEventParamWrapper(event, eventInput);
|
||||
|
||||
// attempt to clone the event input if possible
|
||||
// this is done to reduce the likely hood that one event listener
|
||||
// will make change the event parameter for other listeners
|
||||
T input = eventInput;
|
||||
if (eventInput instanceof IDhApiEventParam)
|
||||
{
|
||||
try
|
||||
{
|
||||
//noinspection unchecked
|
||||
input = (T) ((IDhApiEventParam) eventInput).copy();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Unable to clone event parameter ["+eventInput.getClass().getSimpleName()+"], error: ["+e.getMessage()+"].", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DhApiEventParam<T> eventParam = createEventParamWrapper(event, input);
|
||||
event.fireEvent(eventParam);
|
||||
|
||||
if (eventParam instanceof DhApiCancelableEventParam)
|
||||
|
||||
@@ -34,14 +34,14 @@ public final class ModInfo
|
||||
public static final String NAME = "DistantHorizons";
|
||||
/** Human-readable version of NAME */
|
||||
public static final String READABLE_NAME = "Distant Horizons";
|
||||
public static final String VERSION = "2.0.4-a-dev";
|
||||
public static final String VERSION = "2.1.3-a-dev";
|
||||
/** Returns true if the current build is an unstable developer build, false otherwise. */
|
||||
public static boolean IS_DEV_BUILD = VERSION.toLowerCase().contains("dev");
|
||||
|
||||
/** This version should only be updated when breaking changes are introduced to the DH API */
|
||||
public static final int API_MAJOR_VERSION = 1;
|
||||
public static final int API_MAJOR_VERSION = 3;
|
||||
/** This version should be updated whenever new methods are added to the DH API */
|
||||
public static final int API_MINOR_VERSION = 1;
|
||||
public static final int API_MINOR_VERSION = 0;
|
||||
/** This version should be updated whenever non-breaking fixes are added to the DH API */
|
||||
public static final int API_PATH_VERSION = 0;
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
package com.seibel.distanthorizons.coreapi.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.StringCharacterIterator;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@@ -85,4 +86,25 @@ 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.coreapi.util.math;
|
||||
|
||||
import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
||||
|
||||
/**
|
||||
* A (almost) exact copy of Minecraft's 1.16.5
|
||||
* implementation of a 3 element float vector.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 11-11-2021
|
||||
*/
|
||||
public class Vec3f
|
||||
{
|
||||
public static Vec3f XNeg = new Vec3f(-1.0F, 0.0F, 0.0F);
|
||||
public static Vec3f XPos = new Vec3f(1.0F, 0.0F, 0.0F);
|
||||
public static Vec3f YNeg = new Vec3f(0.0F, -1.0F, 0.0F);
|
||||
public static Vec3f YPos = new Vec3f(0.0F, 1.0F, 0.0F);
|
||||
public static Vec3f ZNeg = new Vec3f(0.0F, 0.0F, -1.0F);
|
||||
public static Vec3f ZPos = new Vec3f(0.0F, 0.0F, 1.0F);
|
||||
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
|
||||
|
||||
|
||||
public Vec3f()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Vec3f(float x, float y, float z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obj != null && this.getClass() == obj.getClass())
|
||||
{
|
||||
Vec3f Vec3f = (Vec3f) obj;
|
||||
if (Float.compare(Vec3f.x, this.x) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (Float.compare(Vec3f.y, this.y) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Float.compare(Vec3f.z, this.z) == 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int i = Float.floatToIntBits(this.x);
|
||||
i = 31 * i + Float.floatToIntBits(this.y);
|
||||
return 31 * i + Float.floatToIntBits(this.z);
|
||||
}
|
||||
|
||||
public void mul(float scalar)
|
||||
{
|
||||
this.x *= scalar;
|
||||
this.y *= scalar;
|
||||
this.z *= scalar;
|
||||
}
|
||||
|
||||
public void mul(float x, float y, float z)
|
||||
{
|
||||
this.x *= x;
|
||||
this.y *= y;
|
||||
this.z *= z;
|
||||
}
|
||||
|
||||
public void clamp(float min, float max)
|
||||
{
|
||||
this.x = MathUtil.clamp(min, this.x, max);
|
||||
this.y = MathUtil.clamp(min, this.y, max);
|
||||
this.z = MathUtil.clamp(min, this.z, max);
|
||||
}
|
||||
|
||||
public void set(float x, float y, float z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public void add(float x, float y, float z)
|
||||
{
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
}
|
||||
|
||||
public void add(Vec3f vector)
|
||||
{
|
||||
this.x += vector.x;
|
||||
this.y += vector.y;
|
||||
this.z += vector.z;
|
||||
}
|
||||
|
||||
public void subtract(Vec3f vector)
|
||||
{
|
||||
this.x -= vector.x;
|
||||
this.y -= vector.y;
|
||||
this.z -= vector.z;
|
||||
}
|
||||
|
||||
public float dotProduct(Vec3f vector)
|
||||
{
|
||||
return this.x * vector.x + this.y * vector.y + this.z * vector.z;
|
||||
}
|
||||
|
||||
/** Returns true if normalization had to be done */
|
||||
public boolean normalize()
|
||||
{
|
||||
float squaredSum = this.x * this.x + this.y * this.y + this.z * this.z;
|
||||
if (squaredSum < 1.0E-5D)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
float f1 = MathUtil.fastInvSqrt(squaredSum);
|
||||
this.x *= f1;
|
||||
this.y *= f1;
|
||||
this.z *= f1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void crossProduct(Vec3f vector)
|
||||
{
|
||||
float f = this.x;
|
||||
float f1 = this.y;
|
||||
float f2 = this.z;
|
||||
float f3 = vector.x;
|
||||
float f4 = vector.y;
|
||||
float f5 = vector.z;
|
||||
this.x = f1 * f5 - f2 * f4;
|
||||
this.y = f2 * f3 - f * f5;
|
||||
this.z = f * f4 - f1 * f3;
|
||||
}
|
||||
|
||||
/* Matrix3f is not currently needed/implemented
|
||||
public void transform(Matrix3f p_229188_1_)
|
||||
{
|
||||
float f = this.x;
|
||||
float f1 = this.y;
|
||||
float f2 = this.z;
|
||||
this.x = p_229188_1_.m00 * f + p_229188_1_.m01 * f1 + p_229188_1_.m02 * f2;
|
||||
this.y = p_229188_1_.m10 * f + p_229188_1_.m11 * f1 + p_229188_1_.m12 * f2;
|
||||
this.z = p_229188_1_.m20 * f + p_229188_1_.m21 * f1 + p_229188_1_.m22 * f2;
|
||||
}
|
||||
*/
|
||||
|
||||
/* Quaternions are not currently needed/implemented
|
||||
public void transform(Quaternion p_214905_1_)
|
||||
{
|
||||
Quaternion quaternion = new Quaternion(p_214905_1_);
|
||||
quaternion.mul(new Quaternion(this.x(), this.y(), this.z(), 0.0F));
|
||||
Quaternion quaternion1 = new Quaternion(p_214905_1_);
|
||||
quaternion1.conj();
|
||||
quaternion.mul(quaternion1);
|
||||
this.set(quaternion.i(), quaternion.j(), quaternion.k());
|
||||
}
|
||||
*/
|
||||
|
||||
/* not currently needed
|
||||
* percent may actually be partial ticks (which is available when rendering)
|
||||
public void linearInterp(Vec3f resultingVector, float percent)
|
||||
{
|
||||
float f = 1.0F - percent;
|
||||
this.x = this.x * f + resultingVector.x * percent;
|
||||
this.y = this.y * f + resultingVector.y * percent;
|
||||
this.z = this.z * f + resultingVector.z * percent;
|
||||
}
|
||||
*/
|
||||
|
||||
/* Quaternions are not currently needed/implemented
|
||||
public Quaternion rotation(float p_229193_1_)
|
||||
{
|
||||
return new Quaternion(this, p_229193_1_, false);
|
||||
}
|
||||
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public Quaternion rotationDegrees(float p_229187_1_)
|
||||
{
|
||||
return new Quaternion(this, p_229187_1_, true);
|
||||
}
|
||||
*/
|
||||
|
||||
public Vec3f copy()
|
||||
{
|
||||
return new Vec3f(this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
/* not currently needed/implemented
|
||||
public void map(Float2FloatFunction p_229191_1_)
|
||||
{
|
||||
this.x = p_229191_1_.get(this.x);
|
||||
this.y = p_229191_1_.get(this.y);
|
||||
this.z = p_229191_1_.get(this.z);
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "[" + this.x + ", " + this.y + ", " + this.z + "]";
|
||||
}
|
||||
|
||||
// Forge start
|
||||
public Vec3f(float[] values)
|
||||
{
|
||||
set(values);
|
||||
}
|
||||
|
||||
public void set(float[] values)
|
||||
{
|
||||
this.x = values[0];
|
||||
this.y = values[1];
|
||||
this.z = values[2];
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id "java"
|
||||
id "com.github.johnrengelman.shadow" version '7.1.2' apply false // Set this to true if you're using the standalone Core project
|
||||
id "com.github.johnrengelman.shadow" version '8.1.1' apply false // Set this to true if you're using the standalone Core project
|
||||
}
|
||||
|
||||
apply plugin: "application"
|
||||
@@ -57,7 +57,7 @@ artifacts {
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
def librariesLocation = "distanthorizons.libraries"
|
||||
def librariesLocation = "DistantHorizons.libraries"
|
||||
// relocate "it.unimi.dsi.fastutil", "${librariesLocation}.unimi.dsi.fastutil"
|
||||
mergeServiceFiles()
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
package com.seibel.distanthorizons.core;
|
||||
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.GenericRenderObjectFactory;
|
||||
import com.seibel.distanthorizons.core.sql.DatabaseUpdater;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
@@ -93,6 +94,7 @@ public class Initializer
|
||||
DhApi.Delayed.terrainRepo = DhApiTerrainDataRepo.INSTANCE;
|
||||
DhApi.Delayed.worldProxy = DhApiWorldProxy.INSTANCE;
|
||||
DhApi.Delayed.renderProxy = DhApiRenderProxy.INSTANCE;
|
||||
DhApi.Delayed.customRenderObjectFactory = GenericRenderObjectFactory.INSTANCE;
|
||||
DhApi.Delayed.wrapperFactory = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
|
||||
if (DhApi.Delayed.wrapperFactory == null)
|
||||
{
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.api.external.methods.config.client;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.config.IDhApiConfigValue;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.client.IDhApiGenericRenderingConfig;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.client.IDhApiNoiseTextureConfig;
|
||||
import com.seibel.distanthorizons.api.objects.config.DhApiConfigValue;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
|
||||
public class DhApiGenericRenderingConfig implements IDhApiGenericRenderingConfig
|
||||
{
|
||||
public static DhApiGenericRenderingConfig INSTANCE = new DhApiGenericRenderingConfig();
|
||||
|
||||
private DhApiGenericRenderingConfig() { }
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> renderingEnabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.GenericRendering.enableRendering); }
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> beaconRenderingEnabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.GenericRendering.enableBeaconRendering); }
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> cloudRenderingEnabled()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.GenericRendering.enableCloudRendering); }
|
||||
|
||||
}
|
||||
-3
@@ -36,7 +36,4 @@ 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); }
|
||||
|
||||
}
|
||||
|
||||
+6
-4
@@ -22,10 +22,7 @@ package com.seibel.distanthorizons.core.api.external.methods.config.client;
|
||||
import com.seibel.distanthorizons.api.enums.config.*;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiTransparency;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.IDhApiConfigValue;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.client.IDhApiAmbientOcclusionConfig;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.client.IDhApiFogConfig;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.client.IDhApiGraphicsConfig;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.client.IDhApiNoiseTextureConfig;
|
||||
import com.seibel.distanthorizons.api.interfaces.config.client.*;
|
||||
import com.seibel.distanthorizons.api.objects.config.DhApiConfigValue;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
@@ -42,9 +39,14 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig
|
||||
// inner layers //
|
||||
//==============//
|
||||
|
||||
@Override
|
||||
public IDhApiFogConfig fog() { return DhApiFogConfig.INSTANCE; }
|
||||
@Override
|
||||
public IDhApiAmbientOcclusionConfig ambientOcclusion() { return DhApiAmbientOcclusionConfig.INSTANCE; }
|
||||
@Override
|
||||
public IDhApiNoiseTextureConfig noiseTexture() { return DhApiNoiseTextureConfig.INSTANCE; }
|
||||
@Override
|
||||
public IDhApiGenericRenderingConfig genericRendering() { return DhApiGenericRenderingConfig.INSTANCE; }
|
||||
|
||||
|
||||
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package com.seibel.distanthorizons.core.api.external.methods.data;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.data.IDhApiTerrainDataCache;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
public class DhApiTerrainDataCache implements IDhApiTerrainDataCache
|
||||
{
|
||||
private final Object modificationLock = new Object();
|
||||
private Long2ReferenceOpenHashMap<SoftReference<FullDataSourceV2>> posToFullDataRef = new Long2ReferenceOpenHashMap<>();
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(DhApiTerrainDataCache.class.getSimpleName());
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// internal methods //
|
||||
//==================//
|
||||
|
||||
public void add(long pos, FullDataSourceV2 dataSource)
|
||||
{
|
||||
synchronized (this.modificationLock)
|
||||
{
|
||||
this.posToFullDataRef.put(pos, new SoftReference<>(dataSource));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FullDataSourceV2 get(long pos)
|
||||
{
|
||||
synchronized (this.modificationLock)
|
||||
{
|
||||
SoftReference<FullDataSourceV2> ref = this.posToFullDataRef.get(pos);
|
||||
if (ref != null)
|
||||
{
|
||||
return ref.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// API methods //
|
||||
//=============//
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
synchronized (this.modificationLock)
|
||||
{
|
||||
LongSet keySet = this.posToFullDataRef.keySet();
|
||||
for (long pos : keySet)
|
||||
{
|
||||
SoftReference<FullDataSourceV2> dataRef = this.posToFullDataRef.remove(pos);
|
||||
if (dataRef != null)
|
||||
{
|
||||
FullDataSourceV2 dataSource = dataRef.get();
|
||||
if (dataSource != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataSource.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Unable to close data source, error: [" + e.getMessage() + "].", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
+143
-90
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.api.external.methods.data;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.data.IDhApiTerrainDataCache;
|
||||
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||
import com.seibel.distanthorizons.api.objects.DhApiResult;
|
||||
import com.seibel.distanthorizons.api.objects.data.DhApiRaycastResult;
|
||||
@@ -35,6 +36,7 @@ import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.util.FullDataPointUtil;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RayCastUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.core.world.AbstractDhWorld;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
@@ -43,12 +45,12 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRen
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3i;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3i;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -56,9 +58,6 @@ import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* Allows interfacing with the terrain data Distant Horizons has stored.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2022-11-19
|
||||
*/
|
||||
public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
{
|
||||
@@ -68,12 +67,15 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
|
||||
// debugging values
|
||||
private static volatile boolean debugThreadRunning = false;
|
||||
private static String currentDebugBiomeName = "";
|
||||
private static int currentDebugBlockColorInt = -1;
|
||||
private static DhApiTerrainDataCache debugDataCache = new DhApiTerrainDataCache();
|
||||
private static DhApiVec3i currentDebugVec3i = new Vec3i();
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
private DhApiTerrainDataRepo()
|
||||
{
|
||||
|
||||
@@ -86,41 +88,32 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
//================//
|
||||
|
||||
@Override
|
||||
public DhApiResult<DhApiTerrainDataPoint> getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ)
|
||||
{
|
||||
return getTerrainDataAtBlockYPos(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), blockPosY);
|
||||
}
|
||||
public DhApiResult<DhApiTerrainDataPoint> getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ, @Nullable IDhApiTerrainDataCache dataCache)
|
||||
{ return getTerrainDataAtBlockYPos(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), blockPosY, dataCache); }
|
||||
@Override
|
||||
public DhApiResult<DhApiTerrainDataPoint[]> getColumnDataAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosZ)
|
||||
{
|
||||
return getTerrainDataColumnArray(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), null);
|
||||
}
|
||||
public DhApiResult<DhApiTerrainDataPoint[]> getColumnDataAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosZ, @Nullable IDhApiTerrainDataCache dataCache)
|
||||
{ return getTerrainDataColumnArray(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), null, dataCache); }
|
||||
|
||||
@Override
|
||||
public DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ)
|
||||
{
|
||||
return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkPosX, chunkPosZ));
|
||||
}
|
||||
public DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ, @Nullable IDhApiTerrainDataCache dataCache)
|
||||
{ return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkPosX, chunkPosZ), dataCache); }
|
||||
|
||||
@Override
|
||||
public DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ)
|
||||
{
|
||||
return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, new DhLodPos(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ));
|
||||
}
|
||||
public DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ, @Nullable IDhApiTerrainDataCache dataCache)
|
||||
{ return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, new DhLodPos(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ), dataCache); }
|
||||
|
||||
@Override
|
||||
public DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ)
|
||||
{
|
||||
return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, new DhLodPos(detailLevel, posX, posZ));
|
||||
}
|
||||
public DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ, @Nullable IDhApiTerrainDataCache dataCache)
|
||||
{ return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, new DhLodPos(detailLevel, posX, posZ), dataCache); }
|
||||
|
||||
|
||||
|
||||
// private getters //
|
||||
|
||||
/** Returns a single API terrain datapoint that contains the given Y block position */
|
||||
private static DhApiResult<DhApiTerrainDataPoint> getTerrainDataAtBlockYPos(IDhApiLevelWrapper levelWrapper, DhLodPos requestedColumnPos, Integer blockYPos)
|
||||
private static DhApiResult<DhApiTerrainDataPoint> getTerrainDataAtBlockYPos(IDhApiLevelWrapper levelWrapper, DhLodPos requestedColumnPos, Integer blockYPos, @Nullable IDhApiTerrainDataCache dataCache)
|
||||
{
|
||||
DhApiResult<DhApiTerrainDataPoint[]> result = getTerrainDataColumnArray(levelWrapper, requestedColumnPos, blockYPos);
|
||||
DhApiResult<DhApiTerrainDataPoint[]> result = getTerrainDataColumnArray(levelWrapper, requestedColumnPos, blockYPos, dataCache);
|
||||
if (result.success && result.payload.length > 0)
|
||||
{
|
||||
return DhApiResult.createSuccess(result.message, result.payload[0]);
|
||||
@@ -140,7 +133,9 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
*
|
||||
* will stop and return the in progress data if any errors are encountered.
|
||||
*/
|
||||
private static DhApiResult<DhApiTerrainDataPoint[][][]> getTerrainDataOverAreaForPositionDetailLevel(IDhApiLevelWrapper levelWrapper, DhLodPos requestedAreaPos)
|
||||
private static DhApiResult<DhApiTerrainDataPoint[][][]> getTerrainDataOverAreaForPositionDetailLevel(
|
||||
IDhApiLevelWrapper levelWrapper, DhLodPos requestedAreaPos,
|
||||
@Nullable IDhApiTerrainDataCache dataCache)
|
||||
{
|
||||
DhLodPos startingBlockPos = requestedAreaPos.getCornerLodPos(LodUtil.BLOCK_DETAIL_LEVEL);
|
||||
int widthOfAreaInBlocks = BitShiftUtil.powerOfTwo(requestedAreaPos.detailLevel);
|
||||
@@ -154,7 +149,7 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
for (int z = 0; z < widthOfAreaInBlocks; z++)
|
||||
{
|
||||
DhLodPos blockColumnPos = new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, startingBlockPos.x + x, startingBlockPos.z + z);
|
||||
DhApiResult<DhApiTerrainDataPoint[]> result = getTerrainDataColumnArray(levelWrapper, blockColumnPos, null);
|
||||
DhApiResult<DhApiTerrainDataPoint[]> result = getTerrainDataColumnArray(levelWrapper, blockColumnPos, null, dataCache);
|
||||
if (result.success)
|
||||
{
|
||||
returnArray[x][z] = result.payload;
|
||||
@@ -177,8 +172,15 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
* If the ApiResult is successful there will be an array of data. <br>
|
||||
* The returned array will be empty if no data could be retrieved.
|
||||
*/
|
||||
private static DhApiResult<DhApiTerrainDataPoint[]> getTerrainDataColumnArray(IDhApiLevelWrapper levelWrapper, DhLodPos requestedColumnPos, Integer nullableBlockYPos)
|
||||
private static DhApiResult<DhApiTerrainDataPoint[]> getTerrainDataColumnArray(
|
||||
IDhApiLevelWrapper levelWrapper,
|
||||
DhLodPos requestedColumnPos, Integer nullableBlockYPos,
|
||||
@Nullable IDhApiTerrainDataCache apiDataCache)
|
||||
{
|
||||
//============//
|
||||
// validation //
|
||||
//============//
|
||||
|
||||
AbstractDhWorld currentWorld = SharedApi.getAbstractDhWorld();
|
||||
if (currentWorld == null)
|
||||
{
|
||||
@@ -194,6 +196,15 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
ILevelWrapper coreLevelWrapper = (ILevelWrapper) levelWrapper;
|
||||
|
||||
|
||||
if (!(apiDataCache instanceof DhApiTerrainDataCache))
|
||||
{
|
||||
// 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);
|
||||
if (level == null)
|
||||
{
|
||||
@@ -209,70 +220,96 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
DhLodPos relativePos = requestedColumnPos.getDhSectionRelativePositionForDetailLevel();
|
||||
|
||||
|
||||
|
||||
//=====================//
|
||||
// get the data source //
|
||||
//=====================//
|
||||
|
||||
try
|
||||
{
|
||||
// attempt to get/generate the data source for this section
|
||||
FullDataSourceV2 dataSource = level.getFullDataProvider().getAsync(sectionPos).get();
|
||||
FullDataSourceV2 dataSource = null;
|
||||
|
||||
// try using the cached data if possible
|
||||
if (dataCache != null)
|
||||
{
|
||||
dataSource = dataCache.get(sectionPos);
|
||||
}
|
||||
|
||||
if (dataSource == null)
|
||||
{
|
||||
return DhApiResult.createFail("Unable to find/generate any data at the " + DhSectionPos.class.getSimpleName() + " [" + DhSectionPos.toString(sectionPos) + "].");
|
||||
}
|
||||
else
|
||||
{
|
||||
// attempt to get the LOD data from the data source
|
||||
FullDataPointIdMap mapping = dataSource.mapping;
|
||||
LongArrayList dataColumn = dataSource.get(relativePos.x, relativePos.z);
|
||||
if (dataColumn != null)
|
||||
// attempt to get/generate the data source for this section
|
||||
dataSource = level.getFullDataProvider().getAsync(sectionPos).get();
|
||||
if (dataSource == null)
|
||||
{
|
||||
int dataColumnIndexCount = dataColumn.size();
|
||||
DhApiTerrainDataPoint[] returnArray = new DhApiTerrainDataPoint[dataColumnIndexCount];
|
||||
long dataPoint;
|
||||
return DhApiResult.createFail("Unable to find/generate any data at the " + DhSectionPos.class.getSimpleName() + " [" + DhSectionPos.toString(sectionPos) + "].");
|
||||
}
|
||||
dataCache.add(sectionPos, dataSource);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===============================//
|
||||
// get LOD data from data source //
|
||||
//===============================//
|
||||
|
||||
FullDataPointIdMap mapping = dataSource.mapping;
|
||||
LongArrayList dataColumn = dataSource.get(relativePos.x, relativePos.z);
|
||||
if (dataColumn != null)
|
||||
{
|
||||
int dataColumnIndexCount = dataColumn.size();
|
||||
DhApiTerrainDataPoint[] returnArray = new DhApiTerrainDataPoint[dataColumnIndexCount];
|
||||
long dataPoint;
|
||||
|
||||
boolean getSpecificYCoordinate = nullableBlockYPos != null;
|
||||
int levelMinimumHeight = levelWrapper.getMinHeight();
|
||||
|
||||
|
||||
// search for a datapoint that contains the block y position
|
||||
for (int i = 0; i < dataColumnIndexCount; i++)
|
||||
{
|
||||
dataPoint = dataColumn.getLong(i);
|
||||
|
||||
boolean getSpecificYCoordinate = nullableBlockYPos != null;
|
||||
int levelMinimumHeight = levelWrapper.getMinHeight();
|
||||
|
||||
|
||||
// search for a datapoint that contains the block y position
|
||||
for (int i = 0; i < dataColumnIndexCount; i++)
|
||||
if (!getSpecificYCoordinate)
|
||||
{
|
||||
dataPoint = dataColumn.getLong(i);
|
||||
|
||||
if (!getSpecificYCoordinate)
|
||||
// if we aren't look for a specific datapoint, add each datapoint to the return array
|
||||
returnArray[i] = generateApiDatapoint(levelWrapper, mapping, requestedDetailLevel, dataPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are looking for a specific datapoint,
|
||||
// don't look at null ones
|
||||
if (dataPoint != 0)
|
||||
{
|
||||
// if we aren't look for a specific datapoint, add each datapoint to the return array
|
||||
returnArray[i] = generateApiDatapoint(levelWrapper, mapping, requestedDetailLevel, dataPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are looking for a specific datapoint,
|
||||
// don't look at null ones
|
||||
if (dataPoint != 0)
|
||||
int requestedY = nullableBlockYPos;
|
||||
int bottomY = FullDataPointUtil.getBottomY(dataPoint) + levelMinimumHeight;
|
||||
int height = FullDataPointUtil.getHeight(dataPoint);
|
||||
int topY = bottomY + height;
|
||||
|
||||
// does this datapoint contain the requested Y position?
|
||||
if (bottomY <= requestedY && requestedY < topY) // blockPositions start from the bottom of the block, thus "<=" for bottomY, just "<" for topY
|
||||
{
|
||||
int requestedY = nullableBlockYPos;
|
||||
int bottomY = FullDataPointUtil.getBottomY(dataPoint) + levelMinimumHeight;
|
||||
int height = FullDataPointUtil.getHeight(dataPoint);
|
||||
int topY = bottomY + height;
|
||||
|
||||
// does this datapoint contain the requested Y position?
|
||||
if (bottomY <= requestedY && requestedY < topY) // blockPositions start from the bottom of the block, thus "<=" for bottomY, just "<" for topY
|
||||
{
|
||||
// this datapoint contains the requested block position, return it
|
||||
DhApiTerrainDataPoint apiTerrainData = generateApiDatapoint(levelWrapper, mapping, requestedDetailLevel, dataPoint);
|
||||
return DhApiResult.createSuccess(new DhApiTerrainDataPoint[]{apiTerrainData});
|
||||
}
|
||||
// this datapoint contains the requested block position, return it
|
||||
DhApiTerrainDataPoint apiTerrainData = generateApiDatapoint(levelWrapper, mapping, requestedDetailLevel, dataPoint);
|
||||
return DhApiResult.createSuccess(new DhApiTerrainDataPoint[]{apiTerrainData});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return all collected data
|
||||
return DhApiResult.createSuccess(returnArray);
|
||||
}
|
||||
|
||||
// the requested data wasn't present in this column (and/or the column wasn't able to be accessed/generated)
|
||||
return DhApiResult.createSuccess(new DhApiTerrainDataPoint[0]);
|
||||
// return all collected data
|
||||
return DhApiResult.createSuccess(returnArray);
|
||||
}
|
||||
|
||||
// the requested data wasn't present in this column (and/or the column wasn't able to be accessed/generated)
|
||||
return DhApiResult.createSuccess(new DhApiTerrainDataPoint[0]);
|
||||
}
|
||||
catch (InterruptedException | ExecutionException e)
|
||||
{
|
||||
// shouldn't normally happen, but just in case
|
||||
LOGGER.error("getTerrainDataColumnArray operation canceled. Error: [" + e.getMessage() + "]", e);
|
||||
return DhApiResult.createFail("Operation cancled before it could complete: [" + e.getMessage() + "].");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// shouldn't normally happen, but just in case
|
||||
LOGGER.error("Unexpected exception in getTerrainDataColumnArray. Error: [" + e.getMessage() + "]", e);
|
||||
@@ -306,9 +343,11 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
IDhApiLevelWrapper levelWrapper,
|
||||
double rayOriginX, double rayOriginY, double rayOriginZ,
|
||||
float rayDirectionX, float rayDirectionY, float rayDirectionZ,
|
||||
int maxRayBlockLength)
|
||||
int maxRayBlockLength,
|
||||
@Nullable
|
||||
IDhApiTerrainDataCache dataCache)
|
||||
{
|
||||
return this.raycastLodData(levelWrapper, new Vec3d(rayOriginX, rayOriginY, rayOriginZ), new Vec3f(rayDirectionX, rayDirectionY, rayDirectionZ), maxRayBlockLength);
|
||||
return this.raycastLodData(levelWrapper, new Vec3d(rayOriginX, rayOriginY, rayOriginZ), new Vec3f(rayDirectionX, rayDirectionY, rayDirectionZ), maxRayBlockLength, dataCache);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,12 +356,17 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
* Works by walking through the world and attempting to get the LOD <br>
|
||||
* data present at each step.
|
||||
*/
|
||||
private DhApiResult<DhApiRaycastResult> raycastLodData(IDhApiLevelWrapper levelWrapper, Vec3d rayOrigin, Vec3f rayDirection, int maxRayBlockLength)
|
||||
private DhApiResult<DhApiRaycastResult> raycastLodData(
|
||||
IDhApiLevelWrapper levelWrapper,
|
||||
Vec3d rayOrigin, Vec3f rayDirection,
|
||||
int maxRayBlockLength,
|
||||
@Nullable
|
||||
IDhApiTerrainDataCache dataCache)
|
||||
{
|
||||
rayDirection.normalize();
|
||||
|
||||
int minBlockHeight = levelWrapper.getMinHeight();
|
||||
int maxBlockHeight = levelWrapper.getHeight();
|
||||
int maxBlockHeight = levelWrapper.getMaxHeight();
|
||||
|
||||
|
||||
|
||||
@@ -346,7 +390,7 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
for (Vec3i columnPos : columnPositions)
|
||||
{
|
||||
// check each column
|
||||
DhApiResult<DhApiTerrainDataPoint[]> result = this.getColumnDataAtBlockPos(levelWrapper, columnPos.x, columnPos.z);
|
||||
DhApiResult<DhApiTerrainDataPoint[]> result = this.getColumnDataAtBlockPos(levelWrapper, columnPos.x, columnPos.z, dataCache);
|
||||
if (!result.success)
|
||||
{
|
||||
// if there was an error, stop and return it
|
||||
@@ -414,7 +458,7 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
*/
|
||||
private static ArrayList<Vec3i> getIntersectingColumnsAtPosition(Vec3i rayEndingPos, Vec3f rayDirection)
|
||||
{
|
||||
ArrayList<Vec3i> returnList = new ArrayList<Vec3i>(9);
|
||||
ArrayList<Vec3i> returnList = new ArrayList<>(9);
|
||||
|
||||
for (int x = -1; x <= 1; x++)
|
||||
{
|
||||
@@ -469,6 +513,15 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// API helpers //
|
||||
//=============//
|
||||
|
||||
@Override
|
||||
public IDhApiTerrainDataCache getSoftCache() { return new DhApiTerrainDataCache(); }
|
||||
|
||||
|
||||
|
||||
//===============//
|
||||
// debug methods //
|
||||
//===============//
|
||||
@@ -485,15 +538,15 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
|
||||
Thread thread = new Thread(() -> {
|
||||
try
|
||||
{
|
||||
DhApiResult<DhApiTerrainDataPoint> single = getTerrainDataAtBlockYPos(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), blockPosY);
|
||||
DhApiResult<DhApiTerrainDataPoint[]> column = getTerrainDataColumnArray(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), null);
|
||||
DhApiResult<DhApiTerrainDataPoint> single = getTerrainDataAtBlockYPos(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), blockPosY, debugDataCache);
|
||||
DhApiResult<DhApiTerrainDataPoint[]> column = getTerrainDataColumnArray(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), null, debugDataCache);
|
||||
|
||||
DhLodPos chunkPos = new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ).convertToDetailLevel(LodUtil.CHUNK_DETAIL_LEVEL);
|
||||
DhApiResult<DhApiTerrainDataPoint[][][]> area = getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, chunkPos);
|
||||
DhApiResult<DhApiTerrainDataPoint[][][]> area = getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, chunkPos, debugDataCache);
|
||||
|
||||
|
||||
IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
DhApiResult<DhApiRaycastResult> rayCast = INSTANCE.raycastLodData(levelWrapper, MC_RENDER.getCameraExactPosition(), MC_RENDER.getLookAtVector(), 1000);
|
||||
DhApiResult<DhApiRaycastResult> rayCast = INSTANCE.raycastLodData(levelWrapper, MC_RENDER.getCameraExactPosition(), MC_RENDER.getLookAtVector(), 1000, debugDataCache);
|
||||
if (rayCast.payload != null && !rayCast.payload.pos.equals(currentDebugVec3i))
|
||||
{
|
||||
currentDebugVec3i = rayCast.payload.pos;
|
||||
|
||||
@@ -38,7 +38,7 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedSpamLogger;
|
||||
import com.seibel.distanthorizons.core.logging.SpamReducedLogger;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.renderer.TestRenderer;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
@@ -71,7 +71,7 @@ public class ClientApi
|
||||
public static boolean prefLoggerEnabled = false;
|
||||
|
||||
public static final ClientApi INSTANCE = new ClientApi();
|
||||
public static TestRenderer testRenderer = new TestRenderer();
|
||||
public static final TestRenderer TEST_RENDERER = new TestRenderer();
|
||||
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
@@ -80,6 +80,7 @@ public class ClientApi
|
||||
public static final long SPAM_LOGGER_FLUSH_NS = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
|
||||
|
||||
private boolean configOverrideReminderPrinted = false;
|
||||
private boolean lowMemoryWarningPrinted = false;
|
||||
|
||||
private final Queue<String> chatMessageQueueForNextFrame = new LinkedBlockingQueue<>();
|
||||
|
||||
@@ -475,29 +476,7 @@ public class ClientApi
|
||||
{
|
||||
// logging //
|
||||
|
||||
// dev build
|
||||
if (ModInfo.IS_DEV_BUILD && !this.configOverrideReminderPrinted && MC.playerExists())
|
||||
{
|
||||
this.configOverrideReminderPrinted = true;
|
||||
|
||||
// remind the user that this is a development build
|
||||
MC.sendChatMessage("Distant Horizons nightly/unstable build, version: [" + ModInfo.VERSION+"].");
|
||||
MC.sendChatMessage("Issues may occur with this version.");
|
||||
MC.sendChatMessage("Here be dragons!");
|
||||
MC.sendChatMessage("");
|
||||
}
|
||||
|
||||
// generic messages
|
||||
while (!this.chatMessageQueueForNextFrame.isEmpty())
|
||||
{
|
||||
String message = this.chatMessageQueueForNextFrame.poll();
|
||||
if (message == null)
|
||||
{
|
||||
// done to prevent potential null pointers
|
||||
message = "";
|
||||
}
|
||||
MC.sendChatMessage(message);
|
||||
}
|
||||
this.sendChatMessagesNow();
|
||||
|
||||
IProfilerWrapper profiler = MC.getProfiler();
|
||||
profiler.pop(); // get out of "terrain"
|
||||
@@ -573,13 +552,13 @@ public class ClientApi
|
||||
|
||||
if (!DhApi.Delayed.renderProxy.getDeferTransparentRendering())
|
||||
{
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, renderEventParam);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, null);
|
||||
}
|
||||
}
|
||||
else if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEBUG)
|
||||
{
|
||||
profiler.push("Render Debug");
|
||||
ClientApi.testRenderer.render();
|
||||
ClientApi.TEST_RENDERER.render();
|
||||
profiler.pop();
|
||||
}
|
||||
}
|
||||
@@ -594,7 +573,7 @@ public class ClientApi
|
||||
|
||||
if (DhApi.Delayed.renderProxy.getDeferTransparentRendering())
|
||||
{
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, renderEventParam);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,10 +584,22 @@ public class ClientApi
|
||||
|
||||
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons renderer has encountered an exception!");
|
||||
MC.sendChatMessage("\u00A74Renderer is now disabled to prevent further issues.");
|
||||
MC.sendChatMessage("\u00A74Please restart your game to re-enable Distant Horizons' LOD rendering.");
|
||||
MC.sendChatMessage("\u00A74Exception detail: " + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
// these tasks always need to be called, regardless of whether the renderer is enabled or not to prevent memory leaks
|
||||
GLProxy.getInstance().runRenderThreadTasks();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Unexpected issue running render thread tasks.", e);
|
||||
}
|
||||
|
||||
|
||||
profiler.pop(); // end LOD
|
||||
profiler.push("terrain"); // go back into "terrain"
|
||||
}
|
||||
@@ -648,6 +639,53 @@ public class ClientApi
|
||||
}
|
||||
}
|
||||
|
||||
private void sendChatMessagesNow()
|
||||
{
|
||||
// dev build
|
||||
if (ModInfo.IS_DEV_BUILD && !this.configOverrideReminderPrinted && MC.playerExists())
|
||||
{
|
||||
this.configOverrideReminderPrinted = true;
|
||||
|
||||
// remind the user that this is a development build
|
||||
MC.sendChatMessage("\u00A72" + "Distant Horizons: nightly/unstable build, version: [" + ModInfo.VERSION+"]." + "\u00A7r");
|
||||
MC.sendChatMessage("Issues may occur with this version.");
|
||||
MC.sendChatMessage("Here be dragons!");
|
||||
MC.sendChatMessage("");
|
||||
}
|
||||
|
||||
// memory
|
||||
if (!this.lowMemoryWarningPrinted && Config.Client.Advanced.Logging.showLowMemoryWarningOnStartup.get())
|
||||
{
|
||||
this.lowMemoryWarningPrinted = true;
|
||||
|
||||
// 4 GB
|
||||
long minimumRecommendedMemoryInBytes = 4L * 1_000_000_000L;
|
||||
|
||||
// Java returned 17,171,480,576 for 16 GB so it might be slightly off what you'd expect
|
||||
long maxMemoryInBytes = Runtime.getRuntime().maxMemory();
|
||||
if (maxMemoryInBytes < minimumRecommendedMemoryInBytes)
|
||||
{
|
||||
MC.sendChatMessage("\u00A76" + "Distant Horizons: Low memory detected." + "\u00A7r");
|
||||
MC.sendChatMessage("Stuttering or low FPS may occur.");
|
||||
MC.sendChatMessage("Please increase Minecraft's available memory to 4 gigabytes.");
|
||||
MC.sendChatMessage("This warning can be disabled in DH's config under Advanced -> Logging.");
|
||||
MC.sendChatMessage("");
|
||||
}
|
||||
}
|
||||
|
||||
// generic messages
|
||||
while (!this.chatMessageQueueForNextFrame.isEmpty())
|
||||
{
|
||||
String message = this.chatMessageQueueForNextFrame.poll();
|
||||
if (message == null)
|
||||
{
|
||||
// done to prevent potential null pointers
|
||||
message = "";
|
||||
}
|
||||
MC.sendChatMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues the given message to appear in chat the next valid frame.
|
||||
* Useful for queueing up messages that may be triggered before the user has loaded into the world.
|
||||
|
||||
@@ -141,7 +141,7 @@ public class ServerApi
|
||||
//=======================//
|
||||
|
||||
public void serverChunkLoadEvent(IChunkWrapper chunkWrapper, ILevelWrapper level) { SharedApi.INSTANCE.applyChunkUpdate(chunkWrapper, level, false); }
|
||||
public void serverChunkSaveEvent(IChunkWrapper chunkWrapper, ILevelWrapper level) { SharedApi.INSTANCE.applyChunkUpdate(chunkWrapper, level, false); }
|
||||
public void serverChunkSaveEvent(IChunkWrapper chunkWrapper, ILevelWrapper level) { SharedApi.INSTANCE.applyChunkUpdate(chunkWrapper, level, true); }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||
import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo;
|
||||
import com.seibel.distanthorizons.core.util.TimerUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.Pair;
|
||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||
@@ -41,10 +42,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
@@ -59,7 +57,7 @@ public class SharedApi
|
||||
private static final Set<DhChunkPos> UPDATING_CHUNK_POS_SET = ConcurrentHashMap.newKeySet();
|
||||
/** how many chunks can be queued for updating per thread, used to prevent updates from infinitely pilling up if the user flys around extremely fast */
|
||||
private static final int MAX_UPDATING_CHUNK_COUNT_PER_THREAD = 500;
|
||||
private static final int MIN_MS_BETWEEN_OVERLOADED_LOG_MESSAGE = 5_000;
|
||||
private static final int MIN_MS_BETWEEN_OVERLOADED_LOG_MESSAGE = 30_000;
|
||||
|
||||
private static final Timer CHUNK_UPDATE_TIMER = TimerUtil.CreateTimer("ChunkUpdateTimer");
|
||||
|
||||
@@ -68,23 +66,13 @@ public class SharedApi
|
||||
private static int lastWorldGenTickDelta = 0;
|
||||
private static long lastOverloadedLogMessageMsTime = 0;
|
||||
|
||||
public F3Screen.DynamicMessage f3Message;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
private SharedApi()
|
||||
{
|
||||
this.f3Message = new F3Screen.DynamicMessage(() ->
|
||||
{
|
||||
int maxUpdateCount = MAX_UPDATING_CHUNK_COUNT_PER_THREAD * Config.Client.Advanced.MultiThreading.numberOfLodBuilderThreads.get();
|
||||
return LodUtil.formatLog("Queued chunk updates: " + UPDATING_CHUNK_POS_SET.size() + " / " + maxUpdateCount);
|
||||
});
|
||||
}
|
||||
|
||||
private SharedApi() { }
|
||||
public static void init() { Initializer.init(); }
|
||||
|
||||
|
||||
@@ -110,6 +98,8 @@ public class SharedApi
|
||||
ThreadPoolUtil.shutdownThreadPools();
|
||||
DebugRenderer.clearRenderables();
|
||||
MC_RENDER.clearTargetFrameBuffer();
|
||||
// shouldn't be necessary, but if we missed closing one of the connections this should make sure they're all closed
|
||||
AbstractDhRepo.closeAllConnections();
|
||||
// needs to be closed on world shutdown to clear out un-processed chunks
|
||||
UPDATING_CHUNK_POS_SET.clear();
|
||||
|
||||
@@ -146,7 +136,8 @@ public class SharedApi
|
||||
* Used to prevent getting a full chunk from MC if it isn't necessary. <br>
|
||||
* This is important since asking MC for a chunk is slow and may block the render thread.
|
||||
*/
|
||||
public static boolean isChunkAtBlockPosAlreadyUpdating(int blockPosX, int blockPosZ) { return UPDATING_CHUNK_POS_SET.contains(new DhChunkPos(new DhBlockPos2D(blockPosX, blockPosZ))); }
|
||||
public static boolean isChunkAtBlockPosAlreadyUpdating(int blockPosX, int blockPosZ)
|
||||
{ return UPDATING_CHUNK_POS_SET.contains(new DhChunkPos(new DhBlockPos2D(blockPosX, blockPosZ))); }
|
||||
|
||||
|
||||
/** handles both block place and break events */
|
||||
@@ -223,7 +214,13 @@ public class SharedApi
|
||||
if (msBetweenLastLog >= MIN_MS_BETWEEN_OVERLOADED_LOG_MESSAGE)
|
||||
{
|
||||
lastOverloadedLogMessageMsTime = System.currentTimeMillis();
|
||||
LOGGER.warn("Too many chunks queued for updating, max queue count ["+maxQueueCount+"] (["+MAX_UPDATING_CHUNK_COUNT_PER_THREAD+"] per thread). Some LODs may not be updated or may be missing. Please move through the world slower, decrease your vanilla render distance, or increase the CPU load config.");
|
||||
|
||||
String message = "Distant Horizons overloaded, too many chunks queued for updating. " +
|
||||
"\nThis may result in holes in your LODs. " +
|
||||
"\nPlease move through the world slower, decrease your vanilla render distance, slow down your world pre-generator, or increase the Distant Horizons' CPU load config. " +
|
||||
"\nMax queue count ["+maxQueueCount+"] (["+MAX_UPDATING_CHUNK_COUNT_PER_THREAD+"] per thread).";
|
||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
||||
LOGGER.warn(message);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -302,6 +299,35 @@ public class SharedApi
|
||||
|
||||
try
|
||||
{
|
||||
// check if this chunk has been converted into an LOD already
|
||||
int oldChunkHash = dhLevel.getChunkHash(chunkWrapper.getChunkPos()); // shouldn't happen on the render thread since it may take a few moments to run
|
||||
int newChunkHash = chunkWrapper.getBlockBiomeHashCode();
|
||||
if (oldChunkHash == newChunkHash)
|
||||
{
|
||||
// if the chunk hashes are the same then we don't need to bother with lighting the chunk
|
||||
// or creating/updating the LODs
|
||||
//LOGGER.info("skipping: "+chunkWrapper.getChunkPos()+" "+newChunkHash);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//LOGGER.info("g: "+chunkWrapper.getChunkPos()+" "+newChunkHash);
|
||||
}
|
||||
|
||||
|
||||
// having a list of the nearby chunks is needed for lighting and beacon generation
|
||||
ArrayList<IChunkWrapper> nearbyChunkList;
|
||||
if (neighbourChunkList != null)
|
||||
{
|
||||
nearbyChunkList = neighbourChunkList;
|
||||
}
|
||||
else
|
||||
{
|
||||
nearbyChunkList = new ArrayList<>(1);
|
||||
nearbyChunkList.add(chunkWrapper);
|
||||
}
|
||||
|
||||
|
||||
// Save or populate the chunk wrapper's lighting
|
||||
// this is done so we don't have to worry about MC unloading the lighting data for this chunk
|
||||
boolean onlyUseDhLighting = Config.Client.Advanced.LodBuilding.onlyUseDhLightingEngine.get();
|
||||
@@ -320,22 +346,18 @@ public class SharedApi
|
||||
else
|
||||
{
|
||||
// generate the chunk's lighting, using neighboring chunks if present
|
||||
|
||||
ArrayList<IChunkWrapper> nearbyChunkList;
|
||||
if (neighbourChunkList != null)
|
||||
{
|
||||
nearbyChunkList = neighbourChunkList;
|
||||
}
|
||||
else
|
||||
{
|
||||
nearbyChunkList = new ArrayList<>(1);
|
||||
nearbyChunkList.add(chunkWrapper);
|
||||
}
|
||||
|
||||
DhLightingEngine.INSTANCE.lightChunk(chunkWrapper, nearbyChunkList, dhLevel.hasSkyLight() ? 15 : 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get this chunk's active beacons
|
||||
List<BeaconBeamDTO> beaconBeamList = chunkWrapper.getAllActiveBeacons(nearbyChunkList);
|
||||
dhLevel.setBeaconBeamsForChunk(chunkWrapper.getChunkPos(), beaconBeamList);
|
||||
|
||||
|
||||
dhLevel.updateChunkAsync(chunkWrapper);
|
||||
dhLevel.setChunkHash(chunkWrapper.getChunkPos(), newChunkHash);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -366,4 +388,18 @@ public class SharedApi
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// F3 Menu //
|
||||
//=========//
|
||||
|
||||
public String getDebugMenuString()
|
||||
{
|
||||
int maxUpdateCount = MAX_UPDATING_CHUNK_COUNT_PER_THREAD * Config.Client.Advanced.MultiThreading.numberOfLodBuilderThreads.get();
|
||||
String updatingCountStr = F3Screen.NUMBER_FORMAT.format(UPDATING_CHUNK_POS_SET.size());
|
||||
String maxUpdateCountStr = F3Screen.NUMBER_FORMAT.format(maxUpdateCount);
|
||||
return "Queued chunk updates: "+updatingCountStr+" / "+maxUpdateCountStr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ public class Config
|
||||
|
||||
public static ConfigEntry<Boolean> optionsButton = new ConfigEntry.Builder<Boolean>()
|
||||
.set(true)
|
||||
.setAppearance(EConfigEntryAppearance.ONLY_IN_FILE)
|
||||
.comment("" +
|
||||
"Should Distant Horizon's config button appear in the options screen next to fov slider?")
|
||||
.build();
|
||||
@@ -135,6 +136,7 @@ public class Config
|
||||
public static ConfigCategory fog = new ConfigCategory.Builder().set(Fog.class).build();
|
||||
public static ConfigCategory ssao = new ConfigCategory.Builder().set(Ssao.class).build();
|
||||
public static ConfigCategory noiseTextureSettings = new ConfigCategory.Builder().set(NoiseTextureSettings.class).build();
|
||||
public static ConfigCategory genericRendering = new ConfigCategory.Builder().set(GenericRendering.class).build();
|
||||
public static ConfigCategory advancedGraphics = new ConfigCategory.Builder().set(AdvancedGraphics.class).build();
|
||||
|
||||
|
||||
@@ -279,7 +281,7 @@ public class Config
|
||||
private static final Double FOG_RANGE_MAX = Math.sqrt(2.0);
|
||||
|
||||
public static ConfigEntry<Double> farFogStart = new ConfigEntry.Builder<Double>()
|
||||
.setMinDefaultMax(FOG_RANGE_MIN, 0.0, FOG_RANGE_MAX)
|
||||
.setMinDefaultMax(FOG_RANGE_MIN, 0.4, FOG_RANGE_MAX)
|
||||
.comment(""
|
||||
+ "At what distance should the far fog start? \n"
|
||||
+ "\n"
|
||||
@@ -510,7 +512,8 @@ public class Config
|
||||
public static ConfigEntry<Integer> noiseSteps = new ConfigEntry.Builder<Integer>()
|
||||
.setMinDefaultMax(1, 4, null)
|
||||
.comment(""
|
||||
+ "How many steps of noise should be applied to LODs?")
|
||||
+ "How many steps of noise should be applied to LODs?"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Double> noiseIntensity = new ConfigEntry.Builder<Double>() // TODO: Make this a float (the ClassicConfigGUI doesn't support floats)
|
||||
@@ -523,7 +526,34 @@ public class Config
|
||||
.setMinDefaultMax(0, 1024, null)
|
||||
.comment(""
|
||||
+ "Defines how far should the noise texture render before it fades away. (in blocks) \n"
|
||||
+ "Set to 0 to disable noise from fading away")
|
||||
+ "Set to 0 to disable noise from fading away \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
public static class GenericRendering
|
||||
{
|
||||
public static ConfigEntry<Boolean> enableRendering = new ConfigEntry.Builder<Boolean>()
|
||||
.set(true)
|
||||
.comment(""
|
||||
+ "If true non terrain objects will be rendered in DH's terrain. \n"
|
||||
+ "This includes beacon beams and clouds. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Boolean> enableBeaconRendering = new ConfigEntry.Builder<Boolean>()
|
||||
.set(true)
|
||||
.comment(""
|
||||
+ "If true LOD beacon beams will be rendered. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Boolean> enableCloudRendering = new ConfigEntry.Builder<Boolean>()
|
||||
.set(true)
|
||||
.comment(""
|
||||
+ "If true LOD clouds will be rendered. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
}
|
||||
@@ -715,7 +745,7 @@ public class Config
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Integer> worldGenerationTimeoutLengthInSeconds = new ConfigEntry.Builder<Integer>()
|
||||
.setMinDefaultMax(5, 60, 60 * 10/*10 minutes*/ )
|
||||
.setMinDefaultMax(5, 60 * 3, 60 * 10/*10 minutes*/ )
|
||||
.comment(""
|
||||
+ "How long should a world generator thread run for before timing out? \n"
|
||||
+ "Note: If you are experiencing timeout errors it is better to lower your CPU usage first \n"
|
||||
@@ -751,6 +781,20 @@ public class Config
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Boolean> pullLightingForPregeneratedChunks = new ConfigEntry.Builder<Boolean>()
|
||||
.set(false)
|
||||
.comment(""
|
||||
+ "If true LOD generation for pre-existing chunks will attempt to pull the lighting data \n"
|
||||
+ "saved in Minecraft's Region files. \n"
|
||||
+ "If false DH will pull in chunks without lighting and re-light them. \n"
|
||||
+ " \n"
|
||||
+ "Setting this to true will result in faster LOD generation \n"
|
||||
+ "for already generated worlds, but is broken by most lighting mods. \n"
|
||||
+ " \n"
|
||||
+ "Set this to false if LODs are black. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiDataCompressionMode> dataCompression = new ConfigEntry.Builder<EDhApiDataCompressionMode>()
|
||||
.set(EDhApiDataCompressionMode.LZMA2)
|
||||
.comment(""
|
||||
@@ -799,12 +843,12 @@ 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<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();
|
||||
|
||||
}
|
||||
|
||||
@@ -1010,30 +1054,6 @@ 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 ConfigEntry<Boolean> gpuUploadAsync = new ConfigEntry.Builder<Boolean>()
|
||||
.set(true)
|
||||
.comment(""
|
||||
+ "If true geometry data will be uploaded on a DH controlled thread, reducing FPS stuttering. \n"
|
||||
+ "If false uploading will be done on Minecraft's main rendering thread. \n"
|
||||
+ "\n"
|
||||
+ "Setting this to false may reduce crashes or corrupted geometry on systems with an AMD GPU when Sodium is installed.\n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
public static class AutoUpdater
|
||||
@@ -1053,11 +1073,12 @@ public class Config
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiUpdateBranch> updateBranch = new ConfigEntry.Builder<EDhApiUpdateBranch>()
|
||||
.set(
|
||||
ModInfo.IS_DEV_BUILD? EDhApiUpdateBranch.NIGHTLY: EDhApiUpdateBranch.STABLE // If it's already a nightly build, then download the nightly build ofc
|
||||
)
|
||||
.set(EDhApiUpdateBranch.AUTO)
|
||||
.comment(""
|
||||
+ " If DH should use the nightly (provided by Gitlab), or stable (provided by Modrinth) build")
|
||||
+ "If DH should use the nightly (provided by Gitlab), or stable (provided by Modrinth) build. \n"
|
||||
+ "If ["+EDhApiUpdateBranch.AUTO+"] is selected DH will update to new stable releases if the current jar is a stable jar \n"
|
||||
+ "and will update to new nightly builds if the current jar is a nightly jar (IE the version number ends in '-dev')."
|
||||
+ "")
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -1066,68 +1087,76 @@ public class Config
|
||||
// TODO add change all option
|
||||
// TODO default to error chat and info file
|
||||
public static ConfigEntry<EDhApiLoggerMode> logWorldGenEvent = new ConfigEntry.Builder<EDhApiLoggerMode>()
|
||||
.set(EDhApiLoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE)
|
||||
.set(EDhApiLoggerMode.LOG_ERROR_TO_CHAT)
|
||||
.comment(""
|
||||
+ "If enabled, the mod will log information about the world generation process. \n"
|
||||
+ "This can be useful for debugging.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiLoggerMode> logWorldGenPerformance = new ConfigEntry.Builder<EDhApiLoggerMode>()
|
||||
.set(EDhApiLoggerMode.LOG_WARNING_TO_CHAT_AND_FILE)
|
||||
.set(EDhApiLoggerMode.LOG_ERROR_TO_CHAT)
|
||||
.comment(""
|
||||
+ "If enabled, the mod will log performance about the world generation process. \n"
|
||||
+ "This can be useful for debugging.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiLoggerMode> logWorldGenLoadEvent = new ConfigEntry.Builder<EDhApiLoggerMode>()
|
||||
.set(EDhApiLoggerMode.LOG_WARNING_TO_CHAT_AND_FILE)
|
||||
.set(EDhApiLoggerMode.LOG_ERROR_TO_CHAT)
|
||||
.comment(""
|
||||
+ "If enabled, the mod will log information about the world generation process. \n"
|
||||
+ "This can be useful for debugging.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiLoggerMode> logLodBuilderEvent = new ConfigEntry.Builder<EDhApiLoggerMode>()
|
||||
.set(EDhApiLoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE)
|
||||
.set(EDhApiLoggerMode.LOG_ERROR_TO_CHAT)
|
||||
.comment(""
|
||||
+ "If enabled, the mod will log information about the LOD generation process. \n"
|
||||
+ "This can be useful for debugging.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiLoggerMode> logRendererBufferEvent = new ConfigEntry.Builder<EDhApiLoggerMode>()
|
||||
.set(EDhApiLoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE)
|
||||
.set(EDhApiLoggerMode.LOG_ERROR_TO_CHAT)
|
||||
.comment(""
|
||||
+ "If enabled, the mod will log information about the renderer buffer process. \n"
|
||||
+ "This can be useful for debugging.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiLoggerMode> logRendererGLEvent = new ConfigEntry.Builder<EDhApiLoggerMode>()
|
||||
.set(EDhApiLoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE)
|
||||
.set(EDhApiLoggerMode.LOG_ERROR_TO_CHAT)
|
||||
.comment(""
|
||||
+ "If enabled, the mod will log information about the renderer OpenGL process. \n"
|
||||
+ "This can be useful for debugging.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiLoggerMode> logFileReadWriteEvent = new ConfigEntry.Builder<EDhApiLoggerMode>()
|
||||
.set(EDhApiLoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE)
|
||||
.set(EDhApiLoggerMode.LOG_ERROR_TO_CHAT)
|
||||
.comment(""
|
||||
+ "If enabled, the mod will log information about file read/write operations. \n"
|
||||
+ "This can be useful for debugging.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiLoggerMode> logFileSubDimEvent = new ConfigEntry.Builder<EDhApiLoggerMode>()
|
||||
.set(EDhApiLoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE)
|
||||
.set(EDhApiLoggerMode.LOG_ERROR_TO_CHAT)
|
||||
.comment(""
|
||||
+ "If enabled, the mod will log information about file sub-dimension operations. \n"
|
||||
+ "This can be useful for debugging.")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<EDhApiLoggerMode> logNetworkEvent = new ConfigEntry.Builder<EDhApiLoggerMode>()
|
||||
.set(EDhApiLoggerMode.LOG_WARNING_TO_CHAT_AND_INFO_TO_FILE)
|
||||
.set(EDhApiLoggerMode.LOG_ERROR_TO_CHAT)
|
||||
.comment(""
|
||||
+ "If enabled, the mod will log information about network operations. \n"
|
||||
+ "This can be useful for debugging.")
|
||||
.build();
|
||||
|
||||
|
||||
public static ConfigEntry<Boolean> showLowMemoryWarningOnStartup = new ConfigEntry.Builder<Boolean>()
|
||||
.set(true)
|
||||
.comment(""
|
||||
+ "If enabled, a chat message will be displayed if Java doesn't have enough \n"
|
||||
+ "memory allocated to run DH well.")
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
public static class Debugging
|
||||
@@ -1195,6 +1224,15 @@ public class Config
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Boolean> logBufferGarbageCollection = new ConfigEntry.Builder<Boolean>()
|
||||
.set(false)
|
||||
.comment(""
|
||||
+ "If true OpenGL Buffer garbage collection will be logged \n"
|
||||
+ "this also includes the number of live buffers. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
|
||||
// Note: This will reset on game restart, and should have a warning on the tooltip
|
||||
public static ConfigEntry<Boolean> allowUnsafeValues = new ConfigEntry.Builder<Boolean>()
|
||||
.set(false)
|
||||
|
||||
+23
-24
@@ -37,28 +37,27 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
public static final ThreadPresetConfigEventHandler INSTANCE = new ThreadPresetConfigEventHandler();
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final boolean LOW_THREAD_COUNT_CPU = (Runtime.getRuntime().availableProcessors() <= 4);
|
||||
|
||||
|
||||
|
||||
public static int getWorldGenDefaultThreadCount() { return getThreadCountByPercent(0.15); }
|
||||
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>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getWorldGenDefaultThreadCount());
|
||||
this.put(EDhApiThreadPreset.BALANCED, getThreadCountByPercent(0.25));
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, getThreadCountByPercent(0.5));
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, getThreadCountByPercent(1.0));
|
||||
this.put(EDhApiThreadPreset.BALANCED, getThreadCountByPercent(0.15));
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, getThreadCountByPercent(0.25));
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, getThreadCountByPercent(0.5));
|
||||
}});
|
||||
public static double getWorldGenDefaultRunTimeRatio() { return LOW_THREAD_COUNT_CPU ? 0.5 : 0.75; }
|
||||
public static double getWorldGenDefaultRunTimeRatio() { return 0.5; }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Double> worldGenRunTime = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.runTimeRatioForWorldGenerationThreads,
|
||||
new HashMap<EDhApiThreadPreset, Double>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, LOW_THREAD_COUNT_CPU ? 0.1 : 0.25);
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getWorldGenDefaultRunTimeRatio());
|
||||
this.put(EDhApiThreadPreset.BALANCED, LOW_THREAD_COUNT_CPU ? 0.5 : 0.75);
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, LOW_THREAD_COUNT_CPU ? 0.75 : 1.0);
|
||||
this.put(EDhApiThreadPreset.BALANCED, 0.75);
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, 1.0);
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, 1.0);
|
||||
}});
|
||||
|
||||
@@ -71,13 +70,13 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getFileHandlerDefaultThreadCount());
|
||||
this.put(EDhApiThreadPreset.BALANCED, getThreadCountByPercent(0.2));
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, getThreadCountByPercent(0.2));
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, getThreadCountByPercent(1.0));
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, getThreadCountByPercent(0.5));
|
||||
}});
|
||||
public static double getFileHandlerDefaultRunTimeRatio() { return 0.75; }
|
||||
public static double getFileHandlerDefaultRunTimeRatio() { return 0.5; }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Double> fileHandlerRunTime = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.runTimeRatioForFileHandlerThreads,
|
||||
new HashMap<EDhApiThreadPreset, Double>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.50);
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.25);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getFileHandlerDefaultRunTimeRatio());
|
||||
this.put(EDhApiThreadPreset.BALANCED, 1.0);
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, 1.0);
|
||||
@@ -85,24 +84,24 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
}});
|
||||
|
||||
|
||||
public static int getUpdatePropagatorDefaultThreadCount() { return getThreadCountByPercent(0.25); }
|
||||
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>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getUpdatePropagatorDefaultThreadCount());
|
||||
this.put(EDhApiThreadPreset.BALANCED, getThreadCountByPercent(0.5));
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, getThreadCountByPercent(0.75));
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, getThreadCountByPercent(1.0));
|
||||
this.put(EDhApiThreadPreset.BALANCED, getThreadCountByPercent(0.25));
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, getThreadCountByPercent(0.50));
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, getThreadCountByPercent(0.75));
|
||||
}});
|
||||
public static double getUpdatePropagatorDefaultRunTimeRatio() { return 0.5; }
|
||||
public static double getUpdatePropagatorDefaultRunTimeRatio() { return 0.25; }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Double> UpdatePropagatorRunTime = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.runTimeRatioForUpdatePropagatorThreads,
|
||||
new HashMap<EDhApiThreadPreset, Double>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.25);
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getUpdatePropagatorDefaultRunTimeRatio());
|
||||
this.put(EDhApiThreadPreset.BALANCED, 0.75);
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, 1.0);
|
||||
this.put(EDhApiThreadPreset.BALANCED, 0.50);
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, 0.75);
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, 1.0);
|
||||
}});
|
||||
|
||||
@@ -115,16 +114,16 @@ public class ThreadPresetConfigEventHandler extends AbstractPresetConfigEventHan
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getLodBuilderDefaultThreadCount());
|
||||
this.put(EDhApiThreadPreset.BALANCED, getThreadCountByPercent(0.2));
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, getThreadCountByPercent(0.4));
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, getThreadCountByPercent(1.0));
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, getThreadCountByPercent(0.6));
|
||||
}});
|
||||
public static double getLodBuilderDefaultRunTimeRatio() { return LOW_THREAD_COUNT_CPU ? 0.25 : 0.5; }
|
||||
public static double getLodBuilderDefaultRunTimeRatio() { return 0.25; }
|
||||
private final ConfigEntryWithPresetOptions<EDhApiThreadPreset, Double> lodBuilderRunTime = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.MultiThreading.runTimeRatioForLodBuilderThreads,
|
||||
new HashMap<EDhApiThreadPreset, Double>()
|
||||
{{
|
||||
this.put(EDhApiThreadPreset.MINIMAL_IMPACT, 0.1);
|
||||
this.put(EDhApiThreadPreset.LOW_IMPACT, getLodBuilderDefaultRunTimeRatio());
|
||||
this.put(EDhApiThreadPreset.BALANCED, LOW_THREAD_COUNT_CPU ? 0.5 : 0.75);
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, 1.0);
|
||||
this.put(EDhApiThreadPreset.BALANCED, 0.5);
|
||||
this.put(EDhApiThreadPreset.AGGRESSIVE, 0.75);
|
||||
this.put(EDhApiThreadPreset.I_PAID_FOR_THE_WHOLE_CPU, 1.0);
|
||||
}});
|
||||
|
||||
|
||||
+5
-1
@@ -265,7 +265,11 @@ public class ConfigFileHandling
|
||||
)
|
||||
return;
|
||||
|
||||
nightConfig.setComment(entry.getNameWCategory(), " " + entry.getComment().replaceAll("\n", "\n ") + "\n ");
|
||||
String comment = entry.getComment().replaceAll("\n", "\n ").trim();
|
||||
// the new line makes it easier to read and separate configs
|
||||
// the space makes sure the first word of a comment isn't directly in line with the "#"
|
||||
comment = "\n " + comment;
|
||||
nightConfig.setComment(entry.getNameWCategory(), comment);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-2
@@ -82,8 +82,7 @@ public class OpenGLConfigScreen extends AbstractScreen
|
||||
|
||||
private void createBuffer()
|
||||
{
|
||||
GLProxy.getInstance().recordOpenGlCall(() -> sharedContextBuffer = createTextingBuffer());
|
||||
GLProxy.ensureAllGLJobCompleted();
|
||||
sharedContextBuffer = createTextingBuffer();
|
||||
sameContextBuffer = createTextingBuffer();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.seibel.distanthorizons.core.config.types.enums.EConfigEntryAppearance
|
||||
*
|
||||
* @author coolGi
|
||||
*/
|
||||
@Deprecated // FIXME doesn't work with localization
|
||||
public class ConfigLinkedEntry extends AbstractConfigType<AbstractConfigType<?, ?>, ConfigLinkedEntry>
|
||||
{
|
||||
public ConfigLinkedEntry(AbstractConfigType<?, ?> value)
|
||||
|
||||
+11
-9
@@ -75,7 +75,7 @@ public class FullDataSourceV1 implements IDataSource<IDhLevel>
|
||||
/** A flattened 2D array (for the X and Z directions) containing an array for the Y direction. */
|
||||
private final long[][] dataArrays;
|
||||
|
||||
private long sectionPos;
|
||||
private long pos;
|
||||
|
||||
private boolean isEmpty = true;
|
||||
|
||||
@@ -86,11 +86,11 @@ public class FullDataSourceV1 implements IDataSource<IDhLevel>
|
||||
//==============//
|
||||
|
||||
public static FullDataSourceV1 createEmpty(long pos) { return new FullDataSourceV1(pos); }
|
||||
private FullDataSourceV1(long sectionPos)
|
||||
private FullDataSourceV1(long pos)
|
||||
{
|
||||
this.dataArrays = new long[WIDTH * WIDTH][0];
|
||||
this.mapping = new FullDataPointIdMap(sectionPos);
|
||||
this.sectionPos = sectionPos;
|
||||
this.mapping = new FullDataPointIdMap(pos);
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,19 +111,21 @@ public class FullDataSourceV1 implements IDataSource<IDhLevel>
|
||||
//=====================//
|
||||
|
||||
@Override
|
||||
public Long getKey() { return this.sectionPos; }
|
||||
public Long getKey() { return this.pos; }
|
||||
@Override
|
||||
public String getKeyDisplayString() { return DhSectionPos.toString(this.pos); }
|
||||
|
||||
@Override
|
||||
public Long getPos() { return this.sectionPos; }
|
||||
public Long getPos() { return this.pos; }
|
||||
|
||||
public void resizeDataStructuresForRepopulation(long pos)
|
||||
{
|
||||
// no data structures need to be changed, only the source's position
|
||||
this.sectionPos = pos;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getDataDetailLevel() { return (byte) (DhSectionPos.getDetailLevel(this.sectionPos) - SECTION_SIZE_OFFSET); }
|
||||
public byte getDataDetailLevel() { return (byte) (DhSectionPos.getDetailLevel(this.pos) - SECTION_SIZE_OFFSET); }
|
||||
|
||||
public boolean isEmpty() { return this.isEmpty; }
|
||||
|
||||
@@ -370,7 +372,7 @@ public class FullDataSourceV1 implements IDataSource<IDhLevel>
|
||||
throw new IOException("Invalid data content end guard for ID mapping");
|
||||
}
|
||||
|
||||
return FullDataPointIdMap.deserialize(inputStream, this.sectionPos, levelWrapper);
|
||||
return FullDataPointIdMap.deserialize(inputStream, this.pos, levelWrapper);
|
||||
}
|
||||
public void setIdMapping(FullDataPointIdMap mappings) { this.mapping.mergeAndReturnRemappedEntityIds(mappings); }
|
||||
|
||||
|
||||
+2
@@ -74,6 +74,8 @@ public class FullDataSourceV2 implements IDataSource<IDhLevel>
|
||||
private long pos;
|
||||
@Override
|
||||
public Long getKey() { return this.pos; }
|
||||
@Override
|
||||
public String getKeyDisplayString() { return DhSectionPos.toString(this.pos); }
|
||||
|
||||
|
||||
public final FullDataPointIdMap mapping;
|
||||
|
||||
+2
@@ -218,6 +218,8 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
public Long getPos() { return this.pos; }
|
||||
@Override
|
||||
public Long getKey() { return this.pos; }
|
||||
@Override
|
||||
public String getKeyDisplayString() { return DhSectionPos.toString(this.pos); }
|
||||
|
||||
public byte getDataDetailLevel() { return (byte) (DhSectionPos.getDetailLevel(this.pos) - SECTION_SIZE_OFFSET); }
|
||||
|
||||
|
||||
+3
-2
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
@@ -475,10 +476,10 @@ public class ColumnBox
|
||||
throw new RuntimeException("Loop error");
|
||||
if (previousAdjDepth > adjYMax)
|
||||
{
|
||||
if (irisBlockMaterialId == IBlockStateWrapper.IrisBlockMaterial.GRASS)
|
||||
if (irisBlockMaterialId == EDhApiBlockMaterial.GRASS.index)
|
||||
{
|
||||
// this LOD is underneath another, grass will never show here
|
||||
irisBlockMaterialId = IBlockStateWrapper.IrisBlockMaterial.DIRT;
|
||||
irisBlockMaterialId = EDhApiBlockMaterial.DIRT.index;
|
||||
}
|
||||
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color, irisBlockMaterialId,
|
||||
|
||||
+122
-248
@@ -20,16 +20,11 @@
|
||||
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.enums.EGLProxyContext;
|
||||
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;
|
||||
@@ -51,19 +46,21 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
|
||||
private static final long MAX_BUFFER_UPLOAD_TIMEOUT_NANOSECONDS = 1_000_000;
|
||||
|
||||
public static final int QUADS_BYTE_SIZE = LodUtil.LOD_VERTEX_FORMAT.getByteSize() * 4; // TODO what does the 4 represent
|
||||
public static final int MAX_QUADS_PER_BUFFER = (1024 * 1024 * 1) / QUADS_BYTE_SIZE; // TODO what do these multiples represent?
|
||||
/** 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_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;
|
||||
|
||||
private GLVertexBuffer[] vbos;
|
||||
private GLVertexBuffer[] vbosTransparent;
|
||||
public SharedVbo.BufferSlice[] opaqueBufferSlices;
|
||||
public SharedVbo.BufferSlice[] transparentBufferSlices;
|
||||
|
||||
|
||||
|
||||
@@ -74,14 +71,12 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
public ColumnRenderBuffer(DhBlockPos pos)
|
||||
{
|
||||
this.pos = pos;
|
||||
this.vbos = new GLVertexBuffer[0];
|
||||
this.vbosTransparent = new GLVertexBuffer[0];
|
||||
this.opaqueBufferSlices = new SharedVbo.BufferSlice[0];
|
||||
this.transparentBufferSlices = new SharedVbo.BufferSlice[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// buffer uploading //
|
||||
//==================//
|
||||
@@ -92,249 +87,166 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
LodUtil.assertTrue(Thread.currentThread().getName().startsWith(ThreadUtil.THREAD_NAME_PREFIX), "Buffer uploading needs to be done on a DH thread to prevent locking up any MC threads.");
|
||||
|
||||
|
||||
// the async is relative to MC's render thread
|
||||
boolean uploadAsync = Config.Client.Advanced.GpuBuffers.gpuUploadAsync.get();
|
||||
if (uploadAsync)
|
||||
// upload on MC's render thread
|
||||
CompletableFuture<Void> uploadFuture = new CompletableFuture<>();
|
||||
minecraftClient.executeOnRenderThread(() ->
|
||||
{
|
||||
// upload here on a DH thread
|
||||
GLProxy glProxy = GLProxy.getInstance();
|
||||
EGLProxyContext oldContext = glProxy.getGlContext();
|
||||
glProxy.setGlContext(EGLProxyContext.LOD_BUILDER);
|
||||
try
|
||||
{
|
||||
this.uploadBuffersUsingUploadMethod(builder, gpuUploadMethod);
|
||||
uploadFuture.complete(null);
|
||||
}
|
||||
finally
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
glProxy.setGlContext(oldContext);
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}
|
||||
else
|
||||
});
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// upload on MC's render thread
|
||||
CompletableFuture<Void> uploadFuture = new CompletableFuture<>();
|
||||
minecraftClient.executeOnRenderThread(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
this.uploadBuffersUsingUploadMethod(builder, gpuUploadMethod);
|
||||
uploadFuture.complete(null);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// wait for the upload to finish
|
||||
uploadFuture.get(1000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (ExecutionException e)
|
||||
{
|
||||
LOGGER.warn("Error uploading builder ["+builder+"] synchronously. Error: "+e.getMessage(), e);
|
||||
}
|
||||
catch (TimeoutException e)
|
||||
{
|
||||
// timeouts can be ignored because it generally means the
|
||||
// MC Render thread executor was closed
|
||||
//LOGGER.warn("Error uploading builder ["+builder+"] synchronously. Error: "+e.getMessage(), e);
|
||||
}
|
||||
|
||||
|
||||
// wait for the upload to finish
|
||||
uploadFuture.get(5_000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (ExecutionException e)
|
||||
{
|
||||
LOGGER.warn("Error uploading builder ["+builder+"] synchronously. Error: "+e.getMessage(), e);
|
||||
}
|
||||
catch (TimeoutException e)
|
||||
{
|
||||
// timeouts can be ignored because it generally means the
|
||||
// MC Render thread executor was closed
|
||||
//LOGGER.warn("Error uploading builder ["+builder+"] synchronously. Error: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
private void uploadBuffersUsingUploadMethod(LodQuadBuilder builder, EDhApiGpuUploadMethod gpuUploadMethod) throws InterruptedException
|
||||
{
|
||||
if (gpuUploadMethod.useEarlyMapping)
|
||||
{
|
||||
this.uploadBuffersMapped(builder, gpuUploadMethod);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.uploadBuffersDirect(builder, gpuUploadMethod);
|
||||
}
|
||||
//if (gpuUploadMethod.useEarlyMapping)
|
||||
//{
|
||||
// this.uploadBuffersMapped(builder, gpuUploadMethod);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
this.uploadBuffersDirect(builder);
|
||||
//}
|
||||
|
||||
this.buffersUploaded = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void uploadBuffersMapped(LodQuadBuilder builder, EDhApiGpuUploadMethod method)
|
||||
//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 uploadBuffersDirect(LodQuadBuilder builder)
|
||||
{
|
||||
// opaque vbos //
|
||||
|
||||
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)
|
||||
{
|
||||
this.vbos[i] = new GLVertexBuffer(method.useBufferStorage);
|
||||
}
|
||||
}
|
||||
LodQuadBuilder.BufferFiller func = builder.makeOpaqueBufferFiller(method);
|
||||
for (GLVertexBuffer vbo : this.vbos)
|
||||
{
|
||||
func.fill(vbo);
|
||||
SharedVbo.OPAQUE.deallocate(this.opaqueBufferSlices);
|
||||
this.opaqueBufferSlices = new SharedVbo.BufferSlice[opaqueSliceCount];
|
||||
}
|
||||
uploadBuffersDirect(SharedVbo.OPAQUE, this.opaqueBufferSlices, builder.makeOpaqueVertexBuffers());
|
||||
|
||||
|
||||
// transparent vbos //
|
||||
|
||||
this.vbosTransparent = ColumnRenderBufferBuilder.resizeBuffer(this.vbosTransparent, builder.getCurrentNeededTransparentVertexBufferCount());
|
||||
for (int i = 0; i < this.vbosTransparent.length; i++)
|
||||
int transparentSliceCount = builder.getCurrentNeededTransparentVertexBufferCount();
|
||||
if (this.transparentBufferSlices.length != transparentSliceCount)
|
||||
{
|
||||
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);
|
||||
SharedVbo.TRANSPARENT.deallocate(this.transparentBufferSlices);
|
||||
this.transparentBufferSlices = new SharedVbo.BufferSlice[transparentSliceCount];
|
||||
}
|
||||
uploadBuffersDirect(SharedVbo.TRANSPARENT, this.transparentBufferSlices, builder.makeTransparentVertexBuffers());
|
||||
}
|
||||
|
||||
private void uploadBuffersDirect(LodQuadBuilder builder, EDhApiGpuUploadMethod method) throws InterruptedException
|
||||
private static void uploadBuffersDirect(SharedVbo handler, SharedVbo.BufferSlice[] bufferSlices, Iterator<ByteBuffer> iter)
|
||||
{
|
||||
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;
|
||||
int i = 0;
|
||||
while (iter.hasNext())
|
||||
{
|
||||
if (vboIndex >= vbos.length)
|
||||
if (i >= bufferSlices.length)
|
||||
{
|
||||
throw new RuntimeException("Too many vertex buffers!!");
|
||||
}
|
||||
|
||||
|
||||
// get or create the VBO
|
||||
if (vbos[vboIndex] == null)
|
||||
// get or create the buffer
|
||||
if (bufferSlices[i] == null)
|
||||
{
|
||||
vbos[vboIndex] = new GLVertexBuffer(method.useBufferStorage);
|
||||
bufferSlices[i] = handler.allocateSlice();
|
||||
}
|
||||
GLVertexBuffer vbo = vbos[vboIndex];
|
||||
SharedVbo.BufferSlice slice = bufferSlices[i];
|
||||
|
||||
|
||||
ByteBuffer bb = iter.next();
|
||||
int size = bb.limit() - bb.position();
|
||||
|
||||
ByteBuffer buffer = iter.next();
|
||||
try
|
||||
{
|
||||
vbo.bind();
|
||||
vbo.uploadBuffer(bb, size / LodUtil.LOD_VERTEX_FORMAT.getByteSize(), method, FULL_SIZED_BUFFER);
|
||||
handler.updateBuffer(slice, buffer);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
vbos[vboIndex] = null;
|
||||
vbo.close();
|
||||
LOGGER.error("Failed to upload buffer: ", e);
|
||||
bufferSlices[i] = null;
|
||||
handler.deallocate(slice);
|
||||
LOGGER.error("Failed to upload buffer. Error: ["+e.getMessage()+"].", e);
|
||||
}
|
||||
|
||||
|
||||
if (MBPerMS > 0)
|
||||
{
|
||||
// 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++;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (vboIndex < vbos.length)
|
||||
if (i < bufferSlices.length)
|
||||
{
|
||||
throw new RuntimeException("Too few vertex buffers!!");
|
||||
throw new RuntimeException("Too few buffer chunks!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
|
||||
/** @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;
|
||||
}
|
||||
//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);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
@@ -342,50 +254,28 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
// misc methods //
|
||||
//==============//
|
||||
|
||||
// TODO
|
||||
/** can be used when debugging */
|
||||
public boolean hasNonNullVbos() { return this.vbos != null || this.vbosTransparent != null; }
|
||||
public boolean hasNonNullVbos() { return false; } //this.vbos != null || this.vbosTransparent != null; }
|
||||
|
||||
/** can be used when debugging */
|
||||
public int vboBufferCount()
|
||||
public int bufferSliceCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (this.vbos != null)
|
||||
if (this.opaqueBufferSlices != null)
|
||||
{
|
||||
count += this.vbos.length;
|
||||
count += this.opaqueBufferSlices.length;
|
||||
}
|
||||
|
||||
if (this.vbosTransparent != null)
|
||||
|
||||
if (this.transparentBufferSlices != null)
|
||||
{
|
||||
count += this.vbosTransparent.length;
|
||||
count += this.transparentBufferSlices.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
|
||||
@@ -397,24 +287,8 @@ public class ColumnRenderBuffer implements AutoCloseable
|
||||
{
|
||||
this.buffersUploaded = false;
|
||||
|
||||
GLProxy.getInstance().queueRunningOnRenderThread(() ->
|
||||
{
|
||||
for (GLVertexBuffer buffer : this.vbos)
|
||||
{
|
||||
if (buffer != null)
|
||||
{
|
||||
buffer.destroy(false);
|
||||
}
|
||||
}
|
||||
|
||||
for (GLVertexBuffer buffer : this.vbosTransparent)
|
||||
{
|
||||
if (buffer != null)
|
||||
{
|
||||
buffer.destroy(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
SharedVbo.OPAQUE.deallocate(this.opaqueBufferSlices);
|
||||
SharedVbo.TRANSPARENT.deallocate(this.transparentBufferSlices);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-33
@@ -54,11 +54,6 @@ public class ColumnRenderBufferBuilder
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
|
||||
public static final int MAX_NUMBER_OF_CONCURRENT_CALLS_PER_THREAD = 3;
|
||||
public static int maxNumberOfConcurrentCalls = MAX_NUMBER_OF_CONCURRENT_CALLS_PER_THREAD;
|
||||
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// vbo building //
|
||||
@@ -338,32 +333,4 @@ 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-17
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderSource;
|
||||
import com.seibel.distanthorizons.core.pos.DhLodPos;
|
||||
@@ -95,53 +96,54 @@ public class CubicLodTemplate
|
||||
}
|
||||
case SHOW_BLOCK_MATERIAL:
|
||||
{
|
||||
switch (blockMaterialId)
|
||||
|
||||
switch (EDhApiBlockMaterial.getFromIndex(blockMaterialId))
|
||||
{
|
||||
case IBlockStateWrapper.IrisBlockMaterial.UNKOWN:
|
||||
case IBlockStateWrapper.IrisBlockMaterial.AIR: // shouldn't normally be rendered, but just in case
|
||||
case UNKNOWN:
|
||||
case AIR: // shouldn't normally be rendered, but just in case
|
||||
color = ColorUtil.HOT_PINK;
|
||||
break;
|
||||
|
||||
case IBlockStateWrapper.IrisBlockMaterial.LEAVES:
|
||||
case LEAVES:
|
||||
color = ColorUtil.DARK_GREEN;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.STONE:
|
||||
case STONE:
|
||||
color = ColorUtil.GRAY;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.WOOD:
|
||||
case WOOD:
|
||||
color = ColorUtil.BROWN;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.METAL:
|
||||
case METAL:
|
||||
color = ColorUtil.DARK_GRAY;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.DIRT:
|
||||
case DIRT:
|
||||
color = ColorUtil.LIGHT_BROWN;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.LAVA:
|
||||
case LAVA:
|
||||
color = ColorUtil.ORANGE;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.DEEPSLATE:
|
||||
case DEEPSLATE:
|
||||
color = ColorUtil.BLACK;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.SNOW:
|
||||
case SNOW:
|
||||
color = ColorUtil.WHITE;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.SAND:
|
||||
case SAND:
|
||||
color = ColorUtil.TAN;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.TERRACOTTA:
|
||||
case TERRACOTTA:
|
||||
color = ColorUtil.DARK_ORANGE;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.NETHER_STONE:
|
||||
case NETHER_STONE:
|
||||
color = ColorUtil.DARK_RED;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.WATER:
|
||||
case WATER:
|
||||
color = ColorUtil.BLUE;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.GRASS:
|
||||
case GRASS:
|
||||
color = ColorUtil.GREEN;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.ILLUMINATED:
|
||||
case ILLUMINATED:
|
||||
color = ColorUtil.YELLOW;
|
||||
break;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user