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,
"altLow": 80, "altHigh": 800
}
}
},
"atmoTurbidity": 3.5
}

View File

@@ -24,5 +24,6 @@
"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"
}

View File

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

View File

@@ -152,7 +152,7 @@ object Skybox : Disposable {
val elevations = (0..150)
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 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 turbiditiesD = turbidities.map { 1.0 + it / turbDivisor }
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.Input
import com.badlogic.gdx.Input.Keys
import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.graphics.Texture
@@ -353,13 +352,16 @@ class BasicDebugInfoWindow : UICanvas() {
private val colGraphFore = Color(1f, 1f, 1f, 0.5f)
private val colGraphForf = Color(1f, 1f, 1f, 0.25f)
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) {
val bw = 50*3 + 1
val bh = 100
val xstart = (bw/3)*1
val xw = (bw/3)
val MIN_RULE_GAP = 5.0
val bw = GRAPH_CW * 3 + 1
val bh = GRAPH_CH
val xw = GRAPH_CW
val xi = (box.x * xw).roundToInt()
// back
batch.color = colGraphBack
@@ -368,8 +370,10 @@ class BasicDebugInfoWindow : UICanvas() {
batch.color = colGraphFore
Toolkit.drawBoxBorder(batch, x + 1, y + 1, bw - 1, bh - 1)
// x grids
Toolkit.drawStraightLine(batch, x + (bw/3)*1, y, y+bh, 1, true)
Toolkit.drawStraightLine(batch, x + (bw/3)*2, 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 + (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
val yrange =
//// 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)
}
// 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()
// 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 {
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
for (index in 0 until pys.lastIndex) {
val px = x + xstart + index.toFloat()
val xis = xi + (xw / 2)
for (index in xis until xis + bw - 1) {
val px = x - xis + index + 1f
it.rectLine(
px,
App.scr.hf - 1 - (y + pys[index]),
px + 1f,
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
batch.begin()
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
batch.color = Color.WHITE

View File

@@ -133,17 +133,21 @@ internal object WeatherMixer : RNGConsumer {
weatherbox = Weatherbox()
// TEST FILL WITH RANDOM VALUES
(0..3).map { takeUniformRand(0f..1f) }.let {
weatherbox.windDir.p0 = it[0]
weatherbox.windDir.p1 = it[1]
weatherbox.windDir.p2 = it[2]
weatherbox.windDir.p3 = it[3]
(0..5).map { takeUniformRand(0f..1f) }.let {
weatherbox.windDir.pM1 = it[0]
weatherbox.windDir.p0 = it[1]
weatherbox.windDir.p1 = it[2]
weatherbox.windDir.p2 = it[3]
weatherbox.windDir.p3 = it[4]
weatherbox.windDir.p4 = it[5]
}
(0..3).map { takeUniformRand(-1f..1f) }.let {
weatherbox.windSpeed.p0 = currentWeather.getRandomWindSpeed(it[0])
weatherbox.windSpeed.p1 = currentWeather.getRandomWindSpeed(it[1])
weatherbox.windSpeed.p2 = currentWeather.getRandomWindSpeed(it[2])
weatherbox.windSpeed.p3 = currentWeather.getRandomWindSpeed(it[3])
(0..5).map { takeUniformRand(-1f..1f) }.let {
weatherbox.windSpeed.pM1 = currentWeather.getRandomWindSpeed(it[0])
weatherbox.windSpeed.p0 = currentWeather.getRandomWindSpeed(it[1])
weatherbox.windSpeed.p1 = currentWeather.getRandomWindSpeed(it[2])
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()
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 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 {
synchronized(WeatherMixer.RNG) {
@@ -19,10 +30,14 @@ data class WeatherStateBox(var x: Float = 0f, var p0: Float = 0f, var p1: Float
x += xdelta
while (x >= 1.0) {
x -= 1.0f
pM2 = pM1
pM1 = p0
p0 = p1
p1 = p2
p2 = p3
p3 = next()
p3 = p4
p4 = p5
p5 = next()
}
return y
}
@@ -30,7 +45,7 @@ data class WeatherStateBox(var x: Float = 0f, var p0: Float = 0f, var p1: Float
companion object {
// 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 c2: Float = -0.5f * p0 + 0.5f * p2
val c3: Float = p0 - 2.5f * p1 + 2.0f * p2 - 0.5f * p3