Tile -> Block && Map -> World

This commit is contained in:
Song Minjae
2017-04-27 01:57:45 +09:00
parent a9eb1f579e
commit f4db93ca9e
80 changed files with 1075 additions and 1645 deletions

View File

@@ -0,0 +1,64 @@
package net.torvald.terrarum.worldgenerator
import net.torvald.random.HQRNG
import java.util.Random
object FloatingIslandsPreset {
val PRESETS = 5
internal fun generatePreset(random: HQRNG): Array<IntArray> {
val index = random.nextInt(PRESETS)
return generatePreset(index, random)
}
internal fun generatePreset(index: Int, random: Random): Array<IntArray> {
if (index == 0) {
return processPreset(random, FloatingIslePreset01.data, FloatingIslePreset01.w, FloatingIslePreset01.h)
}
else if (index == 1) {
return processPreset(random, FloatingIslePreset02.data, FloatingIslePreset02.w, FloatingIslePreset02.h)
}
else if (index == 2) {
return processPreset(random, FloatingIslePreset03.data, FloatingIslePreset03.w, FloatingIslePreset03.h)
}
else if (index == 3) {
return processPreset(random, FloatingIslePreset04.data, FloatingIslePreset04.w, FloatingIslePreset04.h)
}
else {
return processPreset(random, FloatingIslePreset05.data, FloatingIslePreset05.w, FloatingIslePreset05.h)
}
}
private fun processPreset(random: Random, preset: IntArray, w: Int, h: Int): Array<IntArray> {
val temp = Array(h) { IntArray(w) }
var counter = 0
val mirrored = random.nextBoolean()
for (i in 0..h - 1) {
for (j in 0..w - 1) {
if (!mirrored) {
if (counter < preset.size - 1) {
temp[i][j] = preset[counter]
counter++
}
else {
temp[i][j] = 0
}
}
else {
if (counter < preset.size - 1) {
temp[i][w - 1 - j] = preset[counter]
counter++
}
else {
temp[i][w - 1 - j] = 0
}
}
}
}
return temp
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
package net.torvald.terrarum.worldgenerator
/**
* Created by minjaesong on 16-03-31.
*/
interface NoiseFilter {
fun getGrad(func_argX: Int, start: Double, end: Double): Double
}

View File

@@ -0,0 +1,46 @@
package net.torvald.terrarum.worldgenerator
import com.jme3.math.FastMath
/**
* Double Quadratic polynomial
* (16/9) * (start-end)/height^2 * (x-height)^2 + end
* 16/9: terrain is formed from 1/4 of height.
* 1 - (1/4) = 3/4, reverse it and square it.
* That makes 16/9.
* Shape:
* cavity -
* small
* -
* -
* --
* ----
* cavity --------
* large ----------------
* @param func_argX
* *
* @param start
* *
* @param end
* *
* @return
* Created by minjaesong on 16-03-31.
*/
object NoiseFilterCubic : NoiseFilter {
override fun getGrad(func_argX: Int, start: Double, end: Double): Double {
val graph_gradient = -FastMath.pow(FastMath.pow((1 - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat(), 3f), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9
(start - end) / FastMath.pow(WorldGenerator.HEIGHT.toFloat(), 3f) *
FastMath.pow((func_argX - WorldGenerator.HEIGHT).toFloat(), 3f) + end
if (func_argX < WorldGenerator.TERRAIN_AVERAGE_HEIGHT) {
return start
} else if (func_argX >= WorldGenerator.HEIGHT) {
return end
} else {
return graph_gradient
}
}
}

View File

@@ -0,0 +1,46 @@
package net.torvald.terrarum.worldgenerator
import com.jme3.math.FastMath
/**
* Quadratic polynomial
* -(16/9) * (start-end)/height^2 * (x - 0.25 * height)^2 + start
* 16/9: terrain is formed from 1/4 of height.
* 1 - (1/4) = 3/4, reverse it and square it.
* That makes 16/9.
* Shape:
* cavity _
* small
* _
* _
* __
* ____
* cavity ________
* large ________________
* @param func_argX
* *
* @param start
* *
* @param end
* *
* @return
* Created by minjaesong on 16-03-31.
*/
object NoiseFilterMinusQuadratic : NoiseFilter {
override fun getGrad(func_argX: Int, start: Double, end: Double): Double {
val graph_gradient = -FastMath.pow(FastMath.sqr((1 - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9
(start - end) / FastMath.sqr(WorldGenerator.HEIGHT.toFloat()) *
FastMath.sqr((func_argX - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()) + start
if (func_argX < WorldGenerator.TERRAIN_AVERAGE_HEIGHT) {
return start
} else if (func_argX >= WorldGenerator.HEIGHT) {
return end
} else {
return graph_gradient
}
}
}

View File

@@ -0,0 +1,47 @@
package net.torvald.terrarum.worldgenerator
import com.jme3.math.FastMath
/**
* Quadratic polynomial
* (16/9) * (start-end)/height^2 * (x-height)^2 + end
* 16/9: terrain is formed from 1/4 of height.
* 1 - (1/4) = 3/4, reverse it and square it.
* That makes 16/9.
* Shape:
* cavity -
* small
* -
* -
* --
* ----
* cavity --------
* large ----------------
* @param func_argX
* *
* @param start
* *
* @param end
* *
* @return
*
* Created by minjaesong on 16-03-31.
*/
object NoiseFilterQuadratic : NoiseFilter {
override fun getGrad(func_argX: Int, start: Double, end: Double): Double {
val graph_gradient = FastMath.pow(FastMath.sqr((1 - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()), -1f) * // 1/4 -> 3/4 -> 9/16 -> 16/9
(start - end) / FastMath.sqr(WorldGenerator.HEIGHT.toFloat()) *
FastMath.sqr((func_argX - WorldGenerator.HEIGHT).toFloat()) + end
if (func_argX < WorldGenerator.TERRAIN_AVERAGE_HEIGHT) {
return start
} else if (func_argX >= WorldGenerator.HEIGHT) {
return end
} else {
return graph_gradient
}
}
}

View File

@@ -0,0 +1,20 @@
package net.torvald.terrarum.worldgenerator
import com.jme3.math.FastMath
/**
* Created by minjaesong on 16-03-31.
*/
object NoiseFilterSqrt : NoiseFilter {
override fun getGrad(func_argX: Int, start: Double, end: Double): Double {
val graph_gradient = (end - start) / FastMath.sqrt((WorldGenerator.HEIGHT - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()) * FastMath.sqrt((func_argX - WorldGenerator.TERRAIN_AVERAGE_HEIGHT).toFloat()) + start
if (func_argX < WorldGenerator.TERRAIN_AVERAGE_HEIGHT) {
return start
} else if (func_argX >= WorldGenerator.HEIGHT) {
return end
} else {
return graph_gradient
}
}
}

View File

@@ -0,0 +1,10 @@
package net.torvald.terrarum.worldgenerator
/**
* Created by minjaesong on 16-03-31.
*/
object NoiseFilterUniform : NoiseFilter {
override fun getGrad(func_argX: Int, start: Double, end: Double): Double {
return 1.0
}
}

View File

@@ -0,0 +1,64 @@
package net.torvald.terrarum.worldgenerator
import net.torvald.dataclass.IntArrayStack
import net.torvald.colourutil.Col4096
import net.torvald.random.HQRNG
import org.newdawn.slick.Color
import java.util.*
/**
* Created by minjaesong on 16-02-23.
*/
object RoguelikeRandomiser {
val POTION_PRIMARY_COLSET = intArrayOf(15, 15, 7, 7, 0, 0)
var potionColours: HashMap<Int, Col4096> = HashMap()
var coloursDiscovered: HashMap<Col4096, Boolean> = HashMap()
val coloursTaken: ArrayList<Col4096> = ArrayList()
var seed: Long = 0
private val random: Random = HQRNG()
private val POTION_HEAL_TIER1 = 0x00
private val POTION_HEAL_TIRE2 = 0x01
private val POTION_MAGIC_REGEN_TIER1 = 0x10
private val POTION_BERSERK_TIER1 = 0x20
fun setupColours() {
}
/**
* For external classes/objects, does not touch COLOUR SET
* @param arr Array of Int(0-15)
*/
fun composeColourFrom(arr: IntArray): Color {
val colourElements = arr.copyOf()
shuffleArrayInt(colourElements, HQRNG())
val colourStack = IntArrayStack(colourElements)
return Col4096(colourStack.pop(),
colourStack.pop(),
colourStack.pop())
.toSlickColour()
}
fun shuffleArrayInt(ar: IntArray, rnd: Random) {
for (i in ar.size - 1 downTo 0) {
val index = rnd.nextInt(i + 1);
// Simple swap
val a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
}

View File

@@ -0,0 +1,73 @@
package net.torvald.terrarum.worldgenerator
import net.torvald.random.HQRNG
import com.jme3.math.FastMath
class SimplexNoise
/**
* @param largestFeature
* *
* @param persistence higher the value, rougher the output
* *
* @param seed
*/
(internal var largestFeature: Int, internal var persistence: Float, internal var seed: Long) {
internal var octaves: Array<SimplexNoise_octave>
internal var frequencys: FloatArray
internal var amplitudes: FloatArray
init {
//receives a number (e.g. 128) and calculates what power of 2 it is (e.g. 2^7)
val numberOfOctaves = FastMath.intLog2(largestFeature)
val rnd = HQRNG(seed)
octaves = Array<SimplexNoise_octave>(numberOfOctaves, {i -> SimplexNoise_octave(rnd.nextInt())})
frequencys = FloatArray(numberOfOctaves)
amplitudes = FloatArray(numberOfOctaves)
for (i in 0..numberOfOctaves - 1) {
octaves[i] = SimplexNoise_octave(rnd.nextInt())
frequencys[i] = FastMath.pow(2f, i.toFloat())
amplitudes[i] = FastMath.pow(persistence, (octaves.size - i).toFloat())
}
}
fun getNoise(x: Int, y: Int): Float {
var result = 0f
for (i in octaves.indices) {
//float frequency = FastMath.pow(2,i);
//float amplitude = FastMath.pow(persistence,octaves.length-i);
result += (octaves[i].noise((x / frequencys[i]).toDouble(), (y / frequencys[i]).toDouble()) * amplitudes[i]).toFloat()
}
return result
}
fun getNoise(x: Int, y: Int, z: Int): Float {
var result = 0f
for (i in octaves.indices) {
val frequency = FastMath.pow(2f, i.toFloat())
val amplitude = FastMath.pow(persistence, (octaves.size - i).toFloat())
result += (octaves[i].noise((x / frequency).toDouble(), (y / frequency).toDouble(), (z / frequency).toDouble()) * amplitude).toFloat()
}
return result
}
}

View File

@@ -0,0 +1,457 @@
package net.torvald.terrarum.worldgenerator
/*
* A speed-improved simplex noise algorithm for 2D, 3D and 4D in Java.
*
* Based on example code by Stefan Gustavson (stegu@itn.liu.se).
* Optimisations by Peter Eastman (peastman@drizzle.stanford.edu).
* Better rank ordering method by Stefan Gustavson in 2012.
*
* This could be speeded up even further, but it's useful as it is.
*
* Version 2012-03-09
*
* This code was placed in the public domain by its original author,
* Stefan Gustavson. You may use it as you see fit, but
* attribution is appreciated.
*
*/
import net.torvald.random.HQRNG
class SimplexNoise_octave(seed: Int) { // Simplex noise in 2D, 3D and 4D
private var p = ShortArray(p_supply.size)
// To remove the need for index wrapping, double the permutation table length
private val perm = ShortArray(512)
private val permMod12 = ShortArray(512)
init {
p = p_supply.clone()
if (seed == RANDOMSEED) {
throw IllegalArgumentException("Seed cannot be zero.")
}
//the random for the swaps
val rand = HQRNG(seed.toLong())
//the seed determines the swaps that occur between the default order and the order we're actually going to use
for (i in 0..NUMBEROFSWAPS - 1) {
val swapFrom = rand.nextInt(p.size)
val swapTo = rand.nextInt(p.size)
val temp = p[swapFrom]
p[swapFrom] = p[swapTo]
p[swapTo] = temp
}
for (i in 0..511) {
perm[i] = p[i and 255]
permMod12[i] = (perm[i] % 12).toShort()
}
}
// 2D simplex noise
fun noise(xin: Double, yin: Double): Double {
val n0: Double
val n1: Double
val n2: Double // Noise contributions from the three corners
// Skew the input space to determine which simplex cell we're in
val s = (xin + yin) * F2 // Hairy factor for 2D
val i = fastfloor(xin + s)
val j = fastfloor(yin + s)
val t = (i + j) * G2
val X0 = i - t // Unskew the cell origin back to (x,y) space
val Y0 = j - t
val x0 = xin - X0 // The x,y distances from the cell origin
val y0 = yin - Y0
// For the 2D case, the simplex shape is an equilateral triangle.
// Determine which simplex we are in.
val i1: Int
val j1: Int // Offsets for second (middle) corner of simplex in (i,j) coords
if (x0 > y0) {
i1 = 1
j1 = 0
} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
else {
i1 = 0
j1 = 1
} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
// c = (3-sqrt(3))/6
val x1 = x0 - i1 + G2 // Offsets for middle corner in (x,y) unskewed coords
val y1 = y0 - j1 + G2
val x2 = x0 - 1.0 + 2.0 * G2 // Offsets for last corner in (x,y) unskewed coords
val y2 = y0 - 1.0 + 2.0 * G2
// Work out the hashed gradient indices of the three simplex corners
val ii = i and 255
val jj = j and 255
val gi0 = permMod12[ii + perm[jj]].toInt()
val gi1 = permMod12[ii + i1 + perm[jj + j1].toInt()].toInt()
val gi2 = permMod12[ii + 1 + perm[jj + 1].toInt()].toInt()
// Calculate the contribution from the three corners
var t0 = 0.5 - x0 * x0 - y0 * y0
if (t0 < 0)
n0 = 0.0
else {
t0 *= t0
n0 = t0 * t0 * dot(grad3[gi0], x0, y0) // (x,y) of grad3 used for 2D gradient
}
var t1 = 0.5 - x1 * x1 - y1 * y1
if (t1 < 0)
n1 = 0.0
else {
t1 *= t1
n1 = t1 * t1 * dot(grad3[gi1], x1, y1)
}
var t2 = 0.5 - x2 * x2 - y2 * y2
if (t2 < 0)
n2 = 0.0
else {
t2 *= t2
n2 = t2 * t2 * dot(grad3[gi2], x2, y2)
}
// Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1].
return 70.0 * (n0 + n1 + n2)
}
// 3D simplex noise
fun noise(xin: Double, yin: Double, zin: Double): Double {
val n0: Double
val n1: Double
val n2: Double
val n3: Double // Noise contributions from the four corners
// Skew the input space to determine which simplex cell we're in
val s = (xin + yin + zin) * F3 // Very nice and simple skew factor for 3D
val i = fastfloor(xin + s)
val j = fastfloor(yin + s)
val k = fastfloor(zin + s)
val t = (i + j + k) * G3
val X0 = i - t // Unskew the cell origin back to (x,y,z) space
val Y0 = j - t
val Z0 = k - t
val x0 = xin - X0 // The x,y,z distances from the cell origin
val y0 = yin - Y0
val z0 = zin - Z0
// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
// Determine which simplex we are in.
val i1: Int
val j1: Int
val k1: Int // Offsets for second corner of simplex in (i,j,k) coords
val i2: Int
val j2: Int
val k2: Int // Offsets for third corner of simplex in (i,j,k) coords
if (x0 >= y0) {
if (y0 >= z0) {
i1 = 1
j1 = 0
k1 = 0
i2 = 1
j2 = 1
k2 = 0
} // X Y Z order
else if (x0 >= z0) {
i1 = 1
j1 = 0
k1 = 0
i2 = 1
j2 = 0
k2 = 1
} // X Z Y order
else {
i1 = 0
j1 = 0
k1 = 1
i2 = 1
j2 = 0
k2 = 1
} // Z X Y order
}
else {
// x0<y0
if (y0 < z0) {
i1 = 0
j1 = 0
k1 = 1
i2 = 0
j2 = 1
k2 = 1
} // Z Y X order
else if (x0 < z0) {
i1 = 0
j1 = 1
k1 = 0
i2 = 0
j2 = 1
k2 = 1
} // Y Z X order
else {
i1 = 0
j1 = 1
k1 = 0
i2 = 1
j2 = 1
k2 = 0
} // Y X Z order
}
// A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
// a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
// a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
// c = 1/6.
val x1 = x0 - i1 + G3 // Offsets for second corner in (x,y,z) coords
val y1 = y0 - j1 + G3
val z1 = z0 - k1 + G3
val x2 = x0 - i2 + 2.0 * G3 // Offsets for third corner in (x,y,z) coords
val y2 = y0 - j2 + 2.0 * G3
val z2 = z0 - k2 + 2.0 * G3
val x3 = x0 - 1.0 + 3.0 * G3 // Offsets for last corner in (x,y,z) coords
val y3 = y0 - 1.0 + 3.0 * G3
val z3 = z0 - 1.0 + 3.0 * G3
// Work out the hashed gradient indices of the four simplex corners
val ii = i and 255
val jj = j and 255
val kk = k and 255
val gi0 = permMod12[ii + perm[jj + perm[kk]]].toInt()
val gi1 = permMod12[ii + i1 + perm[jj + j1 + perm[kk + k1].toInt()].toInt()].toInt()
val gi2 = permMod12[ii + i2 + perm[jj + j2 + perm[kk + k2].toInt()].toInt()].toInt()
val gi3 = permMod12[ii + 1 + perm[jj + 1 + perm[kk + 1].toInt()].toInt()].toInt()
// Calculate the contribution from the four corners
var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0
if (t0 < 0)
n0 = 0.0
else {
t0 *= t0
n0 = t0 * t0 * dot(grad3[gi0], x0, y0, z0)
}
var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1
if (t1 < 0)
n1 = 0.0
else {
t1 *= t1
n1 = t1 * t1 * dot(grad3[gi1], x1, y1, z1)
}
var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2
if (t2 < 0)
n2 = 0.0
else {
t2 *= t2
n2 = t2 * t2 * dot(grad3[gi2], x2, y2, z2)
}
var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3
if (t3 < 0)
n3 = 0.0
else {
t3 *= t3
n3 = t3 * t3 * dot(grad3[gi3], x3, y3, z3)
}
// Add contributions from each corner to get the final noise value.
// The result is scaled to stay just inside [-1,1]
return 32.0 * (n0 + n1 + n2 + n3)
}
// 4D simplex noise, better simplex rank ordering method 2012-03-09
fun noise(x: Double, y: Double, z: Double, w: Double): Double {
val n0: Double
val n1: Double
val n2: Double
val n3: Double
val n4: Double // Noise contributions from the five corners
// Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
val s = (x + y + z + w) * F4 // Factor for 4D skewing
val i = fastfloor(x + s)
val j = fastfloor(y + s)
val k = fastfloor(z + s)
val l = fastfloor(w + s)
val t = (i + j + k + l) * G4 // Factor for 4D unskewing
val X0 = i - t // Unskew the cell origin back to (x,y,z,w) space
val Y0 = j - t
val Z0 = k - t
val W0 = l - t
val x0 = x - X0 // The x,y,z,w distances from the cell origin
val y0 = y - Y0
val z0 = z - Z0
val w0 = w - W0
// For the 4D case, the simplex is a 4D shape I won't even try to describe.
// To find out which of the 24 possible simplices we're in, we need to
// determine the magnitude ordering of x0, y0, z0 and w0.
// Six pair-wise comparisons are performed between each possible pair
// of the four coordinates, and the results are used to rank the numbers.
var rankx = 0
var ranky = 0
var rankz = 0
var rankw = 0
if (x0 > y0) rankx++ else ranky++
if (x0 > z0) rankx++ else rankz++
if (x0 > w0) rankx++ else rankw++
if (y0 > z0) ranky++ else rankz++
if (y0 > w0) ranky++ else rankw++
if (z0 > w0) rankz++ else rankw++
val i1: Int
val j1: Int
val k1: Int
val l1: Int // The integer offsets for the second simplex corner
val i2: Int
val j2: Int
val k2: Int
val l2: Int // The integer offsets for the third simplex corner
val i3: Int
val j3: Int
val k3: Int
val l3: Int // The integer offsets for the fourth simplex corner
// simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
// Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
// impossible. Only the 24 indices which have non-zero entries make any sense.
// We use a thresholding to set the coordinates in turn from the largest magnitude.
// Rank 3 denotes the largest coordinate.
i1 = if (rankx >= 3) 1 else 0
j1 = if (ranky >= 3) 1 else 0
k1 = if (rankz >= 3) 1 else 0
l1 = if (rankw >= 3) 1 else 0
// Rank 2 denotes the second largest coordinate.
i2 = if (rankx >= 2) 1 else 0
j2 = if (ranky >= 2) 1 else 0
k2 = if (rankz >= 2) 1 else 0
l2 = if (rankw >= 2) 1 else 0
// Rank 1 denotes the second smallest coordinate.
i3 = if (rankx >= 1) 1 else 0
j3 = if (ranky >= 1) 1 else 0
k3 = if (rankz >= 1) 1 else 0
l3 = if (rankw >= 1) 1 else 0
// The fifth corner has all coordinate offsets = 1, so no need to compute that.
val x1 = x0 - i1 + G4 // Offsets for second corner in (x,y,z,w) coords
val y1 = y0 - j1 + G4
val z1 = z0 - k1 + G4
val w1 = w0 - l1 + G4
val x2 = x0 - i2 + 2.0 * G4 // Offsets for third corner in (x,y,z,w) coords
val y2 = y0 - j2 + 2.0 * G4
val z2 = z0 - k2 + 2.0 * G4
val w2 = w0 - l2 + 2.0 * G4
val x3 = x0 - i3 + 3.0 * G4 // Offsets for fourth corner in (x,y,z,w) coords
val y3 = y0 - j3 + 3.0 * G4
val z3 = z0 - k3 + 3.0 * G4
val w3 = w0 - l3 + 3.0 * G4
val x4 = x0 - 1.0 + 4.0 * G4 // Offsets for last corner in (x,y,z,w) coords
val y4 = y0 - 1.0 + 4.0 * G4
val z4 = z0 - 1.0 + 4.0 * G4
val w4 = w0 - 1.0 + 4.0 * G4
// Work out the hashed gradient indices of the five simplex corners
val ii = i and 255
val jj = j and 255
val kk = k and 255
val ll = l and 255
val gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32
val gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1].toInt()].toInt()].toInt()] % 32
val gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2].toInt()].toInt()].toInt()] % 32
val gi3 = perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3].toInt()].toInt()].toInt()] % 32
val gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1].toInt()].toInt()].toInt()] % 32
// Calculate the contribution from the five corners
var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0
if (t0 < 0)
n0 = 0.0
else {
t0 *= t0
n0 = t0 * t0 * dot(grad4[gi0], x0, y0, z0, w0)
}
var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1
if (t1 < 0)
n1 = 0.0
else {
t1 *= t1
n1 = t1 * t1 * dot(grad4[gi1], x1, y1, z1, w1)
}
var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2
if (t2 < 0)
n2 = 0.0
else {
t2 *= t2
n2 = t2 * t2 * dot(grad4[gi2], x2, y2, z2, w2)
}
var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3
if (t3 < 0)
n3 = 0.0
else {
t3 *= t3
n3 = t3 * t3 * dot(grad4[gi3], x3, y3, z3, w3)
}
var t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4
if (t4 < 0)
n4 = 0.0
else {
t4 *= t4
n4 = t4 * t4 * dot(grad4[gi4], x4, y4, z4, w4)
}
// Sum up and scale the result to cover the range [-1,1]
return 27.0 * (n0 + n1 + n2 + n3 + n4)
}
// Inner class to speed upp gradient computations
// (array access is a lot slower than member access)
private class Grad {
internal var x: Double = 0.toDouble()
internal var y: Double = 0.toDouble()
internal var z: Double = 0.toDouble()
internal var w: Double = 0.toDouble()
internal constructor(x: Double, y: Double, z: Double) {
this.x = x
this.y = y
this.z = z
}
internal constructor(x: Double, y: Double, z: Double, w: Double) {
this.x = x
this.y = y
this.z = z
this.w = w
}
}
companion object {
var RANDOMSEED = 0
private val NUMBEROFSWAPS = 400
private val grad3 = arrayOf(Grad(1.0, 1.0, 0.0), Grad(-1.0, 1.0, 0.0), Grad(1.0, -1.0, 0.0), Grad(-1.0, -1.0, 0.0), Grad(1.0, 0.0, 1.0), Grad(-1.0, 0.0, 1.0), Grad(1.0, 0.0, -1.0), Grad(-1.0, 0.0, -1.0), Grad(0.0, 1.0, 1.0), Grad(0.0, -1.0, 1.0), Grad(0.0, 1.0, -1.0), Grad(0.0, -1.0, -1.0))
private val grad4 = arrayOf(Grad(0.0, 1.0, 1.0, 1.0), Grad(0.0, 1.0, 1.0, -1.0), Grad(0.0, 1.0, -1.0, 1.0), Grad(0.0, 1.0, -1.0, -1.0), Grad(0.0, -1.0, 1.0, 1.0), Grad(0.0, -1.0, 1.0, -1.0), Grad(0.0, -1.0, -1.0, 1.0), Grad(0.0, -1.0, -1.0, -1.0), Grad(1.0, 0.0, 1.0, 1.0), Grad(1.0, 0.0, 1.0, -1.0), Grad(1.0, 0.0, -1.0, 1.0), Grad(1.0, 0.0, -1.0, -1.0), Grad(-1.0, 0.0, 1.0, 1.0), Grad(-1.0, 0.0, 1.0, -1.0), Grad(-1.0, 0.0, -1.0, 1.0), Grad(-1.0, 0.0, -1.0, -1.0), Grad(1.0, 1.0, 0.0, 1.0), Grad(1.0, 1.0, 0.0, -1.0), Grad(1.0, -1.0, 0.0, 1.0), Grad(1.0, -1.0, 0.0, -1.0), Grad(-1.0, 1.0, 0.0, 1.0), Grad(-1.0, 1.0, 0.0, -1.0), Grad(-1.0, -1.0, 0.0, 1.0), Grad(-1.0, -1.0, 0.0, -1.0), Grad(1.0, 1.0, 1.0, 0.0), Grad(1.0, 1.0, -1.0, 0.0), Grad(1.0, -1.0, 1.0, 0.0), Grad(1.0, -1.0, -1.0, 0.0), Grad(-1.0, 1.0, 1.0, 0.0), Grad(-1.0, 1.0, -1.0, 0.0), Grad(-1.0, -1.0, 1.0, 0.0), Grad(-1.0, -1.0, -1.0, 0.0))
private val p_supply = shortArrayOf(151, 160, 137, 91, 90, 15, //this contains all the numbers between 0 and 255, these are put in a random order depending upon the seed
131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180)
// Skewing and unskewing factors for 2, 3, and 4 dimensions
private val F2 = 0.5 * (Math.sqrt(3.0) - 1.0)
private val G2 = (3.0 - Math.sqrt(3.0)) / 6.0
private val F3 = 1.0 / 3.0
private val G3 = 1.0 / 6.0
private val F4 = (Math.sqrt(5.0) - 1.0) / 4.0
private val G4 = (5.0 - Math.sqrt(5.0)) / 20.0
// This method is a *lot* faster than using (int)Math.floor(x)
private fun fastfloor(x: Double): Int {
val xi = x.toInt()
return if (x < xi) xi - 1 else xi
}
private fun dot(g: Grad, x: Double, y: Double): Double {
return g.x * x + g.y * y
}
private fun dot(g: Grad, x: Double, y: Double, z: Double): Double {
return g.x * x + g.y * y + g.z * z
}
private fun dot(g: Grad, x: Double, y: Double, z: Double, w: Double): Double {
return g.x * x + g.y * y + g.z * z + g.w * w
}
}
}

