mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-10 22:01:52 +09:00
update gitignore, new worldgen wip
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -12,9 +12,11 @@ replay_pid*
|
|||||||
# OS files
|
# OS files
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
desktop.ini
|
||||||
|
|
||||||
# Resources that should not be tracked
|
# Resources that should not be tracked
|
||||||
assets/mods/basegame/demoworld
|
assets/mods/basegame/demoworld
|
||||||
|
external_resource_packs
|
||||||
#assets/mods/basegame/demoworld.gz
|
#assets/mods/basegame/demoworld.gz
|
||||||
external_resource_packs.zip
|
external_resource_packs.zip
|
||||||
|
|
||||||
@@ -33,4 +35,3 @@ tmp_*
|
|||||||
*.index
|
*.index
|
||||||
*.threads
|
*.threads
|
||||||
*_Leak_Suspects.zip
|
*_Leak_Suspects.zip
|
||||||
desktop.ini
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package net.torvald.terrarum.modulebasegame.worldgenerator
|
||||||
|
|
||||||
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2019-09-02.
|
||||||
|
*/
|
||||||
|
object Biomegen : Gen {
|
||||||
|
override var generationStarted: Boolean
|
||||||
|
get() = TODO("not implemented")
|
||||||
|
set(value) {}
|
||||||
|
override val generationDone: Boolean
|
||||||
|
get() = TODO("not implemented")
|
||||||
|
|
||||||
|
override fun invoke(world: GameWorld, seed: Long, params: Any) {
|
||||||
|
TODO("not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class BiomegenParams(
|
||||||
|
val featureSize: Double = 80.0
|
||||||
|
)
|
||||||
@@ -0,0 +1,336 @@
|
|||||||
|
package net.torvald.terrarum.modulebasegame.worldgenerator
|
||||||
|
|
||||||
|
import com.sudoplay.joise.Joise
|
||||||
|
import com.sudoplay.joise.module.*
|
||||||
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
|
import net.torvald.terrarum.concurrent.ThreadParallel
|
||||||
|
import net.torvald.terrarum.concurrent.mapToThreadPoolDirectly
|
||||||
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2019-07-23.
|
||||||
|
*/
|
||||||
|
object Terragen : Gen {
|
||||||
|
|
||||||
|
override var generationStarted: Boolean = false
|
||||||
|
override val generationDone: Boolean
|
||||||
|
get() = generationStarted && ThreadParallel.allFinished()
|
||||||
|
|
||||||
|
override fun invoke(world: GameWorld, seed: Long, params: Any) {
|
||||||
|
val joise = getGenerator(seed, params as TerragenParams)
|
||||||
|
|
||||||
|
(0 until world.width).mapToThreadPoolDirectly(this.javaClass.simpleName) { range ->
|
||||||
|
for (y in 0 until world.height) {
|
||||||
|
for (x in range) {
|
||||||
|
val sampleTheta = (x.toDouble() / world.width) * TWO_PI
|
||||||
|
val sampleOffset = world.width / 8.0
|
||||||
|
val sampleX = sin(sampleTheta) * sampleOffset + sampleOffset // plus sampleOffset to make only
|
||||||
|
val sampleZ = cos(sampleTheta) * sampleOffset + sampleOffset // positive points are to be sampled
|
||||||
|
val sampleY = y.toDouble()
|
||||||
|
val noise = joise.map { it.get(sampleX, sampleY, sampleZ) }
|
||||||
|
|
||||||
|
draw(x, y, noise, world)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadParallel.startAll()
|
||||||
|
generationStarted = true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val groundDepthBlock = listOf(
|
||||||
|
Block.AIR, Block.DIRT, Block.STONE
|
||||||
|
)
|
||||||
|
|
||||||
|
fun draw(x: Int, y: Int, noiseValue: List<Double>, world: GameWorld) {
|
||||||
|
fun Double.tiered(vararg tiers: Double): Int {
|
||||||
|
tiers.reversed().forEachIndexed { index, it ->
|
||||||
|
if (this >= it) return (tiers.lastIndex - index) // why??
|
||||||
|
}
|
||||||
|
return tiers.lastIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
val terr = noiseValue[0].tiered(.0, .5, .88)
|
||||||
|
val cave = if (noiseValue[1] < 0.5) 0 else 1
|
||||||
|
|
||||||
|
val wallBlock = groundDepthBlock[terr]
|
||||||
|
val terrBlock = wallBlock * cave // AIR is always zero, this is the standard
|
||||||
|
|
||||||
|
world.setTileTerrain(x, y, terrBlock)
|
||||||
|
world.setTileWall(x, y, wallBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun getGenerator(seed: Long, params: TerragenParams): List<Joise> {
|
||||||
|
val lowlandMagic: Long = 0x41A21A114DBE56 // Maria Lindberg
|
||||||
|
val highlandMagic: Long = 0x0114E091 // Olive Oyl
|
||||||
|
val mountainMagic: Long = 0x115AA4DE2504 // Lisa Anderson
|
||||||
|
val selectionMagic: Long = 0x41E10D9B100 // Melody Blue
|
||||||
|
|
||||||
|
val caveMagic: Long = 0x00215741CDF // Urist McDF
|
||||||
|
val cavePerturbMagic: Long = 0xA2410C // Armok
|
||||||
|
val caveBlockageMagic: Long = 0xD15A57E5 // Disaster
|
||||||
|
|
||||||
|
|
||||||
|
val groundGradient = ModuleGradient()
|
||||||
|
groundGradient.setGradient(0.0, 0.0, 0.0, 1.0)
|
||||||
|
|
||||||
|
/* lowlands */
|
||||||
|
|
||||||
|
val lowlandShapeFractal = ModuleFractal()
|
||||||
|
lowlandShapeFractal.setType(ModuleFractal.FractalType.BILLOW)
|
||||||
|
lowlandShapeFractal.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
||||||
|
lowlandShapeFractal.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
||||||
|
lowlandShapeFractal.setNumOctaves(2)
|
||||||
|
lowlandShapeFractal.setFrequency(0.25)
|
||||||
|
lowlandShapeFractal.seed = seed shake lowlandMagic
|
||||||
|
|
||||||
|
val lowlandAutoCorrect = ModuleAutoCorrect()
|
||||||
|
lowlandAutoCorrect.setSource(lowlandShapeFractal)
|
||||||
|
lowlandAutoCorrect.setLow(0.0)
|
||||||
|
lowlandAutoCorrect.setHigh(1.0)
|
||||||
|
|
||||||
|
val lowlandScale = ModuleScaleOffset()
|
||||||
|
lowlandScale.setScale(0.125)
|
||||||
|
lowlandScale.setOffset(params.lowlandScaleOffset) // TODO linearly alters the height
|
||||||
|
|
||||||
|
val lowlandYScale = ModuleScaleDomain()
|
||||||
|
lowlandYScale.setSource(lowlandScale)
|
||||||
|
lowlandYScale.setScaleY(0.02) // greater = more distortion, overhangs
|
||||||
|
|
||||||
|
val lowlandTerrain = ModuleTranslateDomain()
|
||||||
|
lowlandTerrain.setSource(groundGradient)
|
||||||
|
lowlandTerrain.setAxisYSource(lowlandYScale)
|
||||||
|
|
||||||
|
/* highlands */
|
||||||
|
|
||||||
|
val highlandShapeFractal = ModuleFractal()
|
||||||
|
highlandShapeFractal.setType(ModuleFractal.FractalType.FBM)
|
||||||
|
highlandShapeFractal.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
||||||
|
highlandShapeFractal.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
||||||
|
highlandShapeFractal.setNumOctaves(4)
|
||||||
|
highlandShapeFractal.setFrequency(2.0)
|
||||||
|
highlandShapeFractal.seed = seed shake highlandMagic
|
||||||
|
|
||||||
|
val highlandAutocorrect = ModuleAutoCorrect()
|
||||||
|
highlandAutocorrect.setSource(highlandShapeFractal)
|
||||||
|
highlandAutocorrect.setLow(-1.0)
|
||||||
|
highlandAutocorrect.setHigh(1.0)
|
||||||
|
|
||||||
|
val highlandScale = ModuleScaleOffset()
|
||||||
|
highlandScale.setSource(highlandAutocorrect)
|
||||||
|
highlandScale.setScale(0.25)
|
||||||
|
highlandScale.setOffset(params.highlandScaleOffset) // TODO linearly alters the height
|
||||||
|
|
||||||
|
val highlandYScale = ModuleScaleDomain()
|
||||||
|
highlandYScale.setSource(highlandScale)
|
||||||
|
highlandYScale.setScaleY(0.14) // greater = more distortion, overhangs
|
||||||
|
|
||||||
|
val highlandTerrain = ModuleTranslateDomain()
|
||||||
|
highlandTerrain.setSource(groundGradient)
|
||||||
|
highlandTerrain.setAxisYSource(highlandYScale)
|
||||||
|
|
||||||
|
/* mountains */
|
||||||
|
|
||||||
|
val mountainShapeFractal = ModuleFractal()
|
||||||
|
mountainShapeFractal.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
||||||
|
mountainShapeFractal.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
||||||
|
mountainShapeFractal.setNumOctaves(8)
|
||||||
|
mountainShapeFractal.setFrequency(1.0)
|
||||||
|
mountainShapeFractal.seed = seed shake mountainMagic
|
||||||
|
|
||||||
|
val mountainAutocorrect = ModuleAutoCorrect()
|
||||||
|
mountainAutocorrect.setSource(mountainShapeFractal)
|
||||||
|
mountainAutocorrect.setLow(-1.0)
|
||||||
|
mountainAutocorrect.setHigh(1.0)
|
||||||
|
|
||||||
|
val mountainScale = ModuleScaleOffset()
|
||||||
|
mountainScale.setSource(mountainAutocorrect)
|
||||||
|
mountainScale.setScale(0.45)
|
||||||
|
mountainScale.setOffset(params.mountainScaleOffset) // TODO linearly alters the height
|
||||||
|
|
||||||
|
val mountainYScale = ModuleScaleDomain()
|
||||||
|
mountainYScale.setSource(mountainScale)
|
||||||
|
mountainYScale.setScaleY(params.mountainDisturbance) // greater = more distortion, overhangs
|
||||||
|
|
||||||
|
val mountainTerrain = ModuleTranslateDomain()
|
||||||
|
mountainTerrain.setSource(groundGradient)
|
||||||
|
mountainTerrain.setAxisYSource(mountainYScale)
|
||||||
|
|
||||||
|
/* selection */
|
||||||
|
|
||||||
|
val terrainTypeFractal = ModuleFractal()
|
||||||
|
terrainTypeFractal.setType(ModuleFractal.FractalType.FBM)
|
||||||
|
terrainTypeFractal.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
||||||
|
terrainTypeFractal.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
||||||
|
terrainTypeFractal.setNumOctaves(3)
|
||||||
|
terrainTypeFractal.setFrequency(0.125)
|
||||||
|
terrainTypeFractal.seed = seed shake selectionMagic
|
||||||
|
|
||||||
|
val terrainAutocorrect = ModuleAutoCorrect()
|
||||||
|
terrainAutocorrect.setSource(terrainTypeFractal)
|
||||||
|
terrainAutocorrect.setLow(0.0)
|
||||||
|
terrainAutocorrect.setHigh(1.0)
|
||||||
|
|
||||||
|
val terrainTypeYScale = ModuleScaleDomain()
|
||||||
|
terrainTypeYScale.setSource(terrainAutocorrect)
|
||||||
|
terrainTypeYScale.setScaleY(0.0)
|
||||||
|
|
||||||
|
val terrainTypeCache = ModuleCache()
|
||||||
|
terrainTypeCache.setSource(terrainTypeYScale)
|
||||||
|
|
||||||
|
val highlandMountainSelect = ModuleSelect()
|
||||||
|
highlandMountainSelect.setLowSource(highlandTerrain)
|
||||||
|
highlandMountainSelect.setHighSource(mountainTerrain)
|
||||||
|
highlandMountainSelect.setControlSource(terrainTypeCache)
|
||||||
|
highlandMountainSelect.setThreshold(0.55)
|
||||||
|
highlandMountainSelect.setFalloff(0.2)
|
||||||
|
|
||||||
|
val highlandLowlandSelect = ModuleSelect()
|
||||||
|
highlandLowlandSelect.setLowSource(lowlandTerrain)
|
||||||
|
highlandLowlandSelect.setHighSource(highlandMountainSelect)
|
||||||
|
highlandLowlandSelect.setControlSource(terrainTypeCache)
|
||||||
|
highlandLowlandSelect.setThreshold(0.25)
|
||||||
|
highlandLowlandSelect.setFalloff(0.15)
|
||||||
|
|
||||||
|
val highlandLowlandSelectCache = ModuleCache()
|
||||||
|
highlandLowlandSelectCache.setSource(highlandLowlandSelect)
|
||||||
|
|
||||||
|
val groundSelect = ModuleSelect()
|
||||||
|
groundSelect.setLowSource(0.0)
|
||||||
|
groundSelect.setHighSource(1.0)
|
||||||
|
groundSelect.setThreshold(0.5)
|
||||||
|
groundSelect.setControlSource(highlandLowlandSelectCache)
|
||||||
|
|
||||||
|
val groundSelect2 = ModuleSelect()
|
||||||
|
groundSelect2.setLowSource(0.0)
|
||||||
|
groundSelect2.setHighSource(1.0)
|
||||||
|
groundSelect2.setThreshold(0.8)
|
||||||
|
groundSelect2.setControlSource(highlandLowlandSelectCache)
|
||||||
|
|
||||||
|
/* caves */
|
||||||
|
|
||||||
|
val caveShape = ModuleFractal()
|
||||||
|
caveShape.setType(ModuleFractal.FractalType.RIDGEMULTI)
|
||||||
|
caveShape.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
||||||
|
caveShape.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
||||||
|
caveShape.setNumOctaves(1)
|
||||||
|
caveShape.setFrequency(params.caveShapeFreq) // TODO adjust the "density" of the caves
|
||||||
|
caveShape.seed = seed shake caveMagic
|
||||||
|
|
||||||
|
val caveAttenuateBias = ModuleBias()
|
||||||
|
caveAttenuateBias.setSource(highlandLowlandSelectCache)
|
||||||
|
caveAttenuateBias.setBias(params.caveAttenuateBias) // TODO (0.5+) adjust the "concentration" of the cave gen. Lower = larger voids
|
||||||
|
|
||||||
|
val caveShapeAttenuate = ModuleCombiner()
|
||||||
|
caveShapeAttenuate.setType(ModuleCombiner.CombinerType.MULT)
|
||||||
|
caveShapeAttenuate.setSource(0, caveShape)
|
||||||
|
caveShapeAttenuate.setSource(1, caveAttenuateBias)
|
||||||
|
|
||||||
|
val cavePerturbFractal = ModuleFractal()
|
||||||
|
cavePerturbFractal.setType(ModuleFractal.FractalType.FBM)
|
||||||
|
cavePerturbFractal.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
||||||
|
cavePerturbFractal.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
||||||
|
cavePerturbFractal.setNumOctaves(6)
|
||||||
|
cavePerturbFractal.setFrequency(3.0)
|
||||||
|
cavePerturbFractal.seed = seed shake cavePerturbMagic
|
||||||
|
|
||||||
|
val cavePerturbScale = ModuleScaleOffset()
|
||||||
|
cavePerturbScale.setSource(cavePerturbFractal)
|
||||||
|
cavePerturbScale.setScale(0.45)
|
||||||
|
cavePerturbScale.setOffset(0.0)
|
||||||
|
|
||||||
|
val cavePerturb = ModuleTranslateDomain()
|
||||||
|
cavePerturb.setSource(caveShapeAttenuate)
|
||||||
|
cavePerturb.setAxisXSource(cavePerturbScale)
|
||||||
|
|
||||||
|
val caveSelect = ModuleSelect()
|
||||||
|
caveSelect.setLowSource(1.0)
|
||||||
|
caveSelect.setHighSource(0.0)
|
||||||
|
caveSelect.setControlSource(cavePerturb)
|
||||||
|
caveSelect.setThreshold(params.caveSelectThre) // TODO also adjust this if you've touched the bias value. Number can be greater than 1.0
|
||||||
|
caveSelect.setFalloff(0.0)
|
||||||
|
|
||||||
|
val caveBlockageFractal = ModuleFractal()
|
||||||
|
caveBlockageFractal.setType(ModuleFractal.FractalType.RIDGEMULTI)
|
||||||
|
caveBlockageFractal.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
||||||
|
caveBlockageFractal.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
||||||
|
caveBlockageFractal.setNumOctaves(2)
|
||||||
|
caveBlockageFractal.setFrequency(params.caveBlockageFractalFreq) // TODO same as caveShape frequency?
|
||||||
|
caveBlockageFractal.seed = seed shake caveBlockageMagic
|
||||||
|
|
||||||
|
// will only close-up deeper caves. Shallow caves will be less likely to be closed up
|
||||||
|
val caveBlockageAttenuate = ModuleCombiner()
|
||||||
|
caveBlockageAttenuate.setType(ModuleCombiner.CombinerType.MULT)
|
||||||
|
caveBlockageAttenuate.setSource(0, caveBlockageFractal)
|
||||||
|
caveBlockageAttenuate.setSource(1, caveAttenuateBias)
|
||||||
|
|
||||||
|
val caveBlockageSelect = ModuleSelect()
|
||||||
|
caveBlockageSelect.setLowSource(0.0)
|
||||||
|
caveBlockageSelect.setHighSource(1.0)
|
||||||
|
caveBlockageSelect.setControlSource(caveBlockageAttenuate)
|
||||||
|
caveBlockageSelect.setThreshold(params.caveBlockageSelectThre) // TODO adjust cave cloing-up strength. Larger = more closing
|
||||||
|
caveBlockageSelect.setFalloff(0.0)
|
||||||
|
|
||||||
|
// note: gradient-multiply DOESN'T generate "naturally cramped" cave entrance
|
||||||
|
|
||||||
|
val caveInMix = ModuleCombiner()
|
||||||
|
caveInMix.setType(ModuleCombiner.CombinerType.ADD)
|
||||||
|
caveInMix.setSource(0, caveSelect)
|
||||||
|
caveInMix.setSource(1, caveBlockageSelect)
|
||||||
|
|
||||||
|
/*val groundCaveMult = ModuleCombiner()
|
||||||
|
groundCaveMult.setType(ModuleCombiner.CombinerType.MULT)
|
||||||
|
groundCaveMult.setSource(0, caveInMix)
|
||||||
|
//groundCaveMult.setSource(0, caveSelect) // disables the cave-in for quick cavegen testing
|
||||||
|
groundCaveMult.setSource(1, groundSelect)*/
|
||||||
|
|
||||||
|
// this noise tree WILL generate noise value greater than 1.0
|
||||||
|
// they should be treated properly when you actually generate the world out of the noisemap
|
||||||
|
// for the visualisation, no treatment will be done in this demo app.
|
||||||
|
|
||||||
|
val groundClamp = ModuleClamp()
|
||||||
|
groundClamp.setRange(0.0, 100.0)
|
||||||
|
groundClamp.setSource(highlandLowlandSelectCache)
|
||||||
|
|
||||||
|
val groundScaling = ModuleScaleDomain()
|
||||||
|
groundScaling.setScaleX(1.0 / params.featureSize) // adjust this value to change features size
|
||||||
|
groundScaling.setScaleY(1.0 / params.featureSize)
|
||||||
|
groundScaling.setScaleZ(1.0 / params.featureSize)
|
||||||
|
groundScaling.setSource(groundClamp)
|
||||||
|
|
||||||
|
|
||||||
|
val caveClamp = ModuleClamp()
|
||||||
|
caveClamp.setRange(0.0, 1.0)
|
||||||
|
caveClamp.setSource(caveInMix)
|
||||||
|
|
||||||
|
val caveScaling = ModuleScaleDomain()
|
||||||
|
caveScaling.setScaleX(1.0 / params.featureSize) // adjust this value to change features size
|
||||||
|
caveScaling.setScaleY(1.0 / params.featureSize)
|
||||||
|
caveScaling.setScaleZ(1.0 / params.featureSize)
|
||||||
|
caveScaling.setSource(caveClamp)
|
||||||
|
|
||||||
|
//return Joise(caveInMix)
|
||||||
|
return listOf(
|
||||||
|
Joise(groundScaling),
|
||||||
|
Joise(caveScaling)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class TerragenParams(
|
||||||
|
val featureSize: Double = 333.0,
|
||||||
|
val lowlandScaleOffset: Double = -0.65, // linearly alters the height
|
||||||
|
val highlandScaleOffset: Double = -0.2, // linearly alters the height
|
||||||
|
val mountainScaleOffset: Double = -0.1, // linearly alters the height
|
||||||
|
val mountainDisturbance: Double = 0.7, // greater = more distortion, overhangs
|
||||||
|
val caveShapeFreq: Double = 7.4, //adjust the "density" of the caves
|
||||||
|
val caveAttenuateBias: Double = 0.90, // adjust the "concentration" of the cave gen. Lower = larger voids
|
||||||
|
val caveSelectThre: Double = 0.89, // also adjust this if you've touched the bias value. Number can be greater than 1.0
|
||||||
|
val caveBlockageFractalFreq: Double = 8.88,
|
||||||
|
val caveBlockageSelectThre: Double = 1.40 // adjust cave cloing-up strength. Larger = more closing
|
||||||
|
)
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package net.torvald.terrarum.modulebasegame.worldgenerator
|
||||||
|
|
||||||
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New world generator.
|
||||||
|
*
|
||||||
|
* Created by minjaesong on 2019-09-02.
|
||||||
|
*/
|
||||||
|
object Worldgen {
|
||||||
|
|
||||||
|
operator fun invoke(worldIndex: Int, params: WorldgenParams) {
|
||||||
|
|
||||||
|
val world = GameWorld(worldIndex, params.width, params.height, System.currentTimeMillis() / 1000, System.currentTimeMillis() / 1000, 0)
|
||||||
|
|
||||||
|
val jobs = listOf(
|
||||||
|
Work("Reticulating Splines") { Terragen(world, params.seed, params.terragenParams) },
|
||||||
|
Work("Adding Vegetations") { Biomegen(world, params.seed, params.biomegenParams) }
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class Work(val loadingScreenName: String, val theWork: () -> Unit)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Gen {
|
||||||
|
var generationStarted: Boolean
|
||||||
|
val generationDone: Boolean
|
||||||
|
operator fun invoke(world: GameWorld, seed: Long, params: Any)
|
||||||
|
}
|
||||||
|
|
||||||
|
data class WorldgenParams(
|
||||||
|
val width: Int,
|
||||||
|
val height: Int,
|
||||||
|
val seed: Long,
|
||||||
|
// optional parametres
|
||||||
|
val terragenParams: TerragenParams = TerragenParams(),
|
||||||
|
val biomegenParams: BiomegenParams = BiomegenParams()
|
||||||
|
)
|
||||||
|
|
||||||
|
infix fun Long.shake(other: Long): Long {
|
||||||
|
var s0 = this
|
||||||
|
var s1 = other
|
||||||
|
|
||||||
|
s1 = s1 xor s0
|
||||||
|
s0 = s0 shl 55 or s0.ushr(9) xor s1 xor (s1 shl 14)
|
||||||
|
s1 = s1 shl 36 or s1.ushr(28)
|
||||||
|
|
||||||
|
return s0 + s1
|
||||||
|
}
|
||||||
|
|
||||||
|
val TWO_PI = Math.PI * 2.0
|
||||||
@@ -19,6 +19,9 @@ import net.torvald.terrarum.concurrent.ThreadParallel
|
|||||||
import net.torvald.terrarum.concurrent.mapToThreadPoolDirectly
|
import net.torvald.terrarum.concurrent.mapToThreadPoolDirectly
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import net.torvald.terrarum.inUse
|
import net.torvald.terrarum.inUse
|
||||||
|
import net.torvald.terrarum.modulebasegame.worldgenerator.BiomegenParams
|
||||||
|
import net.torvald.terrarum.modulebasegame.worldgenerator.TerragenParams
|
||||||
|
import net.torvald.terrarum.modulebasegame.worldgenerator.shake
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
@@ -115,7 +118,7 @@ class WorldgenNoiseSandbox : ApplicationAdapter() {
|
|||||||
private val NOISE_MAKER = AccidentalCave
|
private val NOISE_MAKER = AccidentalCave
|
||||||
|
|
||||||
private fun getNoiseGenerator(SEED: Long): List<Joise> {
|
private fun getNoiseGenerator(SEED: Long): List<Joise> {
|
||||||
return NOISE_MAKER.getGenerator(SEED)
|
return NOISE_MAKER.getGenerator(SEED, TerragenParams())
|
||||||
}
|
}
|
||||||
|
|
||||||
val colourNull = Color(0x1b3281ff)
|
val colourNull = Color(0x1b3281ff)
|
||||||
@@ -167,7 +170,7 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
interface NoiseMaker {
|
interface NoiseMaker {
|
||||||
fun draw(x: Int, y: Int, noiseValue: List<Double>, outTex: Pixmap)
|
fun draw(x: Int, y: Int, noiseValue: List<Double>, outTex: Pixmap)
|
||||||
fun getGenerator(seed: Long): List<Joise>
|
fun getGenerator(seed: Long, params: Any): List<Joise>
|
||||||
}
|
}
|
||||||
|
|
||||||
object BiomeMaker : NoiseMaker {
|
object BiomeMaker : NoiseMaker {
|
||||||
@@ -181,7 +184,8 @@ object BiomeMaker : NoiseMaker {
|
|||||||
outTex.drawPixel(x, y)
|
outTex.drawPixel(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGenerator(seed: Long): List<Joise> {
|
override fun getGenerator(seed: Long, params: Any): List<Joise> {
|
||||||
|
val params = params as BiomegenParams
|
||||||
//val biome = ModuleBasisFunction()
|
//val biome = ModuleBasisFunction()
|
||||||
//biome.setType(ModuleBasisFunction.BasisType.SIMPLEX)
|
//biome.setType(ModuleBasisFunction.BasisType.SIMPLEX)
|
||||||
|
|
||||||
@@ -199,9 +203,9 @@ object BiomeMaker : NoiseMaker {
|
|||||||
|
|
||||||
val scale = ModuleScaleDomain()
|
val scale = ModuleScaleDomain()
|
||||||
scale.setSource(autocorrect)
|
scale.setSource(autocorrect)
|
||||||
scale.setScaleX(1.0 / 80.0) // adjust this value to change features size
|
scale.setScaleX(1.0 / params.featureSize) // adjust this value to change features size
|
||||||
scale.setScaleY(1.0 / 80.0)
|
scale.setScaleY(1.0 / params.featureSize)
|
||||||
scale.setScaleZ(1.0 / 80.0)
|
scale.setScaleZ(1.0 / params.featureSize)
|
||||||
|
|
||||||
val last = scale
|
val last = scale
|
||||||
|
|
||||||
@@ -269,7 +273,9 @@ object AccidentalCave : NoiseMaker {
|
|||||||
outTex.drawPixel(x, y)
|
outTex.drawPixel(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGenerator(seed: Long): List<Joise> {
|
override fun getGenerator(seed: Long, params: Any): List<Joise> {
|
||||||
|
val params = params as TerragenParams
|
||||||
|
|
||||||
val lowlandMagic: Long = 0x41A21A114DBE56 // Maria Lindberg
|
val lowlandMagic: Long = 0x41A21A114DBE56 // Maria Lindberg
|
||||||
val highlandMagic: Long = 0x0114E091 // Olive Oyl
|
val highlandMagic: Long = 0x0114E091 // Olive Oyl
|
||||||
val mountainMagic: Long = 0x115AA4DE2504 // Lisa Anderson
|
val mountainMagic: Long = 0x115AA4DE2504 // Lisa Anderson
|
||||||
@@ -300,7 +306,7 @@ object AccidentalCave : NoiseMaker {
|
|||||||
|
|
||||||
val lowlandScale = ModuleScaleOffset()
|
val lowlandScale = ModuleScaleOffset()
|
||||||
lowlandScale.setScale(0.125)
|
lowlandScale.setScale(0.125)
|
||||||
lowlandScale.setOffset(-0.65) // TODO linearly alters the height
|
lowlandScale.setOffset(params.lowlandScaleOffset) // TODO linearly alters the height
|
||||||
|
|
||||||
val lowlandYScale = ModuleScaleDomain()
|
val lowlandYScale = ModuleScaleDomain()
|
||||||
lowlandYScale.setSource(lowlandScale)
|
lowlandYScale.setSource(lowlandScale)
|
||||||
@@ -328,7 +334,7 @@ object AccidentalCave : NoiseMaker {
|
|||||||
val highlandScale = ModuleScaleOffset()
|
val highlandScale = ModuleScaleOffset()
|
||||||
highlandScale.setSource(highlandAutocorrect)
|
highlandScale.setSource(highlandAutocorrect)
|
||||||
highlandScale.setScale(0.25)
|
highlandScale.setScale(0.25)
|
||||||
highlandScale.setOffset(-0.2) // TODO linearly alters the height
|
highlandScale.setOffset(params.highlandScaleOffset) // TODO linearly alters the height
|
||||||
|
|
||||||
val highlandYScale = ModuleScaleDomain()
|
val highlandYScale = ModuleScaleDomain()
|
||||||
highlandYScale.setSource(highlandScale)
|
highlandYScale.setSource(highlandScale)
|
||||||
@@ -355,11 +361,11 @@ object AccidentalCave : NoiseMaker {
|
|||||||
val mountainScale = ModuleScaleOffset()
|
val mountainScale = ModuleScaleOffset()
|
||||||
mountainScale.setSource(mountainAutocorrect)
|
mountainScale.setSource(mountainAutocorrect)
|
||||||
mountainScale.setScale(0.45)
|
mountainScale.setScale(0.45)
|
||||||
mountainScale.setOffset(-0.1) // TODO linearly alters the height
|
mountainScale.setOffset(params.mountainScaleOffset) // TODO linearly alters the height
|
||||||
|
|
||||||
val mountainYScale = ModuleScaleDomain()
|
val mountainYScale = ModuleScaleDomain()
|
||||||
mountainYScale.setSource(mountainScale)
|
mountainYScale.setSource(mountainScale)
|
||||||
mountainYScale.setScaleY(0.7) // greater = more distortion, overhangs
|
mountainYScale.setScaleY(params.mountainDisturbance) // greater = more distortion, overhangs
|
||||||
|
|
||||||
val mountainTerrain = ModuleTranslateDomain()
|
val mountainTerrain = ModuleTranslateDomain()
|
||||||
mountainTerrain.setSource(groundGradient)
|
mountainTerrain.setSource(groundGradient)
|
||||||
@@ -423,12 +429,12 @@ object AccidentalCave : NoiseMaker {
|
|||||||
caveShape.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
caveShape.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
||||||
caveShape.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
caveShape.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
||||||
caveShape.setNumOctaves(1)
|
caveShape.setNumOctaves(1)
|
||||||
caveShape.setFrequency(7.4) // TODO adjust the "density" of the caves
|
caveShape.setFrequency(params.caveShapeFreq) // TODO adjust the "density" of the caves
|
||||||
caveShape.seed = seed shake caveMagic
|
caveShape.seed = seed shake caveMagic
|
||||||
|
|
||||||
val caveAttenuateBias = ModuleBias()
|
val caveAttenuateBias = ModuleBias()
|
||||||
caveAttenuateBias.setSource(highlandLowlandSelectCache)
|
caveAttenuateBias.setSource(highlandLowlandSelectCache)
|
||||||
caveAttenuateBias.setBias(0.90) // TODO (0.5+) adjust the "concentration" of the cave gen. Lower = larger voids
|
caveAttenuateBias.setBias(params.caveAttenuateBias) // TODO (0.5+) adjust the "concentration" of the cave gen. Lower = larger voids
|
||||||
|
|
||||||
val caveShapeAttenuate = ModuleCombiner()
|
val caveShapeAttenuate = ModuleCombiner()
|
||||||
caveShapeAttenuate.setType(ModuleCombiner.CombinerType.MULT)
|
caveShapeAttenuate.setType(ModuleCombiner.CombinerType.MULT)
|
||||||
@@ -456,7 +462,7 @@ object AccidentalCave : NoiseMaker {
|
|||||||
caveSelect.setLowSource(1.0)
|
caveSelect.setLowSource(1.0)
|
||||||
caveSelect.setHighSource(0.0)
|
caveSelect.setHighSource(0.0)
|
||||||
caveSelect.setControlSource(cavePerturb)
|
caveSelect.setControlSource(cavePerturb)
|
||||||
caveSelect.setThreshold(0.89) // TODO also adjust this if you've touched the bias value. Number can be greater than 1.0
|
caveSelect.setThreshold(params.caveSelectThre) // TODO also adjust this if you've touched the bias value. Number can be greater than 1.0
|
||||||
caveSelect.setFalloff(0.0)
|
caveSelect.setFalloff(0.0)
|
||||||
|
|
||||||
val caveBlockageFractal = ModuleFractal()
|
val caveBlockageFractal = ModuleFractal()
|
||||||
@@ -464,7 +470,7 @@ object AccidentalCave : NoiseMaker {
|
|||||||
caveBlockageFractal.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
caveBlockageFractal.setAllSourceBasisTypes(ModuleBasisFunction.BasisType.GRADIENT)
|
||||||
caveBlockageFractal.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
caveBlockageFractal.setAllSourceInterpolationTypes(ModuleBasisFunction.InterpolationType.QUINTIC)
|
||||||
caveBlockageFractal.setNumOctaves(2)
|
caveBlockageFractal.setNumOctaves(2)
|
||||||
caveBlockageFractal.setFrequency(8.88) // TODO same as caveShape frequency?
|
caveBlockageFractal.setFrequency(params.caveBlockageFractalFreq) // TODO same as caveShape frequency?
|
||||||
caveBlockageFractal.seed = seed shake caveBlockageMagic
|
caveBlockageFractal.seed = seed shake caveBlockageMagic
|
||||||
|
|
||||||
// will only close-up deeper caves. Shallow caves will be less likely to be closed up
|
// will only close-up deeper caves. Shallow caves will be less likely to be closed up
|
||||||
@@ -477,7 +483,7 @@ object AccidentalCave : NoiseMaker {
|
|||||||
caveBlockageSelect.setLowSource(0.0)
|
caveBlockageSelect.setLowSource(0.0)
|
||||||
caveBlockageSelect.setHighSource(1.0)
|
caveBlockageSelect.setHighSource(1.0)
|
||||||
caveBlockageSelect.setControlSource(caveBlockageAttenuate)
|
caveBlockageSelect.setControlSource(caveBlockageAttenuate)
|
||||||
caveBlockageSelect.setThreshold(1.40) // TODO adjust cave cloing-up strength. Larger = more closing
|
caveBlockageSelect.setThreshold(params.caveBlockageSelectThre) // TODO adjust cave cloing-up strength. Larger = more closing
|
||||||
caveBlockageSelect.setFalloff(0.0)
|
caveBlockageSelect.setFalloff(0.0)
|
||||||
|
|
||||||
// note: gradient-multiply DOESN'T generate "naturally cramped" cave entrance
|
// note: gradient-multiply DOESN'T generate "naturally cramped" cave entrance
|
||||||
@@ -502,9 +508,9 @@ object AccidentalCave : NoiseMaker {
|
|||||||
groundClamp.setSource(highlandLowlandSelectCache)
|
groundClamp.setSource(highlandLowlandSelectCache)
|
||||||
|
|
||||||
val groundScaling = ModuleScaleDomain()
|
val groundScaling = ModuleScaleDomain()
|
||||||
groundScaling.setScaleX(1.0 / 333.0) // adjust this value to change features size
|
groundScaling.setScaleX(1.0 / params.featureSize) // adjust this value to change features size
|
||||||
groundScaling.setScaleY(1.0 / 333.0)
|
groundScaling.setScaleY(1.0 / params.featureSize)
|
||||||
groundScaling.setScaleZ(1.0 / 333.0)
|
groundScaling.setScaleZ(1.0 / params.featureSize)
|
||||||
groundScaling.setSource(groundClamp)
|
groundScaling.setSource(groundClamp)
|
||||||
|
|
||||||
|
|
||||||
@@ -513,9 +519,9 @@ object AccidentalCave : NoiseMaker {
|
|||||||
caveClamp.setSource(caveInMix)
|
caveClamp.setSource(caveInMix)
|
||||||
|
|
||||||
val caveScaling = ModuleScaleDomain()
|
val caveScaling = ModuleScaleDomain()
|
||||||
caveScaling.setScaleX(1.0 / 333.0) // adjust this value to change features size
|
caveScaling.setScaleX(1.0 / params.featureSize) // adjust this value to change features size
|
||||||
caveScaling.setScaleY(1.0 / 333.0)
|
caveScaling.setScaleY(1.0 / params.featureSize)
|
||||||
caveScaling.setScaleZ(1.0 / 333.0)
|
caveScaling.setScaleZ(1.0 / params.featureSize)
|
||||||
caveScaling.setSource(caveClamp)
|
caveScaling.setSource(caveClamp)
|
||||||
|
|
||||||
//return Joise(caveInMix)
|
//return Joise(caveInMix)
|
||||||
@@ -528,7 +534,7 @@ object AccidentalCave : NoiseMaker {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
infix fun Long.shake(other: Long): Long {
|
/*infix fun Long.shake(other: Long): Long {
|
||||||
var s0 = this
|
var s0 = this
|
||||||
var s1 = other
|
var s1 = other
|
||||||
|
|
||||||
@@ -537,4 +543,4 @@ infix fun Long.shake(other: Long): Long {
|
|||||||
s1 = s1 shl 36 or s1.ushr(28)
|
s1 = s1 shl 36 or s1.ushr(28)
|
||||||
|
|
||||||
return s0 + s1
|
return s0 + s1
|
||||||
}
|
}*/
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<module type="JAVA_MODULE" version="4">
|
<module type="JAVA_MODULE" version="4">
|
||||||
<component name="FacetManager">
|
<component name="FacetManager">
|
||||||
<facet type="kotlin-language" name="Kotlin">
|
<facet type="kotlin-language" name="Kotlin">
|
||||||
<configuration version="3" platform="JVM 12">
|
<configuration version="3" platform="JVM 12" allPlatforms="JVM [12]">
|
||||||
<compilerSettings />
|
<compilerSettings />
|
||||||
<compilerArguments>
|
<compilerArguments>
|
||||||
<option name="jvmTarget" value="12" />
|
<option name="jvmTarget" value="12" />
|
||||||
|
|||||||
Reference in New Issue
Block a user