scrolling weatherbox; new skybox clut

This commit is contained in:
minjaesong
2023-08-31 22:32:55 +09:00
parent 5eed921288
commit c75fa73bac
8 changed files with 92 additions and 45 deletions

Binary file not shown.

View File

@@ -18,5 +18,6 @@
"baseScale": 1.0, "scaleVariance": 0.6, "baseScale": 1.0, "scaleVariance": 0.6,
"altLow": 80, "altHigh": 800 "altLow": 80, "altHigh": 800
} }
} },
"atmoTurbidity": 3.5
} }

View File

@@ -24,5 +24,6 @@
"altLow": 1600, "altHigh": 2400 "altLow": 1600, "altHigh": 2400
} }
}, },
"atmoTurbidity": 3.5,
"__comment__": "Make a texture for altocumulus so that this weather can be realised with less than 1000 sprites" "__comment__": "Make a texture for altocumulus so that this weather can be realised with less than 1000 sprites"
} }

View File

@@ -6,7 +6,7 @@
"cloudGamma": [2.2, 2.0], "cloudGamma": [2.2, 2.0],
"cloudGammaVariance": [0.1, 0.1], "cloudGammaVariance": [0.1, 0.1],
"windSpeed": 10.45, "windSpeed": 10.45,
"windSpeedVariance": 1.0, "windSpeedVariance": 0.5,
"clouds": { "clouds": {
"cumulus": { "cumulus": {
"filename": "cloud_normal.png", "tw": 1024, "th": 512, "probability": 0.1, "filename": "cloud_normal.png", "tw": 1024, "th": 512, "probability": 0.1,
@@ -23,5 +23,6 @@
"baseScale": 4.0, "scaleVariance": 0.1, "baseScale": 4.0, "scaleVariance": 0.1,
"altLow": 100, "altHigh": 100 "altLow": 100, "altHigh": 100
} }
} },
"atmoTurbidity": 9.5
} }

View File

