mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 02:54:04 +09:00
hosek skybox moved outside of basegame; moonlight impl
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
package net.torvald.terrarum.modulebasegame
|
package net.torvald.terrarum
|
||||||
|
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -1,19 +1,16 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.clut
|
package net.torvald.terrarum.clut
|
||||||
|
|
||||||
import net.torvald.colourutil.CIEXYZ
|
import net.torvald.colourutil.CIEXYZ
|
||||||
import net.torvald.colourutil.toColor
|
import net.torvald.colourutil.toColor
|
||||||
import net.torvald.colourutil.toRGB
|
import net.torvald.colourutil.toRGB
|
||||||
import net.torvald.parametricsky.ArHosekSkyModel
|
import net.torvald.parametricsky.ArHosekSkyModel
|
||||||
import net.torvald.terrarum.abs
|
import net.torvald.terrarum.abs
|
||||||
import net.torvald.terrarum.modulebasegame.clut.Skybox.coerceInSmoothly
|
import net.torvald.terrarum.clut.Skybox.coerceInSmoothly
|
||||||
import net.torvald.terrarum.modulebasegame.clut.Skybox.mapCircle
|
import net.torvald.terrarum.clut.Skybox.mapCircle
|
||||||
import net.torvald.terrarum.modulebasegame.clut.Skybox.scaleToFit
|
import net.torvald.terrarum.clut.Skybox.scaleToFit
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.HALF_PI
|
import net.torvald.terrarum.modulebasegame.worldgenerator.HALF_PI
|
||||||
import net.torvald.terrarum.serialise.toLittle
|
import net.torvald.terrarum.serialise.toLittle
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.math.PI
|
|
||||||
import kotlin.math.pow
|
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2023-08-01.
|
* Created by minjaesong on 2023-08-01.
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.clut
|
package net.torvald.terrarum.clut
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
@@ -11,9 +12,7 @@ import net.torvald.colourutil.toRGB
|
|||||||
import net.torvald.parametricsky.ArHosekSkyModel
|
import net.torvald.parametricsky.ArHosekSkyModel
|
||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.ModMgr
|
|
||||||
import net.torvald.terrarum.abs
|
import net.torvald.terrarum.abs
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.HALF_PI
|
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
@@ -22,6 +21,10 @@ import kotlin.math.*
|
|||||||
*/
|
*/
|
||||||
object Skybox : Disposable {
|
object Skybox : Disposable {
|
||||||
|
|
||||||
|
private const val HALF_PI = 1.5707963267948966
|
||||||
|
private const val PI = 3.141592653589793
|
||||||
|
private const val TWO_PI = 6.283185307179586
|
||||||
|
|
||||||
const val gradSize = 64
|
const val gradSize = 64
|
||||||
|
|
||||||
private lateinit var gradTexBinLowAlbedo: Array<TextureRegion>
|
private lateinit var gradTexBinLowAlbedo: Array<TextureRegion>
|
||||||
@@ -32,7 +35,7 @@ object Skybox : Disposable {
|
|||||||
private lateinit var texStripRegions: TextureRegionPack
|
private lateinit var texStripRegions: TextureRegionPack
|
||||||
|
|
||||||
fun loadlut() {
|
fun loadlut() {
|
||||||
tex = Texture(ModMgr.getGdxFile("basegame", "weathers/main_skybox.png"))
|
tex = Texture(Gdx.files.internal("assets/clut/skybox.png"))
|
||||||
tex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
tex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||||
texRegions = TextureRegionPack(tex, 2, gradSize - 2, 0, 2, 0, 1)
|
texRegions = TextureRegionPack(tex, 2, gradSize - 2, 0, 2, 0, 1)
|
||||||
texStripRegions = TextureRegionPack(tex, elevCnt, gradSize - 2, 0, 2, 0, 1)
|
texStripRegions = TextureRegionPack(tex, elevCnt, gradSize - 2, 0, 2, 0, 1)
|
||||||
@@ -230,8 +233,8 @@ object Skybox : Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
if (::gradTexBinLowAlbedo.isInitialized) gradTexBinLowAlbedo.forEach { it.texture.dispose() }
|
if (Skybox::gradTexBinLowAlbedo.isInitialized) gradTexBinLowAlbedo.forEach { it.texture.dispose() }
|
||||||
if (::gradTexBinHighAlbedo.isInitialized) gradTexBinHighAlbedo.forEach { it.texture.dispose() }
|
if (Skybox::gradTexBinHighAlbedo.isInitialized) gradTexBinHighAlbedo.forEach { it.texture.dispose() }
|
||||||
if (::tex.isInitialized) tex.dispose()
|
if (Skybox::tex.isInitialized) tex.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ class WorldTime(initTime: Long = 0L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline val moonPhase: Double
|
inline val moonPhase: Double
|
||||||
get() = (TIME_T.plus(1700000L) % LUNAR_CYCLE).toDouble() / LUNAR_CYCLE
|
get() = (TIME_T.plus(700000L) % LUNAR_CYCLE).toDouble() / LUNAR_CYCLE
|
||||||
|
|
||||||
fun getSolarElevationAt(ordinalDay: Int, second: Int): Double {
|
fun getSolarElevationAt(ordinalDay: Int, second: Int): Double {
|
||||||
val TIME_T = DAY_LENGTH * ordinalDay + second
|
val TIME_T = DAY_LENGTH * ordinalDay + second
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import net.torvald.terrarum.gameworld.GameWorld
|
|||||||
import net.torvald.terrarum.gameworld.WorldTime
|
import net.torvald.terrarum.gameworld.WorldTime
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
import net.torvald.terrarum.modulebasegame.clut.Skybox
|
import net.torvald.terrarum.clut.Skybox
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UILoadGovernor
|
import net.torvald.terrarum.modulebasegame.ui.UILoadGovernor
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIRemoCon
|
import net.torvald.terrarum.modulebasegame.ui.UIRemoCon
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml
|
import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import net.torvald.util.IntArrayStack
|
import net.torvald.util.IntArrayStack
|
||||||
import net.torvald.colourutil.Col4096
|
import net.torvald.colourutil.Col4096
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.modulebasegame.RNGConsumer
|
import net.torvald.terrarum.RNGConsumer
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import net.torvald.terrarum.worlddrawer.WorldCamera
|
|||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.sign
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-03-14.
|
* Created by minjaesong on 2016-03-14.
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package net.torvald.terrarum.weather
|
package net.torvald.terrarum.weather
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.Input
|
|
||||||
import com.badlogic.gdx.graphics.*
|
import com.badlogic.gdx.graphics.*
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
import com.badlogic.gdx.math.Vector2
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.gdx.graphics.Cvec
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
@@ -12,14 +10,11 @@ import net.torvald.terrarum.*
|
|||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.gameworld.WorldTime
|
import net.torvald.terrarum.gameworld.WorldTime
|
||||||
import net.torvald.terrarum.gameworld.WorldTime.Companion.DAY_LENGTH
|
import net.torvald.terrarum.gameworld.WorldTime.Companion.DAY_LENGTH
|
||||||
import net.torvald.terrarum.modulebasegame.RNGConsumer
|
import net.torvald.terrarum.RNGConsumer
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.clut.Skybox
|
||||||
import net.torvald.terrarum.modulebasegame.clut.Skybox
|
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.ParticleMegaRain
|
|
||||||
import net.torvald.terrarum.utils.JsonFetcher
|
import net.torvald.terrarum.utils.JsonFetcher
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -68,7 +63,7 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
var forceTurbidity: Double? = null
|
var forceTurbidity: Double? = null
|
||||||
|
|
||||||
// doesn't work if the png is in greyscale/indexed mode
|
// doesn't work if the png is in greyscale/indexed mode
|
||||||
val starmapTex: TextureRegion = TextureRegion(Texture(ModMgr.getGdxFile("basegame", "weathers/astrum.png"))).also {
|
val starmapTex: TextureRegion = TextureRegion(Texture(Gdx.files.internal("./assets/graphics/astrum.png"))).also {
|
||||||
it.texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
it.texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||||
it.texture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat)
|
it.texture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat)
|
||||||
}
|
}
|
||||||
@@ -78,6 +73,8 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
private var astrumOffX = 0f
|
private var astrumOffX = 0f
|
||||||
private var astrumOffY = 0f
|
private var astrumOffY = 0f
|
||||||
|
|
||||||
|
private val moonlightMax = Cvec(0.23f, 0.24f, 0.25f, 0.21f) // actual moonlight is around ~4100K but our mesopic vision makes it appear blueish (wikipedia: Purkinje effect)
|
||||||
|
|
||||||
override fun loadFromSave(s0: Long, s1: Long) {
|
override fun loadFromSave(s0: Long, s1: Long) {
|
||||||
super.loadFromSave(s0, s1)
|
super.loadFromSave(s0, s1)
|
||||||
internalReset(s0, s1)
|
internalReset(s0, s1)
|
||||||
@@ -100,18 +97,18 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
|
|
||||||
|
|
||||||
// read weather descriptions from assets/weather (modular weather)
|
// read weather descriptions from assets/weather (modular weather)
|
||||||
val weatherRawValidList = ArrayList<File>()
|
val weatherRawValidList = ArrayList<Pair<String, File>>()
|
||||||
val weatherRawsDir = ModMgr.getFilesFromEveryMod("weathers")
|
val weatherRawsDir = ModMgr.getFilesFromEveryMod("weathers")
|
||||||
weatherRawsDir.forEach { (modname, parentdir) ->
|
weatherRawsDir.forEach { (modname, parentdir) ->
|
||||||
printdbg(this, "Scanning dir $parentdir")
|
printdbg(this, "Scanning dir $parentdir")
|
||||||
parentdir.listFiles(FileFilter { !it.isDirectory && it.name.endsWith(".json") })?.forEach {
|
parentdir.listFiles(FileFilter { !it.isDirectory && it.name.endsWith(".json") })?.forEach {
|
||||||
weatherRawValidList.add(it)
|
weatherRawValidList.add(modname to it)
|
||||||
printdbg(this, "Registering weather '$it' from module $modname")
|
printdbg(this, "Registering weather '$it' from module $modname")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// --> read from directory and store file that looks like RAW
|
// --> read from directory and store file that looks like RAW
|
||||||
for (raw in weatherRawValidList) {
|
for ((modname, raw) in weatherRawValidList) {
|
||||||
val weather = readFromJson(raw)
|
val weather = readFromJson(modname, raw)
|
||||||
|
|
||||||
// if List for the classification does not exist, make one
|
// if List for the classification does not exist, make one
|
||||||
if (!weatherList.containsKey(weather.classification))
|
if (!weatherList.containsKey(weather.classification))
|
||||||
@@ -151,21 +148,6 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
// currentWeather = weatherList[WEATHER_GENERIC]!![0] // force set weather
|
// currentWeather = weatherList[WEATHER_GENERIC]!![0] // force set weather
|
||||||
|
|
||||||
|
|
||||||
// test rain toggled by F2
|
|
||||||
if (KeyToggler.isOn(Input.Keys.F2) && Terrarum.ingame is TerrarumIngame) {
|
|
||||||
val playerPosX = player.hitbox.centeredX
|
|
||||||
val playerPosY = player.hitbox.centeredY
|
|
||||||
kotlin.repeat(7) {
|
|
||||||
val rainParticle = ParticleMegaRain(
|
|
||||||
playerPosX + HQRNG().nextInt(App.scr.width) - App.scr.halfw,
|
|
||||||
playerPosY - App.scr.height
|
|
||||||
)
|
|
||||||
(Terrarum.ingame!! as TerrarumIngame).addParticle(rainParticle)
|
|
||||||
}
|
|
||||||
//globalLightNow.set(getGlobalLightOfTime((INGAME.world).time.todaySeconds).mul(0.3f, 0.3f, 0.3f, 0.58f))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!globalLightOverridden) {
|
if (!globalLightOverridden) {
|
||||||
world.globalLight = WeatherMixer.globalLightNow
|
world.globalLight = WeatherMixer.globalLightNow
|
||||||
}
|
}
|
||||||
@@ -200,8 +182,10 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
world.worldTime.solarElevationDeg
|
world.worldTime.solarElevationDeg
|
||||||
val daylightClut = currentWeather.daylightClut
|
val daylightClut = currentWeather.daylightClut
|
||||||
// calculate global light
|
// calculate global light
|
||||||
val globalLight = getGradientColour2(daylightClut, solarElev, timeNow)
|
val moonSize = (-(2.0 * world.worldTime.moonPhase - 1.0).abs() + 1.0).toFloat()
|
||||||
globalLightNow.set(globalLight)
|
val globalLightBySun: Cvec = getGradientColour2(daylightClut, solarElev, timeNow)
|
||||||
|
val globalLightByMoon: Cvec = moonlightMax * moonSize
|
||||||
|
globalLightNow.set(globalLightBySun max globalLightByMoon)
|
||||||
|
|
||||||
/* (copied from the shader source)
|
/* (copied from the shader source)
|
||||||
UV mapping coord.y
|
UV mapping coord.y
|
||||||
@@ -260,7 +244,13 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private operator fun Color.times(other: Color) = Color(this.r * other.r, this.g * other.g, this.b * other.b, 1f)
|
private operator fun Cvec.times(other: Float) = Cvec(this.r * other, this.g * other, this.b * other, this.a * other)
|
||||||
|
private infix fun Cvec.max(other: Cvec) = Cvec(
|
||||||
|
if (this.r > other.r) this.r else other.r,
|
||||||
|
if (this.g > other.g) this.g else other.g,
|
||||||
|
if (this.b > other.b) this.b else other.b,
|
||||||
|
if (this.a > other.a) this.a else other.a
|
||||||
|
)
|
||||||
|
|
||||||
fun colorMix(one: Color, two: Color, scale: Float): Color {
|
fun colorMix(one: Color, two: Color, scale: Float): Color {
|
||||||
return Color(
|
return Color(
|
||||||
@@ -344,9 +334,9 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
fun getRandomWeather(classification: String) =
|
fun getRandomWeather(classification: String) =
|
||||||
getWeatherList(classification)[RNG.nextInt(getWeatherList(classification).size)]
|
getWeatherList(classification)[RNG.nextInt(getWeatherList(classification).size)]
|
||||||
|
|
||||||
fun readFromJson(file: File): BaseModularWeather = readFromJson(file.path)
|
fun readFromJson(modname: String, file: File): BaseModularWeather = readFromJson(modname, file.path)
|
||||||
|
|
||||||
fun readFromJson(path: String): BaseModularWeather {
|
fun readFromJson(modname: String, path: String): BaseModularWeather {
|
||||||
/* JSON structure:
|
/* JSON structure:
|
||||||
{
|
{
|
||||||
"skyboxGradColourMap": "colourmap/sky_colour.tga", // string (path to image) for dynamic. Image must be RGBA8888 or RGB888
|
"skyboxGradColourMap": "colourmap/sky_colour.tga", // string (path to image) for dynamic. Image must be RGBA8888 or RGB888
|
||||||
@@ -367,14 +357,13 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
val lightbox = JSON.getString("daylightClut")
|
val lightbox = JSON.getString("daylightClut")
|
||||||
val extraImagesPath = JSON.get("extraImages").asStringArray()
|
val extraImagesPath = JSON.get("extraImages").asStringArray()
|
||||||
|
|
||||||
val skybox = GdxColorMap(ModMgr.getGdxFile("basegame", "$pathToImage/${skyboxInJson}"))
|
val skybox = GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${skyboxInJson}"))
|
||||||
|
val daylight = GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${lightbox}"))
|
||||||
val daylight = GdxColorMap(ModMgr.getGdxFile("basegame", "$pathToImage/${lightbox}"))
|
|
||||||
|
|
||||||
|
|
||||||
val extraImages = ArrayList<Texture>()
|
val extraImages = ArrayList<Texture>()
|
||||||
for (i in extraImagesPath)
|
for (i in extraImagesPath)
|
||||||
extraImages.add(Texture(ModMgr.getGdxFile("basegame", "$pathToImage/${i}")))
|
extraImages.add(Texture(ModMgr.getGdxFile(modname, "$pathToImage/${i}")))
|
||||||
|
|
||||||
|
|
||||||
val classification = JSON.getString("classification")
|
val classification = JSON.getString("classification")
|
||||||
|
|||||||
Reference in New Issue
Block a user