View File

@@ -0,0 +1,67 @@
package net.torvald.terrarum.worldgenerator
/**
* Created by minjaesong on 16-06-13.
*/
class ThreadProcessNoiseLayers(val startIndex: Int, val endIndex: Int,
val noiseRecords: Array<WorldGenerator.TaggedJoise>) : Runnable {
override fun run() {
for (record in noiseRecords) {
println("[mapgenerator] ${record.message}...")
for (y in startIndex..endIndex) {
for (x in 0..WorldGenerator.WIDTH - 1) {
// straight-line sampling
/*val noise: Float = record.noiseModule.get(
x.toDouble() / 48.0, // 48: Fixed value
y.toDouble() / 48.0
).toFloat()*/
// circular sampling
// Mapping function:
// World(x, y) -> Joise(sin x, y, cos x)
val sampleDensity = 48.0 / 2 // 48.0: magic number from old code
val sampleTheta = (x.toDouble() / WorldGenerator.WIDTH) * WorldGenerator.TWO_PI
val sampleOffset = (WorldGenerator.WIDTH / sampleDensity) / 8.0
val sampleX = Math.sin(sampleTheta) * sampleOffset + sampleOffset // plus sampleOffset to make only
val sampleZ = Math.cos(sampleTheta) * sampleOffset + sampleOffset // positive points are to be sampled
val sampleY = y / sampleDensity
val noise: Double = record.noiseModule.get(sampleX, sampleY, sampleZ)
val fromTerr = record.replaceFromTerrain
val fromWall = record.replaceFromWall
val to: Int = when (record.replaceTo) {
// replace to designated tile
is Int -> record.replaceTo as Int
// replace to randomly selected tile from given array of tile IDs
is IntArray -> (record.replaceTo as IntArray)[WorldGenerator.random.nextInt((record.replaceTo as IntArray).size)]
else -> throw IllegalArgumentException("[mapgenerator] Unknown replaceTo tile type '${record.replaceTo.javaClass.canonicalName}': Only 'kotlin.Int' and 'kotlin.IntArray' is valid.")
}
// replace to ALL? this is bullshit
if (to == WorldGenerator.TILE_MACRO_ALL) throw IllegalArgumentException("[mapgenerator] Invalid replaceTo: TILE_MACRO_ALL")
// filtered threshold
val threshold = record.filter.getGrad(y, record.filterArg1, record.filterArg2)
if (noise > threshold * record.scarcity) {
if (fromTerr is IntArray) {
for (i in 0..fromTerr.size - 1) {
val fromTerrVariable = fromTerr[i]
if ((WorldGenerator.world.getTileFromTerrain(x, y) == fromTerrVariable || fromTerrVariable == WorldGenerator.TILE_MACRO_ALL)
&& (WorldGenerator.world.getTileFromWall(x, y) == fromWall || fromWall == WorldGenerator.TILE_MACRO_ALL)) {
WorldGenerator.world.setTileTerrain(x, y, to)
}
}
}
else if ((WorldGenerator.world.getTileFromTerrain(x, y) == fromTerr || fromTerr == WorldGenerator.TILE_MACRO_ALL)
&& (WorldGenerator.world.getTileFromWall(x, y) == fromWall || fromWall == WorldGenerator.TILE_MACRO_ALL)) {
WorldGenerator.world.setTileTerrain(x, y, to)
}
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB