mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 03:24:06 +09:00
Noise generator test for procedural lighting bolt
Former-commit-id: 20e12a834857c58464ff82025884f2fe54066bc8 Former-commit-id: 851efee817914c6b65d01c084f6f41feb2034a58
This commit is contained in:
@@ -4,5 +4,6 @@ package net.torvald.random
|
|||||||
* Created by minjaesong on 16-10-28.
|
* Created by minjaesong on 16-10-28.
|
||||||
*/
|
*/
|
||||||
interface NoiseGenerator1D {
|
interface NoiseGenerator1D {
|
||||||
fun get(x: Double): Double
|
fun generate(seed: Long)
|
||||||
|
operator fun get(x: Int): Float
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,81 @@
|
|||||||
package net.torvald.random
|
package net.torvald.random
|
||||||
|
|
||||||
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.terrarum.gameactors.floorInt
|
||||||
|
import net.torvald.terrarum.gameactors.round
|
||||||
|
import net.torvald.terrarum.gameactors.roundInt
|
||||||
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate value noise that is always "tileably looped" every x in loopSize.
|
* Generate value noise that is always "tileably looped" every x in loopSize.
|
||||||
*
|
*
|
||||||
|
* @param width: power of 2's are recommended.
|
||||||
* Created by minjaesong on 16-10-28.
|
* Created by minjaesong on 16-10-28.
|
||||||
*/
|
*/
|
||||||
class TileableValueNoise(
|
class TileableValueNoise(
|
||||||
val octaves: Int, val persistency: Double,
|
val octaves: Int, val persistency: Float, val width: Int) {
|
||||||
val loopSize: Double = 1.0, val seed: Long? = null
|
|
||||||
) : NoiseGenerator1D {
|
|
||||||
|
|
||||||
val rng = if (seed != null) HQRNG(seed) else HQRNG()
|
private val noiseData = Array<Float>(width + 1, { 0f })
|
||||||
|
private var noiseGenerated = false
|
||||||
|
|
||||||
override fun get(x: Double): Double {
|
fun generate(seed: Long) {
|
||||||
TODO()
|
val rng = HQRNG(seed)
|
||||||
|
|
||||||
|
// initialise
|
||||||
|
Arrays.fill(noiseData, 0f)
|
||||||
|
|
||||||
|
|
||||||
|
for (i in 1..octaves) {
|
||||||
|
// octave 1 samples four points
|
||||||
|
val samples = 4 * i
|
||||||
|
val amp = FastMath.pow(persistency, (i - 1).toFloat())
|
||||||
|
|
||||||
|
var pointThis = 0f
|
||||||
|
var pointNext = rng.nextBipolarFloat()
|
||||||
|
var pointLoop = pointThis
|
||||||
|
|
||||||
|
|
||||||
|
for (x in 0..width) {
|
||||||
|
val thisSampleStart: Int = // 0-256 -> 0-4 -> 0-256(qnt)
|
||||||
|
(x / width.toFloat() * samples).floorInt() * (width / samples)
|
||||||
|
val nextSampleStart: Int =
|
||||||
|
(x / width.toFloat() * samples).floorInt().plus(1) * (width / samples)
|
||||||
|
val stepWithinWindow: Int = x % (width / samples)
|
||||||
|
val windowScale: Float = stepWithinWindow.toFloat() / (width / samples)
|
||||||
|
|
||||||
|
// next pair of points
|
||||||
|
if (stepWithinWindow == 0 && x > 0) {
|
||||||
|
pointThis = pointNext
|
||||||
|
pointNext = if (nextSampleStart >= width) pointLoop else rng.nextBipolarFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// additive mix
|
||||||
|
val noiseValue = FastMath.interpolateLinear(windowScale, pointThis, pointNext) * amp
|
||||||
|
noiseData[x] += noiseValue
|
||||||
|
|
||||||
|
|
||||||
|
/*println("x: $x\tstart: $thisSampleStart\tnext: $nextSampleStart\t" +
|
||||||
|
"window: $stepWithinWindow\t" +
|
||||||
|
"pThis: $pointThis\tpNext: $pointNext\tvalue: $noiseValue")*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x in 0..width - 1) {
|
||||||
|
//println(noiseData[x])
|
||||||
|
}
|
||||||
|
|
||||||
|
noiseGenerated = true
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun get(x: Int): Float {
|
||||||
|
if (!noiseGenerated) throw Error("Noise not generated; use 'generate(seed: Long)'")
|
||||||
|
return noiseData[x fmod width]
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Random.nextBipolarFloat(): Float {
|
||||||
|
val d = this.nextFloat()
|
||||||
|
return d.times(2f).minus(1f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ package net.torvald.terrarum
|
|||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.point.Point2d
|
import net.torvald.point.Point2d
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
|
import net.torvald.random.TileableValueNoise
|
||||||
import net.torvald.terrarum.gameactors.floorInt
|
import net.torvald.terrarum.gameactors.floorInt
|
||||||
import net.torvald.terrarum.gameactors.roundInt
|
import net.torvald.terrarum.gameactors.roundInt
|
||||||
import net.torvald.terrarum.virtualcomputer.terminal.ALException
|
import net.torvald.terrarum.virtualcomputer.terminal.ALException
|
||||||
@@ -28,29 +29,57 @@ import javax.sound.sampled.AudioSystem
|
|||||||
*/
|
*/
|
||||||
class StateTestingSandbox : BasicGameState() {
|
class StateTestingSandbox : BasicGameState() {
|
||||||
|
|
||||||
|
|
||||||
override fun init(container: GameContainer?, game: StateBasedGame?) {
|
|
||||||
}
|
|
||||||
|
|
||||||
val lightning_start = Point2d(50.0, 200.0)
|
val lightning_start = Point2d(50.0, 200.0)
|
||||||
val lightning_end = Point2d(750.0, 200.0)
|
val lightning_end = Point2d(750.0, 200.0)
|
||||||
|
|
||||||
val bolt = LightingBolt(lightning_start, lightning_end, 20)
|
val bolt = LightingBolt(lightning_start, lightning_end, 50)
|
||||||
|
|
||||||
|
val noiseGen = TileableValueNoise(12, 0.5f, 128)
|
||||||
|
|
||||||
|
override fun init(container: GameContainer?, game: StateBasedGame?) {
|
||||||
|
noiseGen.generate(seed)
|
||||||
|
}
|
||||||
|
|
||||||
override fun update(container: GameContainer?, game: StateBasedGame?, delta: Int) {
|
override fun update(container: GameContainer?, game: StateBasedGame?, delta: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getID() = Terrarum.STATE_ID_TEST_SHIT
|
override fun getID() = Terrarum.STATE_ID_TEST_SHIT
|
||||||
|
|
||||||
|
|
||||||
|
private var regenTime = 17
|
||||||
|
private var seed = 1L
|
||||||
|
|
||||||
override fun render(container: GameContainer, game: StateBasedGame, g: Graphics) {
|
override fun render(container: GameContainer, game: StateBasedGame, g: Graphics) {
|
||||||
g.color = Color.white
|
g.color = Color.white
|
||||||
g.lineWidth = 3f
|
g.lineWidth = 3f
|
||||||
|
|
||||||
//g.drawLine(lightning_start, lightning_end)
|
//g.drawLine(lightning_start, lightning_end)
|
||||||
bolt.draw(g)
|
//bolt.draw(g)
|
||||||
|
|
||||||
|
|
||||||
|
val amp = 60f
|
||||||
|
val xoff = 10f
|
||||||
|
val yoff = 300f
|
||||||
|
|
||||||
|
for (x in noiseGen.width downTo 1) {
|
||||||
|
val pStart = noiseGen[x] * amp + yoff
|
||||||
|
val pEnd = noiseGen[x - 1] * amp + yoff
|
||||||
|
val step = 6
|
||||||
|
|
||||||
|
g.drawLine((noiseGen.width - x) * step + xoff, pStart,
|
||||||
|
(noiseGen.width - x +1) * step + xoff, pEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
g.color = Color.red
|
||||||
|
g.lineWidth = 1f
|
||||||
|
|
||||||
|
g.drawLine(xoff, yoff, xoff + noiseGen.width * 6, yoff)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun keyPressed(key: Int, c: Char) {
|
||||||
|
if (c == ' ') noiseGen.generate(++seed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Graphics.drawLine(p1: Point2d, p2: Point2d) {
|
fun Graphics.drawLine(p1: Point2d, p2: Point2d) {
|
||||||
|
|||||||
@@ -96,13 +96,13 @@ constructor(gamename: String) : StateBasedGame(gamename) {
|
|||||||
gc.graphics.clear() // clean up any 'dust' in the buffer
|
gc.graphics.clear() // clean up any 'dust' in the buffer
|
||||||
|
|
||||||
//addState(StateVTTest())
|
//addState(StateVTTest())
|
||||||
//addState(StateTestingSandbox())
|
addState(StateTestingSandbox())
|
||||||
//addState(StateSplash())
|
//addState(StateSplash())
|
||||||
//addState(StateMonitorCheck())
|
//addState(StateMonitorCheck())
|
||||||
//addState(StateFontTester())
|
//addState(StateFontTester())
|
||||||
|
|
||||||
ingame = StateInGame()
|
//ingame = StateInGame()
|
||||||
addState(ingame)
|
//addState(ingame)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
Reference in New Issue
Block a user