mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
more versatile weather CLUT defs
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"identifier": "clear01",
|
"identifier": "clear01",
|
||||||
"skyboxGradColourMap": "generic_skybox.tga",
|
"skyboxGradColourMap": "model:hosek",
|
||||||
"daylightClut": "clut_daylight.tga",
|
"daylightClut": "lut:clut_daylight.tga",
|
||||||
"tags": "generic,clear",
|
"tags": "generic,clear",
|
||||||
"cloudChance": 12,
|
"cloudChance": 12,
|
||||||
"cloudGamma": [1.2, 2.4],
|
"cloudGamma": [1.2, 2.4],
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"identifier": "generic01",
|
"identifier": "generic01",
|
||||||
"skyboxGradColourMap": "generic_skybox.tga",
|
"skyboxGradColourMap": "model:hosek",
|
||||||
"daylightClut": "clut_daylight.tga",
|
"daylightClut": "lut:clut_daylight.tga",
|
||||||
"tags": "generic",
|
"tags": "generic",
|
||||||
"cloudChance": 60,
|
"cloudChance": 60,
|
||||||
"cloudGamma": [0.9, 2.4],
|
"cloudGamma": [0.9, 2.4],
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"identifier": "generic02",
|
"identifier": "generic02",
|
||||||
"skyboxGradColourMap": "generic_skybox.tga",
|
"skyboxGradColourMap": "model:hosek",
|
||||||
"daylightClut": "clut_daylight.tga",
|
"daylightClut": "lut:clut_daylight.tga",
|
||||||
"tags": "generic2",
|
"tags": "generic2",
|
||||||
"cloudChance": 150,
|
"cloudChance": 150,
|
||||||
"cloudGamma": [0.9, 2.4],
|
"cloudGamma": [0.9, 2.4],
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"identifier": "overcast01",
|
"identifier": "overcast01",
|
||||||
"skyboxGradColourMap": "generic_skybox.tga",
|
"skyboxGradColourMap": "model:hosek",
|
||||||
"daylightClut": "clut_daylight.tga",
|
"daylightClut": "lut:clut_daylight.tga",
|
||||||
"tags": "overcast",
|
"tags": "overcast",
|
||||||
"cloudChance": 200,
|
"cloudChance": 200,
|
||||||
"cloudGamma": [1.45, 1.0],
|
"cloudGamma": [1.45, 1.0],
|
||||||
|
|||||||
15
assets/mods/basegame/weathers/weatherSpace.json
Normal file
15
assets/mods/basegame/weathers/weatherSpace.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"identifier": "space",
|
||||||
|
"skyboxGradColourMap": "static:#020202,#060604",
|
||||||
|
"daylightClut": "static:#FFFFFF",
|
||||||
|
"tags": "space",
|
||||||
|
"cloudChance": 0,
|
||||||
|
"cloudGamma": [1.0, 1.0],
|
||||||
|
"cloudGammaVariance": [0.0, 0.0],
|
||||||
|
"windSpeed": 0.0,
|
||||||
|
"windSpeedVariance": 0.0,
|
||||||
|
"windSpeedDamping": 0.0,
|
||||||
|
"clouds": {},
|
||||||
|
"atmoTurbidity": 1.0,
|
||||||
|
"shaderVibrancy": [1.0, 1.0]
|
||||||
|
}
|
||||||
@@ -13,14 +13,11 @@ import net.torvald.unicode.EMDASH
|
|||||||
import net.torvald.colourutil.*
|
import net.torvald.colourutil.*
|
||||||
import net.torvald.parametricsky.datasets.DatasetCIEXYZ
|
import net.torvald.parametricsky.datasets.DatasetCIEXYZ
|
||||||
import net.torvald.terrarum.abs
|
import net.torvald.terrarum.abs
|
||||||
import net.torvald.terrarum.clut.Skybox
|
|
||||||
import net.torvald.terrarum.clut.Skybox.coerceInSmoothly
|
|
||||||
import net.torvald.terrarum.clut.Skybox.mapCircle
|
|
||||||
import net.torvald.terrarum.inUse
|
import net.torvald.terrarum.inUse
|
||||||
import net.torvald.terrarum.modulebasegame.worldgenerator.HALF_PI
|
import net.torvald.terrarum.modulebasegame.worldgenerator.HALF_PI
|
||||||
|
import net.torvald.terrarum.weather.SkyboxModelHosek.coerceInSmoothly
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
import java.lang.Math.pow
|
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,15 @@ class GdxColorMap {
|
|||||||
is2D = (height > 1)
|
is2D = (height > 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(width: Int, height: Int, colours: List<Color>) {
|
||||||
|
dataRaw = colours.map { it.toIntBits() }.toIntArray()
|
||||||
|
dataGdxColor = dataRaw.map { Color(it) }.toTypedArray()
|
||||||
|
dataCvec = dataRaw.map { Cvec(it) }.toTypedArray()
|
||||||
|
this.width = width
|
||||||
|
this.height = height
|
||||||
|
is2D = (height > 1)
|
||||||
|
}
|
||||||
|
|
||||||
private val dataRaw: IntArray
|
private val dataRaw: IntArray
|
||||||
private val dataGdxColor: Array<Color>
|
private val dataGdxColor: Array<Color>
|
||||||
private val dataCvec: Array<Cvec>
|
private val dataCvec: Array<Cvec>
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ import net.torvald.colourutil.toRGB
|
|||||||
import net.torvald.gdx.graphics.Cvec
|
import net.torvald.gdx.graphics.Cvec
|
||||||
import net.torvald.parametricsky.ArHosekSkyModel
|
import net.torvald.parametricsky.ArHosekSkyModel
|
||||||
import net.torvald.terrarum.abs
|
import net.torvald.terrarum.abs
|
||||||
import net.torvald.terrarum.clut.Skybox.coerceInSmoothly
|
|
||||||
import net.torvald.terrarum.clut.Skybox.mapCircle
|
|
||||||
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 net.torvald.terrarum.serialise.toUint
|
import net.torvald.terrarum.serialise.toUint
|
||||||
|
import net.torvald.terrarum.weather.SkyboxModelHosek
|
||||||
|
import net.torvald.terrarum.weather.SkyboxModelHosek.coerceInSmoothly
|
||||||
|
import net.torvald.terrarum.weather.SkyboxModelHosek.mapCircle
|
||||||
|
import net.torvald.terrarum.weather.SkyboxModelHosek.scaleToFit
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
@@ -42,7 +43,7 @@ class GenerateSkyboxTextureAtlas {
|
|||||||
val state =
|
val state =
|
||||||
ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevationRad.abs())
|
ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevationRad.abs())
|
||||||
|
|
||||||
for (yp in 0 until Skybox.gradSize) {
|
for (yp in 0 until SkyboxModelHosek.gradSize) {
|
||||||
val yi = yp - 10
|
val yi = yp - 10
|
||||||
val xf = -elevationDeg / 90.0
|
val xf = -elevationDeg / 90.0
|
||||||
var yf = (yi / 58.0).coerceIn(0.0, 1.0).mapCircle().coerceInSmoothly(0.0, 0.95)
|
var yf = (yi / 58.0).coerceIn(0.0, 1.0).mapCircle().coerceInSmoothly(0.0, 0.95)
|
||||||
@@ -81,9 +82,9 @@ class GenerateSkyboxTextureAtlas {
|
|||||||
// y: increasing turbidity (1.0 .. 10.0, in steps of 0.333)
|
// y: increasing turbidity (1.0 .. 10.0, in steps of 0.333)
|
||||||
// x: elevations (-75 .. 75 in steps of 1, then albedo of [0.1, 0.3, 0.5, 0.7, 0.9])
|
// x: elevations (-75 .. 75 in steps of 1, then albedo of [0.1, 0.3, 0.5, 0.7, 0.9])
|
||||||
val TGA_HEADER_SIZE = 18
|
val TGA_HEADER_SIZE = 18
|
||||||
val texh = Skybox.gradSize * Skybox.turbCnt
|
val texh = SkyboxModelHosek.gradSize * SkyboxModelHosek.turbCnt
|
||||||
val texh2 = Skybox.turbCnt
|
val texh2 = SkyboxModelHosek.turbCnt
|
||||||
val texw = Skybox.elevCnt * Skybox.albedoCnt * 2
|
val texw = SkyboxModelHosek.elevCnt * SkyboxModelHosek.albedoCnt * 2
|
||||||
val bytesSize = texw * texh
|
val bytesSize = texw * texh
|
||||||
val bytes2Size = texw * texh2
|
val bytes2Size = texw * texh2
|
||||||
val bytes = ByteArray(TGA_HEADER_SIZE + bytesSize * 4 + 26)
|
val bytes = ByteArray(TGA_HEADER_SIZE + bytesSize * 4 + 26)
|
||||||
@@ -113,18 +114,18 @@ class GenerateSkyboxTextureAtlas {
|
|||||||
// write pixels
|
// write pixels
|
||||||
for (gammaPair in 0..1) {
|
for (gammaPair in 0..1) {
|
||||||
|
|
||||||
for (albedo0 in 0 until Skybox.albedoCnt) {
|
for (albedo0 in 0 until SkyboxModelHosek.albedoCnt) {
|
||||||
val albedo = Skybox.albedos[albedo0]
|
val albedo = SkyboxModelHosek.albedos[albedo0]
|
||||||
println("Albedo=$albedo")
|
println("Albedo=$albedo")
|
||||||
for (turb0 in 0 until Skybox.turbCnt) {
|
for (turb0 in 0 until SkyboxModelHosek.turbCnt) {
|
||||||
val turbidity = Skybox.turbiditiesD[turb0]
|
val turbidity = SkyboxModelHosek.turbiditiesD[turb0]
|
||||||
println("....... Turbidity=$turbidity")
|
println("....... Turbidity=$turbidity")
|
||||||
for (elev0 in 0 until Skybox.elevCnt) {
|
for (elev0 in 0 until SkyboxModelHosek.elevCnt) {
|
||||||
var elevationDeg = Skybox.elevationsD[elev0]
|
var elevationDeg = SkyboxModelHosek.elevationsD[elev0]
|
||||||
if (elevationDeg == 0.0) elevationDeg = 0.5 // dealing with the edge case
|
if (elevationDeg == 0.0) elevationDeg = 0.5 // dealing with the edge case
|
||||||
generateStrip(gammaPair, albedo, turbidity, elevationDeg) { yp, i, colour ->
|
generateStrip(gammaPair, albedo, turbidity, elevationDeg) { yp, i, colour ->
|
||||||
val imgOffX = albedo0 * Skybox.elevCnt + elev0 + Skybox.elevCnt * Skybox.albedoCnt * gammaPair
|
val imgOffX = albedo0 * SkyboxModelHosek.elevCnt + elev0 + SkyboxModelHosek.elevCnt * SkyboxModelHosek.albedoCnt * gammaPair
|
||||||
val imgOffY = texh - 1 - (Skybox.gradSize * turb0 + yp)
|
val imgOffY = texh - 1 - (SkyboxModelHosek.gradSize * turb0 + yp)
|
||||||
val fileOffset = TGA_HEADER_SIZE + 4 * (imgOffY * texw + imgOffX)
|
val fileOffset = TGA_HEADER_SIZE + 4 * (imgOffY * texw + imgOffX)
|
||||||
bytes[fileOffset + i] = colour
|
bytes[fileOffset + i] = colour
|
||||||
}
|
}
|
||||||
@@ -140,8 +141,8 @@ class GenerateSkyboxTextureAtlas {
|
|||||||
private val gradSizes = listOf(50)
|
private val gradSizes = listOf(50)
|
||||||
|
|
||||||
private fun getByte(gammaPair: Int, albedo0: Int, turb0: Int, elev0: Int, yp: Int, channel: Int): Byte {
|
private fun getByte(gammaPair: Int, albedo0: Int, turb0: Int, elev0: Int, yp: Int, channel: Int): Byte {
|
||||||
val imgOffX = albedo0 * Skybox.elevCnt + elev0 + Skybox.elevCnt * Skybox.albedoCnt * gammaPair
|
val imgOffX = albedo0 * SkyboxModelHosek.elevCnt + elev0 + SkyboxModelHosek.elevCnt * SkyboxModelHosek.albedoCnt * gammaPair
|
||||||
val imgOffY = texh - 1 - (Skybox.gradSize * turb0 + yp)
|
val imgOffY = texh - 1 - (SkyboxModelHosek.gradSize * turb0 + yp)
|
||||||
val fileOffset = TGA_HEADER_SIZE + 4 * (imgOffY * texw + imgOffX)
|
val fileOffset = TGA_HEADER_SIZE + 4 * (imgOffY * texw + imgOffX)
|
||||||
return bytes[fileOffset + channel]
|
return bytes[fileOffset + channel]
|
||||||
}
|
}
|
||||||
@@ -171,13 +172,13 @@ class GenerateSkyboxTextureAtlas {
|
|||||||
|
|
||||||
for (gammaPair in 0..1) {
|
for (gammaPair in 0..1) {
|
||||||
|
|
||||||
for (albedo0 in 0 until Skybox.albedoCnt) {
|
for (albedo0 in 0 until SkyboxModelHosek.albedoCnt) {
|
||||||
val albedo = Skybox.albedos[albedo0]
|
val albedo = SkyboxModelHosek.albedos[albedo0]
|
||||||
println("Albedo=$albedo")
|
println("Albedo=$albedo")
|
||||||
for (turb0 in 0 until Skybox.turbCnt) {
|
for (turb0 in 0 until SkyboxModelHosek.turbCnt) {
|
||||||
val turbidity = Skybox.turbiditiesD[turb0]
|
val turbidity = SkyboxModelHosek.turbiditiesD[turb0]
|
||||||
println("....... Turbidity=$turbidity")
|
println("....... Turbidity=$turbidity")
|
||||||
for (elev0 in 0 until Skybox.elevCnt) {
|
for (elev0 in 0 until SkyboxModelHosek.elevCnt) {
|
||||||
|
|
||||||
val avrB = (gradSizes.sumOf { getByte(gammaPair, albedo0, turb0, elev0, it, 0).toUint() }.toDouble() / gradSizes.size).div(255.0).toFloat()
|
val avrB = (gradSizes.sumOf { getByte(gammaPair, albedo0, turb0, elev0, it, 0).toUint() }.toDouble() / gradSizes.size).div(255.0).toFloat()
|
||||||
val avrG = (gradSizes.sumOf { getByte(gammaPair, albedo0, turb0, elev0, it, 1).toUint() }.toDouble() / gradSizes.size).div(255.0).toFloat()
|
val avrG = (gradSizes.sumOf { getByte(gammaPair, albedo0, turb0, elev0, it, 1).toUint() }.toDouble() / gradSizes.size).div(255.0).toFloat()
|
||||||
@@ -193,7 +194,7 @@ class GenerateSkyboxTextureAtlas {
|
|||||||
colour.a.times(255f).roundToInt().coerceIn(0..255).toByte()
|
colour.a.times(255f).roundToInt().coerceIn(0..255).toByte()
|
||||||
)
|
)
|
||||||
|
|
||||||
val imgOffX = albedo0 * Skybox.elevCnt + elev0 + Skybox.elevCnt * Skybox.albedoCnt * gammaPair
|
val imgOffX = albedo0 * SkyboxModelHosek.elevCnt + elev0 + SkyboxModelHosek.elevCnt * SkyboxModelHosek.albedoCnt * gammaPair
|
||||||
val imgOffY = texh2 - 1 - turb0
|
val imgOffY = texh2 - 1 - turb0
|
||||||
val fileOffset = TGA_HEADER_SIZE + 4 * (imgOffY * texw + imgOffX)
|
val fileOffset = TGA_HEADER_SIZE + 4 * (imgOffY * texw + imgOffX)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import net.torvald.terrarum.App.printdbgerr
|
|||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
||||||
import net.torvald.terrarum.clut.Skybox
|
|
||||||
import net.torvald.terrarum.console.CommandDict
|
import net.torvald.terrarum.console.CommandDict
|
||||||
import net.torvald.terrarum.gameactors.*
|
import net.torvald.terrarum.gameactors.*
|
||||||
import net.torvald.terrarum.gameactors.ai.ActorAI
|
import net.torvald.terrarum.gameactors.ai.ActorAI
|
||||||
@@ -35,8 +34,8 @@ import net.torvald.terrarum.realestate.LandUtil
|
|||||||
import net.torvald.terrarum.serialise.ReadSimpleWorld
|
import net.torvald.terrarum.serialise.ReadSimpleWorld
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
import net.torvald.terrarum.ui.UIItemTextButton
|
|
||||||
import net.torvald.terrarum.utils.OpenURL
|
import net.torvald.terrarum.utils.OpenURL
|
||||||
|
import net.torvald.terrarum.weather.SkyboxModelHosek
|
||||||
import net.torvald.terrarum.weather.WeatherMixer
|
import net.torvald.terrarum.weather.WeatherMixer
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
import net.torvald.util.CircularArray
|
import net.torvald.util.CircularArray
|
||||||
@@ -247,7 +246,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
uiContainer.add(uiRemoCon)
|
uiContainer.add(uiRemoCon)
|
||||||
|
|
||||||
CommandDict // invoke
|
CommandDict // invoke
|
||||||
Skybox.loadlut() // invoke
|
SkyboxModelHosek.loadlut() // invoke
|
||||||
// Skybox.initiate() // invoke the lengthy calculation
|
// Skybox.initiate() // invoke the lengthy calculation
|
||||||
// TODO add console here
|
// TODO add console here
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import kotlin.math.absoluteValue
|
|||||||
data class BaseModularWeather(
|
data class BaseModularWeather(
|
||||||
val identifier: String,
|
val identifier: String,
|
||||||
val json: JsonValue,
|
val json: JsonValue,
|
||||||
var skyboxGradColourMap: GdxColorMap, // row 0: skybox grad top, row 1: skybox grad bottom, row 2: sunlight (RGBA)
|
var skyboxGradColourMap: SkyboxModel, // row 0: skybox grad top, row 1: skybox grad bottom, row 2: sunlight (RGBA)
|
||||||
val daylightClut: GdxColorMap,
|
val daylightClut: GdxColorMap,
|
||||||
val tags: List<String>,
|
val tags: List<String>,
|
||||||
val cloudChance: Float,
|
val cloudChance: Float,
|
||||||
|
|||||||
12
src/net/torvald/terrarum/weather/SkyboxGradSimple.kt
Normal file
12
src/net/torvald/terrarum/weather/SkyboxGradSimple.kt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package net.torvald.terrarum.weather
|
||||||
|
|
||||||
|
import net.torvald.terrarum.GdxColorMap
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2025-03-22.
|
||||||
|
*/
|
||||||
|
class SkyboxGradSimple(val clut: GdxColorMap): SkyboxModel {
|
||||||
|
|
||||||
|
|
||||||
|
override fun dispose() {}
|
||||||
|
}
|
||||||
9
src/net/torvald/terrarum/weather/SkyboxModel.kt
Normal file
9
src/net/torvald/terrarum/weather/SkyboxModel.kt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package net.torvald.terrarum.weather
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2025-03-22.
|
||||||
|
*/
|
||||||
|
interface SkyboxModel : Disposable {
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.torvald.terrarum.clut
|
package net.torvald.terrarum.weather
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
@@ -14,14 +14,13 @@ import net.torvald.terrarum.App
|
|||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.abs
|
import net.torvald.terrarum.abs
|
||||||
import net.torvald.terrarum.floorToInt
|
import net.torvald.terrarum.floorToInt
|
||||||
import net.torvald.terrarum.toInt
|
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2023-07-09.
|
* Created by minjaesong on 2023-07-09.
|
||||||
*/
|
*/
|
||||||
object Skybox : Disposable {
|
object SkyboxModelHosek : SkyboxModel {
|
||||||
|
|
||||||
private const val HALF_PI = 1.5707963267948966
|
private const val HALF_PI = 1.5707963267948966
|
||||||
private const val PI = 3.141592653589793
|
private const val PI = 3.141592653589793
|
||||||
@@ -294,8 +293,8 @@ object Skybox : Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
if (Skybox::gradTexBinLowAlbedo.isInitialized) gradTexBinLowAlbedo.forEach { it.texture.dispose() }
|
if (SkyboxModelHosek::gradTexBinLowAlbedo.isInitialized) gradTexBinLowAlbedo.forEach { it.texture.dispose() }
|
||||||
if (Skybox::gradTexBinHighAlbedo.isInitialized) gradTexBinHighAlbedo.forEach { it.texture.dispose() }
|
if (SkyboxModelHosek::gradTexBinHighAlbedo.isInitialized) gradTexBinHighAlbedo.forEach { it.texture.dispose() }
|
||||||
if (Skybox::tex.isInitialized) tex.dispose()
|
if (SkyboxModelHosek::tex.isInitialized) tex.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.weather
|
package net.torvald.terrarum.weather
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.math.Vector2
|
import com.badlogic.gdx.math.Vector2
|
||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
@@ -39,6 +40,8 @@ class WeatherCodex : Disposable {
|
|||||||
|
|
||||||
fun readFromJson(modname: String, file: File) = readFromJson(modname, file.path)
|
fun readFromJson(modname: String, file: File) = readFromJson(modname, file.path)
|
||||||
|
|
||||||
|
private val pathToImage = "weathers"
|
||||||
|
|
||||||
fun readFromJson(modname: String, path: String) {
|
fun readFromJson(modname: String, path: String) {
|
||||||
/* JSON structure:
|
/* JSON structure:
|
||||||
{
|
{
|
||||||
@@ -52,12 +55,11 @@ class WeatherCodex : Disposable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
val pathToImage = "weathers"
|
|
||||||
|
|
||||||
val JSON = JsonFetcher(path)
|
val JSON = JsonFetcher(path)
|
||||||
|
|
||||||
val skyboxInJson = JSON.getString("skyboxGradColourMap")
|
val skyboxModel = JSON.getString("skyboxGradColourMap")
|
||||||
val lightbox = JSON.getString("daylightClut")
|
val lightboxModel = JSON.getString("daylightClut")
|
||||||
|
|
||||||
val cloudsMap = ArrayList<CloudProps>()
|
val cloudsMap = ArrayList<CloudProps>()
|
||||||
val clouds = JSON["clouds"]
|
val clouds = JSON["clouds"]
|
||||||
@@ -81,8 +83,8 @@ class WeatherCodex : Disposable {
|
|||||||
val obj = BaseModularWeather(
|
val obj = BaseModularWeather(
|
||||||
identifier = ident,
|
identifier = ident,
|
||||||
json = JSON,
|
json = JSON,
|
||||||
skyboxGradColourMap = GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${skyboxInJson}")),
|
skyboxGradColourMap = getSkyboxModelByName(modname, skyboxModel),
|
||||||
daylightClut = GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${lightbox}")),
|
daylightClut = getLightboxModelByName(modname, lightboxModel),
|
||||||
tags = tags,
|
tags = tags,
|
||||||
cloudChance = JSON.getFloat("cloudChance"),
|
cloudChance = JSON.getFloat("cloudChance"),
|
||||||
windSpeed = JSON.getFloat("windSpeed"),
|
windSpeed = JSON.getFloat("windSpeed"),
|
||||||
@@ -118,4 +120,71 @@ class WeatherCodex : Disposable {
|
|||||||
}
|
}
|
||||||
else getByTag(tag)!!.random()
|
else getByTag(tag)!!.random()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getSkyboxModelByName(modname: String, name: String): SkyboxModel {
|
||||||
|
return if (name.startsWith("model:")) {
|
||||||
|
when (name.substring(6)) {
|
||||||
|
"hosek" -> SkyboxModelHosek
|
||||||
|
else -> throw UnsupportedOperationException("Unknown skybox model: '$name'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (name.startsWith("lut:")) {
|
||||||
|
val filename = name.substring(4)
|
||||||
|
val colourMap = GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${filename}"))
|
||||||
|
SkyboxGradSimple(colourMap)
|
||||||
|
}
|
||||||
|
else if (name.startsWith("static:")) {
|
||||||
|
val argstr = name.substring(7)
|
||||||
|
val args = argstr.split(',').map {
|
||||||
|
if (it.length == 7) // #RRGGBB
|
||||||
|
Color(
|
||||||
|
it.substring(1, 3).toInt(16) / 255.0f,
|
||||||
|
it.substring(3, 5).toInt(16) / 255.0f,
|
||||||
|
it.substring(5, 7).toInt(16) / 255.0f,
|
||||||
|
1f,
|
||||||
|
)
|
||||||
|
else if (it.length == 9) // #RRGGBBAA
|
||||||
|
Color(
|
||||||
|
it.substring(1, 3).toInt(16) / 255.0f,
|
||||||
|
it.substring(3, 5).toInt(16) / 255.0f,
|
||||||
|
it.substring(5, 7).toInt(16) / 255.0f,
|
||||||
|
it.substring(7, 9).toInt(16) / 255.0f,
|
||||||
|
)
|
||||||
|
else if (it.length == 4) // #RGB
|
||||||
|
Color(
|
||||||
|
it.substring(1, 2).toInt(16) / 15.0f,
|
||||||
|
it.substring(2, 3).toInt(16) / 15.0f,
|
||||||
|
it.substring(3, 4).toInt(16) / 15.0f,
|
||||||
|
1f,
|
||||||
|
)
|
||||||
|
else if (it.length == 5) // #RGBA
|
||||||
|
Color(
|
||||||
|
it.substring(1, 2).toInt(16) / 15.0f,
|
||||||
|
it.substring(2, 3).toInt(16) / 15.0f,
|
||||||
|
it.substring(3, 4).toInt(16) / 15.0f,
|
||||||
|
it.substring(4, 5).toInt(16) / 15.0f,
|
||||||
|
)
|
||||||
|
else throw IllegalArgumentException("Unknown colour code: $it")
|
||||||
|
}
|
||||||
|
SkyboxGradSimple(GdxColorMap(args.size, 1, args))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw UnsupportedOperationException("Unknown skybox: '$name'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLightboxModelByName(modname: String, name: String): GdxColorMap {
|
||||||
|
return if (name.startsWith("lut:")) {
|
||||||
|
val filename = name.substring(4)
|
||||||
|
GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${filename}"))
|
||||||
|
}
|
||||||
|
else if (name.startsWith("static:")) {
|
||||||
|
val argstr = name.substring(7)
|
||||||
|
val args = argstr.split(',').map { Color.WHITE }
|
||||||
|
GdxColorMap(args.size, 1, args)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw UnsupportedOperationException("Unknown skybox: '$name'")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,17 +19,11 @@ 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.RNGConsumer
|
import net.torvald.terrarum.RNGConsumer
|
||||||
import net.torvald.terrarum.clut.Skybox
|
import net.torvald.terrarum.weather.SkyboxModelHosek.elevCnt
|
||||||
import net.torvald.terrarum.clut.Skybox.elevCnt
|
|
||||||
import net.torvald.terrarum.utils.JsonFetcher
|
|
||||||
import net.torvald.terrarum.utils.forEachSiblings
|
|
||||||
import net.torvald.terrarum.weather.WeatherObjectCloud.Companion.ALPHA_ROLLOFF_Z
|
import net.torvald.terrarum.weather.WeatherObjectCloud.Companion.ALPHA_ROLLOFF_Z
|
||||||
import net.torvald.terrarum.weather.WeatherObjectCloud.Companion.NEWBORN_GROWTH_TIME
|
import net.torvald.terrarum.weather.WeatherObjectCloud.Companion.NEWBORN_GROWTH_TIME
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
|
||||||
import net.torvald.util.SortedArrayList
|
import net.torvald.util.SortedArrayList
|
||||||
import java.io.File
|
|
||||||
import java.io.FileFilter
|
|
||||||
import java.lang.Double.doubleToLongBits
|
import java.lang.Double.doubleToLongBits
|
||||||
import java.lang.Math.toDegrees
|
import java.lang.Math.toDegrees
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
@@ -57,7 +51,7 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
val DEFAULT_WEATHER = BaseModularWeather(
|
val DEFAULT_WEATHER = BaseModularWeather(
|
||||||
"default",
|
"default",
|
||||||
JsonValue(JsonValue.ValueType.`object`),
|
JsonValue(JsonValue.ValueType.`object`),
|
||||||
GdxColorMap(1, 3, Color(0x55aaffff), Color(0xaaffffff.toInt()), Color.WHITE),
|
SkyboxGradSimple(GdxColorMap(1, 2, Color(0x55aaffff), Color(0xaaffffff.toInt()))),
|
||||||
GdxColorMap(2, 2, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE),
|
GdxColorMap(2, 2, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE),
|
||||||
listOf("default"),
|
listOf("default"),
|
||||||
0f,
|
0f,
|
||||||
@@ -556,7 +550,7 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
fun g(x: Double) = Math.toDegrees(atan(RECIPROCAL_OF_APPARENT_SOLAR_Y_AT_45DEG * x))
|
fun g(x: Double) = Math.toDegrees(atan(RECIPROCAL_OF_APPARENT_SOLAR_Y_AT_45DEG * x))
|
||||||
val phi = currentsolarDeg + CLOUD_SOLARDEG_OFFSET
|
val phi = currentsolarDeg + CLOUD_SOLARDEG_OFFSET
|
||||||
val x = cloudY
|
val x = cloudY
|
||||||
return g(x + a(phi)).bipolarClamp(Skybox.elevMax)
|
return g(x + a(phi)).bipolarClamp(SkyboxModelHosek.elevMax)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -661,7 +655,7 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
|
|
||||||
val gradY = -(gH - App.scr.height) * ((parallax + 1f) / 2f)
|
val gradY = -(gH - App.scr.height) * ((parallax + 1f) / 2f)
|
||||||
|
|
||||||
val (tex, uvs, turbTihsBlend, albThisBlend, turbOldBlend, albOldBlend) = Skybox.getUV(
|
val (tex, uvs, turbTihsBlend, albThisBlend, turbOldBlend, albOldBlend) = SkyboxModelHosek.getUV(
|
||||||
solarElev,
|
solarElev,
|
||||||
oldTurbidity,
|
oldTurbidity,
|
||||||
oldAlbedo,
|
oldAlbedo,
|
||||||
@@ -819,14 +813,14 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
val angleX2 = (angleX1 + 1).coerceAtMost(150)
|
val angleX2 = (angleX1 + 1).coerceAtMost(150)
|
||||||
val ax = solarAngleInDeg - solarAngleInDegInt
|
val ax = solarAngleInDeg - solarAngleInDegInt
|
||||||
// fine-grained
|
// fine-grained
|
||||||
val turbY = turbidity.coerceIn(Skybox.turbiditiesD.first(), Skybox.turbiditiesD.last()).minus(1.0)
|
val turbY = turbidity.coerceIn(SkyboxModelHosek.turbiditiesD.first(), SkyboxModelHosek.turbiditiesD.last()).minus(1.0)
|
||||||
.times(Skybox.turbDivisor)
|
.times(SkyboxModelHosek.turbDivisor)
|
||||||
val turbY1 = turbY.floorToInt()
|
val turbY1 = turbY.floorToInt()
|
||||||
val turbY2 = (turbY1 + 1).coerceAtMost(Skybox.turbCnt - 1)
|
val turbY2 = (turbY1 + 1).coerceAtMost(SkyboxModelHosek.turbCnt - 1)
|
||||||
val tx = turbY - turbY1
|
val tx = turbY - turbY1
|
||||||
// coarse-grained
|
// coarse-grained
|
||||||
val albX =
|
val albX =
|
||||||
albedo.coerceIn(Skybox.albedos.first(), Skybox.albedos.last()).times(5.0) // 0..5
|
albedo.coerceIn(SkyboxModelHosek.albedos.first(), SkyboxModelHosek.albedos.last()).times(5.0) // 0..5
|
||||||
val albX1 = albX.floorToInt() * elevCnt
|
val albX1 = albX.floorToInt() * elevCnt
|
||||||
val albX2 = (albX + 1).floorToInt().coerceAtMost(5) * elevCnt
|
val albX2 = (albX + 1).floorToInt().coerceAtMost(5) * elevCnt
|
||||||
val bx = ((albX * elevCnt) - albX1) / elevCnt
|
val bx = ((albX * elevCnt) - albX1) / elevCnt
|
||||||
@@ -844,14 +838,14 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
val a2t1b2A = colorMap.getCvec(albX2 + angleX2, turbY1)
|
val a2t1b2A = colorMap.getCvec(albX2 + angleX2, turbY1)
|
||||||
val a1t2b2A = colorMap.getCvec(albX2 + angleX1, turbY2)
|
val a1t2b2A = colorMap.getCvec(albX2 + angleX1, turbY2)
|
||||||
val a2t2b2A = colorMap.getCvec(albX2 + angleX2, turbY2)
|
val a2t2b2A = colorMap.getCvec(albX2 + angleX2, turbY2)
|
||||||
val a1t1b1B = colorMap.getCvec(albX1 + angleX1 + Skybox.albedoCnt * elevCnt, turbY1)
|
val a1t1b1B = colorMap.getCvec(albX1 + angleX1 + SkyboxModelHosek.albedoCnt * elevCnt, turbY1)
|
||||||
val a2t1b1B = colorMap.getCvec(albX1 + angleX2 + Skybox.albedoCnt * elevCnt, turbY1)
|
val a2t1b1B = colorMap.getCvec(albX1 + angleX2 + SkyboxModelHosek.albedoCnt * elevCnt, turbY1)
|
||||||
val a1t2b1B = colorMap.getCvec(albX1 + angleX1 + Skybox.albedoCnt * elevCnt, turbY2)
|
val a1t2b1B = colorMap.getCvec(albX1 + angleX1 + SkyboxModelHosek.albedoCnt * elevCnt, turbY2)
|
||||||
val a2t2b1B = colorMap.getCvec(albX1 + angleX2 + Skybox.albedoCnt * elevCnt, turbY2)
|
val a2t2b1B = colorMap.getCvec(albX1 + angleX2 + SkyboxModelHosek.albedoCnt * elevCnt, turbY2)
|
||||||
val a1t1b2B = colorMap.getCvec(albX2 + angleX1 + Skybox.albedoCnt * elevCnt, turbY1)
|
val a1t1b2B = colorMap.getCvec(albX2 + angleX1 + SkyboxModelHosek.albedoCnt * elevCnt, turbY1)
|
||||||
val a2t1b2B = colorMap.getCvec(albX2 + angleX2 + Skybox.albedoCnt * elevCnt, turbY1)
|
val a2t1b2B = colorMap.getCvec(albX2 + angleX2 + SkyboxModelHosek.albedoCnt * elevCnt, turbY1)
|
||||||
val a1t2b2B = colorMap.getCvec(albX2 + angleX1 + Skybox.albedoCnt * elevCnt, turbY2)
|
val a1t2b2B = colorMap.getCvec(albX2 + angleX1 + SkyboxModelHosek.albedoCnt * elevCnt, turbY2)
|
||||||
val a2t2b2B = colorMap.getCvec(albX2 + angleX2 + Skybox.albedoCnt * elevCnt, turbY2)
|
val a2t2b2B = colorMap.getCvec(albX2 + angleX2 + SkyboxModelHosek.albedoCnt * elevCnt, turbY2)
|
||||||
|
|
||||||
// no srgblerp here to match the skybox shader's behaviour
|
// no srgblerp here to match the skybox shader's behaviour
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user