TileableValueNoise: it's working

Former-commit-id: 00c8c9490726fe8d7073044de7dd47482cc6788b
Former-commit-id: 9eb4521219f1465bdb2fe924282e09f81035dd99
This commit is contained in:
Song Minjae
2016-11-02 22:17:12 +09:00
parent cddbdeab7d
commit 5a366a84da
2 changed files with 38 additions and 26 deletions

View File

@@ -16,6 +16,11 @@ import java.util.*
class TileableValueNoise( class TileableValueNoise(
val octaves: Int, val persistency: Float, val width: Int) { val octaves: Int, val persistency: Float, val width: Int) {
init {
// FIXME wow, such primitive!
if (!FastMath.isPowerOfTwo(width)) throw Error("width is not power of two!")
}
private val noiseData = Array<Float>(width + 1, { 0f }) private val noiseData = Array<Float>(width + 1, { 0f })
private var noiseGenerated = false private var noiseGenerated = false
@@ -25,23 +30,25 @@ class TileableValueNoise(
// initialise // initialise
Arrays.fill(noiseData, 0f) Arrays.fill(noiseData, 0f)
val octavesIntStream = Array(octaves, { 1.shl(it) }) // array of (1, 2, 4, 8, ...)
for (i in 1..octaves) {
octaveLoop@ for (octcnt in 0..octaves - 1) { // 1, 2, 3, 4, ...
val i = octavesIntStream[octcnt] // 1, 2, 4, 8, ...
// octave 1 samples four points // octave 1 samples four points
val samples = 4 * i val samples = 4 * i
val amp = FastMath.pow(persistency, (i - 1).toFloat()) val amp = FastMath.pow(persistency, octcnt.toFloat()) // 1/1, 1/2, 1/3, 1/4, ...
var pointThis = 0f var pointThis = 0f
var pointNext = rng.nextBipolarFloat() var pointNext = rng.nextBipolarFloat()
var pointLoop = pointThis var pointLoop = pointThis
try {
for (x in 0..width) { for (x in 0..width) {
val thisSampleStart: Int = // 0-256 -> 0-4 -> 0-256(qnt) val thisSampleStart: Int = // 0-256 -> 0-4 -> 0-256(qnt)
(x / width.toFloat() * samples).floorInt() * (width / samples) (x / width.toFloat() * samples).floorInt() * (width / samples)
val nextSampleStart: Int = val nextSampleStart: Int =
(x / width.toFloat() * samples).floorInt().plus(1) * (width / samples) (x / width.toFloat() * samples).floorInt().plus(1) * (width / samples)
val stepWithinWindow: Int = x % (width / samples) val stepWithinWindow: Int = x % (nextSampleStart - thisSampleStart)
val windowScale: Float = stepWithinWindow.toFloat() / (width / samples) val windowScale: Float = stepWithinWindow.toFloat() / (width / samples)
// next pair of points // next pair of points
@@ -61,6 +68,11 @@ class TileableValueNoise(
"pThis: $pointThis\tpNext: $pointNext\tvalue: $noiseValue")*/ "pThis: $pointThis\tpNext: $pointNext\tvalue: $noiseValue")*/
} }
} }
catch (e: ArithmeticException) {
println("[TileableValueNoise] division by zero error occured, aborting further octave iteration.")
break@octaveLoop
} // division by zero; which means octave value was too high
}
for (x in 0..width - 1) { for (x in 0..width - 1) {
//println(noiseData[x]) //println(noiseData[x])

View File

@@ -34,7 +34,7 @@ class StateTestingSandbox : BasicGameState() {
val bolt = LightingBolt(lightning_start, lightning_end, 50) val bolt = LightingBolt(lightning_start, lightning_end, 50)
val noiseGen = TileableValueNoise(12, 0.5f, 128) val noiseGen = TileableValueNoise(6, 0.4f, 128)
override fun init(container: GameContainer?, game: StateBasedGame?) { override fun init(container: GameContainer?, game: StateBasedGame?) {
noiseGen.generate(seed) noiseGen.generate(seed)
@@ -61,13 +61,13 @@ class StateTestingSandbox : BasicGameState() {
val xoff = 10f val xoff = 10f
val yoff = 300f val yoff = 300f
for (x in noiseGen.width downTo 1) { for (x in 0..noiseGen.width - 1) {
val pStart = noiseGen[x] * amp + yoff val pStart = noiseGen[x] * amp + yoff
val pEnd = noiseGen[x - 1] * amp + yoff val pEnd = noiseGen[x + 1] * amp + yoff
val step = 6 val step = 6
g.drawLine((noiseGen.width - x) * step + xoff, pStart, g.drawLine(x * step + xoff, pStart,
(noiseGen.width - x +1) * step + xoff, pEnd) (x+1) * step + xoff, pEnd)
} }
g.color = Color.red g.color = Color.red