@@ -152,7 +152,7 @@ object Skybox : Disposable {
val elevations = (0..150) val elevations = (0..150)
val elevMax = elevations.last / 2.0 val elevMax = elevations.last / 2.0
val elevationsD = elevations.map { -elevMax + it } // -75, -74, -73, ..., 74, 75 // (specifically using whole number of angles because angle units any finer than 1.0 would make "hack" sunsut happen too fast) val elevationsD = elevations.map { -elevMax + it } // -75, -74, -73, ..., 74, 75 // (specifically using whole number of angles because angle units any finer than 1.0 would make "hack" sunsut happen too fast)
val turbidities = (0..25) // 1, 1.2, 1.4, 1.6, ..., 6.0 val turbidities = (0..45) // 1, 1.2, 1.4, 1.6, ..., 10.0
val turbDivisor = 5.0 val turbDivisor = 5.0
val turbiditiesD = turbidities.map { 1.0 + it / turbDivisor } val turbiditiesD = turbidities.map { 1.0 + it / turbDivisor }
val albedos = arrayOf(0.0, 0.2, 0.4, 0.6, 0.8, 1.0) val albedos = arrayOf(0.0, 0.2, 0.4, 0.6, 0.8, 1.0)

View File

@@ -3,7 +3,6 @@ package net.torvald.terrarum.ui
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input import com.badlogic.gdx.Input
import com.badlogic.gdx.Input.Keys import com.badlogic.gdx.Input.Keys
import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.Texture
@@ -353,13 +352,16 @@ class BasicDebugInfoWindow : UICanvas() {
private val colGraphFore = Color(1f, 1f, 1f, 0.5f) private val colGraphFore = Color(1f, 1f, 1f, 0.5f)
private val colGraphForf = Color(1f, 1f, 1f, 0.25f) private val colGraphForf = Color(1f, 1f, 1f, 0.25f)
private val colGraphForg = Color(1f, 1f, 1f, 0.125f) private val colGraphForg = Color(1f, 1f, 1f, 0.125f)
private val MIN_RULE_GAP = 5.0
private val GRAPH_CW = 50
private val GRAPH_CH = 100
private fun drawWeatherStateBox(batch: SpriteBatch, box: WeatherStateBox, label: String, x: Int, y: Int, ymax: Double = 1.0) { private fun drawWeatherStateBox(batch: SpriteBatch, box: WeatherStateBox, label: String, x: Int, y: Int, ymax: Double = 1.0) {
val bw = 50*3 + 1 val bw = GRAPH_CW * 3 + 1
val bh = 100 val bh = GRAPH_CH
val xstart = (bw/3)*1 val xw = GRAPH_CW
val xw = (bw/3) val xi = (box.x * xw).roundToInt()
val MIN_RULE_GAP = 5.0
// back // back
batch.color = colGraphBack batch.color = colGraphBack
@@ -368,8 +370,10 @@ class BasicDebugInfoWindow : UICanvas() {
batch.color = colGraphFore batch.color = colGraphFore
Toolkit.drawBoxBorder(batch, x + 1, y + 1, bw - 1, bh - 1) Toolkit.drawBoxBorder(batch, x + 1, y + 1, bw - 1, bh - 1)
// x grids // x grids
Toolkit.drawStraightLine(batch, x + (bw/3)*1, y, y+bh, 1, true) if (box.x < 0.5) Toolkit.drawStraightLine(batch, x + (GRAPH_CW * 0.5).toInt() - xi, y, y+bh, 1, true)
Toolkit.drawStraightLine(batch, x + (bw/3)*2, y, y+bh, 1, true) Toolkit.drawStraightLine(batch, x + (GRAPH_CW * 1.5).toInt() - xi, y, y+bh, 1, true)
Toolkit.drawStraightLine(batch, x + (GRAPH_CW * 2.5).toInt() - xi, y, y+bh, 1, true)
if (box.x > 0.5) Toolkit.drawStraightLine(batch, x + (GRAPH_CW * 3.5).toInt() - xi, y, y+bh, 1, true)
// y grids // y grids
val yrange = val yrange =
//// ymax small and bh tall enought to fit the 0.25 rules? //// ymax small and bh tall enought to fit the 0.25 rules?
@@ -402,39 +406,60 @@ class BasicDebugInfoWindow : UICanvas() {
} }
Toolkit.drawStraightLine(batch, x, y + yc, x + bw, 1, false) Toolkit.drawStraightLine(batch, x, y + yc, x + bw, 1, false)
} }
// graph points
batch.color = colGraph
Toolkit.fillArea(batch, x + - 1, y + bh-(box.p0 * bh / ymax).roundToInt(), 3, 3)
Toolkit.fillArea(batch, x + (bw/3)*1 - 1, y + bh-(box.p1 * bh / ymax).roundToInt(), 3, 3)
Toolkit.fillArea(batch, x + (bw/3)*2 - 1, y + bh-(box.p2 * bh / ymax).roundToInt(), 3, 3)
Toolkit.fillArea(batch, x + bw - 1, y + bh-(box.p3 * bh / ymax).roundToInt(), 3, 3)
batch.end() batch.end()
// interpolated values
val pys = (0 until xw).map {
val px = it.toFloat() / xw
bh - (bh * WeatherStateBox.interpolateCatmullRom(px, box.p0, box.p1, box.p2, box.p3) / ymax).toFloat()
}
// here draws actual data
App.shapeRender.inUse { App.shapeRender.inUse {
val pysM1 = (0 until xw).map {
val px = it.toFloat() / xw
bh - (bh * WeatherStateBox.interpolate(px, box.pM2, box.pM1, box.p0, box.p1) / ymax).toFloat()
}
val pys0 = (0 until xw).map {
val px = it.toFloat() / xw
bh - (bh * WeatherStateBox.interpolate(px, box.pM1, box.p0, box.p1, box.p2) / ymax).toFloat()
}
val pys1 = (0 until xw).map {
val px = it.toFloat() / xw
bh - (bh * WeatherStateBox.interpolate(px, box.p0, box.p1, box.p2, box.p3) / ymax).toFloat()
}
val pys2 = (0 until xw).map {
val px = it.toFloat() / xw
bh - (bh * WeatherStateBox.interpolate(px, box.p1, box.p2, box.p3, box.p4) / ymax).toFloat()
}
val pys3 = (0 until xw).map {
val px = it.toFloat() / xw
bh - (bh * WeatherStateBox.interpolate(px, box.p2, box.p3, box.p4, box.p5) / ymax).toFloat()
}
val pys = pysM1 + pys0 + pys1 + pys2 + pys3 + box.p4
// interpolated values
it.color = colGraph it.color = colGraph
for (index in 0 until pys.lastIndex) { val xis = xi + (xw / 2)
val px = x + xstart + index.toFloat() for (index in xis until xis + bw - 1) {
val px = x - xis + index + 1f
it.rectLine( it.rectLine(
px, px,
App.scr.hf - 1 - (y + pys[index]), App.scr.hf - 1 - (y + pys[index]),
px + 1f, px + 1f,
App.scr.hf - 1 - (y + pys[index + 1]), App.scr.hf - 1 - (y + pys[index + 1]),
1.5f 1f
) )
} }
// graph points
it.color = colGraph
if (box.x < 0.5) it.circle(x + (GRAPH_CW * 0.5f) - xi, App.scr.hf - 1 - (y + bh-(box.p0 * bh / ymax).toFloat()), 2.5f)
it.circle(x + (GRAPH_CW * 1.5f) - xi, App.scr.hf - 1 - (y + bh-(box.p1 * bh / ymax).toFloat()), 2.5f)
it.circle(x + (GRAPH_CW * 2.5f) - xi, App.scr.hf - 1 - (y + bh-(box.p2 * bh / ymax).toFloat()), 2.5f)
if (box.x > 0.5) it.circle(x + (GRAPH_CW * 3.5f) - xi, App.scr.hf - 1 - (y + bh-(box.p3 * bh / ymax).toFloat()), 2.5f)
} }
// hairline // hairline
batch.begin() batch.begin()
batch.color = colHairline batch.color = colHairline
Toolkit.drawStraightLine(batch, x + xstart + (box.x * xw).roundToInt(), y, y+bh, 1, true) Toolkit.drawStraightLine(batch, x + bw / 2, y, y+bh, 1, true)
// text // text
batch.color = Color.WHITE batch.color = Color.WHITE

View File

@@ -133,17 +133,21 @@ internal object WeatherMixer : RNGConsumer {
weatherbox = Weatherbox() weatherbox = Weatherbox()
// TEST FILL WITH RANDOM VALUES // TEST FILL WITH RANDOM VALUES
(0..3).map { takeUniformRand(0f..1f) }.let { (0..5).map { takeUniformRand(0f..1f) }.let {
weatherbox.windDir.p0 = it[0] weatherbox.windDir.pM1 = it[0]
weatherbox.windDir.p1 = it[1] weatherbox.windDir.p0 = it[1]
weatherbox.windDir.p2 = it[2] weatherbox.windDir.p1 = it[2]
weatherbox.windDir.p3 = it[3] weatherbox.windDir.p2 = it[3]
weatherbox.windDir.p3 = it[4]
weatherbox.windDir.p4 = it[5]
} }
(0..3).map { takeUniformRand(-1f..1f) }.let { (0..5).map { takeUniformRand(-1f..1f) }.let {
weatherbox.windSpeed.p0 = currentWeather.getRandomWindSpeed(it[0]) weatherbox.windSpeed.pM1 = currentWeather.getRandomWindSpeed(it[0])
weatherbox.windSpeed.p1 = currentWeather.getRandomWindSpeed(it[1]) weatherbox.windSpeed.p0 = currentWeather.getRandomWindSpeed(it[1])
weatherbox.windSpeed.p2 = currentWeather.getRandomWindSpeed(it[2]) weatherbox.windSpeed.p1 = currentWeather.getRandomWindSpeed(it[2])
weatherbox.windSpeed.p3 = currentWeather.getRandomWindSpeed(it[3]) weatherbox.windSpeed.p2 = currentWeather.getRandomWindSpeed(it[3])
weatherbox.windSpeed.p3 = currentWeather.getRandomWindSpeed(it[4])
weatherbox.windSpeed.p4 = currentWeather.getRandomWindSpeed(it[5])
} }
} }
@@ -579,7 +583,7 @@ internal object WeatherMixer : RNGConsumer {
gdxBlendNormalStraightAlpha() gdxBlendNormalStraightAlpha()
turbidity = (3.5 + turbidityCoeff * 2.5).coerceIn(1.0, 6.0) turbidity = (currentWeather.json.getDouble("atmoTurbidity") + turbidityCoeff * 2.5).coerceIn(1.0, 10.0)
val thisTurbidity = forceTurbidity ?: turbidity val thisTurbidity = forceTurbidity ?: turbidity
val gradY = -(gH - App.scr.height) * ((parallax + 1f) / 2f) val gradY = -(gH - App.scr.height) * ((parallax + 1f) / 2f)

View File

@@ -9,9 +9,20 @@ class Weatherbox {
} }
data class WeatherStateBox(var x: Float = 0f, var p0: Float = 0f, var p1: Float = 0f, var p2: Float = 0f, var p3: Float = 0f) { data class WeatherStateBox(
var x: Float = 0f,
var pM2: Float = 0f,
var pM1: Float = 0f,
var p0: Float = 0f,
var p1: Float = 0f,
var p2: Float = 0f,
var p3: Float = 0f,
var p4: Float = 0f,
var p5: Float = 0f,
// pM1 and p4 only exists for the sake of better weather forecasting
) {
fun get() = interpolateCatmullRom(x, p0, p1, p2, p3) fun get() = interpolate(x, p0, p1, p2, p3)
fun getAndUpdate(xdelta: Float, next: () -> Float): Float { fun getAndUpdate(xdelta: Float, next: () -> Float): Float {
synchronized(WeatherMixer.RNG) { synchronized(WeatherMixer.RNG) {
@@ -19,10 +30,14 @@ data class WeatherStateBox(var x: Float = 0f, var p0: Float = 0f, var p1: Float
x += xdelta x += xdelta
while (x >= 1.0) { while (x >= 1.0) {
x -= 1.0f x -= 1.0f
pM2 = pM1
pM1 = p0
p0 = p1 p0 = p1
p1 = p2 p1 = p2
p2 = p3 p2 = p3
p3 = next() p3 = p4
p4 = p5
p5 = next()
} }
return y return y
} }
@@ -30,7 +45,7 @@ data class WeatherStateBox(var x: Float = 0f, var p0: Float = 0f, var p1: Float
companion object { companion object {
// fixed with T=0.5 // fixed with T=0.5
fun interpolateCatmullRom(u: Float, p0: Float, p1: Float, p2: Float, p3: Float): Float { fun interpolate(u: Float, p0: Float, p1: Float, p2: Float, p3: Float): Float {
val c1: Float = p1 val c1: Float = p1
val c2: Float = -0.5f * p0 + 0.5f * p2 val c2: Float = -0.5f * p0 + 0.5f * p2
val c3: Float = p0 - 2.5f * p1 + 2.0f * p2 - 0.5f * p3 val c3: Float = p0 - 2.5f * p1 + 2.0f * p2 - 0.5f * p3