Compare commits

..

1 Commits

Author SHA1 Message Date
Mikal 968746f988 Merge fb0dbda296 into 8366a5288b 2025-03-20 11:02:05 -04:00
455 changed files with 11602 additions and 5239 deletions
+1 -2
View File
@@ -44,7 +44,6 @@ You must put an x in all the boxes that it applies to. (Like this: [x])
<!-- There is an included `.editorconfig` file in the base of the repo. Please use a plugin for your IDE of choice that follows those settings. -->
- [ ] I have read the [`CONTRIBUTING.md`](https://github.com/PolyhedralDev/Terra/blob/master/CONTRIBUTING.md)
document in the root of the git repository.
- [ ] LLM-based tools were not used to create this PR. (ChatGPT, Claude, etc)
#### Types of changes
@@ -99,7 +98,7 @@ You must put an x in all the boxes that it applies to. (Like this: [x])
- [ ] I am not the original author of this code, but it is in public domain or
released under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) or a compatible license.
<!--
Please provide reliable evidence of this. LLM-generated code does not satisfy this requirement.
Please provide reliable evidence of this.
NOTE: for compatible licenses, you must make sure to add the included license somewhere in the program, if so required.
(And even if it's not required, it's still nice to do it. Also add attribution somewhere.)
-->
+4 -4
View File
@@ -17,16 +17,16 @@ jobs:
contents: read
steps:
- uses: actions/checkout@v4.2.2
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- name: Set up JDK 21
uses: actions/setup-java@v4.7.1
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
with:
java-version: '21'
distribution: 'temurin'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- uses: burrunan/gradle-cache-action@v3.0.1
- uses: burrunan/gradle-cache-action@03c71a8ba93d670980695505f48f49daf43704a6
name: Build Terra
with:
# Specifies arguments for Gradle execution
@@ -44,4 +44,4 @@ jobs:
# Properties are passed as -Pname=value
properties: |
kotlin.js.compiler=ir
kotlin.parallel.tasks.in.project=true
kotlin.parallel.tasks.in.project=true
+2 -5
View File
@@ -258,9 +258,6 @@ as [GitHub Pull Requests](https://guides.github.com/activities/forking/#making-a
see instead** and why.
- **Explain why this enhancement would be useful** to most Terra users and isn't
something that can or should be implemented as an addon.
- **Do not use LLM/"AI" tools to create your pull request.** Your pr should be written
by you. Using an LLM to automate small, tedious tasks (regex and other fiddly things like it)
is acceptable, but submitting a low-effort, completely LLM-generated PR will result in a ban.
## Styleguides
@@ -384,7 +381,7 @@ compatibilities are welcome and encouraged, in the form of addons.**
### Platform-Agnostic Design
Terra must, at all times, remain platform-agnostic. This means it must be able
Terra must, at all times, remain platform agnostic. This means it must be able
to run on theoretically any voxel based platform. Including non-minecraft games
like Terasology.
@@ -394,7 +391,7 @@ it'll be running on.
Examples:
- Don't assume the world height is 256.
- Don't assume that a specific block, item, or entity exists. (E.g. don't assume
- Don't assume that a specific block, item, or entity exists. (Eg. don't assume
there exists a block called `minecraft:grass_block`)
### Data-Driven
Vendored
-149
View File
@@ -1,149 +0,0 @@
pipeline {
agent any
tools {
jdk "Temurin Java 21"
}
triggers {
githubPush()
}
environment {
DISCORD_WEBHOOK_URL = credentials('polydev-discord-webhook-url')
}
stages {
stage('Checkout') {
steps {
scmSkip(deleteBuild: true)
}
}
stage('Setup Gradle') {
steps {
sh 'chmod +x gradlew'
}
}
stage('Build') {
steps {
withGradle {
sh './gradlew build --rerun-tasks -x check'
sh './gradlew javadoc'
}
}
post {
success {
archiveArtifacts artifacts: 'platforms/fabric/build/libs/Terra-fabric*.jar,platforms/bukkit/build/libs/Terra-bukkit*-shaded.jar,platforms/allay/build/libs/Terra-allay*.jar,platforms/minestom/build/libs/Terra-minestom*.jar', fingerprint: true, onlyIfSuccessful: true
javadoc javadocDir: 'common/api/build/docs/javadoc', keepAll: true
}
}
}
stage('Tests') {
steps {
withGradle {
sh './gradlew test --rerun-tasks'
}
}
}
// stage('Deploy to snapshots repositories') {
// when {
// allOf {
// not { buildingTag() }
// not { expression { env.TAG_NAME != null && env.TAG_NAME.matches('v\\d+\\.\\d+\\.\\d+') } }
// }
// }
//
// steps {
// withCredentials([
// string(credentialsId: 'maven-signing-key', variable: 'ORG_GRADLE_PROJECT_signingKey'),
// string(credentialsId: 'maven-signing-key-password', variable: 'ORG_GRADLE_PROJECT_signingPassword'),
// usernamePassword(
// credentialsId: 'solo-studios-maven',
// passwordVariable: 'ORG_GRADLE_PROJECT_SoloStudiosSnapshotsPassword',
// usernameVariable: 'ORG_GRADLE_PROJECT_SoloStudiosSnapshotsUsername'
// )
// ]) {
// withGradle {
// sh './gradlew publishAllPublicationsToSoloStudiosSnapshotsRepository'
// }
// }
// }
// }
stage('Deploy to releases repositories') {
// when {
// allOf {
// buildingTag()
// expression { env.TAG_NAME != null && env.TAG_NAME.matches('v\\d+\\.\\d+\\.\\d+') }
// }
// }
steps {
withCredentials([
string(credentialsId: 'maven-signing-key', variable: 'ORG_GRADLE_PROJECT_signingKey'),
string(credentialsId: 'maven-signing-key-password', variable: 'ORG_GRADLE_PROJECT_signingPassword'),
usernamePassword(
credentialsId: 'solo-studios-maven',
passwordVariable: 'ORG_GRADLE_PROJECT_SoloStudiosReleasesPassword',
usernameVariable: 'ORG_GRADLE_PROJECT_SoloStudiosReleasesUsername'
),
// TODO: does not yet exist (uncomment once added)
// usernamePassword(
// credentialsId: 'sonatype-maven-credentials',
// passwordVariable: 'ORG_GRADLE_PROJECT_SonatypePassword',
// usernameVariable: 'ORG_GRADLE_PROJECT_SonatypeUsername'
// ),
// usernamePassword(
// credentialsId: 'codemc-maven-credentials',
// passwordVariable: 'ORG_GRADLE_PROJECT_CodeMCPassword',
// usernameVariable: 'ORG_GRADLE_PROJECT_CodeMCUsername'
// )
]) {
withGradle {
sh './gradlew publish'
//sh './gradlew publishAllPublicationsToSoloStudiosReleasesRepository'
// sh './gradlew publishAllPublicationsToSonatypeRepository'
// sh './gradlew publishAllPublicationsToCodeMCRepository'
}
}
}
}
}
post {
always {
discoverReferenceBuild()
// junit testResults: '**/build/test-results/*/TEST-*.xml'
recordIssues(
aggregatingResults: true,
enabledForFailure: true,
minimumSeverity: 'ERROR',
sourceCodeEncoding: 'UTF-8',
checksAnnotationScope: 'ALL',
sourceCodeRetention: 'LAST_BUILD',
tools: [java(), javaDoc()]
)
discordSend(
title: env.JOB_NAME + ' ' + env.BUILD_DISPLAY_NAME,
showChangeset: true,
enableArtifactsList: true,
link: env.BUILD_URL,
result: currentBuild.currentResult,
customAvatarUrl: 'https://github.com/PolyhedralDev.png',
customUsername: 'Solo Studios Jenkins',
webhookURL: env.DISCORD_WEBHOOK_URL,
)
cleanWs()
}
}
}
+6 -13
View File
@@ -6,12 +6,6 @@ plugins {
repositories {
mavenCentral()
gradlePluginPortal()
maven("https://maven.solo-studios.ca/releases") {
name = "Solo Studios"
}
maven("https://maven.solo-studios.ca/snapshots") {
name = "Solo Studios"
}
maven("https://repo.codemc.org/repository/maven-public") {
name = "CodeMC"
}
@@ -22,11 +16,10 @@ repositories {
dependencies {
//TODO Allow pulling from Versions.kt
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.9")
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.18")
implementation("org.ow2.asm", "asm", "9.9")
implementation("org.ow2.asm", "asm-tree", "9.9")
implementation("com.dfsek.tectonic", "common", "4.3.1")
implementation("org.yaml", "snakeyaml", "2.5")
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1")
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:2.0.0-beta.16")
implementation("org.ow2.asm", "asm", "9.7")
implementation("org.ow2.asm", "asm-tree", "9.7")
implementation("com.dfsek.tectonic", "common", "4.2.1")
implementation("org.yaml", "snakeyaml", "2.3")
}
@@ -13,7 +13,6 @@ import org.gradle.kotlin.dsl.getByName
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.withType
import org.gradle.language.jvm.tasks.ProcessResources
import org.gradle.plugins.ide.idea.model.IdeaModel
fun Project.configureCompilation() {
apply(plugin = "maven-publish")
@@ -22,13 +21,6 @@ fun Project.configureCompilation() {
apply(plugin = "idea")
apply<TectonicDocPlugin>()
configure<IdeaModel> {
module {
isDownloadJavadoc = true
isDownloadSources = true
}
}
configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
+10 -10
View File
@@ -30,12 +30,6 @@ fun Project.configureDependencies() {
repositories {
mavenCentral()
gradlePluginPortal()
maven("https://maven.solo-studios.ca/releases") {
name = "Solo Studios"
}
maven("https://maven.solo-studios.ca/snapshots") {
name = "Solo Studios"
}
maven("https://maven.fabricmc.net/") {
name = "FabricMC"
}
@@ -57,14 +51,20 @@ fun Project.configureDependencies() {
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") {
name = "Sonatype Snapshots"
}
maven("https://repo.onarandombox.com/multiverse-releases") {
name = "onarandombox"
maven("https://repo.opencollab.dev/maven-releases/") {
name = "OpenCollab Releases"
}
maven("https://repo.opencollab.dev/maven-snapshots/") {
name = "OpenCollab Snapshots"
}
maven("https://storehouse.okaeri.eu/repository/maven-public/") {
name = "Okaeri"
}
}
dependencies {
testImplementation("org.junit.jupiter", "junit-jupiter", Versions.Libraries.Internal.junit)
"testRuntimeOnly"("org.junit.platform", "junit-platform-launcher")
testImplementation("org.junit.jupiter", "junit-jupiter-api", Versions.Libraries.Internal.junit)
testImplementation("org.junit.jupiter", "junit-jupiter-engine", Versions.Libraries.Internal.junit)
compileOnly("org.jetbrains", "annotations", Versions.Libraries.Internal.jetBrainsAnnotations)
compileOnly("com.google.guava", "guava", Versions.Libraries.Internal.guava)
+5 -24
View File
@@ -49,21 +49,10 @@ fun Project.configureDistribution() {
doFirst {
try {
file("${buildDir}/resources/main/packs/").deleteRecursively()
file("${buildDir}/resources/main/metapacks/").deleteRecursively()
val overworldPackUrl =
URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/" + Versions.Terra.overworldConfig + "/Overworld.zip")
val reimagENDPackUrl =
URL("https://github.com/PolyhedralDev/ReimagEND/releases/download/" + Versions.Terra.reimagENDConfig + "/ReimagEND.zip")
val tartarusPackUrl =
URL("https://github.com/PolyhedralDev/Tartarus/releases/download/" + Versions.Terra.tartarusConfig + "/Tartarus.zip")
val defaultPackUrl =
URL("https://github.com/PolyhedralDev/DefaultMetapack/releases/download/" + Versions.Terra.defaultConfig + "/default.zip")
downloadPack(overworldPackUrl, project)
downloadPack(reimagENDPackUrl, project)
downloadPack(tartarusPackUrl, project)
downloadPack(defaultPackUrl, project, true)
} catch (_: Exception) {
}
URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/" + Versions.Terra.overworldConfig + "/default.zip")
downloadPack(defaultPackUrl, project)
} catch (_:Exception) {}
}
}
@@ -107,13 +96,6 @@ fun Project.configureDistribution() {
resources.computeIfAbsent("packs") { ArrayList() }.add(it.name)
}
val metaPacksDir = File("${project.buildDir}/resources/main/metapacks/")
metaPacksDir.walkTopDown().forEach {
if (it.isDirectory || !it.name.endsWith(".zip")) return@forEach
resources.computeIfAbsent("metapacks") { ArrayList() }.add(it.name)
}
val langDir = File("${project(":common:implementation").buildDir}/resources/main/lang/")
langDir.walkTopDown().forEach {
@@ -181,10 +163,9 @@ fun Project.configureDistribution() {
}
}
fun downloadPack(packUrl: URL, project: Project, metapack: Boolean = false) {
fun downloadPack(packUrl: URL, project: Project) {
val fileName = packUrl.file.substring(packUrl.file.lastIndexOf("/"))
val resourceType = if (metapack) "metapacks" else "packs"
val file = File("${project.buildDir}/resources/main/${resourceType}/${fileName}")
val file = File("${project.buildDir}/resources/main/packs/${fileName}")
file.parentFile.mkdirs()
file.outputStream().write(packUrl.readBytes())
}
+6 -7
View File
@@ -16,17 +16,16 @@ fun Project.configurePublishing() {
}
repositories {
val mavenUrl = "https://maven.solo-studios.ca/releases/"
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
//val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
maven(mavenUrl) {
val SoloStudiosReleasesUsername: String? by project
val SoloStudiosReleasesPassword: String? by project
if (SoloStudiosReleasesUsername != null && SoloStudiosReleasesPassword != null) {
val mavenUsername: String? by project
val mavenPassword: String? by project
if (mavenUsername != null && mavenPassword != null) {
credentials {
username = SoloStudiosReleasesUsername
password = SoloStudiosReleasesPassword
username = mavenUsername
password = mavenPassword
}
}
}
+32 -45
View File
@@ -1,39 +1,35 @@
object Versions {
object Terra {
const val overworldConfig = "latest"
const val reimagENDConfig = "latest"
const val tartarusConfig = "latest"
const val defaultConfig = "latest"
const val overworldConfig = "v1.3.4"
}
object Libraries {
const val tectonic = "4.3.1"
const val paralithic = "2.0.1"
const val tectonic = "4.2.1"
const val paralithic = "0.8.1"
const val strata = "1.3.2"
const val seismic = "2.5.7"
const val cloud = "2.0.0"
const val caffeine = "3.2.2"
const val caffeine = "3.1.8"
const val slf4j = "2.0.16"
const val slf4j = "2.0.17"
object Internal {
const val shadow = "8.3.9"
const val apacheText = "1.14.0"
const val apacheIO = "2.20.0"
const val guava = "33.5.0-jre"
const val asm = "9.9"
const val snakeYml = "2.5"
const val jetBrainsAnnotations = "26.0.2-1"
const val junit = "6.0.0"
const val shadow = "8.3.3"
const val apacheText = "1.12.0"
const val apacheIO = "2.17.0"
const val guava = "33.3.1-jre"
const val asm = "9.7.1"
const val snakeYml = "2.3"
const val jetBrainsAnnotations = "26.0.1"
const val junit = "5.11.3"
const val nbt = "6.1"
}
}
object Fabric {
const val fabricAPI = "0.134.1+${Mod.minecraft}"
const val cloud = "2.0.0-beta.13"
const val fabricAPI = "0.118.0+${Mod.minecraft}"
const val cloud = "2.0.0-beta.9"
}
//
// object Quilt {
@@ -42,15 +38,14 @@ object Versions {
// }
object Mod {
const val mixin = "0.16.4+mixin.0.8.7"
const val mixinExtras = "0.5.0"
const val mixin = "0.15.3+mixin.0.8.7"
const val minecraft = "1.21.10"
const val yarn = "$minecraft+build.1"
const val fabricLoader = "0.18.2"
const val minecraft = "1.21.4"
const val yarn = "$minecraft+build.8"
const val fabricLoader = "0.16.10"
const val architecuryLoom = "1.11.451"
const val architecturyPlugin = "3.4.162"
const val architecuryLoom = "1.9.428"
const val architecturyPlugin = "3.4.161"
}
//
@@ -60,20 +55,18 @@ object Versions {
// }
object Bukkit {
const val minecraft = "1.21.10"
const val nms = "$minecraft-R0.1"
const val paperBuild = "$nms-20251012.013929-7"
const val minecraft = "1.21.4"
const val paperBuild = "$minecraft-R0.1-20250317.101324-208"
const val paper = paperBuild
const val paperLib = "1.0.8"
const val reflectionRemapper = "0.1.3"
const val reflectionRemapper = "0.1.1"
const val paperDevBundle = paperBuild
const val runPaper = "2.3.1"
const val paperWeight = "2.0.0-beta.19"
const val cloud = "2.0.0-beta.12"
const val multiverse = "5.3.0"
const val paperWeight = "2.0.0-beta.16"
const val cloud = "2.0.0-beta.10"
}
//
//
// object Sponge {
// const val sponge = "9.0.0-SNAPSHOT"
// const val mixin = "0.8.2"
@@ -81,21 +74,15 @@ object Versions {
// }
//
object CLI {
const val logback = "1.5.19"
const val picocli = "4.7.7"
const val logback = "1.5.8"
const val picocli = "4.7.6"
}
object Allay {
const val api = "0.20.0"
const val gson = "2.13.2"
const val mappings = "366baa6"
const val mappingsGenerator = "e957088"
const val mcmeta = "c976eb3"
const val api = "0.1.3"
}
object Minestom {
const val minestom = "2025.10.04-1.21.8"
const val minestom = "187931e50b"
}
}
@@ -46,6 +46,6 @@ class BaseBiomeColumn implements Column<Biome> {
@Override
public Biome get(int y) {
return biomeProvider.pipeline.extrude(base, x, y, z, seed);
return biomeProvider.extrude(base, x, y, z, seed);
}
}
@@ -6,33 +6,37 @@ import java.util.Set;
import java.util.stream.Collectors;
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
import com.dfsek.terra.addons.biome.extrusion.utils.ExtrusionPipeline;
import com.dfsek.terra.addons.biome.extrusion.utils.ExtrusionPipelineFactory;
import com.dfsek.terra.api.util.Column;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomeExtrusionProvider implements BiomeProvider {
public final ExtrusionPipeline pipeline;
private final BiomeProvider delegate;
private final Set<Biome> biomes;
private final List<Extrusion> extrusions;
private final int resolution;
public BiomeExtrusionProvider(BiomeProvider delegate, List<Extrusion> extrusions, int resolution) {
this.delegate = delegate;
this.biomes = delegate.stream().collect(Collectors.toSet());
extrusions.forEach(e -> biomes.addAll(e.getBiomes()));
this.pipeline = ExtrusionPipelineFactory.create(extrusions);
this.extrusions = extrusions;
this.resolution = resolution;
}
@Override
public Biome getBiome(int x, int y, int z, long seed) {
Biome delegated = delegate.getBiome(x, y, z, seed);
return pipeline.extrude(delegated, x, y, z, seed);
return extrude(delegated, x, y, z, seed);
}
public Biome extrude(Biome original, int x, int y, int z, long seed) {
for(Extrusion extrusion : extrusions) {
original = extrusion.extrude(original, x, y, z, seed);
}
return original;
}
@Override
@@ -60,4 +64,4 @@ public class BiomeExtrusionProvider implements BiomeProvider {
public BiomeProvider getDelegate() {
return delegate;
}
}
}
@@ -1,17 +1,17 @@
package com.dfsek.terra.addons.biome.extrusion.config.extrusions;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.Range;
public abstract class SamplerExtrusionTemplate implements ObjectTemplate<Extrusion> {
@Value("sampler")
protected @Meta Sampler sampler;
protected @Meta NoiseSampler sampler;
@Value("range")
protected @Meta Range range;
@@ -1,7 +1,5 @@
package com.dfsek.terra.addons.biome.extrusion.extrusions;
import com.dfsek.seismic.type.sampler.Sampler;
import java.util.Collection;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -9,9 +7,9 @@ import java.util.stream.Collectors;
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
import com.dfsek.terra.addons.biome.query.api.BiomeQueries;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.util.collection.TriStateIntCache;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.world.biome.Biome;
@@ -19,42 +17,26 @@ import com.dfsek.terra.api.world.biome.Biome;
* Sets biomes at locations based on a sampler.
*/
public class ReplaceExtrusion implements Extrusion {
private final Sampler sampler;
private final Range range;
private final ProbabilityCollection<ReplaceableBiome> biomes;
private final Predicate<Biome> hasTag;
private final TriStateIntCache cache;
private final NoiseSampler sampler;
public ReplaceExtrusion(Sampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes, String tag) {
private final Range range;
private final ProbabilityCollection<ReplaceableBiome> biomes;
private final Predicate<Biome> hasTag;
public ReplaceExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes, String tag) {
this.sampler = sampler;
this.range = range;
this.biomes = biomes;
this.hasTag = BiomeQueries.has(tag);
this.cache = new TriStateIntCache(Biome.INT_ID_COUNTER.get());
}
@Override
public Biome extrude(Biome original, int x, int y, int z, long seed) {
int id = original.getIntID();
long state = cache.get(id);
boolean passes;
if(state == TriStateIntCache.STATE_UNSET) {
// Only run the test if unset in cache
passes = hasTag.test(original);
cache.set(id, passes);
} else {
// Read the primitive long directly
passes = (state == TriStateIntCache.STATE_TRUE);
if(hasTag.test(original)) {
return range.ifInRange(y, () -> biomes.get(sampler, x, y, z, seed).get(original), original);
}
if(passes) {
if(range.isInRange(y)) {
return biomes.get(sampler, x, y, z, seed).get(original);
}
}
return original;
}
@@ -1,15 +1,14 @@
package com.dfsek.terra.addons.biome.extrusion.extrusions;
import com.dfsek.seismic.type.sampler.Sampler;
import java.util.Collection;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.world.biome.Biome;
@@ -17,13 +16,13 @@ import com.dfsek.terra.api.world.biome.Biome;
* Sets biomes at locations based on a sampler.
*/
public class SetExtrusion implements Extrusion {
private final Sampler sampler;
private final NoiseSampler sampler;
private final Range range;
private final ProbabilityCollection<ReplaceableBiome> biomes;
public SetExtrusion(Sampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes) {
public SetExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes) {
this.sampler = sampler;
this.range = range;
this.biomes = biomes;
@@ -1,8 +0,0 @@
package com.dfsek.terra.addons.biome.extrusion.utils;
import com.dfsek.terra.api.world.biome.Biome;
public interface ExtrusionPipeline {
Biome extrude(Biome original, int x, int y, int z, long seed);
}
@@ -1,158 +0,0 @@
package com.dfsek.terra.addons.biome.extrusion.utils;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
import com.dfsek.terra.api.world.biome.Biome;
import static org.objectweb.asm.Opcodes.AALOAD;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ARETURN;
import static org.objectweb.asm.Opcodes.GETFIELD;
import static org.objectweb.asm.Opcodes.ILOAD;
import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
import static org.objectweb.asm.Opcodes.LLOAD;
import static org.objectweb.asm.Opcodes.PUTFIELD;
import static org.objectweb.asm.Opcodes.RETURN;
import static org.objectweb.asm.Opcodes.SIPUSH;
import static org.objectweb.asm.Opcodes.SWAP;
import static org.objectweb.asm.Opcodes.V1_8;
public class ExtrusionPipelineFactory {
private static final AtomicInteger ID_COUNTER = new AtomicInteger(0);
// Type Descriptors
private static final String EXTRUSION_TYPE = Type.getInternalName(Extrusion.class);
private static final String EXTRUSION_DESC = Type.getDescriptor(Extrusion.class);
private static final String BIOME_DESC = Type.getDescriptor(Biome.class);
private static final String PIPELINE_INTERFACE = Type.getInternalName(ExtrusionPipeline.class);
// Method Signature: (Biome, int, int, int, long) -> Biome
private static final String EXTRUDE_SIG = "(" + BIOME_DESC + "IIIJ)" + BIOME_DESC;
public static ExtrusionPipeline create(List<Extrusion> extrusions) {
// Optimization: If empty, return identity
if(extrusions.isEmpty()) {
return (original, x, y, z, seed) -> original;
}
String className = "com/dfsek/terra/addons/biome/extrusion/GeneratedExtrusionPipeline_" + ID_COUNTER.getAndIncrement();
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
// 1. Define Class
cw.visit(V1_8, ACC_PUBLIC | ACC_FINAL, className, null, "java/lang/Object", new String[]{ PIPELINE_INTERFACE });
// 2. Define Fields (e0, e1, e2...)
for(int i = 0; i < extrusions.size(); i++) {
FieldVisitor fv = cw.visitField(ACC_PRIVATE | ACC_FINAL, "e" + i, EXTRUSION_DESC, null, null);
fv.visitEnd();
}
// 3. Generate Constructor(Extrusion[])
generateConstructor(cw, className, extrusions.size());
// 4. Generate extrude() method
generateExtrudeMethod(cw, className, extrusions.size());
cw.visitEnd();
// 5. Load and Instantiate
byte[] bytecode = cw.toByteArray();
try {
Class<?> generatedClass = new PipelineClassLoader(ExtrusionPipelineFactory.class.getClassLoader())
.defineClass(className.replace('/', '.'), bytecode);
return (ExtrusionPipeline) generatedClass.getConstructor(Extrusion[].class)
.newInstance((Object) extrusions.toArray(new Extrusion[0]));
} catch(Exception e) {
throw new RuntimeException("Failed to generate ExtrusionPipeline", e);
}
}
private static void generateConstructor(ClassWriter cw, String className, int count) {
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([L" + EXTRUSION_TYPE + ";)V", null, null);
mv.visitCode();
// super()
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
// Assign array elements to fields
for(int i = 0; i < count; i++) {
mv.visitVarInsn(ALOAD, 0); // Load this
mv.visitVarInsn(ALOAD, 1); // Load array argument
mv.visitIntInsn(SIPUSH, i); // Load index
mv.visitInsn(AALOAD); // Load array[i]
mv.visitFieldInsn(PUTFIELD, className, "e" + i, EXTRUSION_DESC);
}
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0); // Computed automatically
mv.visitEnd();
}
private static void generateExtrudeMethod(ClassWriter cw, String className, int count) {
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "extrude", EXTRUDE_SIG, null, null);
mv.visitCode();
// Helper var indices:
// 0: this
// 1: Biome original (We will update this or chain it on stack)
// 2: int x
// 3: int y
// 4: int z
// 5: long seed
mv.visitVarInsn(ALOAD, 1); // Load 'original' Biome onto stack initially
for(int i = 0; i < count; i++) {
// Stack contains: [CurrentBiome]
mv.visitVarInsn(ALOAD, 0); // Load 'this'
mv.visitFieldInsn(GETFIELD, className, "e" + i, EXTRUSION_DESC); // Load Extrusion field
// Stack: [CurrentBiome, Extrusion]
// We need: [Extrusion, CurrentBiome, x, y, z, seed]
mv.visitInsn(SWAP); // Swap to get [Extrusion, CurrentBiome]
mv.visitVarInsn(ILOAD, 2); // x
mv.visitVarInsn(ILOAD, 3); // y
mv.visitVarInsn(ILOAD, 4); // z
mv.visitVarInsn(LLOAD, 5); // seed
// Invoke Extrusion.extrude(Biome, x, y, z, seed)
mv.visitMethodInsn(INVOKEINTERFACE, EXTRUSION_TYPE, "extrude", EXTRUDE_SIG, true);
// Stack now contains: [NewBiome]
// Loop continues using this result as input for the next one
}
mv.visitInsn(ARETURN); // Return the final Biome
mv.visitMaxs(0, 0);
mv.visitEnd();
}
// Custom ClassLoader to inject the bytes
private static class PipelineClassLoader extends ClassLoader {
public PipelineClassLoader(ClassLoader parent) {
super(parent);
}
public Class<?> defineClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}
}
@@ -9,8 +9,6 @@ package com.dfsek.terra.addons.biome.image;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.function.Supplier;
import com.dfsek.terra.addons.biome.image.config.ImageProviderTemplate;
import com.dfsek.terra.addons.biome.image.config.converter.ClosestBiomeColorConverterTemplate;
import com.dfsek.terra.addons.biome.image.config.converter.ExactBiomeColorConverterTemplate;
@@ -29,6 +27,8 @@ import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import java.util.function.Supplier;
public class ImageBiomeProviderAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
@@ -7,7 +7,8 @@
package com.dfsek.terra.addons.biome.pipeline;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.api.util.cache.SeededVector2Key;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
@@ -21,9 +22,9 @@ import com.dfsek.terra.addons.biome.pipeline.api.BiomeChunk;
import com.dfsek.terra.addons.biome.pipeline.api.Pipeline;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.registry.key.StringIdentifiable;
import com.dfsek.terra.api.util.Column;
import com.dfsek.terra.api.util.cache.SeededVector2Key;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@@ -33,11 +34,11 @@ public class PipelineBiomeProvider implements BiomeProvider {
private final LoadingCache<SeededVector2Key, BiomeChunk> biomeChunkCache;
private final int chunkSize;
private final int resolution;
private final Sampler mutator;
private final NoiseSampler mutator;
private final double noiseAmp;
private final Set<Biome> biomes;
public PipelineBiomeProvider(Pipeline pipeline, int resolution, Sampler mutator, double noiseAmp) {
public PipelineBiomeProvider(Pipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) {
this.resolution = resolution;
this.mutator = mutator;
this.noiseAmp = noiseAmp;
@@ -82,8 +83,8 @@ public class PipelineBiomeProvider implements BiomeProvider {
public Biome getBiome(int x, int z, long seed) {
x += (int) (mutator.getSample(seed + 1, x, z) * noiseAmp);
z += (int) (mutator.getSample(seed + 2, x, z) * noiseAmp);
x += mutator.noise(seed + 1, x, z) * noiseAmp;
z += mutator.noise(seed + 2, x, z) * noiseAmp;
x /= resolution;
z /= resolution;
@@ -1,9 +1,9 @@
package com.dfsek.terra.addons.biome.pipeline.api;
import java.util.List;
import com.dfsek.terra.api.util.cache.SeededVector2Key;
import java.util.List;
public interface Pipeline {
BiomeChunk generateChunk(SeededVector2Key worldCoordinates);
@@ -7,7 +7,6 @@
package com.dfsek.terra.addons.biome.pipeline.config;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Description;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -20,6 +19,7 @@ import com.dfsek.terra.addons.biome.pipeline.api.Source;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.pipeline.PipelineImpl;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@@ -36,7 +36,7 @@ public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
@Value("blend.sampler")
@Default
@Description("A sampler to use for blending the edges of biomes via domain warping.")
protected @Meta Sampler blendSampler = Sampler.zero();
protected @Meta NoiseSampler blendSampler = NoiseSampler.zero();
@Value("blend.amplitude")
@Default
@Description("The amplitude at which to perform blending.")
@@ -7,7 +7,6 @@
package com.dfsek.terra.addons.biome.pipeline.config.source;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Description;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -15,13 +14,14 @@ import com.dfsek.terra.addons.biome.pipeline.api.Source;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.source.SamplerSource;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class SamplerSourceTemplate extends SourceTemplate {
@Value("sampler")
@Description("The sampler used to distribute biomes.")
private @Meta Sampler noise;
private @Meta NoiseSampler noise;
@Value("biomes")
@Description("The biomes to be distributed.")
@@ -7,17 +7,17 @@
package com.dfsek.terra.addons.biome.pipeline.config.stage;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Description;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
public abstract class StageTemplate implements ObjectTemplate<Stage> {
@Value("sampler")
@Description("Sampler to use for stage distribution.")
protected @Meta Sampler noise;
protected @Meta NoiseSampler noise;
}
@@ -1,7 +1,5 @@
package com.dfsek.terra.addons.biome.pipeline.pipeline;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import java.util.List;
import com.dfsek.terra.addons.biome.pipeline.api.BiomeChunk;
@@ -73,13 +71,12 @@ public class BiomeChunkImpl implements BiomeChunk {
lookupArray = tempArray;
// Apply stage to working grid
ViewPoint viewPoint = new ViewPoint(this, gridInterval, lookupArray, size);
for(int gridZ = 0; gridZ < gridSize; gridZ = gridZ + 1) {
for(int gridX = 0; gridX < gridSize; gridX = gridX + 1) {
int xIndex = gridOrigin + gridX * gridInterval;
int zIndex = gridOrigin + gridZ * gridInterval;
viewPoint.set(gridX, gridZ, xIndex, zIndex);
biomes[(xIndex * size) + zIndex] = stage.apply(viewPoint);
biomes[(xIndex * size) + zIndex] = stage.apply(
new ViewPoint(this, gridInterval, gridX, gridZ, xIndex, zIndex, lookupArray, size));
}
}
}
@@ -101,7 +98,7 @@ public class BiomeChunkImpl implements BiomeChunk {
// chunk samples points on the same overall grid.
// Without this, shared chunk borders (required because of adjacent cell reads) will not be identical
// because points would be sampled on grids at different offsets, resulting in artifacts at borders.
return FloatingPointFunctions.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
return (int) Math.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
}
private static int calculateFinalGridOrigin(int totalExpanderCount, List<Stage> stages) {
@@ -158,32 +155,25 @@ public class BiomeChunkImpl implements BiomeChunk {
*/
public static class ViewPoint {
private final BiomeChunkImpl chunk;
private PipelineBiome biome;
private final PipelineBiome biome;
private final int gridInterval;
private int gridX;
private int gridZ;
private int xIndex;
private int zIndex;
private final int gridX;
private final int gridZ;
private final int xIndex;
private final int zIndex;
private final PipelineBiome[] lookupArray;
private final int size;
private ViewPoint(BiomeChunkImpl chunk, int gridInterval,
private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex,
PipelineBiome[] lookupArray, int size) {
this.chunk = chunk;
this.gridInterval = gridInterval;
this.gridX = 0;
this.gridZ = 0;
this.xIndex = 0;
this.zIndex = 0;
this.lookupArray = lookupArray;
this.size = size;
}
public void set(int gridX, int gridZ, int xIndex, int zIndex) {
this.gridX = gridX;
this.gridZ = gridZ;
this.xIndex = xIndex;
this.zIndex = zIndex;
this.lookupArray = lookupArray;
this.size = size;
this.biome = lookupArray[(this.xIndex * this.size) + this.zIndex];
}
@@ -1,5 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.pipeline;
import com.dfsek.terra.api.util.cache.SeededVector2Key;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -10,7 +12,6 @@ import com.dfsek.terra.addons.biome.pipeline.api.Expander;
import com.dfsek.terra.addons.biome.pipeline.api.Pipeline;
import com.dfsek.terra.addons.biome.pipeline.api.Source;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.api.util.cache.SeededVector2Key;
public class PipelineImpl implements Pipeline {
@@ -7,18 +7,17 @@
package com.dfsek.terra.addons.biome.pipeline.source;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.addons.biome.pipeline.api.Source;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class SamplerSource implements Source {
private final ProbabilityCollection<PipelineBiome> biomes;
private final Sampler sampler;
private final NoiseSampler sampler;
public SamplerSource(ProbabilityCollection<PipelineBiome> biomes, Sampler sampler) {
public SamplerSource(ProbabilityCollection<PipelineBiome> biomes, NoiseSampler sampler) {
this.biomes = biomes;
this.sampler = sampler;
}
@@ -1,17 +1,16 @@
package com.dfsek.terra.addons.biome.pipeline.stage.expander;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.addons.biome.pipeline.api.Expander;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
import com.dfsek.terra.api.noise.NoiseSampler;
public class FractalExpander implements Expander {
private final Sampler sampler;
private final NoiseSampler sampler;
public FractalExpander(Sampler sampler) {
public FractalExpander(NoiseSampler sampler) {
this.sampler = sampler;
}
@@ -21,7 +20,7 @@ public class FractalExpander implements Expander {
int xMod2 = viewPoint.gridX() % 2;
int zMod2 = viewPoint.gridZ() % 2;
double roll = sampler.getSample(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
if(xMod2 == 1 && zMod2 == 0) { // Pick one of 2 neighbors on X axis randomly
return roll > 0 ? viewPoint.getRelativeBiome(-1, 0) : viewPoint.getRelativeBiome(1, 0);
@@ -7,9 +7,6 @@
package com.dfsek.terra.addons.biome.pipeline.stage.mutators;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.seismic.type.vector.Vector2Int;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -20,12 +17,14 @@ import java.util.function.Predicate;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.util.vector.Vector2Int;
public class BorderListStage implements Stage {
private final String border;
private final Sampler Sampler;
private final NoiseSampler noiseSampler;
private final ProbabilityCollection<PipelineBiome> replaceDefault;
private final String defaultReplace;
private final Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace;
@@ -33,9 +32,9 @@ public class BorderListStage implements Stage {
private final Vector2Int[] borderPoints;
public BorderListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String border, String defaultReplace,
Sampler Sampler, ProbabilityCollection<PipelineBiome> replaceDefault) {
NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replaceDefault) {
this.border = border;
this.Sampler = Sampler;
this.noiseSampler = noiseSampler;
this.replaceDefault = replaceDefault;
this.defaultReplace = defaultReplace;
this.replace = replace;
@@ -68,11 +67,11 @@ public class BorderListStage implements Stage {
PipelineBiome current = viewPoint.getRelativeBiome(point.getX(), point.getZ());
if(current != null && current.getTags().contains(border)) {
if(replace.containsKey(center)) {
PipelineBiome replacement = replace.get(center).get(Sampler, viewPoint.worldX(), viewPoint.worldZ(),
PipelineBiome replacement = replace.get(center).get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
viewPoint.worldSeed());
return replacement.isSelf() ? center : replacement;
}
PipelineBiome replacement = replaceDefault.get(Sampler, viewPoint.worldX(), viewPoint.worldZ(),
PipelineBiome replacement = replaceDefault.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
viewPoint.worldSeed());
return replacement.isSelf() ? center : replacement;
}
@@ -7,9 +7,6 @@
package com.dfsek.terra.addons.biome.pipeline.stage.mutators;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.seismic.type.vector.Vector2Int;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -19,19 +16,21 @@ import java.util.function.Predicate;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.util.vector.Vector2Int;
public class BorderStage implements Stage {
private final String border;
private final Sampler Sampler;
private final NoiseSampler noiseSampler;
private final ProbabilityCollection<PipelineBiome> replace;
private final String replaceTag;
private final Vector2Int[] borderPoints;
public BorderStage(String border, String replaceTag, Sampler Sampler, ProbabilityCollection<PipelineBiome> replace) {
public BorderStage(String border, String replaceTag, NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replace) {
this.border = border;
this.Sampler = Sampler;
this.noiseSampler = noiseSampler;
this.replace = replace;
this.replaceTag = replaceTag;
List<Vector2Int> points = new ArrayList<>();
@@ -51,7 +50,7 @@ public class BorderStage implements Stage {
for(Vector2Int point : borderPoints) {
PipelineBiome current = viewPoint.getRelativeBiome(point.getX(), point.getZ());
if(current != null && current.getTags().contains(border)) {
PipelineBiome replacement = replace.get(Sampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
PipelineBiome replacement = replace.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
return replacement.isSelf() ? center : replacement;
}
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.biome.pipeline.stage.mutators;
import com.dfsek.seismic.type.sampler.Sampler;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -17,17 +15,18 @@ import java.util.stream.Stream;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class ReplaceListStage implements Stage {
private final Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace;
private final Sampler sampler;
private final NoiseSampler sampler;
private final ProbabilityCollection<PipelineBiome> replaceDefault;
private final String defaultTag;
public ReplaceListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String defaultTag,
ProbabilityCollection<PipelineBiome> replaceDefault, Sampler sampler) {
ProbabilityCollection<PipelineBiome> replaceDefault, NoiseSampler sampler) {
this.replace = replace;
this.sampler = sampler;
this.defaultTag = defaultTag;
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.biome.pipeline.stage.mutators;
import com.dfsek.seismic.type.sampler.Sampler;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
@@ -16,15 +14,16 @@ import java.util.stream.Stream;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
public class ReplaceStage implements Stage {
private final String replaceableTag;
private final ProbabilityCollection<PipelineBiome> replace;
private final Sampler sampler;
private final NoiseSampler sampler;
public ReplaceStage(String replaceable, ProbabilityCollection<PipelineBiome> replace, Sampler sampler) {
public ReplaceStage(String replaceable, ProbabilityCollection<PipelineBiome> replace, NoiseSampler sampler) {
this.replaceableTag = replaceable;
this.replace = replace;
this.sampler = sampler;
@@ -7,20 +7,19 @@
package com.dfsek.terra.addons.biome.pipeline.stage.mutators;
import com.dfsek.seismic.type.sampler.Sampler;
import java.util.Objects;
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
import com.dfsek.terra.api.noise.NoiseSampler;
public class SmoothStage implements Stage {
private final Sampler sampler;
private final NoiseSampler sampler;
public SmoothStage(Sampler sampler) {
public SmoothStage(NoiseSampler sampler) {
this.sampler = sampler;
}
@@ -31,7 +30,7 @@ public class SmoothStage implements Stage {
PipelineBiome left = viewPoint.getRelativeBiome(0, 1);
PipelineBiome right = viewPoint.getRelativeBiome(0, -1);
double roll = sampler.getSample(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
boolean vert = Objects.equals(top, bottom);
boolean horiz = Objects.equals(left, right);
@@ -1,24 +1,24 @@
package com.dfsek.terra.addons.chunkgenerator.config.noise;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
public class BiomeNoiseConfigTemplate implements ObjectTemplate<BiomeNoiseProperties> {
@Value("terrain.sampler")
private @Meta Sampler baseSampler;
private @Meta NoiseSampler baseSampler;
@Value("terrain.sampler-2d")
@Default
private @Meta Sampler elevationSampler = Sampler.zero();
private @Meta NoiseSampler elevationSampler = NoiseSampler.zero();
@Value("carving.sampler")
@Default
private @Meta Sampler carvingSampler = Sampler.zero();
private @Meta NoiseSampler carvingSampler = NoiseSampler.zero();
@Value("terrain.blend.distance")
@Default
@@ -1,13 +1,12 @@
package com.dfsek.terra.addons.chunkgenerator.config.noise;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.properties.Properties;
public record BiomeNoiseProperties(Sampler base,
Sampler elevation,
Sampler carving,
public record BiomeNoiseProperties(NoiseSampler base,
NoiseSampler elevation,
NoiseSampler carving,
int blendDistance,
int blendStep,
double blendWeight,
@@ -1,19 +1,19 @@
package com.dfsek.terra.addons.chunkgenerator.config.noise;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.api.noise.NoiseSampler;
public class ThreadLocalNoiseHolder {
private final ThreadLocal<Holder> holder = ThreadLocal.withInitial(Holder::new);
public double getNoise(Sampler sampler, int x, int y, int z, long seed) {
public double getNoise(NoiseSampler sampler, int x, int y, int z, long seed) {
Holder holder = this.holder.get();
if(holder.init && holder.y == y && holder.z == z && holder.x == x && holder.seed == seed) {
return holder.noise;
}
double noise = sampler.getSample(seed, x, y, z);
double noise = sampler.noise(seed, x, y, z);
holder.noise = noise;
holder.x = x;
holder.y = y;
@@ -1,8 +1,7 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math;
import com.dfsek.seismic.type.vector.Vector3;
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
import com.dfsek.terra.api.util.vector.Vector3;
public enum SlantCalculationMethod {
@@ -23,7 +22,7 @@ public enum SlantCalculationMethod {
Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0);
for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) {
var scalar = -sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ());
normalApproximation.add(point.mutable().mulScalar(scalar));
normalApproximation.add(point.mutable().multiply(scalar));
}
return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize());
}
@@ -55,12 +55,12 @@ public class ElevationInterpolator {
}
if(same) {
values[x + 1][z + 1] = center.elevation().getSample(seed, xOrigin + x, zOrigin + z); // no weighting needed!
values[x + 1][z + 1] = center.elevation().noise(seed, xOrigin + x, zOrigin + z); // no weighting needed!
} else {
for(int xi = -smooth; xi <= smooth; xi++) {
for(int zi = -smooth; zi <= smooth; zi++) {
BiomeNoiseProperties gen = gens[x + 1 + smooth + xi][z + 1 + smooth + zi];
noise += gen.elevation().getSample(seed, xOrigin + x, zOrigin + z) * gen.elevationWeight();
noise += gen.elevation().noise(seed, xOrigin + x, zOrigin + z) * gen.elevationWeight();
div += gen.elevationWeight();
}
}
@@ -7,8 +7,7 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions;
import com.dfsek.terra.api.util.MathUtil;
/**
@@ -32,8 +31,6 @@ public class Interpolator {
this.v3 = v3;
}
//TODO this system is not very good, replace it wholesale
/**
* 2D Bilinear interpolation between 4 points on a unit square.
*
@@ -43,8 +40,8 @@ public class Interpolator {
* @return double - The interpolated value.
*/
public double bilerp(double s, double t) {
double v01 = InterpolationFunctions.lerp(v0, v1, s);
double v23 = InterpolationFunctions.lerp(v2, v3, s);
return InterpolationFunctions.lerp(v01, v23, t);
double v01 = MathUtil.lerp(s, v0, v1);
double v23 = MathUtil.lerp(s, v2, v3);
return MathUtil.lerp(t, v01, v23);
}
}
@@ -7,8 +7,7 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions;
import com.dfsek.terra.api.util.MathUtil;
/**
@@ -37,8 +36,7 @@ public class Interpolator3 {
this.bottom = new Interpolator(_100, _110, _101, _111);
}
//TODO this system is not very good, replace it wholesale
public double trilerp(double x, double y, double z) {
return InterpolationFunctions.lerp(top.bilerp(y, z), bottom.bilerp(y, z), x);
return MathUtil.lerp(x, top.bilerp(y, z), bottom.bilerp(y, z));
}
}
@@ -1,10 +1,8 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.api.properties.PropertyKey;
import com.dfsek.terra.api.util.MathUtil;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@@ -29,8 +27,8 @@ public class LazilyEvaluatedInterpolator {
PropertyKey<BiomeNoiseProperties> noisePropertiesKey, int min, int horizontalRes, int verticalRes,
long seed) {
this.noisePropertiesKey = noisePropertiesKey;
int hSamples = FloatingPointFunctions.ceil(16.0 / horizontalRes);
int vSamples = FloatingPointFunctions.ceil((double) (max - min) / verticalRes);
int hSamples = (int) Math.ceil(16.0 / horizontalRes);
int vSamples = (int) Math.ceil((double) (max - min) / verticalRes);
this.zMul = (hSamples + 1);
this.yMul = zMul * zMul;
samples = new Double[yMul * (vSamples + 1)];
@@ -58,7 +56,7 @@ public class LazilyEvaluatedInterpolator {
.getContext()
.get(noisePropertiesKey)
.carving()
.getSample(seed, xi, y, zi);
.noise(seed, xi, y, zi);
samples[index] = sample;
}
return sample;
@@ -83,10 +81,10 @@ public class LazilyEvaluatedInterpolator {
double xFrac = (double) (x % horizontalRes) / horizontalRes;
double zFrac = (double) (z % horizontalRes) / horizontalRes;
double lerp_bottom_0 = InterpolationFunctions.lerp(sample_0_0_0, sample_0_0_1, zFrac);
double lerp_bottom_1 = InterpolationFunctions.lerp(sample_1_0_0, sample_1_0_1, zFrac);
double lerp_bottom_0 = MathUtil.lerp(zFrac, sample_0_0_0, sample_0_0_1);
double lerp_bottom_1 = MathUtil.lerp(zFrac, sample_1_0_0, sample_1_0_1);
double lerp_bottom = InterpolationFunctions.lerp(lerp_bottom_0, lerp_bottom_1, xFrac);
double lerp_bottom = MathUtil.lerp(xFrac, lerp_bottom_0, lerp_bottom_1);
if(yRange) { // we can do bilerp
return lerp_bottom;
@@ -102,11 +100,11 @@ public class LazilyEvaluatedInterpolator {
double sample_1_1_0 = sample(xIndex + 1, yIndex + 1, zIndex, x + horizontalRes, y + verticalRes, z);
double sample_1_1_1 = sample(xIndex + 1, yIndex + 1, zIndex + 1, x + horizontalRes, y + verticalRes, z + horizontalRes);
double lerp_top_0 = InterpolationFunctions.lerp(sample_0_1_0, sample_0_1_1, zFrac);
double lerp_top_1 = InterpolationFunctions.lerp(sample_1_1_0, sample_1_1_1, zFrac);
double lerp_top_0 = MathUtil.lerp(zFrac, sample_0_1_0, sample_0_1_1);
double lerp_top_1 = MathUtil.lerp(zFrac, sample_1_1_0, sample_1_1_1);
double lerp_top = InterpolationFunctions.lerp(lerp_top_0, lerp_top_1, xFrac);
double lerp_top = MathUtil.lerp(xFrac, lerp_top_0, lerp_top_1);
return InterpolationFunctions.lerp(lerp_bottom, lerp_top, yFrac);
return MathUtil.lerp(yFrac, lerp_bottom, lerp_top);
}
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ChunkInterpolator;
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ElevationInterpolator;
@@ -28,8 +26,7 @@ public class Sampler3D {
}
public double sample(double x, double y, double z) {
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FloatingPointFunctions.round(x),
FloatingPointFunctions.round(z));
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation((int) Math.round(x), (int) Math.round(z));
}
public double sample(int x, int y, int z) {
@@ -1,5 +0,0 @@
version = version("1.0.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
}
@@ -1,131 +0,0 @@
package com.dfsek.terra.addons.commands.locate;
import com.dfsek.seismic.type.vector.Vector2Int;
import com.dfsek.seismic.type.vector.Vector3Int;
import com.dfsek.terra.api.util.generic.either.Either;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class BiomeLocator {
/**
* Locates the nearest biome matching the given predicate using a parallelized square spiral search.
*
* @param provider The BiomeProvider to search in.
* @param properties The world properties (needed for seed and height bounds).
* @param originX Starting X coordinate.
* @param originZ Starting Z coordinate.
* @param radius The maximum radius (in blocks) to search.
* @param step The search step/increment. Higher values are faster but less accurate.
* @param filter The condition to match the biome.
* @param search3D If true, searches the entire vertical column at each step. If false, only checks originY.
* @return An Optional containing the location of the found biome, or empty if not found.
*/
public static Optional<Either<Vector3Int, Vector2Int>> search(
@NotNull BiomeProvider provider,
@NotNull WorldProperties properties,
int originX,
int originZ,
int radius,
int step,
@NotNull Predicate<Biome> filter,
boolean search3D
) {
long seed = properties.getSeed();
int minHeight = properties.getMinHeight();
int maxHeight = properties.getMaxHeight();
// 1. Check the exact center first
Optional<Either<Vector3Int, Vector2Int>> centerResult = check(provider, seed, originX, originZ, step, filter, search3D, minHeight, maxHeight);
if (centerResult.isPresent()) {
return centerResult;
}
// 2. Begin Parallel Square Spiral Search
// We iterate rings sequentially to guarantee finding the *nearest* result.
// However, we process all points within a specific ring in parallel.
for (int r = step; r <= radius; r += step) {
final int currentRadius = r;
final int minX = -currentRadius;
final int maxX = currentRadius;
final int minZ = -currentRadius;
final int maxZ = currentRadius;
Stream<int[]> northSide = IntStream.iterate(minX, n -> n < maxX, n -> n + step)
.mapToObj(x -> new int[]{x, minZ}); // Fixed Z (min), varying X
Stream<int[]> eastSide = IntStream.iterate(minZ, n -> n < maxZ, n -> n + step)
.mapToObj(z -> new int[]{maxX, z}); // Fixed X (max), varying Z
Stream<int[]> southSide = IntStream.iterate(maxX, n -> n > minX, n -> n - step)
.mapToObj(x -> new int[]{x, maxZ}); // Fixed Z (max), varying X
Stream<int[]> westSide = IntStream.iterate(maxZ, n -> n > minZ, n -> n - step)
.mapToObj(z -> new int[]{minX, z}); // Fixed X (min), varying Z
Optional<Either<Vector3Int, Vector2Int>> ringResult = Stream.of(northSide, eastSide, southSide, westSide)
.flatMap(Function.identity())
.parallel()
.map(coords -> check(
provider,
seed,
originX + coords[0],
originZ + coords[1],
step,
filter,
search3D,
minHeight,
maxHeight
))
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst(); // findFirst() respects encounter order (North -> East -> South -> West)
if (ringResult.isPresent()) {
return ringResult;
}
}
return Optional.empty();
}
/**
* Helper to check a specific coordinate column or point.
* This logic is executed inside the worker threads.
*/
private static Optional<Either<Vector3Int, Vector2Int>> check(
BiomeProvider provider,
long seed,
int x,
int z,
int step,
Predicate<Biome> filter,
boolean search3D,
int minHeight,
int maxHeight
) {
if (search3D) {
// Iterate from bottom to top of the world using the step
for (int y = minHeight; y < maxHeight; y += step) {
if (filter.test(provider.getBiome(x, y, z, seed))) {
return Optional.of(Either.left(Vector3Int.of(x, y, z)));
}
}
return Optional.empty();
} else {
// 2D Mode: Check only the base biome
// We use a flatMap approach here to be safe with Optionals inside the stream
return provider.getBaseBiome(x, z, seed)
.filter(filter)
.map(b -> Either.right(Vector2Int.of(x, z)));
}
}
}
@@ -1,142 +0,0 @@
package com.dfsek.terra.addons.commands.locate;
import com.dfsek.seismic.type.vector.Vector2Int;
import com.dfsek.seismic.type.vector.Vector3Int;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.component.DefaultValue;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.description.Description;
import org.incendo.cloud.parser.standard.IntegerParser;
import java.util.Optional;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.command.CommandSender;
import com.dfsek.terra.api.command.arguments.RegistryArgument;
import com.dfsek.terra.api.entity.Entity;
import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.util.generic.either.Either;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.World;
import com.dfsek.terra.api.world.biome.Biome;
public class LocateCommandAddon implements AddonInitializer {
@Inject
private Platform platform;
@Inject
private BaseAddon addon;
private static Registry<Biome> getBiomeRegistry(CommandContext<CommandSender> sender) {
return sender.sender().getEntity().orElseThrow().world().getPack().getRegistry(Biome.class);
}
@Override
public void initialize() {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, CommandRegistrationEvent.class)
.then(event -> {
CommandManager<CommandSender> manager = event.getCommandManager();
manager.command(
manager.commandBuilder("search", Description.of("Locate things in the world"))
.literal("biome")
// Argument 1: The Biome to search for
.argument(RegistryArgument.builder("biome",
LocateCommandAddon::getBiomeRegistry,
TypeKey.of(Biome.class)))
// Argument 2: Radius (Optional, default 5000)
.optional("radius", IntegerParser.integerParser(100), DefaultValue.constant(5000))
// Argument 3: Step/Resolution (Optional, default 16)
.optional("step", IntegerParser.integerParser(1), DefaultValue.constant(16))
// Flag: Toggle 3D search (e.g., --3d or -3)
.flag(manager.flagBuilder("3d").withAliases("3").build())
// Flag: Auto resolution mode (e.g., --auto or -a)
.flag(manager.flagBuilder("auto").withAliases("a").build())
.handler(context -> {
// 1. Gather Context & Arguments
Biome targetBiome = context.get("biome");
Entity sender = context.sender().getEntity().orElseThrow(
() -> new Error("Only entities can run this command."));
World world = sender.world();
// Fetch properties needed for the locator
int radius = context.get("radius");
boolean search3D = context.flags().hasFlag("3d");
boolean autoMode = context.flags().hasFlag("auto");
// 2. Determine Initial Step
// If Auto: Start at radius / 2 (very coarse check).
// If Manual: Use provided step.
int stepArg = context.get("step");
int currentStep = autoMode ? Integer.highestOneBit(radius - 1) : stepArg;
// Notify player
String modeMsg = autoMode ? " (Auto Mode)" : " (Step: " + currentStep + ")";
context.sender().sendMessage(
"Searching for " + targetBiome.getID() + " within " + radius + " blocks" + modeMsg + "...");
Optional<Either<Vector3Int, Vector2Int>> result;
// 3. Execute Search Loop
while(true) {
result = BiomeLocator.search(
world.getBiomeProvider(),
world,
sender.position().getFloorX(),
sender.position().getFloorZ(),
radius,
currentStep,
found -> found.equals(targetBiome), // Match specific biome instance
search3D
);
// Exit Conditions:
// 1. Found a result
if(result.isPresent()) {
break;
}
// 2. Not in auto mode (only run once)
if(!autoMode) {
break;
}
// 3. We just ran a search at step arg and failed (lowest resolution)
if(currentStep <= stepArg) {
break;
}
// Reduce step for next iteration (Adaptive Search)
currentStep /= 2;
context.sender().sendMessage("No result found, refining search (Step: " + currentStep + ")...");
}
// 4. Handle Result
if(result.isPresent()) {
Either<Vector3Int, Vector2Int> location = result.get();
String coords;
if(location.hasLeft()) { // 3D Result
Vector3Int vec = location.getLeft().get();
coords = String.format("%d, %d, %d", vec.getX(), vec.getY(), vec.getZ());
} else { // 2D Result
Vector2Int vec = location.getRight().get();
coords = String.format("%d, ~, %d", vec.getX(), vec.getZ());
}
context.sender().sendMessage("Found " + targetBiome.getID() + " at [" + coords + "]");
} else {
context.sender().sendMessage("Could not find " + targetBiome.getID() + " within " + radius + " blocks.");
}
})
.permission("terra.locate.biome")
);
});
}
}
@@ -1,12 +0,0 @@
schema-version: 1
contributors:
- Terra contributors
id: command-locate
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.commands.locate.LocateCommandAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
@@ -1,7 +1,6 @@
package com.dfsek.terra.addons.commands.structure;
import com.dfsek.seismic.type.Rotation;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.component.DefaultValue;
import org.incendo.cloud.context.CommandContext;
@@ -23,6 +22,7 @@ import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.registry.Registry;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.util.Rotation;
import com.dfsek.terra.api.util.reflection.TypeKey;
@@ -8,7 +8,6 @@
package com.dfsek.terra.addons.biome;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import com.dfsek.terra.api.properties.Context;
import com.dfsek.terra.api.world.biome.Biome;
@@ -26,7 +25,6 @@ public class UserDefinedBiome implements Biome {
private final Set<String> tags;
private final Context context = new Context();
private final int intID;
public UserDefinedBiome(PlatformBiome vanilla, BiomeTemplate config) {
this.vanilla = vanilla;
@@ -34,7 +32,6 @@ public class UserDefinedBiome implements Biome {
this.config = config;
this.color = config.getColor();
this.tags = config.getTags();
this.intID = INT_ID_COUNTER.getAndIncrement();
tags.add("BIOME:" + id);
tags.add("ALL");
}
@@ -64,11 +61,6 @@ public class UserDefinedBiome implements Biome {
return tags;
}
@Override
public int getIntID() {
return intID;
}
@Override
public String getID() {
return id;
@@ -7,13 +7,13 @@
package com.dfsek.terra.addons.feature.distributor.config;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.feature.distributor.distributors.SamplerDistributor;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.structure.feature.Distributor;
@@ -23,7 +23,7 @@ public class SamplerDistributorTemplate implements ObjectTemplate<Distributor> {
@Default
private @Meta double threshold = 0;
@Value("sampler")
private @Meta Sampler noise;
private @Meta NoiseSampler noise;
@Override
public Distributor get() {
@@ -1,12 +1,17 @@
package com.dfsek.terra.addons.feature.distributor.distributors;
import com.dfsek.seismic.algorithms.hashing.HashingFunctions;
import com.dfsek.seismic.math.integer.IntegerFunctions;
import java.util.random.RandomGenerator;
import java.util.random.RandomGeneratorFactory;
import com.dfsek.terra.api.structure.feature.Distributor;
import com.dfsek.terra.api.util.MathUtil;
public class PaddedGridDistributor implements Distributor {
private final int width;
private final int cellWidth;
private final int salt;
public PaddedGridDistributor(int width, int padding, int salt) {
@@ -20,26 +25,12 @@ public class PaddedGridDistributor implements Distributor {
int cellX = Math.floorDiv(x, cellWidth);
int cellZ = Math.floorDiv(z, cellWidth);
int localX = x - (cellX * cellWidth);
int localZ = z - (cellZ * cellWidth);
RandomGenerator random = RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus").create(
(MathUtil.murmur64(MathUtil.squash(cellX, cellZ)) ^ seed) + salt);
if (localX >= width || localZ >= width) {
return false;
}
int pointX = random.nextInt(width) + cellX * cellWidth;
int pointZ = random.nextInt(width) + cellZ * cellWidth;
long hash = HashingFunctions.murmur64(IntegerFunctions.squash(cellX, cellZ)) ^ seed;
hash += salt;
hash = HashingFunctions.splitMix64(hash);
int targetX = (int) ((hash & 0x7FFFFFFFFFFFFFFFL) % width);
if (localX != targetX) {
return false;
}
hash = HashingFunctions.splitMix64(hash);
int targetZ = (int) ((hash & 0x7FFFFFFFFFFFFFFFL) % width);
return localZ == targetZ;
return x == pointX && z == pointZ;
}
}
@@ -7,23 +7,22 @@
package com.dfsek.terra.addons.feature.distributor.distributors;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.structure.feature.Distributor;
public class SamplerDistributor implements Distributor {
private final Sampler sampler;
private final NoiseSampler sampler;
private final double threshold;
public SamplerDistributor(Sampler sampler, double threshold) {
public SamplerDistributor(NoiseSampler sampler, double threshold) {
this.sampler = sampler;
this.threshold = threshold;
}
@Override
public boolean matches(int x, int z, long seed) {
return sampler.getSample(seed, x, z) < threshold;
return sampler.noise(seed, x, z) < threshold;
}
}
@@ -7,8 +7,7 @@
package com.dfsek.terra.addons.feature;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.structure.feature.Distributor;
import com.dfsek.terra.api.structure.feature.Feature;
@@ -20,13 +19,13 @@ import com.dfsek.terra.api.world.WritableWorld;
public class ConfiguredFeature implements Feature {
private final ProbabilityCollection<Structure> structures;
private final Sampler structureSelector;
private final NoiseSampler structureSelector;
private final Distributor distributor;
private final Locator locator;
private final String id;
public ConfiguredFeature(ProbabilityCollection<Structure> structures, Sampler structureSelector, Distributor distributor,
public ConfiguredFeature(ProbabilityCollection<Structure> structures, NoiseSampler structureSelector, Distributor distributor,
Locator locator, String id) {
this.structures = structures;
this.structureSelector = structureSelector;
@@ -7,12 +7,12 @@
package com.dfsek.terra.addons.feature;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Final;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.api.config.AbstractableTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.structure.feature.Distributor;
import com.dfsek.terra.api.structure.feature.Locator;
@@ -31,7 +31,7 @@ public class FeatureTemplate implements AbstractableTemplate {
private @Meta Locator locator;
@Value("structures.distribution")
private @Meta Sampler structureNoise;
private @Meta NoiseSampler structureNoise;
@Value("structures.structures")
private @Meta ProbabilityCollection<Structure> structures;
@@ -49,7 +49,7 @@ public class FeatureTemplate implements AbstractableTemplate {
return locator;
}
public Sampler getStructureNoise() {
public NoiseSampler getStructureNoise() {
return structureNoise;
}
@@ -7,7 +7,6 @@
package com.dfsek.terra.addons.flora;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Final;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -17,6 +16,7 @@ import java.util.List;
import com.dfsek.terra.addons.flora.flora.gen.BlockLayer;
import com.dfsek.terra.api.config.AbstractableTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.collection.MaterialSet;
@@ -41,13 +41,13 @@ public class FloraTemplate implements AbstractableTemplate {
private @Meta List<@Meta BlockLayer> layers;
@Value("layer-distribution")
private @Meta Sampler noiseDistribution;
private @Meta NoiseSampler noiseDistribution;
public boolean doPhysics() {
return doPhysics;
}
public Sampler getNoiseDistribution() {
public NoiseSampler getNoiseDistribution() {
return noiseDistribution;
}
@@ -7,10 +7,6 @@
package com.dfsek.terra.addons.flora.flora.gen;
import com.dfsek.seismic.type.Rotation;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.seismic.type.vector.Vector3Int;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
@@ -19,9 +15,12 @@ import java.util.random.RandomGeneratorFactory;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.properties.enums.Direction;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.util.Rotation;
import com.dfsek.terra.api.util.collection.MaterialSet;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
import com.dfsek.terra.api.util.vector.Vector3Int;
import com.dfsek.terra.api.world.WritableWorld;
@@ -32,13 +31,13 @@ public class TerraFlora implements Structure {
private final MaterialSet testRotation;
private final Sampler distribution;
private final NoiseSampler distribution;
private final String id;
public TerraFlora(List<BlockLayer> layers, boolean physics, boolean ceiling,
MaterialSet testRotation,
Sampler distribution, String id) {
NoiseSampler distribution, String id) {
this.physics = physics;
this.testRotation = testRotation;
this.ceiling = ceiling;
@@ -15,7 +15,7 @@ import com.dfsek.terra.addons.feature.locator.locators.AdjacentPatternLocator;
import com.dfsek.terra.addons.feature.locator.patterns.Pattern;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
@SuppressWarnings({ "FieldCanBeLocal", "FieldMayBeFinal" })
@@ -14,7 +14,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.feature.locator.locators.GaussianRandomLocator;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
@SuppressWarnings("FieldMayBeFinal")
@@ -14,7 +14,7 @@ import com.dfsek.terra.addons.feature.locator.locators.PatternLocator;
import com.dfsek.terra.addons.feature.locator.patterns.Pattern;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
public class PatternLocatorTemplate implements ObjectTemplate<Locator> {
@@ -14,7 +14,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.feature.locator.locators.RandomLocator;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
@SuppressWarnings("FieldMayBeFinal")
@@ -7,18 +7,18 @@
package com.dfsek.terra.addons.feature.locator.config;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.feature.locator.locators.Sampler3DLocator;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.structure.feature.Locator;
public class Sampler3DLocatorTemplate implements ObjectTemplate<Locator> {
@Value("sampler")
private @Meta Sampler sampler;
private @Meta NoiseSampler sampler;
@Override
public Locator get() {
@@ -7,7 +7,6 @@
package com.dfsek.terra.addons.feature.locator.config;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
@@ -15,12 +14,13 @@ import java.util.List;
import com.dfsek.terra.addons.feature.locator.locators.SamplerLocator;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.structure.feature.Locator;
public class SamplerLocatorTemplate implements ObjectTemplate<Locator> {
@Value("samplers")
private @Meta List<@Meta Sampler> samplers;
private @Meta List<@Meta NoiseSampler> samplers;
@Override
public Locator get() {
@@ -13,7 +13,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.feature.locator.locators.SurfaceLocator;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
public class SurfaceLocatorTemplate implements ObjectTemplate<Locator> {
@@ -13,7 +13,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.feature.locator.locators.TopLocator;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
public class TopLocatorTemplate implements ObjectTemplate<Locator> {
@@ -14,7 +14,7 @@ import com.dfsek.terra.addons.feature.locator.patterns.MatchPattern;
import com.dfsek.terra.addons.feature.locator.patterns.Pattern;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
public class AirMatchPatternTemplate implements ObjectTemplate<Pattern> {
@@ -13,8 +13,8 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.feature.locator.patterns.MatchPattern;
import com.dfsek.terra.addons.feature.locator.patterns.Pattern;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.util.collection.MaterialSet;
import com.dfsek.terra.api.util.range.Range;
public class BlockSetMatchPatternTemplate implements ObjectTemplate<Pattern> {
@@ -14,7 +14,7 @@ import com.dfsek.terra.addons.feature.locator.patterns.MatchPattern;
import com.dfsek.terra.addons.feature.locator.patterns.Pattern;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
public class SingleBlockMatchPatternTemplate implements ObjectTemplate<Pattern> {
@@ -12,7 +12,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.feature.locator.patterns.MatchPattern;
import com.dfsek.terra.addons.feature.locator.patterns.Pattern;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
public class SolidMatchPatternTemplate implements ObjectTemplate<Pattern> {
@@ -10,7 +10,7 @@ package com.dfsek.terra.addons.feature.locator.locators;
import com.dfsek.terra.addons.feature.locator.patterns.Pattern;
import com.dfsek.terra.api.structure.feature.BinaryColumn;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.world.WritableWorld;
import com.dfsek.terra.api.world.chunk.generation.util.Column;
@@ -12,7 +12,7 @@ import java.util.random.RandomGeneratorFactory;
import com.dfsek.terra.api.structure.feature.BinaryColumn;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.world.chunk.generation.util.Column;
import com.dfsek.terra.api.world.chunk.generation.util.Column.BinaryColumnBuilder;
@@ -10,7 +10,7 @@ package com.dfsek.terra.addons.feature.locator.locators;
import com.dfsek.terra.addons.feature.locator.patterns.Pattern;
import com.dfsek.terra.api.structure.feature.BinaryColumn;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.world.chunk.generation.util.Column;
@@ -12,7 +12,7 @@ import java.util.random.RandomGeneratorFactory;
import com.dfsek.terra.api.structure.feature.BinaryColumn;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.world.chunk.generation.util.Column;
import com.dfsek.terra.api.world.chunk.generation.util.Column.BinaryColumnBuilder;
@@ -7,17 +7,16 @@
package com.dfsek.terra.addons.feature.locator.locators;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.structure.feature.BinaryColumn;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.world.chunk.generation.util.Column;
public class Sampler3DLocator implements Locator {
private final Sampler sampler;
private final NoiseSampler sampler;
public Sampler3DLocator(Sampler sampler) {
public Sampler3DLocator(NoiseSampler sampler) {
this.sampler = sampler;
}
@@ -26,6 +25,6 @@ public class Sampler3DLocator implements Locator {
long seed = column.getWorld().getSeed();
int x = column.getX();
int z = column.getZ();
return column.newBinaryColumn(y -> sampler.getSample(seed, x, y, z) > 0);
return column.newBinaryColumn(y -> sampler.noise(seed, x, y, z) > 0);
}
}
@@ -7,10 +7,9 @@
package com.dfsek.terra.addons.feature.locator.locators;
import com.dfsek.seismic.type.sampler.Sampler;
import java.util.List;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.structure.feature.BinaryColumn;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.world.chunk.generation.util.Column;
@@ -18,9 +17,9 @@ import com.dfsek.terra.api.world.chunk.generation.util.Column.BinaryColumnBuilde
public class SamplerLocator implements Locator {
private final List<Sampler> samplers;
private final List<NoiseSampler> samplers;
public SamplerLocator(List<Sampler> samplers) {
public SamplerLocator(List<NoiseSampler> samplers) {
this.samplers = samplers;
}
@@ -43,7 +42,7 @@ public class SamplerLocator implements Locator {
long seed = column.getWorld().getSeed();
samplers.forEach(sampler -> {
int y = floorToInt(sampler.getSample(seed, column.getX(), column.getZ()));
int y = floorToInt(sampler.noise(seed, column.getX(), column.getZ()));
if(y >= column.getMaxY() || y < column.getMinY()) return;
results.set(y);
});
@@ -9,7 +9,7 @@ package com.dfsek.terra.addons.feature.locator.locators;
import com.dfsek.terra.api.structure.feature.BinaryColumn;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.world.chunk.generation.util.Column;
import com.dfsek.terra.api.world.chunk.generation.util.Column.BinaryColumnBuilder;
@@ -9,7 +9,7 @@ package com.dfsek.terra.addons.feature.locator.locators;
import com.dfsek.terra.api.structure.feature.BinaryColumn;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.world.chunk.generation.util.Column;
@@ -10,7 +10,7 @@ package com.dfsek.terra.addons.feature.locator.patterns;
import java.util.function.Predicate;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.world.WritableWorld;
import com.dfsek.terra.api.world.chunk.generation.util.Column;
@@ -8,26 +8,6 @@
package com.dfsek.terra.addons.noise;
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
import com.dfsek.seismic.algorithms.sampler.arithmetic.AdditionSampler;
import com.dfsek.seismic.algorithms.sampler.arithmetic.DivisionSampler;
import com.dfsek.seismic.algorithms.sampler.arithmetic.MaxSampler;
import com.dfsek.seismic.algorithms.sampler.arithmetic.MinSampler;
import com.dfsek.seismic.algorithms.sampler.arithmetic.MultiplicationSampler;
import com.dfsek.seismic.algorithms.sampler.arithmetic.SubtractionSampler;
import com.dfsek.seismic.algorithms.sampler.noise.cellular.CellularStyleSampler;
import com.dfsek.seismic.algorithms.sampler.noise.random.GaussianNoiseSampler;
import com.dfsek.seismic.algorithms.sampler.noise.random.PositiveWhiteNoiseSampler;
import com.dfsek.seismic.algorithms.sampler.noise.random.WhiteNoiseSampler;
import com.dfsek.seismic.algorithms.sampler.noise.simplex.OpenSimplex2SSampler;
import com.dfsek.seismic.algorithms.sampler.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.seismic.algorithms.sampler.noise.simplex.PerlinSampler;
import com.dfsek.seismic.algorithms.sampler.noise.simplex.SimplexSampler;
import com.dfsek.seismic.algorithms.sampler.noise.value.ValueCubicSampler;
import com.dfsek.seismic.algorithms.sampler.noise.value.ValueSampler;
import com.dfsek.seismic.type.CubicSpline;
import com.dfsek.seismic.type.DistanceFunction;
import com.dfsek.seismic.type.sampler.DerivativeSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.LinkedHashMap;
@@ -36,12 +16,13 @@ import java.util.function.Supplier;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.addons.noise.config.CubicSplinePointTemplate;
import com.dfsek.terra.addons.noise.config.DimensionApplicableSampler;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.templates.BinaryArithmeticTemplate;
import com.dfsek.terra.addons.noise.config.templates.CacheSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.DerivativeSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.DerivativeNoiseSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.DomainWarpTemplate;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.addons.noise.config.templates.ImageSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.KernelTemplate;
import com.dfsek.terra.addons.noise.config.templates.LinearHeightmapSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.TranslateSamplerTemplate;
@@ -64,17 +45,37 @@ import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizer
import com.dfsek.terra.addons.noise.config.templates.normalizer.PosterizationNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.ProbabilityNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.ScaleNormalizerTemplate;
import com.dfsek.terra.addons.noise.math.CubicSpline;
import com.dfsek.terra.addons.noise.samplers.arithmetic.AdditionSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.DivisionSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.MaxSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.MinSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.MultiplicationSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.SubtractionSampler;
import com.dfsek.terra.addons.noise.samplers.noise.CellularSampler;
import com.dfsek.terra.addons.noise.samplers.noise.DistanceSampler;
import com.dfsek.terra.addons.noise.samplers.noise.random.GaussianNoiseSampler;
import com.dfsek.terra.addons.noise.samplers.noise.random.PositiveWhiteNoiseSampler;
import com.dfsek.terra.addons.noise.samplers.noise.random.WhiteNoiseSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2SSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.PerlinSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.SimplexSampler;
import com.dfsek.terra.addons.noise.samplers.noise.value.ValueCubicSampler;
import com.dfsek.terra.addons.noise.samplers.noise.value.ValueSampler;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.util.reflection.TypeKey;
public class NoiseAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<Sampler>>> NOISE_SAMPLER_TOKEN = new TypeKey<>() {
public static final TypeKey<Supplier<ObjectTemplate<NoiseSampler>>> NOISE_SAMPLER_TOKEN = new TypeKey<>() {
};
@Inject
private Platform plugin;
@@ -90,19 +91,19 @@ public class NoiseAddon implements AddonInitializer {
.then(event -> {
ParseOptions expressionParseOptions = event.getPack().getExpressionParseOptions();
CheckedRegistry<Supplier<ObjectTemplate<Sampler>>> noiseRegistry = event.getPack().getOrCreateRegistry(
CheckedRegistry<Supplier<ObjectTemplate<NoiseSampler>>> noiseRegistry = event.getPack().getOrCreateRegistry(
NOISE_SAMPLER_TOKEN);
event.getPack()
.applyLoader(DistanceFunction.class,
(type, o, loader, depthTracker) -> DistanceFunction.valueOf((String) o))
.applyLoader(CellularStyleSampler.CellularReturnType.class,
(type, o, loader, depthTracker) -> CellularStyleSampler.CellularReturnType.valueOf((String) o))
.applyLoader(DistanceFunction.class,
(type, o, loader, depthTracker) -> DistanceFunction.valueOf((String) o))
.applyLoader(DimensionApplicableSampler.class, DimensionApplicableSampler::new)
.applyLoader(CellularSampler.DistanceFunction.class,
(type, o, loader, depthTracker) -> CellularSampler.DistanceFunction.valueOf((String) o))
.applyLoader(CellularSampler.ReturnType.class,
(type, o, loader, depthTracker) -> CellularSampler.ReturnType.valueOf((String) o))
.applyLoader(DistanceSampler.DistanceFunction.class,
(type, o, loader, depthTracker) -> DistanceSampler.DistanceFunction.valueOf((String) o))
.applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::new)
.applyLoader(FunctionTemplate.class, () -> new FunctionTemplate(expressionParseOptions))
.applyLoader(CubicSpline.Point.class, CubicSplinePointTemplate::new)
.applyLoader(DerivativeSampler.class, DerivativeSamplerTemplate::new);
.applyLoader(DerivativeNoiseSampler.class, DerivativeNoiseSamplerTemplate::new);
noiseRegistry.register(addon.key("LINEAR"), LinearNormalizerTemplate::new);
noiseRegistry.register(addon.key("LINEAR_MAP"), LinearMapNormalizerTemplate::new);
@@ -113,27 +114,29 @@ public class NoiseAddon implements AddonInitializer {
noiseRegistry.register(addon.key("POSTERIZATION"), PosterizationNormalizerTemplate::new);
noiseRegistry.register(addon.key("CUBIC_SPLINE"), CubicSplineNormalizerTemplate::new);
noiseRegistry.register(addon.key("IMAGE"), ImageSamplerTemplate::new);
noiseRegistry.register(addon.key("DOMAIN_WARP"), DomainWarpTemplate::new);
noiseRegistry.register(addon.key("FBM"), BrownianMotionTemplate::new);
noiseRegistry.register(addon.key("PING_PONG"), PingPongTemplate::new);
noiseRegistry.register(addon.key("RIDGED"), RidgedFractalTemplate::new);
noiseRegistry.register(addon.key("OPEN_SIMPLEX_2"), () -> new SimpleNoiseTemplate<>(OpenSimplex2Sampler.class));
noiseRegistry.register(addon.key("OPEN_SIMPLEX_2S"), () -> new SimpleNoiseTemplate<>(OpenSimplex2SSampler.class));
noiseRegistry.register(addon.key("PERLIN"), () -> new SimpleNoiseTemplate<>(PerlinSampler.class));
noiseRegistry.register(addon.key("SIMPLEX"), () -> new SimpleNoiseTemplate<>(SimplexSampler.class));
noiseRegistry.register(addon.key("OPEN_SIMPLEX_2"), () -> new SimpleNoiseTemplate(OpenSimplex2Sampler::new));
noiseRegistry.register(addon.key("OPEN_SIMPLEX_2S"), () -> new SimpleNoiseTemplate(OpenSimplex2SSampler::new));
noiseRegistry.register(addon.key("PERLIN"), () -> new SimpleNoiseTemplate(PerlinSampler::new));
noiseRegistry.register(addon.key("SIMPLEX"), () -> new SimpleNoiseTemplate(SimplexSampler::new));
noiseRegistry.register(addon.key("GABOR"), GaborNoiseTemplate::new);
noiseRegistry.register(addon.key("PSEUDOEROSION"), PseudoErosionTemplate::new);
noiseRegistry.register(addon.key("VALUE"), () -> new SimpleNoiseTemplate<>(ValueSampler.class));
noiseRegistry.register(addon.key("VALUE_CUBIC"), () -> new SimpleNoiseTemplate<>(ValueCubicSampler.class));
noiseRegistry.register(addon.key("VALUE"), () -> new SimpleNoiseTemplate(ValueSampler::new));
noiseRegistry.register(addon.key("VALUE_CUBIC"), () -> new SimpleNoiseTemplate(ValueCubicSampler::new));
noiseRegistry.register(addon.key("CELLULAR"), CellularNoiseTemplate::new);
noiseRegistry.register(addon.key("WHITE_NOISE"), () -> new SimpleNoiseTemplate<>(WhiteNoiseSampler.class));
noiseRegistry.register(addon.key("POSITIVE_WHITE_NOISE"), () -> new SimpleNoiseTemplate<>(PositiveWhiteNoiseSampler.class));
noiseRegistry.register(addon.key("GAUSSIAN"), () -> new SimpleNoiseTemplate<>(GaussianNoiseSampler.class));
noiseRegistry.register(addon.key("WHITE_NOISE"), () -> new SimpleNoiseTemplate(WhiteNoiseSampler::new));
noiseRegistry.register(addon.key("POSITIVE_WHITE_NOISE"), () -> new SimpleNoiseTemplate(PositiveWhiteNoiseSampler::new));
noiseRegistry.register(addon.key("GAUSSIAN"), () -> new SimpleNoiseTemplate(GaussianNoiseSampler::new));
noiseRegistry.register(addon.key("DISTANCE"), DistanceSamplerTemplate::new);
@@ -154,10 +157,9 @@ public class NoiseAddon implements AddonInitializer {
noiseRegistry.register(addon.key("CACHE"), CacheSamplerTemplate::new);
Map<String, DimensionApplicableSampler> packSamplers = new LinkedHashMap<>();
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
noiseRegistry.register(addon.key("EXPRESSION"),
() -> new ExpressionFunctionTemplate(packSamplers, packFunctions, expressionParseOptions));
noiseRegistry.register(addon.key("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions, expressionParseOptions));
noiseRegistry.register(addon.key("EXPRESSION_NORMALIZER"),
() -> new ExpressionNormalizerTemplate(packSamplers, packFunctions, expressionParseOptions));
@@ -14,7 +14,7 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.LinkedHashMap;
import java.util.Map;
import com.dfsek.terra.addons.noise.config.DimensionApplicableSampler;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.properties.Properties;
@@ -24,13 +24,13 @@ import com.dfsek.terra.api.properties.Properties;
public class NoiseConfigPackTemplate implements ConfigTemplate, Properties {
@Value("samplers")
@Default
private @Meta Map<String, @Meta DimensionApplicableSampler> noiseBuilderMap = new LinkedHashMap<>();
private @Meta Map<String, @Meta DimensionApplicableNoiseSampler> noiseBuilderMap = new LinkedHashMap<>();
@Value("functions")
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> expressions = new LinkedHashMap<>();
public Map<String, DimensionApplicableSampler> getSamplers() {
public Map<String, DimensionApplicableNoiseSampler> getSamplers() {
return noiseBuilderMap;
}
@@ -1,9 +1,9 @@
package com.dfsek.terra.addons.noise.config;
import com.dfsek.seismic.type.CubicSpline.Point;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.noise.math.CubicSpline.Point;
import com.dfsek.terra.api.config.meta.Meta;
@@ -7,22 +7,22 @@
package com.dfsek.terra.addons.noise.config;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
public class DimensionApplicableSampler implements ObjectTemplate<DimensionApplicableSampler> {
public class DimensionApplicableNoiseSampler implements ObjectTemplate<DimensionApplicableNoiseSampler> {
@Value("dimensions")
private @Meta int dimensions;
@Value(".")
private @Meta Sampler sampler;
private @Meta NoiseSampler sampler;
@Override
public DimensionApplicableSampler get() {
public DimensionApplicableNoiseSampler get() {
return this;
}
@@ -30,7 +30,7 @@ public class DimensionApplicableSampler implements ObjectTemplate<DimensionAppli
return dimensions;
}
public Sampler getSampler() {
public NoiseSampler getSampler() {
return sampler;
}
}
@@ -1,22 +1,22 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.arithmetic.BinaryArithmeticSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.function.BiFunction;
import com.dfsek.terra.addons.noise.samplers.arithmetic.BinaryArithmeticSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
public class BinaryArithmeticTemplate<T extends BinaryArithmeticSampler> extends SamplerTemplate<T> {
private final BiFunction<Sampler, Sampler, T> function;
private final BiFunction<NoiseSampler, NoiseSampler, T> function;
@Value("left")
private @Meta Sampler left;
private @Meta NoiseSampler left;
@Value("right")
private @Meta Sampler right;
private @Meta NoiseSampler right;
public BinaryArithmeticTemplate(BiFunction<Sampler, Sampler, T> function) {
public BinaryArithmeticTemplate(BiFunction<NoiseSampler, NoiseSampler, T> function) {
this.function = function;
}
@@ -1,25 +1,27 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import org.jetbrains.annotations.ApiStatus.Experimental;
import com.dfsek.terra.addons.noise.config.sampler.CacheSampler;
import com.dfsek.terra.addons.noise.samplers.CacheSampler;
import com.dfsek.terra.addons.noise.samplers.LinearHeightmapSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import org.jetbrains.annotations.ApiStatus.Experimental;
@Experimental
public class CacheSamplerTemplate extends SamplerTemplate<CacheSampler> {
@Value("sampler")
@Default
private Sampler sampler;
private NoiseSampler sampler;
public CacheSamplerTemplate() {
}
@Override
public Sampler get() {
public NoiseSampler get() {
return new CacheSampler(sampler, getDimensions());
}
}
@@ -0,0 +1,26 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.exception.ValidationException;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
public class DerivativeNoiseSamplerTemplate extends SamplerTemplate<DerivativeNoiseSampler> {
@Value(".")
private NoiseSampler sampler;
@Override
public boolean validate() throws ValidationException {
if(!DerivativeNoiseSampler.isDifferentiable(sampler)) throw new ValidationException(
"Provided sampler does not support calculating a derivative");
return super.validate();
}
@Override
public DerivativeNoiseSampler get() {
return (DerivativeNoiseSampler) sampler;
}
}
@@ -1,25 +0,0 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.type.sampler.DerivativeSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.exception.ValidationException;
public class DerivativeSamplerTemplate extends SamplerTemplate<DerivativeSampler> {
@Value(".")
private Sampler sampler;
@Override
public boolean validate() throws ValidationException {
if(!DerivativeSampler.isDifferentiable(sampler)) throw new ValidationException(
"Provided sampler does not support calculating a derivative");
return super.validate();
}
@Override
public DerivativeSampler get() {
return (DerivativeSampler) sampler;
}
}
@@ -7,28 +7,28 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.DomainWarpedSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.DomainWarpedSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class DomainWarpTemplate extends SamplerTemplate<DomainWarpedSampler> {
@Value("warp")
private @Meta Sampler warp;
private @Meta NoiseSampler warp;
@Value("sampler")
private @Meta Sampler function;
private @Meta NoiseSampler function;
@Value("amplitude")
@Default
private @Meta double amplitude = 1;
@Override
public Sampler get() {
public NoiseSampler get() {
return new DomainWarpedSampler(function, warp, amplitude);
}
}
@@ -12,12 +12,12 @@ import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import com.dfsek.terra.api.config.meta.Meta;
@SuppressWarnings("unused")
public class FunctionTemplate implements ObjectTemplate<FunctionTemplate> {
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2020-2025 Polyhedral Development
*
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.image.BufferedImage;
import com.dfsek.terra.addons.noise.samplers.ImageSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class ImageSamplerTemplate extends SamplerTemplate<ImageSampler> {
private static final Logger logger = LoggerFactory.getLogger(ImageSamplerTemplate.class);
private static boolean used = false;
@Value("image")
private @Meta BufferedImage image;
@Value("frequency")
private @Meta double frequency;
@Value("channel")
private ImageSampler.@Meta Channel channel;
@Override
public NoiseSampler get() {
if(!used) {
logger.warn("The IMAGE NoiseSampler implemented by the config-noise-function addon is deprecated. " +
"It is recommended to use the IMAGE NoiseSampler implemented by the config-noise-image " +
"addon instead.");
used = true;
}
return new ImageSampler(image, channel, frequency);
}
}
@@ -7,15 +7,15 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.KernelSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.exception.ValidationException;
import java.util.List;
import com.dfsek.terra.addons.noise.samplers.KernelSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
@@ -29,14 +29,14 @@ public class KernelTemplate extends SamplerTemplate<KernelSampler> {
private @Meta double factor = 1;
@Value("sampler")
private @Meta Sampler function;
private @Meta NoiseSampler function;
@Value("frequency")
@Default
private @Meta double frequency = 1;
@Override
public Sampler get() {
public NoiseSampler get() {
double[][] k = new double[kernel.size()][kernel.get(0).size()];
for(int x = 0; x < kernel.size(); x++) {
@@ -45,7 +45,8 @@ public class KernelTemplate extends SamplerTemplate<KernelSampler> {
}
}
KernelSampler sampler = new KernelSampler(frequency, k, function);
KernelSampler sampler = new KernelSampler(k, function);
sampler.setFrequency(frequency);
return sampler;
}
@@ -1,18 +1,18 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.LinearHeightmapSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.LinearHeightmapSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings("FieldMayBeFinal")
public class LinearHeightmapSamplerTemplate extends SamplerTemplate<LinearHeightmapSampler> {
@Value("sampler")
@Default
private @Meta Sampler sampler = Sampler.zero();
private @Meta NoiseSampler sampler = NoiseSampler.zero();
@Value("base")
private @Meta double base;
@@ -22,7 +22,7 @@ public class LinearHeightmapSamplerTemplate extends SamplerTemplate<LinearHeight
private @Meta double scale = 1;
@Override
public Sampler get() {
public NoiseSampler get() {
return new LinearHeightmapSampler(sampler, scale, base);
}
}
@@ -7,7 +7,6 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.ValidatedConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -15,10 +14,11 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.tectonic.api.exception.ValidationException;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings("FieldMayBeFinal")
public abstract class SamplerTemplate<T extends Sampler> implements ValidatedConfigTemplate, ObjectTemplate<Sampler> {
public abstract class SamplerTemplate<T extends NoiseSampler> implements ValidatedConfigTemplate, ObjectTemplate<NoiseSampler> {
@Value("dimensions")
@Default
private @Meta int dimensions = 2;
@@ -1,17 +1,17 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.TranslateSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.TranslateSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
public class TranslateSamplerTemplate extends SamplerTemplate<TranslateSampler> {
@Value("sampler")
private Sampler sampler;
private NoiseSampler sampler;
@Value("x")
@Default
@@ -26,7 +26,7 @@ public class TranslateSamplerTemplate extends SamplerTemplate<TranslateSampler>
private @Meta double z = 0;
@Override
public Sampler get() {
public NoiseSampler get() {
return new TranslateSampler(sampler, x, y, z);
}
}
@@ -7,43 +7,48 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.cellular.CellularSampler;
import com.dfsek.seismic.algorithms.sampler.noise.cellular.CellularStyleSampler;
import com.dfsek.seismic.algorithms.sampler.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.seismic.type.DistanceFunction;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.noise.CellularSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings("FieldMayBeFinal")
public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
@Value("distance")
@Default
private @Meta DistanceFunction cellularDistanceFunction = DistanceFunction.EuclideanSq;
private CellularSampler.@Meta DistanceFunction cellularDistanceFunction = CellularSampler.DistanceFunction.EuclideanSq;
@Value("return")
@Default
private CellularStyleSampler.@Meta CellularReturnType cellularReturnType = CellularStyleSampler.CellularReturnType.Distance;
private CellularSampler.@Meta ReturnType cellularReturnType = CellularSampler.ReturnType.Distance;
@Value("jitter")
@Default
private @Meta double cellularJitter = 1.0D;
@Value("lookup")
@Default
private @Meta Sampler lookup = new OpenSimplex2Sampler(0.02d, 0);
private @Meta NoiseSampler lookup = new OpenSimplex2Sampler();
@Value("salt-lookup")
@Default
private @Meta boolean saltLookup = true;
@Override
public Sampler get() {
CellularSampler sampler = new CellularSampler(frequency, salt, lookup, cellularDistanceFunction, cellularReturnType, cellularJitter,
saltLookup);
public NoiseSampler get() {
CellularSampler sampler = new CellularSampler();
sampler.setNoiseLookup(lookup);
sampler.setFrequency(frequency);
sampler.setJitterModifier(cellularJitter);
sampler.setReturnType(cellularReturnType);
sampler.setDistanceFunction(cellularDistanceFunction);
sampler.setSalt(salt);
sampler.setSaltLookup(saltLookup);
return sampler;
}
}
@@ -7,13 +7,13 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.ConstantSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.ConstantSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings("FieldMayBeFinal")
@@ -23,7 +23,7 @@ public class ConstantNoiseTemplate extends SamplerTemplate<ConstantSampler> {
private @Meta double value = 0d;
@Override
public Sampler get() {
public NoiseSampler get() {
return new ConstantSampler(value);
}
}
@@ -0,0 +1,8 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
public abstract class DerivativeNoiseTemplate<T extends DerivativeNoiseFunction> extends NoiseTemplate<T> {
}
@@ -1,18 +1,19 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.DistanceSampler;
import com.dfsek.seismic.type.DistanceFunction;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.DistanceSampler;
import com.dfsek.terra.addons.noise.samplers.noise.DistanceSampler.DistanceFunction;
import com.dfsek.terra.api.config.meta.Meta;
public class DistanceSamplerTemplate extends NoiseTemplate<DistanceSampler> {
public class DistanceSamplerTemplate extends SamplerTemplate<DistanceSampler> {
@Value("distance-function")
@Default
private @Meta DistanceFunction distanceFunction = DistanceFunction.Euclidean;
private DistanceSampler.@Meta DistanceFunction distanceFunction = DistanceFunction.Euclidean;
@Value("point.x")
@Default
@@ -36,6 +37,6 @@ public class DistanceSamplerTemplate extends NoiseTemplate<DistanceSampler> {
@Override
public DistanceSampler get() {
return new DistanceSampler(salt, distanceFunction, x, y, z, normalize, normalizeRadius);
return new DistanceSampler(distanceFunction, x, y, z, normalize, normalizeRadius);
}
}
@@ -9,8 +9,6 @@ package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.sampler.noise.ExpressionNoiseFunction;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -18,17 +16,19 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import com.dfsek.terra.addons.noise.config.DimensionApplicableSampler;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.ExpressionFunction;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import static com.dfsek.terra.addons.noise.paralithic.FunctionUtil.convertFunctionsAndSamplers;
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionNoiseFunction> {
private final Map<String, DimensionApplicableSampler> globalSamplers;
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFunction> {
private final Map<String, DimensionApplicableNoiseSampler> globalSamplers;
private final Map<String, FunctionTemplate> globalFunctions;
private final ParseOptions parseOptions;
@Value("variables")
@@ -38,12 +38,12 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionNoiseF
private @Meta String expression;
@Value("samplers")
@Default
private @Meta LinkedHashMap<String, @Meta DimensionApplicableSampler> samplers = new LinkedHashMap<>();
private @Meta LinkedHashMap<String, @Meta DimensionApplicableNoiseSampler> samplers = new LinkedHashMap<>();
@Value("functions")
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
public ExpressionFunctionTemplate(Map<String, DimensionApplicableSampler> globalSamplers,
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers,
Map<String, FunctionTemplate> globalFunctions,
ParseOptions parseOptions) {
this.globalSamplers = globalSamplers;
@@ -52,14 +52,13 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionNoiseF
}
@Override
public Sampler get() {
public NoiseSampler get() {
var mergedFunctions = new HashMap<>(globalFunctions);
mergedFunctions.putAll(functions);
var mergedSamplers = new HashMap<>(globalSamplers);
mergedSamplers.putAll(samplers);
try {
return new ExpressionNoiseFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars,
parseOptions);
return new ExpressionFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars, parseOptions);
} catch(ParseException e) {
throw new RuntimeException("Failed to parse expression.", e);
}
@@ -7,16 +7,16 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.GaborSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.noise.GaborNoiseSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings("FieldMayBeFinal")
public class GaborNoiseTemplate extends NoiseTemplate<GaborSampler> {
public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
@Value("rotation")
@Default
private @Meta double rotation = 0.25;
@@ -37,13 +37,16 @@ public class GaborNoiseTemplate extends NoiseTemplate<GaborSampler> {
@Default
private @Meta double f0 = 0.625;
@Value("a")
@Default
private @Meta double a = 0.1;
@Override
public Sampler get() {
GaborSampler gaborSampler = new GaborSampler(frequency, salt, f0, deviation, rotation, impulses, a, isotropic);
return gaborSampler;
public NoiseSampler get() {
GaborNoiseSampler gaborNoiseSampler = new GaborNoiseSampler();
gaborNoiseSampler.setFrequency(frequency);
gaborNoiseSampler.setRotation(rotation);
gaborNoiseSampler.setIsotropic(isotropic);
gaborNoiseSampler.setDeviation(deviation);
gaborNoiseSampler.setImpulsesPerKernel(impulses);
gaborNoiseSampler.setFrequency0(f0);
gaborNoiseSampler.setSalt(salt);
return gaborNoiseSampler;
}
}
@@ -7,11 +7,11 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.NoiseFunction;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
import com.dfsek.terra.api.config.meta.Meta;
@@ -1,12 +1,12 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.PseudoErosionSampler;
import com.dfsek.seismic.algorithms.sampler.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.seismic.type.sampler.DerivativeSampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.noise.PseudoErosionSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
public class PseudoErosionTemplate extends NoiseTemplate<PseudoErosionSampler> {
@@ -45,7 +45,7 @@ public class PseudoErosionTemplate extends NoiseTemplate<PseudoErosionSampler> {
@Value("sampler")
@Default
private DerivativeSampler heightSampler = new OpenSimplex2Sampler(0.02d, 0);
private DerivativeNoiseSampler heightSampler = new OpenSimplex2Sampler();
@Value("slope-mask.enable")
@Default
@@ -69,9 +69,11 @@ public class PseudoErosionTemplate extends NoiseTemplate<PseudoErosionSampler> {
@Override
public PseudoErosionSampler get() {
PseudoErosionSampler pseudoErosion = new PseudoErosionSampler(frequency, salt, octaves, gain, lacunarity,
PseudoErosionSampler pseudoErosion = new PseudoErosionSampler(octaves, gain, lacunarity,
slopeStrength, branchStrength, strength,
erosionFrequency, heightSampler, slopeMask, slopeMaskFull, slopeMaskNone, jitterModifier, averageErosionImpulses);
pseudoErosion.setFrequency(frequency);
pseudoErosion.setSalt(salt);
return pseudoErosion;
}
}
@@ -7,28 +7,24 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.NoiseFunction;
import com.dfsek.seismic.type.sampler.Sampler;
import java.util.function.Supplier;
import java.lang.reflect.InvocationTargetException;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
import com.dfsek.terra.api.noise.NoiseSampler;
public class SimpleNoiseTemplate<T extends NoiseFunction> extends NoiseTemplate<NoiseFunction> {
private final Class<T> samplerClass;
public class SimpleNoiseTemplate extends NoiseTemplate<NoiseFunction> {
private final Supplier<NoiseFunction> samplerSupplier;
public SimpleNoiseTemplate(Class<T> samplerClass) {
this.samplerClass = samplerClass;
public SimpleNoiseTemplate(Supplier<NoiseFunction> samplerSupplier) {
this.samplerSupplier = samplerSupplier;
}
@Override
public Sampler get() {
NoiseFunction sampler;
try {
sampler = samplerClass.getConstructor(double.class, long.class)
.newInstance(frequency, salt);
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
public NoiseSampler get() {
NoiseFunction sampler = samplerSupplier.get();
sampler.setFrequency(frequency);
sampler.setSalt(salt);
return sampler;
}
}
@@ -7,16 +7,18 @@
package com.dfsek.terra.addons.noise.config.templates.noise.fractal;
import com.dfsek.seismic.algorithms.sampler.noise.fractal.BrownianMotionSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.addons.noise.samplers.noise.fractal.BrownianMotionSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
public class BrownianMotionTemplate extends FractalTemplate<BrownianMotionSampler> {
@Override
public Sampler get() {
BrownianMotionSampler sampler = new BrownianMotionSampler(salt, function, fractalGain, fractalLacunarity, weightedStrength,
octaves);
public NoiseSampler get() {
BrownianMotionSampler sampler = new BrownianMotionSampler(function);
sampler.setGain(fractalGain);
sampler.setLacunarity(fractalLacunarity);
sampler.setOctaves(octaves);
sampler.setWeightedStrength(weightedStrength);
return sampler;
}
}

Some files were not shown because too many files have changed in this diff Show More