From 00e8310d72c88686ca3fd6df1e2904f0003648d1 Mon Sep 17 00:00:00 2001 From: kinztechcom Date: Thu, 16 Sep 2021 23:17:29 -0400 Subject: [PATCH 1/3] Initial commit for a day/night cycle. --- src/main/java/rs117/hd/HdPlugin.java | 33 +++++++-- src/main/java/rs117/hd/HdPluginConfig.java | 25 ++++++- .../java/rs117/hd/environments/DayLight.java | 68 +++++++++++++++++++ .../rs117/hd/environments/Environment.java | 17 ++++- .../hd/environments/EnvironmentManager.java | 16 ++++- 5 files changed, 151 insertions(+), 8 deletions(-) create mode 100644 src/main/java/rs117/hd/environments/DayLight.java diff --git a/src/main/java/rs117/hd/HdPlugin.java b/src/main/java/rs117/hd/HdPlugin.java index e07bc3f2b..2696d5d0e 100644 --- a/src/main/java/rs117/hd/HdPlugin.java +++ b/src/main/java/rs117/hd/HdPlugin.java @@ -56,6 +56,8 @@ import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; +import java.time.LocalDate; +import java.time.LocalTime; import java.util.ArrayList; import javax.inject.Inject; import javax.swing.SwingUtilities; @@ -124,6 +126,7 @@ import rs117.hd.config.FogDepthMode; import rs117.hd.config.UIScalingMode; import rs117.hd.config.WaterEffects; +import rs117.hd.environments.DayLight; import rs117.hd.environments.EnvironmentManager; import rs117.hd.lighting.LightManager; import rs117.hd.materials.Material; @@ -158,6 +161,7 @@ public class HdPlugin extends Plugin implements DrawCallbacks private static final int MATERIAL_PROPERTIES_COUNT = 12; private static final int LIGHT_PROPERTIES_COUNT = 8; private static final int SCALAR_BYTES = 4; + private static final LocalDate CURRENT_DATE = LocalDate.now(); @Inject private Client client; @@ -398,6 +402,8 @@ enum ComputeMode public boolean configNpcLights = true; public boolean configShadowsEnabled = false; public boolean configExpandShadowDraw = false; + public boolean configDayNightEnabled = false; + public boolean configDayOnly = false; // Reduces drawing a buggy mess when toggling HD private boolean startUpCompleted = false; @@ -416,6 +422,8 @@ protected void startUp() configNpcLights = config.npcLights(); configShadowsEnabled = config.shadowsEnabled(); configExpandShadowDraw = config.expandShadowDraw(); + configDayNightEnabled = config.dayNight(); + configDayOnly = config.dayOnly(); clientThread.invoke(() -> { @@ -1574,8 +1582,15 @@ private void drawFrame(int overlayColor) Matrix4 lightProjectionMatrix = new Matrix4(); float lightPitch = -128; float lightYaw = 55; + boolean shadowsAvailable = true; + if(configDayNightEnabled) { + DayLight timeOfDay = environmentManager.currentTimeOfDay; + lightPitch = timeOfDay.getCurrentPitch(LocalTime.now()); + lightYaw = timeOfDay.getCurrentYaw(CURRENT_DATE); + shadowsAvailable = timeOfDay.isShadowsEnabled(); + } - if (client.getGameState() == GameState.LOGGED_IN && configShadowsEnabled && fboShadowMap != -1 && environmentManager.currentDirectionalStrength > 0.0f) + if (client.getGameState() == GameState.LOGGED_IN && configShadowsEnabled && shadowsAvailable && fboShadowMap != -1 && environmentManager.currentDirectionalStrength > 0.0f) { // render shadow depth map gl.glViewport(0, 0, config.shadowResolution().getValue(), config.shadowResolution().getValue()); @@ -1771,9 +1786,9 @@ else if (config.fogDepthMode() == FogDepthMode.NONE) double lightX = Math.cos(lightPitchRadians) * Math.sin(lightYawRadians); double lightY = Math.sin(lightPitchRadians); double lightZ = Math.cos(lightPitchRadians) * Math.cos(lightYawRadians); - gl.glUniform1f(uniLightX, (float)lightX); - gl.glUniform1f(uniLightY, (float)lightY); - gl.glUniform1f(uniLightZ, (float)lightZ); + gl.glUniform1f(uniLightX, (float) lightX); + gl.glUniform1f(uniLightY, (float) lightY); + gl.glUniform1f(uniLightZ, (float) lightZ); // use a curve to calculate max bias value based on the density of the shadow map float shadowPixelsPerTile = (float)config.shadowResolution().getValue() / (float)config.shadowDistance().getValue(); @@ -2133,6 +2148,16 @@ public void onConfigChanged(ConfigChanged event) case "expandShadowDraw": configExpandShadowDraw = config.expandShadowDraw(); break; + case "dayNight": + configDayNightEnabled = config.dayNight(); + reloadScene(); + environmentManager.update(); + break; + case "dayOnly": + configDayOnly = config.dayOnly(); + reloadScene(); + environmentManager.update(); + break; } } diff --git a/src/main/java/rs117/hd/HdPluginConfig.java b/src/main/java/rs117/hd/HdPluginConfig.java index 0667c5b96..c3c87aecc 100644 --- a/src/main/java/rs117/hd/HdPluginConfig.java +++ b/src/main/java/rs117/hd/HdPluginConfig.java @@ -295,7 +295,6 @@ default boolean expandShadowDraw() } - /*====== Environment settings ======*/ @ConfigSection( @@ -403,4 +402,28 @@ default boolean tzhaarHD() { return true; } + + @ConfigItem( + keyName = "dayNight", + name = "Day/Night Cycle", + description = "Environmental lighting will be based on your local PC's time of day.", + position = 209, + section = environmentSettings + ) + default boolean dayNight() + { + return false; + } + + @ConfigItem( + keyName = "dayOnly", + name = "Day Only", + description = "Only show day lighting for you local PC time of day.", + position = 210, + section = environmentSettings + ) + default boolean dayOnly() + { + return false; + } } diff --git a/src/main/java/rs117/hd/environments/DayLight.java b/src/main/java/rs117/hd/environments/DayLight.java new file mode 100644 index 000000000..6bd4ffd01 --- /dev/null +++ b/src/main/java/rs117/hd/environments/DayLight.java @@ -0,0 +1,68 @@ +package rs117.hd.environments; + +import lombok.extern.slf4j.Slf4j; + +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalTime; + +@Slf4j +public enum DayLight { + + DAY(LocalTime.of(7, 0), true), + NIGHT(LocalTime.of(17, 0), false); + + private LocalTime startTime; + private boolean shadowsEnabled; + + /** + * This is a day(12-hour) based change. + */ + private static final int START_PITCH = 175; + private static final int END_PITCH = 360; + + /** + * This is a season(month) based changed. + * December/June = -90 degrees + * March/September = -45/-135 degrees + */ + private static final int START_YAW = -45; + private static final int END_YAW = -135; + + /** + * TODO: Calculate this value based on distance between sunrise/sunset. + */ + private static final float CYCLE_LENGTH = 12; + + DayLight(LocalTime startTime, boolean shadowsEnabled) { + this.startTime = startTime; + this.shadowsEnabled = shadowsEnabled; + } + + public boolean isShadowsEnabled() { + return shadowsEnabled; + } + + public static DayLight getTimeOfDay(LocalTime currentTime) { + return currentTime.isAfter(DAY.startTime) && currentTime.isBefore(NIGHT.startTime) ? DAY : NIGHT; + } + + private float percentageOfDaylight(LocalTime currentTime) { + return Math.abs(Duration.between(currentTime, startTime).toHours()) / CYCLE_LENGTH; + } + + private float percentageOfSeason(LocalDate currentDate) { + float month = currentDate.getMonthValue() + (currentDate.getDayOfMonth() / currentDate.lengthOfMonth()); + float normalizedMonth = month <= 6 ? month : month - 7; + return normalizedMonth / 6; + } + + public float getCurrentPitch(LocalTime currentTime) { + return percentageOfDaylight(currentTime) * (END_PITCH - START_PITCH) + START_PITCH; + } + + public float getCurrentYaw(LocalDate currentDate) { + return percentageOfSeason(currentDate) * (END_YAW - START_YAW) + START_YAW; + } + +} diff --git a/src/main/java/rs117/hd/environments/Environment.java b/src/main/java/rs117/hd/environments/Environment.java index a27d3611d..13c5f1150 100644 --- a/src/main/java/rs117/hd/environments/Environment.java +++ b/src/main/java/rs117/hd/environments/Environment.java @@ -757,7 +757,14 @@ public enum Environment UNKNOWN_OVERWORLD(Area.UNKNOWN_OVERWORLD, new Properties()), // overrides 'ALL' to provide default daylight conditions for the overworld area - OVERWORLD(Area.OVERWORLD, new Properties()), + OVERWORLD(Area.OVERWORLD, new Properties(), DayLight.DAY), + OVERWORLD_NIGHT(Area.OVERWORLD, new Properties() + .setFogColor(15, 14, 13) + .setFogDepth(40) + .setAmbientColor("#292828") + .setAmbientStrength(0.4f) + .setDirectionalStrength(0.7f) + .setDirectionalColor("#FFFFFF"), DayLight.NIGHT), // used for underground, instances, etc. ALL(Area.ALL, new Properties() .setFogColor("#31271A") @@ -788,6 +795,7 @@ public enum Environment private final int groundFogStart; private final int groundFogEnd; private final float groundFogOpacity; + private final DayLight timeOfDay; private static class Properties { @@ -935,6 +943,11 @@ public Properties enableLightning() } Environment(Area area, Properties properties) + { + this(area, properties, DayLight.DAY); + } + + Environment(Area area, Properties properties, DayLight timeOfDay) { this.area = area; this.fogDepth = properties.fogDepth; @@ -955,5 +968,7 @@ public Properties enableLightning() this.groundFogStart = properties.groundFogStart; this.groundFogEnd = properties.groundFogEnd; this.groundFogOpacity = properties.groundFogOpacity; + this.timeOfDay = timeOfDay; } + } diff --git a/src/main/java/rs117/hd/environments/EnvironmentManager.java b/src/main/java/rs117/hd/environments/EnvironmentManager.java index 7ef198556..083fb133d 100644 --- a/src/main/java/rs117/hd/environments/EnvironmentManager.java +++ b/src/main/java/rs117/hd/environments/EnvironmentManager.java @@ -25,9 +25,13 @@ package rs117.hd.environments; import com.google.common.primitives.Floats; + +import java.time.LocalTime; import java.util.ArrayList; import javax.inject.Inject; import javax.inject.Singleton; + +import jdk.vm.ci.meta.Local; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.Constants; @@ -57,6 +61,10 @@ public class EnvironmentManager private Environment currentEnvironment; private final Environment defaultEnvironment = Environment.OVERWORLD; + // Assume 7:00 am & pm sunrise/sunset. + private static final LocalTime SUNRISE = LocalTime.of(7, 0); + private static final LocalTime SUNSET = LocalTime.of(23, 0); + // transition time private final int transitionDuration = 3000; // distance in tiles to skip transition (e.g. entering cave, teleporting) @@ -128,6 +136,8 @@ public class EnvironmentManager public boolean lightningEnabled = false; + public DayLight currentTimeOfDay = DayLight.getTimeOfDay(LocalTime.now()); + public void update() { WorldPoint camPosition = localPointToWorldTile(hdPlugin.camTarget[0], hdPlugin.camTarget[1]); @@ -135,9 +145,11 @@ public void update() int camTargetY = camPosition.getY(); int camTargetZ = camPosition.getPlane(); + currentTimeOfDay = hdPlugin.configDayOnly ? DayLight.DAY : DayLight.getTimeOfDay(LocalTime.now()); + for (Environment environment : sceneEnvironments) { - if (environment.getArea().containsPoint(camTargetX, camTargetY, camTargetZ)) + if (environment.getArea().containsPoint(camTargetX, camTargetY, camTargetZ) && environment.getTimeOfDay() == currentTimeOfDay) { if (environment != currentEnvironment) { @@ -210,7 +222,7 @@ public void update() private void changeEnvironment(Environment newEnvironment, int camTargetX, int camTargetY) { currentEnvironment = newEnvironment; - log.debug("currentEnvironment changed to " + newEnvironment); + log.debug("currentEnvironment changed to " + currentEnvironment); startTime = System.currentTimeMillis(); transitionCompleteTime = startTime + transitionDuration; From 3d0d87a05ea16feb17e0b0a4aef58001ac18acf5 Mon Sep 17 00:00:00 2001 From: kinztechcom Date: Thu, 16 Sep 2021 23:25:13 -0400 Subject: [PATCH 2/3] Remove unused constants. --- src/main/java/rs117/hd/environments/EnvironmentManager.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/rs117/hd/environments/EnvironmentManager.java b/src/main/java/rs117/hd/environments/EnvironmentManager.java index 083fb133d..7cac0962d 100644 --- a/src/main/java/rs117/hd/environments/EnvironmentManager.java +++ b/src/main/java/rs117/hd/environments/EnvironmentManager.java @@ -61,10 +61,6 @@ public class EnvironmentManager private Environment currentEnvironment; private final Environment defaultEnvironment = Environment.OVERWORLD; - // Assume 7:00 am & pm sunrise/sunset. - private static final LocalTime SUNRISE = LocalTime.of(7, 0); - private static final LocalTime SUNSET = LocalTime.of(23, 0); - // transition time private final int transitionDuration = 3000; // distance in tiles to skip transition (e.g. entering cave, teleporting) @@ -222,7 +218,7 @@ public void update() private void changeEnvironment(Environment newEnvironment, int camTargetX, int camTargetY) { currentEnvironment = newEnvironment; - log.debug("currentEnvironment changed to " + currentEnvironment); + log.debug("currentEnvironment changed to " + newEnvironment); startTime = System.currentTimeMillis(); transitionCompleteTime = startTime + transitionDuration; From 2228f3ff6e094ab8611676f3d6990c492ad7e5c8 Mon Sep 17 00:00:00 2001 From: kinztechcom Date: Fri, 17 Sep 2021 10:04:51 -0400 Subject: [PATCH 3/3] Fix percentageOfDaylight precision. --- src/main/java/rs117/hd/environments/DayLight.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/rs117/hd/environments/DayLight.java b/src/main/java/rs117/hd/environments/DayLight.java index 6bd4ffd01..3df9825af 100644 --- a/src/main/java/rs117/hd/environments/DayLight.java +++ b/src/main/java/rs117/hd/environments/DayLight.java @@ -48,7 +48,7 @@ public static DayLight getTimeOfDay(LocalTime currentTime) { } private float percentageOfDaylight(LocalTime currentTime) { - return Math.abs(Duration.between(currentTime, startTime).toHours()) / CYCLE_LENGTH; + return Math.abs(Duration.between(currentTime, startTime).toMillis()) / (CYCLE_LENGTH * 60 * 60 * 1000); } private float percentageOfSeason(LocalDate currentDate) {