Compare commits

..

64 Commits

Author SHA1 Message Date
Zoë Gidiere 5829112a74 Merge branch 'ver/6.4.0' into dev/image-caching 2023-10-26 12:56:17 -06:00
Zoë Gidiere c41bf55b7b implement missing methods from last comit 2023-10-26 12:53:55 -06:00
Zoë Gidiere 5d12a560f1 add zero and unit vectors 2023-10-26 11:08:36 -06:00
Zoë Gidiere 6f08908bb4 merge ovre-v2 into ore(v1) 2023-10-26 10:43:13 -06:00
Zoë Gidiere 9292d3de17 Remove FastMath
hotspot has intrinsics for almost everything we use it for
2023-10-26 10:37:25 -06:00
Astrash 0149a29b04 Load correct path 2023-10-24 14:08:56 +11:00
Astrash cd8605850f Replace unload-on-timeout with timeout > 0 2023-10-24 13:47:25 +11:00
Astrash 148b8dfe35 Bump image lib patch version 2023-10-24 13:34:10 +11:00
Astrash 3f485b1825 Add to unload on timeout description 2023-10-24 13:30:09 +11:00
Astrash cb6ecff113 Remove sout 2023-10-24 13:29:53 +11:00
Astrash e30bcbf1ba Improve image caching options 2023-10-24 13:26:35 +11:00
Astrash 805f99f57a Make ore algorithm readable 2023-10-20 10:55:23 +11:00
Astrash 4e5b02ef42 Pass correct coords for ore block checks 2023-10-20 10:30:25 +11:00
Astrash e80e998cec Only log warnings with debug logging 2023-10-20 10:03:04 +11:00
Zoë fde29220af Merge pull request #419 from PolyhedralDev/dev/disable-quilt
Dev/disable quilt
2023-10-19 17:31:40 +00:00
Zoë Gidiere d3a9b57872 disable quilt 2023-10-18 19:53:59 -06:00
Zoë 4671ec5bd3 Merge pull request #417 from PolyhedralDev/dev/folia
Dev/folia
2023-10-19 01:18:45 +00:00
Zoë 9f4a8e06e1 Update DependencyConfig.kt 2023-10-17 21:00:28 -06:00
Zoë c8f2871aaa Update build.gradle.kts 2023-10-17 20:59:27 -06:00
Zoë 4a537a56aa Merge pull request #415 from PolyhedralDev/dev/ore-v2
Add updated ore-v2
2023-10-18 00:33:15 +00:00
Zoë 4917160123 Update README.md 2023-10-17 18:32:00 -06:00
Zoë b3f80dcb64 Merge pull request #410 from PolyhedralDev/dev/1.20.2
1.20.2 + update libs
2023-10-15 19:45:43 +00:00
Zoë Gidiere d49b9ccad5 Merge branch 'dev/1.20.2' into dev/folia 2023-10-14 16:02:54 -06:00
Zoë Gidiere a8387ce419 Merge remote-tracking branch 'origin/ver/6.4.0' into dev/1.20.2 2023-10-14 16:02:40 -06:00
Zoë Gidiere 94854f2bdb update versions 2023-10-14 15:55:43 -06:00
Astrashh 47f531089e Add slant locator (#413)
* Add slant locator addon

* Bump slant locator noise3d dependency version

* Fix slant locator dependency version range

* Actually fix slant locator dependency version range
2023-10-10 00:35:47 +00:00
Astrashh abd83e8278 Add number predicate addon (#412) 2023-10-10 00:35:26 +00:00
Astrash b5e7c7c112 Fix TOP locator 2023-10-10 09:44:53 +11:00
Zoë Gidiere d71f7d4c36 clarify value and change default 2023-10-03 21:03:44 -06:00
Zoë Gidiere 84898a7a6b fixes 2023-10-03 20:03:46 -06:00
Zoë Gidiere 0c1a6efc72 refractor classes 2023-10-03 19:42:15 -06:00
Zoë Gidiere 200281f140 dep orev1 2023-10-03 11:58:32 -06:00
Zoë Gidiere f1ea8074de config-ore-v2 2023-10-03 11:54:18 -06:00
Astrash f896a9a278 Bump noise3d addon minor version 2023-10-03 11:01:50 +11:00
Astrash 79b3b34669 Add slant API for noise3d 2023-10-03 09:51:39 +11:00
Zoë Gidiere ce2b964ce3 Merge branch 'dev/1.20.2' into dev/folia 2023-10-02 01:38:24 -06:00
Zoë Gidiere 0ee5f49972 quilt 2023-10-02 01:38:01 -06:00
Zoë Gidiere 3bc10cdb6a Merge branch 'dev/1.20.2' into dev/folia 2023-10-02 00:42:11 -06:00
Zoë Gidiere 86ba52850d update strata 2023-10-02 00:41:54 -06:00
Zoë Gidiere 27eebf6a47 Folia support
Co-authored-by: Janet Blackquill <uhhadd@gmail.com>
2023-10-02 00:23:19 -06:00
Zoë Gidiere 2d2bba20b6 found an untrue in read me 2023-10-01 23:22:44 -06:00
Zoë Gidiere eb3994005c fix me being fucking stupid 2023-10-01 22:46:41 -06:00
Zoë Gidiere 0a7cdb82a3 update deps + 1.20.2 2023-10-01 22:18:54 -06:00
Zoë 158deaa971 Merge pull request #408 from PolyhedralDev/dev/physics
Allows you to create a block with physics enabled
2023-10-01 19:07:15 -06:00
Astrash e51e025e9c Implement cubic spline sampler 2023-10-02 11:14:43 +11:00
Zoë Gidiere 8e0d64dccd Make bukkit work 2023-09-30 10:49:28 -06:00
Zoë Gidiere 23f47de10a fix pack loading error 2023-09-29 23:35:17 -06:00
Zoë Gidiere 89651597c2 default to info logging 2023-09-29 23:32:40 -06:00
Zoë 5c0c833b70 Update LifecycleEntryPoint.java 2023-09-29 23:09:41 -06:00
Zoë Gidiere 33d654dc8e impl fabric 2023-09-29 23:05:05 -06:00
Zoë Gidiere f0c602d7e7 implement physics on the api side
we will see if platform changes are needed
2023-09-29 22:10:03 -06:00
Zoë Gidiere 0e37a839fe We do a little commonifying 2023-09-29 21:44:12 -06:00
Astrash 3f9ead0d66 Remove repeated code in cellular sampler 2023-09-27 13:39:51 +10:00
David W 5eeb5af6c4 Add cell center offset return to CELLULAR sampler (#407)
* Add offset lookup return to cellular sampler

* bump noise function plugin version

* revert version to 1.1.0

* rename OffsetNoiseLookup, switch axis orientation

* rename return type aswell in cellcampler
2023-09-21 22:23:49 +00:00
Astrash 81e354f91c Use tectonic properly 2023-07-18 22:06:08 +10:00
Astrash aab28ff4f9 Bump version to 6.4.0 2023-07-18 14:32:12 +10:00
Astrash 0e3a756011 Bump config-noise-function to v1.1.0 2023-07-18 14:29:54 +10:00
Astrash 02198e1b88 Implement distance sampler 2023-07-18 14:29:28 +10:00
Astrash 00aeb98419 Implement translation sampler 2023-07-18 14:27:36 +10:00
Astrash 1a784b51ac Implement expression normalizer sampler 2023-07-18 14:25:07 +10:00
Astrash 34c0895c1f Make metalist injection error more user friendly 2023-07-16 22:46:23 +10:00
Astrash 379fa601a3 Meta annotate LINEAR_HEIGHTMAP sampler 2023-07-16 17:04:51 +10:00
Astrash fcbf51d80b Allow Range keys to be meta annotated 2023-07-16 11:51:51 +10:00
Astrash 9d83dfd164 Bump version to 6.3.2 2023-07-16 11:49:14 +10:00
226 changed files with 2551 additions and 1363 deletions
+1 -8
View File
@@ -47,14 +47,7 @@ JARs are produced in `platforms/<platform>/build/libs`.
To run Minecraft with Terra in the IDE (for testing) use the following tasks:
* Bukkit
* `installPaper` - Install a [Paper](https://github.com/PaperMC/Paper) test
server. (Only needs to be run once).
* `installPurpur` - Install a [Purpur](https://github.com/pl3xgaming/Purpur)
test server. (Only needs to be run once).
* `runPaper` - Run the Paper test server with Terra (`installPaper` must
have been run previously).
* `runPurpur` - Run the Purpur test server with Terra (`installPurpur` must
have been run previously).
* `runServer` - Run the Paper test server with Terra installed.
* Fabric
* `runClient` - Run a Minecraft Fabric client with Terra installed.
* `runServer` - Run a Minecraft Fabric server with Terra installed.
+4 -4
View File
@@ -1,8 +1,8 @@
preRelease(true)
versionProjects(":common:api", version("6.3.1"))
versionProjects(":common:implementation", version("6.3.1"))
versionProjects(":platforms", version("6.3.1"))
versionProjects(":common:api", version("6.4.0"))
versionProjects(":common:implementation", version("6.4.0"))
versionProjects(":platforms", version("6.4.0"))
allprojects {
@@ -20,7 +20,7 @@ allprojects {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
maxHeapSize = "4G"
maxHeapSize = "2G"
ignoreFailures = false
failFast = true
maxParallelForks = (Runtime.getRuntime().availableProcessors() - 1).takeIf { it > 0 } ?: 1
+7 -15
View File
@@ -3,15 +3,6 @@ plugins {
kotlin("jvm") version embeddedKotlinVersion
}
buildscript {
configurations.all {
resolutionStrategy {
force("org.ow2.asm:asm:9.3") // TODO: remove when ShadowJar updates ASM version
force("org.ow2.asm:asm-commons:9.3")
}
}
}
repositories {
mavenCentral()
gradlePluginPortal()
@@ -24,11 +15,12 @@ repositories {
}
dependencies {
implementation("gradle.plugin.com.github.jengelman.gradle.plugins:shadow:+")
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.3.5")
//TODO Allow pulling from Versions.kt
implementation("com.github.johnrengelman", "shadow", "8.1.1")
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin","1.5.6")
implementation("org.ow2.asm:asm:9.3")
implementation("org.ow2.asm:asm-tree:9.3")
implementation("com.dfsek.tectonic:common:4.2.0")
implementation("org.yaml:snakeyaml:1.27")
implementation("org.ow2.asm", "asm", "9.5")
implementation("org.ow2.asm", "asm-tree", "9.5")
implementation("com.dfsek.tectonic", "common", "4.2.0")
implementation("org.yaml", "snakeyaml", "2.2")
}
+4 -1
View File
@@ -48,6 +48,9 @@ fun Project.configureDependencies() {
maven("https://jitpack.io") {
name = "JitPack"
}
maven("https://nexuslite.gcnt.net/repos/other/") {
name = "GCNT"
}
}
dependencies {
@@ -58,4 +61,4 @@ fun Project.configureDependencies() {
compileOnly("com.google.guava:guava:30.0-jre")
testImplementation("com.google.guava:guava:30.0-jre")
}
}
}
+40 -38
View File
@@ -1,68 +1,70 @@
object Versions {
object Libraries {
const val tectonic = "4.2.0"
const val paralithic = "0.7.0"
const val strata = "1.1.1"
const val tectonic = "4.2.1"
const val paralithic = "0.7.1"
const val strata = "1.3.2"
const val cloud = "1.8.0"
const val cloud = "1.8.4"
const val slf4j = "1.7.36"
const val log4j_slf4j_impl = "2.14.1"
const val slf4j = "2.0.9"
const val log4j_slf4j_impl = "2.20.0"
object Internal {
const val apacheText = "1.9"
const val jafama = "2.3.2"
const val apacheIO = "2.6"
const val fastutil = "8.5.6"
const val shadow = "8.1.1"
const val apacheText = "1.10.0"
const val apacheIO = "2.14.0"
const val guava = "32.1.3-jre"
const val asm = "9.5"
const val snakeYml = "2.2"
}
}
object Fabric {
const val fabricLoader = "0.14.8"
const val fabricAPI = "0.83.1+1.20.1"
}
object Quilt {
const val quiltLoader = "0.17.0"
const val fabricApi = "6.0.0-beta.3+0.76.0-1.19.4"
const val fabricAPI = "0.90.0+${Mod.minecraft}"
}
//
// object Quilt {
// const val quiltLoader = "0.20.2"
// const val fabricApi = "7.3.1+0.89.3-1.20.1"
// }
object Mod {
const val mixin = "0.11.2+mixin.0.8.5"
const val mixin = "0.12.5+mixin.0.8.5"
const val minecraft = "1.20.1"
const val yarn = "$minecraft+build.2"
const val fabricLoader = "0.14.21"
const val minecraft = "1.20.2"
const val yarn = "$minecraft+build.4"
const val fabricLoader = "0.14.23"
const val architecuryLoom = "0.12.0.290"
const val architecturyPlugin = "3.4-SNAPSHOT"
const val architecuryLoom = "1.3.357"
const val architecturyPlugin = "3.4.146"
const val loomQuiltflower = "1.7.1"
const val loomVineflower = "1.11.0"
}
object Forge {
const val forge = "${Mod.minecraft}-47.0.3"
const val burningwave = "12.53.0"
const val forge = "${Mod.minecraft}-48.0.13"
const val burningwave = "12.63.0"
}
object Bukkit {
const val paper = "1.18.2-R0.1-SNAPSHOT"
const val paperLib = "1.0.5"
const val minecraft = "1.20.1"
const val foliaLib = "0.2.5"
const val minecraft = "1.20.2"
const val reflectionRemapper = "0.1.0-SNAPSHOT"
const val paperDevBundle = "1.20.1-R0.1-SNAPSHOT"
const val paperDevBundle = "1.20.2-R0.1-SNAPSHOT"
const val runPaper = "2.2.0"
const val paperWeight = "1.5.6"
}
object Sponge {
const val sponge = "9.0.0-SNAPSHOT"
const val mixin = "0.8.2"
const val minecraft = "1.17.1"
}
//
// object Sponge {
// const val sponge = "9.0.0-SNAPSHOT"
// const val mixin = "0.8.2"
// const val minecraft = "1.17.1"
// }
//
object CLI {
const val nbt = "6.1"
const val logback = "1.2.9"
const val commonsIO = "2.7"
const val guava = "31.0.1-jre"
const val logback = "1.4.11"
}
}
@@ -3,10 +3,6 @@ version = version("1.0.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
compileOnlyApi(project(":common:addons:library-image"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.biome.image.lib.jafama")
}
}
@@ -9,8 +9,8 @@ package com.dfsek.terra.addons.biome.image.v2;
import java.util.Optional;
import com.dfsek.terra.addons.image.converter.ColorConverter;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.addons.image.converter.ColorConverter;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@@ -13,8 +13,8 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.biome.image.v2.ImageBiomeProvider;
import com.dfsek.terra.addons.image.converter.ColorConverter;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.addons.image.converter.ColorConverter;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@@ -2,10 +2,6 @@ version = version("1.0.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.biome.image.lib.jafama")
}
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.biome.image;
import net.jafama.FastMath;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.HashMap;
@@ -34,7 +32,7 @@ public class ImageBiomeProvider implements BiomeProvider {
}
private static int distance(Color a, Color b) {
return FastMath.abs(a.getRed() - b.getRed()) + FastMath.abs(a.getGreen() - b.getGreen()) + FastMath.abs(a.getBlue() - b.getBlue());
return Math.abs(a.getRed() - b.getRed()) + Math.abs(a.getGreen() - b.getGreen()) + Math.abs(a.getBlue() - b.getBlue());
}
@Override
@@ -70,14 +68,14 @@ public class ImageBiomeProvider implements BiomeProvider {
CENTER {
@Override
public Color getColor(BufferedImage image, int x, int z) {
return new Color(image.getRGB(FastMath.floorMod(x - image.getWidth() / 2, image.getWidth()),
FastMath.floorMod(z - image.getHeight() / 2, image.getHeight())));
return new Color(image.getRGB(Math.floorMod(x - image.getWidth() / 2, image.getWidth()),
Math.floorMod(z - image.getHeight() / 2, image.getHeight())));
}
},
NONE {
@Override
public Color getColor(BufferedImage image, int x, int z) {
return new Color(image.getRGB(FastMath.floorMod(x, image.getWidth()), FastMath.floorMod(z, image.getHeight())));
return new Color(image.getRGB(Math.floorMod(x, image.getWidth()), Math.floorMod(z, image.getHeight())));
}
};
@@ -50,6 +50,7 @@ public class ImageBiomeProviderAddon implements AddonInitializer {
() -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class)));
})
.failThrough();
logger.warn("The biome-provider-image addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the biome-provider-image-v2 addon for future pack development instead.");
if(platform.getTerraConfig().isDebugLog())
logger.warn("The biome-provider-image addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the biome-provider-image-v2 addon for future pack development instead.");
}
}
@@ -2,11 +2,4 @@ version = version("1.0.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.biome.pipeline.lib.jafama")
}
@@ -11,6 +11,9 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.function.Supplier;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.config.BiomePipelineTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.PipelineBiomeLoader;
import com.dfsek.terra.addons.biome.pipeline.v2.config.source.SamplerSourceTemplate;
@@ -20,9 +23,6 @@ import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.BorderStage
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.ReplaceListStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.ReplaceStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.SmoothStageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
@@ -1,13 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.v2;
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline;
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import net.jafama.FastMath;
import java.util.Comparator;
import java.util.HashSet;
@@ -15,6 +9,11 @@ import java.util.Optional;
import java.util.Set;
import java.util.stream.StreamSupport;
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline;
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.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;
@@ -81,8 +80,8 @@ public class PipelineBiomeProvider implements BiomeProvider {
x /= resolution;
z /= resolution;
int chunkX = FastMath.floorDiv(x, chunkSize);
int chunkZ = FastMath.floorDiv(z, chunkSize);
int chunkX = Math.floorDiv(x, chunkSize);
int chunkZ = Math.floorDiv(z, chunkSize);
int chunkWorldX = chunkX * chunkSize;
int chunkWorldZ = chunkZ * chunkSize;
@@ -1,7 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
/**
@@ -1,7 +1,7 @@
package com.dfsek.terra.addons.biome.pipeline.v2.api;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
public interface Stage {
@@ -15,9 +15,9 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.List;
import com.dfsek.terra.addons.biome.pipeline.v2.PipelineBiomeProvider;
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.PipelineImpl;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.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;
@@ -7,8 +7,8 @@
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.expander;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.expander.FractalExpander;
@@ -11,9 +11,9 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.Map;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.BorderListStage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
@@ -9,9 +9,9 @@ package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.BorderStage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
@@ -11,9 +11,9 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.Map;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.ReplaceListStage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
@@ -9,9 +9,9 @@ package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.ReplaceStage;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
@@ -7,8 +7,8 @@
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.SmoothStage;
@@ -1,13 +1,12 @@
package com.dfsek.terra.addons.biome.pipeline.v2.pipeline;
import java.util.List;
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import net.jafama.FastMath;
import java.util.List;
public class BiomeChunkImpl implements BiomeChunk {
@@ -111,7 +110,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 FastMath.ceilToInt((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
return (int) Math.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
}
private static int calculateFinalGridOrigin(int totalExpanderCount, List<Stage> stages) {
@@ -3,8 +3,8 @@ package com.dfsek.terra.addons.biome.pipeline.v2.source;
import java.util.Collections;
import java.util.Set;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
public class SingleSource implements Source {
@@ -2,11 +2,4 @@ version = version("1.0.1")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.biome.pipeline.lib.jafama")
}
@@ -90,6 +90,7 @@ public class BiomePipelineAddon implements AddonInitializer {
event.getPack().applyLoader(BiomeDelegate.class, new BiomeDelegateLoader(biomeRegistry));
});
logger.warn("The biome-provider-pipeline addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the biome-provider-pipeline-v2 addon for future pack development instead.");
if(platform.getTerraConfig().isDebugLog())
logger.warn("The biome-provider-pipeline addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the biome-provider-pipeline-v2 addon for future pack development instead.");
}
}
@@ -9,7 +9,6 @@ package com.dfsek.terra.addons.biome.pipeline;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import net.jafama.FastMath;
import java.util.Comparator;
import java.util.HashSet;
@@ -86,8 +85,8 @@ public class BiomePipelineProvider implements BiomeProvider {
x /= resolution;
z /= resolution;
int fdX = FastMath.floorDiv(x, pipeline.getSize());
int fdZ = FastMath.floorDiv(z, pipeline.getSize());
int fdX = Math.floorDiv(x, pipeline.getSize());
int fdZ = Math.floorDiv(z, pipeline.getSize());
return holderCache.get(new SeededVector(fdX, fdZ, seed)).getBiome(x - fdX * pipeline.getSize(),
z - fdZ * pipeline.getSize()).getBiome();
}
@@ -1,12 +1,5 @@
version = version("1.1.0")
version = version("1.2.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.chunkgenerator.lib.jafama")
}
@@ -16,8 +16,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.block.state.BlockState;
@@ -8,15 +8,14 @@
package com.dfsek.terra.addons.chunkgenerator.generation;
import net.jafama.FastMath;
import org.jetbrains.annotations.NotNull;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
import com.dfsek.terra.addons.chunkgenerator.generation.math.PaletteUtil;
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.LazilyEvaluatedInterpolator;
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.SamplerProvider;
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.config.ConfigPack;
@@ -133,8 +132,8 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
BiomePaletteInfo paletteInfo = biome.getContext().get(paletteInfoPropertyKey);
int fdX = FastMath.floorMod(x, 16);
int fdZ = FastMath.floorMod(z, 16);
int fdX = Math.floorMod(x, 16);
int fdZ = Math.floorMod(z, 16);
Palette palette = PaletteUtil.getPalette(fdX, y, fdZ, sampler, paletteInfo, 0);
double noise = sampler.sample(fdX, y, fdZ);
@@ -155,6 +154,16 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
return biomeProvider.getBiome(x, y, z, world.getSeed()).getContext().get(paletteInfoPropertyKey).paletteHolder().getPalette(y);
}
public double getSlant(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
int fdX = Math.floorMod(x, 16);
int fdZ = Math.floorMod(z, 16);
return biomeProvider.getBiome(x, y, z, world.getSeed())
.getContext()
.get(paletteInfoPropertyKey)
.slantHolder()
.calculateSlant(samplerCache.get(x, z, world, biomeProvider), fdX, y, fdZ);
}
public SamplerProvider samplerProvider() {
return samplerCache;
}
@@ -7,8 +7,8 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math;
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import net.jafama.FastMath;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.api.properties.PropertyKey;
import com.dfsek.terra.api.util.Column;
@@ -134,7 +132,7 @@ public class ChunkInterpolator {
}
private static int reRange(int value, int high) {
return FastMath.max(FastMath.min(value, high), 0);
return Math.max(Math.min(value, high), 0);
}
/**
@@ -146,7 +144,7 @@ public class ChunkInterpolator {
* @return double - The interpolated noise at the coordinates.
*/
public double getNoise(double x, double y, double z) {
return interpGrid[reRange(((int) x) / 4, 3)][(FastMath.max(FastMath.min(((int) y), max), min) - min) / 4][reRange(((int) z) / 4,
return interpGrid[reRange(((int) x) / 4, 3)][(Math.max(Math.min(((int) y), max), min) - min) / 4][reRange(((int) z) / 4,
3)].trilerp(
(x % 4) / 4, (y % 4) / 4, (z % 4) / 4);
}
@@ -1,7 +1,5 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import net.jafama.FastMath;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.api.properties.PropertyKey;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
@@ -30,8 +28,8 @@ public class LazilyEvaluatedInterpolator {
PropertyKey<BiomeNoiseProperties> noisePropertiesKey, int min, int horizontalRes, int verticalRes,
long seed) {
this.noisePropertiesKey = noisePropertiesKey;
int hSamples = FastMath.ceilToInt(16.0 / horizontalRes);
int vSamples = FastMath.ceilToInt((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)];
@@ -52,7 +50,7 @@ public class LazilyEvaluatedInterpolator {
int xi = ox + chunkX;
int zi = oz + chunkZ;
int y = FastMath.min(max, oy);
int y = Math.min(max, oy);
sample = biomeProvider
.getBiome(xi, y, zi, seed)
@@ -93,7 +91,7 @@ public class LazilyEvaluatedInterpolator {
return lerp_bottom;
}
double yFrac = (double) FastMath.floorMod(y, verticalRes) / verticalRes;
double yFrac = (double) Math.floorMod(y, verticalRes) / verticalRes;
double sample_0_1_0 = sample(xIndex, yIndex + 1, zIndex, x, y + verticalRes, z);
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers;
import net.jafama.FastMath;
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,10 +26,10 @@ public class Sampler3D {
}
public double sample(double x, double y, double z) {
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(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) {
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FastMath.roundToInt(x), FastMath.roundToInt(z));
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(x, z);
}
}
@@ -19,7 +19,6 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import net.jafama.FastMath;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.api.Platform;
@@ -45,8 +44,8 @@ public class SamplerProvider {
}
public Sampler3D get(int x, int z, WorldProperties world, BiomeProvider provider) {
int cx = FastMath.floorDiv(x, 16);
int cz = FastMath.floorDiv(z, 16);
int cx = Math.floorDiv(x, 16);
int cz = Math.floorDiv(z, 16);
return getChunk(cx, cz, world, provider);
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.chunkgenerator.palette;
import net.jafama.FastMath;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -55,11 +53,11 @@ public class PaletteHolder {
public PaletteHolder build() {
int min = FastMath.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
int max = FastMath.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
int min = Math.min(paletteMap.keySet().stream().min(Integer::compareTo).orElse(0), 0);
int max = Math.max(paletteMap.keySet().stream().max(Integer::compareTo).orElse(255), 255);
Palette[] palettes = new Palette[paletteMap.lastKey() + 1 - min];
for(int y = min; y <= FastMath.max(paletteMap.lastKey(), max); y++) {
for(int y = min; y <= Math.max(paletteMap.lastKey(), max); y++) {
Palette d = null;
for(Entry<Integer, Palette> e : paletteMap.entrySet()) {
if(e.getKey() >= y) {
@@ -2,11 +2,4 @@ version = version("1.0.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.feature.distributor.lib.jafama")
}
@@ -1,7 +1,5 @@
package com.dfsek.terra.addons.feature.distributor.distributors;
import net.jafama.FastMath;
import java.util.Random;
import com.dfsek.terra.api.structure.feature.Distributor;
@@ -21,21 +19,12 @@ public class PaddedGridDistributor implements Distributor {
this.cellWidth = width + padding;
}
private static long murmur64(long h) {
h ^= h >>> 33;
h *= 0xff51afd7ed558ccdL;
h ^= h >>> 33;
h *= 0xc4ceb9fe1a85ec53L;
h ^= h >>> 33;
return h;
}
@Override
public boolean matches(int x, int z, long seed) {
int cellX = FastMath.floorDiv(x, cellWidth);
int cellZ = FastMath.floorDiv(z, cellWidth);
int cellX = Math.floorDiv(x, cellWidth);
int cellZ = Math.floorDiv(z, cellWidth);
Random random = new Random((murmur64(MathUtil.squash(cellX, cellZ)) ^ seed) + salt);
Random random = new Random((MathUtil.murmur64(MathUtil.squash(cellX, cellZ)) ^ seed) + salt);
int pointX = random.nextInt(width) + cellX * cellWidth;
int pointZ = random.nextInt(width) + cellZ * cellWidth;
@@ -2,10 +2,4 @@ version = version("1.0.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.flora.lib.jafama")
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.flora.flora.gen;
import net.jafama.FastMath;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
@@ -60,7 +58,7 @@ public class TerraFlora implements Structure {
}
private ProbabilityCollection<BlockState> getStateCollection(int layer) {
return layers.get(FastMath.max(FastMath.min(layer, layers.size() - 1), 0));
return layers.get(Math.max(Math.min(layer, layers.size() - 1), 0));
}
private EnumSet<Direction> getFaces(Vector3Int b, WritableWorld world) {
@@ -82,8 +80,8 @@ public class TerraFlora implements Structure {
Direction.class);
if(doRotation && faces.size() == 0) return false; // Don't plant if no faces are valid.
for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor
int lvl = (FastMath.abs(i));
for(int i = 0; Math.abs(i) < size; i += c) { // Down if ceiling, up if floor
int lvl = (Math.abs(i));
BlockState data = getStateCollection((ceiling ? lvl : size - lvl - 1)).get(distribution, location.getX(), location.getY(),
location.getZ(), world.getSeed());
if(doRotation) {
@@ -2,11 +2,4 @@ version = version("1.1.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.feature.locator.lib.jafama")
}
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.feature.locator.locators;
import net.jafama.FastMath;
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;
@@ -27,8 +25,8 @@ public class PatternLocator implements Locator {
@Override
public BinaryColumn getSuitableCoordinates(Column<?> column) {
int min = FastMath.max(column.getMinY(), search.getMin());
int max = FastMath.min(column.getMaxY(), search.getMax());
int min = Math.max(column.getMinY(), search.getMin());
int max = Math.min(column.getMaxY(), search.getMax());
if(min >= max) return BinaryColumn.getNull();
return new BinaryColumn(min, max, y -> pattern.matches(y, column));
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.feature.locator.locators;
import net.jafama.FastMath;
import com.dfsek.terra.api.structure.feature.BinaryColumn;
import com.dfsek.terra.api.structure.feature.Locator;
import com.dfsek.terra.api.util.Range;
@@ -26,8 +24,8 @@ public class SurfaceLocator implements Locator {
@Override
public BinaryColumn getSuitableCoordinates(Column<?> column) {
BinaryColumnBuilder builder = column.newBinaryColumn();
int max = FastMath.min(search.getMax(), column.getMaxY());
int min = FastMath.max(search.getMin(), column.getMinY());
int max = Math.min(search.getMax(), column.getMaxY());
int min = Math.max(search.getMin(), column.getMinY());
if(min >= max) return builder.build();
for(int y = min; y < max; y++) {
if(column.getBlock(y).isAir() && !column.getBlock(y - 1).isAir()) {
@@ -22,7 +22,7 @@ public class TopLocator implements Locator {
@Override
public BinaryColumn getSuitableCoordinates(Column<?> column) {
for(int y : search) {
for(int y = search.getMax(); y >= search.getMin(); y--) {
if(column.getBlock(y).isAir() && !column.getBlock(y - 1).isAir()) {
return new BinaryColumn(y, y + 1, yi -> true);
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.feature.locator.patterns;
import net.jafama.FastMath;
import java.util.function.Predicate;
import com.dfsek.terra.api.block.state.BlockState;
@@ -28,8 +26,8 @@ public class MatchPattern implements Pattern {
@Override
public boolean matches(int y, Column<?> column) {
int min = FastMath.max(column.getMinY(), range.getMin() + y);
int max = FastMath.min(column.getMaxY(), range.getMax() + y);
int min = Math.max(column.getMinY(), range.getMin() + y);
int max = Math.min(column.getMaxY(), range.getMax() + y);
if(max <= min) return false;
for(int i = min; i < max; i++) {
if(!matches.test(column.getBlock(i))) return false;
@@ -39,8 +37,8 @@ public class MatchPattern implements Pattern {
@Override
public boolean matches(WritableWorld world, int x, int y, int z) {
int min = FastMath.max(world.getMinHeight(), range.getMin() + y);
int max = FastMath.min(world.getMaxHeight(), range.getMax() + y);
int min = Math.max(world.getMinHeight(), range.getMin() + y);
int max = Math.min(world.getMaxHeight(), range.getMax() + y);
if(max <= min) return false;
for(int i = min; i < max; i++) {
if(!matches.test(world.getBlockState(x, i, z))) return false;
@@ -1,16 +1,8 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
version = version("1.0.0")
version = version("1.1.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
api("com.dfsek", "paralithic", Versions.Libraries.paralithic)
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<ShadowJar>("shadowJar") {
relocate("com.dfsek.paralithic", "com.dfsek.terra.addons.noise.lib.paralithic")
relocate("net.jafama", "com.dfsek.terra.addons.noise.lib.jafama")
}
@@ -14,6 +14,7 @@ import java.util.Map;
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.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.templates.BinaryArithmeticTemplate;
import com.dfsek.terra.addons.noise.config.templates.DomainWarpTemplate;
@@ -21,8 +22,10 @@ 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;
import com.dfsek.terra.addons.noise.config.templates.noise.CellularNoiseTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.ConstantNoiseTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.DistanceSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.ExpressionFunctionTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.GaborNoiseTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.SimpleNoiseTemplate;
@@ -30,11 +33,14 @@ import com.dfsek.terra.addons.noise.config.templates.noise.fractal.BrownianMotio
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.PingPongTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.RidgedFractalTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.ClampNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.CubicSplineNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.ExpressionNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizerTemplate;
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;
@@ -42,6 +48,7 @@ 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;
@@ -83,8 +90,11 @@ public class NoiseAddon implements AddonInitializer {
(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, FunctionTemplate::new);
.applyLoader(FunctionTemplate.class, FunctionTemplate::new)
.applyLoader(CubicSpline.Point.class, CubicSplinePointTemplate::new);
noiseRegistry.register(addon.key("LINEAR"), LinearNormalizerTemplate::new);
noiseRegistry.register(addon.key("NORMAL"), NormalNormalizerTemplate::new);
@@ -92,6 +102,7 @@ public class NoiseAddon implements AddonInitializer {
noiseRegistry.register(addon.key("PROBABILITY"), ProbabilityNormalizerTemplate::new);
noiseRegistry.register(addon.key("SCALE"), ScaleNormalizerTemplate::new);
noiseRegistry.register(addon.key("POSTERIZATION"), PosterizationNormalizerTemplate::new);
noiseRegistry.register(addon.key("CUBIC_SPLINE"), CubicSplineNormalizerTemplate::new);
noiseRegistry.register(addon.key("IMAGE"), ImageSamplerTemplate::new);
@@ -116,12 +127,15 @@ public class NoiseAddon implements AddonInitializer {
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);
noiseRegistry.register(addon.key("CONSTANT"), ConstantNoiseTemplate::new);
noiseRegistry.register(addon.key("KERNEL"), KernelTemplate::new);
noiseRegistry.register(addon.key("LINEAR_HEIGHTMAP"), LinearHeightmapSamplerTemplate::new);
noiseRegistry.register(addon.key("TRANSLATE"), TranslateSamplerTemplate::new);
noiseRegistry.register(addon.key("ADD"), () -> new BinaryArithmeticTemplate<>(AdditionSampler::new));
noiseRegistry.register(addon.key("SUB"), () -> new BinaryArithmeticTemplate<>(SubtractionSampler::new));
@@ -134,7 +148,7 @@ public class NoiseAddon implements AddonInitializer {
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
noiseRegistry.register(addon.key("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions));
noiseRegistry.register(addon.key("EXPRESSION_NORMALIZER"), () -> new ExpressionNormalizerTemplate(packSamplers, packFunctions));
NoiseConfigPackTemplate template = event.loadTemplate(new NoiseConfigPackTemplate());
packSamplers.putAll(template.getSamplers());
@@ -0,0 +1,25 @@
package com.dfsek.terra.addons.noise.config;
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;
public class CubicSplinePointTemplate implements ObjectTemplate<Point> {
@Value("from")
private @Meta double from;
@Value("to")
private @Meta double to;
@Value("gradient")
private @Meta double gradient;
@Override
public Point get() {
return new Point(from, to, gradient);
}
}
@@ -4,6 +4,7 @@ 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;
@@ -11,14 +12,14 @@ import com.dfsek.terra.api.noise.NoiseSampler;
public class LinearHeightmapSamplerTemplate extends SamplerTemplate<LinearHeightmapSampler> {
@Value("sampler")
@Default
private NoiseSampler sampler = NoiseSampler.zero();
private @Meta NoiseSampler sampler = NoiseSampler.zero();
@Value("base")
private double base;
private @Meta double base;
@Value("scale")
@Default
private double scale = 1;
private @Meta double scale = 1;
@Override
public NoiseSampler get() {
@@ -0,0 +1,32 @@
package com.dfsek.terra.addons.noise.config.templates;
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 NoiseSampler sampler;
@Value("x")
@Default
private @Meta double x = 0;
@Value("y")
@Default
private @Meta double y = 0;
@Value("z")
@Default
private @Meta double z = 0;
@Override
public NoiseSampler get() {
return new TranslateSampler(sampler, x, y ,z);
}
}
@@ -0,0 +1,42 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
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 SamplerTemplate<DistanceSampler> {
@Value("distance-function")
@Default
private DistanceSampler.@Meta DistanceFunction distanceFunction = DistanceFunction.Euclidean;
@Value("point.x")
@Default
private @Meta double x = 0;
@Value("point.y")
@Default
private @Meta double y = 0;
@Value("point.z")
@Default
private @Meta double z = 0;
@Value("normalize")
@Default
private @Meta boolean normalize = false;
@Value("radius")
@Default
private @Meta double normalizeRadius = 100;
@Override
public DistanceSampler get() {
return new DistanceSampler(distanceFunction, x, y, z, normalize, normalizeRadius);
}
}
@@ -8,7 +8,6 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.Function;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -19,17 +18,16 @@ import java.util.Map;
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.paralithic.defined.UserDefinedFunction;
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2;
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
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<ExpressionFunction> {
private final Map<String, DimensionApplicableNoiseSampler> otherFunctions;
private final Map<String, DimensionApplicableNoiseSampler> globalSamplers;
private final Map<String, FunctionTemplate> globalFunctions;
@Value("variables")
@Default
@@ -43,44 +41,19 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> otherFunctions, Map<String, FunctionTemplate> samplers) {
this.otherFunctions = otherFunctions;
this.globalFunctions = samplers;
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers, Map<String, FunctionTemplate> globalFunctions) {
this.globalSamplers = globalSamplers;
this.globalFunctions = globalFunctions;
}
@Override
public NoiseSampler get() {
var mergedFunctions = new HashMap<>(globalFunctions); mergedFunctions.putAll(functions);
var mergedSamplers = new HashMap<>(globalSamplers); mergedSamplers.putAll(samplers);
try {
Map<String, Function> noiseFunctionMap = generateFunctions();
return new ExpressionFunction(noiseFunctionMap, expression, vars);
return new ExpressionFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars);
} catch(ParseException e) {
throw new RuntimeException("Failed to parse expression.", e);
}
}
private Map<String, Function> generateFunctions() throws ParseException {
Map<String, Function> noiseFunctionMap = new HashMap<>();
for(Map.Entry<String, FunctionTemplate> entry : globalFunctions.entrySet()) {
noiseFunctionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue()));
}
for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) {
noiseFunctionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue()));
}
otherFunctions.forEach((id, function) -> {
if(function.getDimensions() == 2) {
noiseFunctionMap.put(id, new NoiseFunction2(function.getSampler()));
} else noiseFunctionMap.put(id, new NoiseFunction3(function.getSampler()));
});
samplers.forEach((id, function) -> {
if(function.getDimensions() == 2) {
noiseFunctionMap.put(id, new NoiseFunction2(function.getSampler()));
} else noiseFunctionMap.put(id, new NoiseFunction3(function.getSampler()));
});
return noiseFunctionMap;
}
}
@@ -0,0 +1,23 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.List;
import com.dfsek.terra.addons.noise.math.CubicSpline;
import com.dfsek.terra.addons.noise.math.CubicSpline.Point;
import com.dfsek.terra.addons.noise.normalizer.CubicSplineNoiseSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
public class CubicSplineNormalizerTemplate extends NormalizerTemplate<CubicSplineNoiseSampler> {
@Value("points")
private @Meta List<@Meta Point> points;
@Override
public NoiseSampler get() {
return new CubicSplineNoiseSampler(function, new CubicSpline(points));
}
}
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2020-2021 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.normalizer;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.addons.noise.normalizer.ExpressionNormalizer;
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({ "unused", "FieldMayBeFinal" })
public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionNormalizer> {
private final Map<String, DimensionApplicableNoiseSampler> globalSamplers;
private final Map<String, FunctionTemplate> globalFunctions;
@Value("expression")
private @Meta String expression;
@Value("variables")
@Default
private @Meta Map<String, @Meta Double> vars = new HashMap<>();
@Value("samplers")
@Default
private @Meta LinkedHashMap<String, @Meta DimensionApplicableNoiseSampler> samplers = new LinkedHashMap<>();
@Value("functions")
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
public ExpressionNormalizerTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers, Map<String, FunctionTemplate> globalFunctions) {
this.globalSamplers = globalSamplers;
this.globalFunctions = globalFunctions;
}
@Override
public NoiseSampler get() {
var mergedFunctions = new HashMap<>(globalFunctions); mergedFunctions.putAll(functions);
var mergedSamplers = new HashMap<>(globalSamplers); mergedSamplers.putAll(samplers);
try {
return new ExpressionNormalizer(function, convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars);
} catch(ParseException e) {
throw new RuntimeException("Failed to parse expression.", e);
}
}
}
@@ -0,0 +1,87 @@
package com.dfsek.terra.addons.noise.math;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
import static com.dfsek.terra.api.util.MathUtil.lerp;
public class CubicSpline {
private final double[] fromValues;
private final double[] toValues;
private final double[] gradients;
public CubicSpline(List<Point> points) {
Collections.sort(points);
this.fromValues = new double[points.size()];
this.toValues = new double[points.size()];
this.gradients = new double[points.size()];
for(int i = 0; i < points.size(); i++) {
fromValues[i] = points.get(i).from;
toValues[i] = points.get(i).to;
gradients[i] = points.get(i).gradient;
}
}
public double apply(double in) {
return calculate(in, fromValues, toValues, gradients);
}
public static double calculate(double in, double[] fromValues, double[] toValues, double[] gradients) {
int pointIdx = floorBinarySearch(in, fromValues) - 1;
int pointIdxLast = fromValues.length - 1;
if (pointIdx < 0) { // If to left of first point return linear function intersecting said point using point's gradient
return gradients[0] * (in - fromValues[0]) + toValues[0];
} else if (pointIdx == pointIdxLast) { // Do same if to right of last point
return gradients[pointIdxLast] * (in - fromValues[pointIdxLast]) + toValues[pointIdxLast];
} else {
double fromLeft = fromValues[pointIdx];
double fromRight = fromValues[pointIdx + 1];
double toLeft = toValues[pointIdx];
double toRight = toValues[pointIdx + 1];
double gradientLeft = gradients[pointIdx];
double gradientRight = gradients[pointIdx + 1];
double fromDelta = fromRight - fromLeft;
double toDelta = toRight - toLeft;
double t = (in - fromLeft) / fromDelta;
return lerp(t, toLeft, toRight) + t * (1.0F - t) * lerp(t, gradientLeft * fromDelta - toDelta, -gradientRight * fromDelta + toDelta);
}
}
private static int floorBinarySearch(double targetValue, double[] values) {
int left = 0;
int right = values.length;
int idx = right - left;
while (idx > 0) {
int halfDelta = idx / 2;
int mid = left + halfDelta;
if (targetValue < values[mid]) {
idx = halfDelta;
} else {
left = mid + 1;
idx -= halfDelta + 1;
}
}
return left;
}
public record Point(double from, double to, double gradient) implements Comparable<Point> {
@Override
public int compareTo(@NotNull CubicSpline.Point o) {
return Double.compare(from, o.from);
}
}
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.noise.normalizer;
import net.jafama.FastMath;
import com.dfsek.terra.api.noise.NoiseSampler;
@@ -24,6 +22,6 @@ public class ClampNormalizer extends Normalizer {
@Override
public double normalize(double in) {
return FastMath.max(FastMath.min(in, max), min);
return Math.max(Math.min(in, max), min);
}
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.addons.noise.normalizer;
import com.dfsek.terra.addons.noise.math.CubicSpline;
import com.dfsek.terra.api.noise.NoiseSampler;
public class CubicSplineNoiseSampler extends Normalizer {
private final CubicSpline spline;
public CubicSplineNoiseSampler(NoiseSampler sampler, CubicSpline spline) {
super(sampler);
this.spline = spline;
}
@Override
public double normalize(double in) {
return spline.apply(in);
}
}
@@ -0,0 +1,33 @@
package com.dfsek.terra.addons.noise.normalizer;
import com.dfsek.paralithic.Expression;
import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.Function;
import java.util.Map;
import com.dfsek.terra.api.noise.NoiseSampler;
public class ExpressionNormalizer extends Normalizer {
private final Expression expression;
public ExpressionNormalizer(NoiseSampler sampler, Map<String, Function> functions, String eq, Map<String, Double> vars)
throws ParseException {
super(sampler);
Parser p = new Parser();
Scope scope = new Scope();
scope.addInvocationVariable("in");
vars.forEach(scope::create);
functions.forEach(p::registerFunction);
expression = p.parse(eq, scope);
}
@Override
public double normalize(double in) {
return expression.evaluate(in);
}
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.noise.normalizer;
import net.jafama.FastMath;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
@@ -41,8 +39,8 @@ public class NormalNormalizer extends Normalizer {
end = mid;
}
}
double left = FastMath.abs(lookup[start] - in);
double right = FastMath.abs(lookup[end] - in);
double left = Math.abs(lookup[start] - in);
double right = Math.abs(lookup[end] - in);
double fin;
if(left <= right) {
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.noise.normalizer;
import net.jafama.FastMath;
import com.dfsek.terra.api.noise.NoiseSampler;
@@ -22,6 +20,6 @@ public class PosterizationNormalizer extends Normalizer {
@Override
public double normalize(double in) {
return FastMath.roundToInt((in + 1) / stepSize) * stepSize - 1;
return (int) Math.round((in + 1) / stepSize) * stepSize - 1;
}
}
@@ -0,0 +1,31 @@
package com.dfsek.terra.addons.noise.paralithic;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.Function;
import java.util.HashMap;
import java.util.Map;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.addons.noise.paralithic.defined.UserDefinedFunction;
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2;
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
public class FunctionUtil {
private FunctionUtil() {}
public static Map<String, Function> convertFunctionsAndSamplers(Map<String, FunctionTemplate> functions,
Map<String, DimensionApplicableNoiseSampler> samplers) throws ParseException {
Map<String, Function> functionMap = new HashMap<>();
for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) {
functionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue()));
}
samplers.forEach((id, sampler) -> functionMap.put(id,
sampler.getDimensions() == 2 ?
new NoiseFunction2(sampler.getSampler()) :
new NoiseFunction3(sampler.getSampler())));
return functionMap;
}
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.noise.samplers;
import net.jafama.FastMath;
import java.awt.image.BufferedImage;
import com.dfsek.terra.api.noise.NoiseSampler;
@@ -28,8 +26,8 @@ public class ImageSampler implements NoiseSampler {
@Override
public double noise(long seed, double x, double y) {
return ((channel.getChannel(image.getRGB(FastMath.floorMod(FastMath.floorToInt(x * frequency), image.getWidth()),
FastMath.floorMod(FastMath.floorToInt(y * frequency), image.getHeight()))) / 255D) - 0.5) *
return ((channel.getChannel(image.getRGB(Math.floorMod((int) Math.floor(x * frequency), image.getWidth()),
Math.floorMod((int) Math.floor(y * frequency), image.getHeight()))) / 255D) - 0.5) *
2;
}
@@ -0,0 +1,27 @@
package com.dfsek.terra.addons.noise.samplers;
import com.dfsek.terra.api.noise.NoiseSampler;
public class TranslateSampler implements NoiseSampler {
private final NoiseSampler sampler;
private final double dx, dy, dz;
public TranslateSampler(NoiseSampler sampler, double dx, double dy, double dz) {
this.sampler = sampler;
this.dx = dx;
this.dy = dy;
this.dz = dz;
}
@Override
public double noise(long seed, double x, double y) {
return sampler.noise(seed, x - dx, y - dz);
}
@Override
public double noise(long seed, double x, double y, double z) {
return sampler.noise(seed, x - dx, y - dy, z - dz);
}
}
@@ -1,7 +1,5 @@
package com.dfsek.terra.addons.noise.samplers.arithmetic;
import net.jafama.FastMath;
import com.dfsek.terra.api.noise.NoiseSampler;
@@ -12,6 +10,6 @@ public class MaxSampler extends BinaryArithmeticSampler {
@Override
public double operate(double left, double right) {
return FastMath.max(left, right);
return Math.max(left, right);
}
}
@@ -1,7 +1,5 @@
package com.dfsek.terra.addons.noise.samplers.arithmetic;
import net.jafama.FastMath;
import com.dfsek.terra.api.noise.NoiseSampler;
@@ -12,6 +10,6 @@ public class MinSampler extends BinaryArithmeticSampler {
@Override
public double operate(double left, double right) {
return FastMath.min(left, right);
return Math.min(left, right);
}
}
@@ -7,8 +7,6 @@
package com.dfsek.terra.addons.noise.samplers.noise;
import net.jafama.FastMath;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.api.noise.NoiseSampler;
@@ -223,8 +221,8 @@ public class CellularSampler extends NoiseFunction {
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int xr = fastRound(x);
int yr = fastRound(y);
int xr = (int) Math.round(x);
int yr = (int) Math.round(y);
double distance0 = Double.MAX_VALUE;
double distance1 = Double.MAX_VALUE;
@@ -240,105 +238,43 @@ public class CellularSampler extends NoiseFunction {
double centerX = x;
double centerY = y;
switch(distanceFunction) {
default:
case Euclidean:
case EuclideanSq:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int hash = hash(seed, xPrimed, yPrimed);
int idx = hash & (255 << 1);
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
double newDistance = vecX * vecX + vecY * vecY;
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int hash = hash(seed, xPrimed, yPrimed);
int idx = hash & (255 << 1);
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
double newDistance = switch(distanceFunction) {
case Manhattan -> Math.abs(vecX) + Math.abs(vecY);
case Hybrid -> (Math.abs(vecX) + Math.abs(vecY)) + (vecX * vecX + vecY * vecY);
default -> vecX * vecX + vecY * vecY;
};
distance1 = Math.max(Math.min(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
break;
case Manhattan:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int hash = hash(seed, xPrimed, yPrimed);
int idx = hash & (255 << 1);
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
double newDistance = fastAbs(vecX) + fastAbs(vecY);
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
case Hybrid:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int hash = hash(seed, xPrimed, yPrimed);
int idx = hash & (255 << 1);
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
double newDistance = (fastAbs(vecX) + fastAbs(vecY)) + (vecX * vecX + vecY * vecY);
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
distance0 = fastSqrt(distance0);
distance0 = Math.sqrt(distance0);
if(returnType != ReturnType.CellValue) {
distance1 = fastSqrt(distance1);
distance1 = Math.sqrt(distance1);
}
}
@@ -351,21 +287,22 @@ public class CellularSampler extends NoiseFunction {
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
case Distance2Div -> distance0 / distance1 - 1;
case NoiseLookup -> noiseLookup.noise(sl, centerX, centerY);
case LocalNoiseLookup -> noiseLookup.noise(sl, x / frequency - centerX, y / frequency - centerY);
case Distance3 -> distance2 - 1;
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
case Distance3Sub -> distance2 - distance0 - 1;
case Distance3Mul -> distance2 * distance0 - 1;
case Distance3Div -> distance0 / distance2 - 1;
case Angle -> FastMath.atan2(y / frequency - centerY, x / frequency - centerX);
case Angle -> Math.atan2(y / frequency - centerY, x / frequency - centerX);
};
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int xr = fastRound(x);
int yr = fastRound(y);
int zr = fastRound(z);
int xr = (int) Math.round(x);
int yr = (int) Math.round(y);
int zr = (int) Math.round(z);
double distance0 = Double.MAX_VALUE;
double distance1 = Double.MAX_VALUE;
@@ -382,126 +319,53 @@ public class CellularSampler extends NoiseFunction {
double centerY = y;
double centerZ = z;
switch(distanceFunction) {
case Euclidean:
case EuclideanSq:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int zPrimed = zPrimedBase;
for(int zi = zr - 1; zi <= zr + 1; zi++) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
int idx = hash & (255 << 2);
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int zPrimed = zPrimedBase;
for(int zi = zr - 1; zi <= zr + 1; zi++) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
int idx = hash & (255 << 2);
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
double newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
centerZ = ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
zPrimed += PRIME_Z;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
case Manhattan:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int zPrimed = zPrimedBase;
for(int zi = zr - 1; zi <= zr + 1; zi++) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
int idx = hash & (255 << 2);
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
double newDistance = fastAbs(vecX) + fastAbs(vecY) + fastAbs(vecZ);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
centerZ = ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
zPrimed += PRIME_Z;
double newDistance = 0;
switch(distanceFunction) {
case Euclidean, EuclideanSq -> newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
case Manhattan -> newDistance = Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ);
case Hybrid -> {
newDistance = (Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ);
distance1 = Math.max(Math.min(distance1, newDistance), distance0);
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
break;
case Hybrid:
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int zPrimed = zPrimedBase;
for(int zi = zr - 1; zi <= zr + 1; zi++) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
int idx = hash & (255 << 2);
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
double newDistance = (fastAbs(vecX) + fastAbs(vecY) + fastAbs(vecZ)) +
(vecX * vecX + vecY * vecY + vecZ * vecZ);
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
centerZ = ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
zPrimed += PRIME_Z;
}
yPrimed += PRIME_Y;
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
centerZ = ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
xPrimed += PRIME_X;
zPrimed += PRIME_Z;
}
break;
default:
break;
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
distance0 = fastSqrt(distance0);
distance0 = Math.sqrt(distance0);
if(returnType != ReturnType.CellValue) {
distance1 = fastSqrt(distance1);
distance1 = Math.sqrt(distance1);
}
}
@@ -514,12 +378,13 @@ public class CellularSampler extends NoiseFunction {
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
case Distance2Div -> distance0 / distance1 - 1;
case NoiseLookup -> noiseLookup.noise(sl, centerX, centerY, centerZ);
case LocalNoiseLookup -> noiseLookup.noise(sl, x / frequency - centerX, y / frequency - centerY, z / frequency - centerZ);
case Distance3 -> distance2 - 1;
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
case Distance3Sub -> distance2 - distance0 - 1;
case Distance3Mul -> distance2 * distance0 - 1;
case Distance3Div -> distance0 / distance2 - 1;
case Angle -> FastMath.atan2(y / frequency - centerY, x / frequency - centerX);
case Angle -> Math.atan2(y / frequency - centerY, x / frequency - centerX);
};
}
@@ -540,6 +405,7 @@ public class CellularSampler extends NoiseFunction {
Distance2Mul,
Distance2Div,
NoiseLookup,
LocalNoiseLookup,
Distance3,
Distance3Add,
Distance3Sub,
@@ -0,0 +1,66 @@
package com.dfsek.terra.addons.noise.samplers.noise;
public class DistanceSampler extends NoiseFunction {
private final DistanceFunction distanceFunction;
private final double ox, oy, oz;
private final boolean normalize;
private final double radius;
private final double distanceAtRadius;
public DistanceSampler(DistanceFunction distanceFunction, double ox, double oy, double oz, boolean normalize, double radius) {
frequency = 1;
this.distanceFunction = distanceFunction;
this.ox = ox;
this.oy = oy;
this.oz = oz;
this.normalize = normalize;
this.radius = radius;
this.distanceAtRadius = distance2d(distanceFunction, radius, 0); // distance2d and distance3d should return the same value
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
double dx = x - ox;
double dy = y - oz;
if (normalize && (Math.abs(dx) > radius || Math.abs(dy) > radius)) return 1;
double dist = distance2d(distanceFunction, dx, dy);
if (normalize) return Math.min(((2*dist)/distanceAtRadius)-1, 1);
return dist;
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
double dx = x - ox;
double dy = y - oy;
double dz = z - oz;
if(normalize && (Math.abs(dx) > radius || Math.abs(dy) > radius || Math.abs(dz) > radius)) return 1;
double dist = distance3d(distanceFunction, dx, dy, dz);
if (normalize) return Math.min(((2*dist)/distanceAtRadius)-1, 1);
return dist;
}
private static double distance2d(DistanceFunction distanceFunction, double x, double z) {
return switch(distanceFunction) {
case Euclidean -> Math.sqrt(x*x + z*z);
case EuclideanSq -> x*x + z*z;
case Manhattan -> Math.abs(x) + Math.abs(z);
};
}
private static double distance3d(DistanceFunction distanceFunction, double x, double y, double z) {
return switch(distanceFunction) {
case Euclidean -> Math.sqrt(x*x + y*y + z*z);
case EuclideanSq -> x*x + y*y + z*z;
case Manhattan -> Math.abs(x) + Math.abs(y) + Math.abs(z);
};
}
public enum DistanceFunction {
Euclidean,
EuclideanSq,
Manhattan
}
}
@@ -7,9 +7,8 @@
package com.dfsek.terra.addons.noise.samplers.noise;
import net.jafama.FastMath;
import com.dfsek.terra.addons.noise.samplers.noise.random.WhiteNoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
public class GaborNoiseSampler extends NoiseFunction {
@@ -17,11 +16,11 @@ public class GaborNoiseSampler extends NoiseFunction {
private double k = 1.0;
private double a = 0.1;
private double f0 = 0.625;
private double kernelRadius = (FastMath.sqrt(-FastMath.log(0.05) / Math.PI) / a);
private double kernelRadius = (Math.sqrt(-Math.log(0.05) / Math.PI) / a);
private double impulsesPerKernel = 64d;
private double impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius));
private double impulsesPerCell = impulseDensity * kernelRadius * kernelRadius;
private double g = FastMath.exp(-impulsesPerCell);
private double g = Math.exp(-impulsesPerCell);
private double omega0 = Math.PI * 0.25;
private boolean isotropic = true;
@@ -32,17 +31,17 @@ public class GaborNoiseSampler extends NoiseFunction {
}
private void recalculateRadiusAndDensity() {
kernelRadius = (FastMath.sqrt(-FastMath.log(0.05) / Math.PI) / this.a);
kernelRadius = (Math.sqrt(-Math.log(0.05) / Math.PI) / this.a);
impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius));
impulsesPerCell = impulseDensity * kernelRadius * kernelRadius;
g = FastMath.exp(-impulsesPerCell);
g = Math.exp(-impulsesPerCell);
}
private double gaborNoise(long seed, double x, double y) {
x /= kernelRadius;
y /= kernelRadius;
int xi = fastFloor(x);
int yi = fastFloor(y);
int xi = (int) Math.floor(x);
int yi = (int) Math.floor(y);
double xf = x - xi;
double yf = y - yi;
double noise = 0;
@@ -55,7 +54,7 @@ public class GaborNoiseSampler extends NoiseFunction {
}
private double calculateCell(long seed, int xi, int yi, double x, double y) {
long mashedSeed = murmur64(31L * xi + yi) + seed;
long mashedSeed = MathUtil.murmur64(31L * xi + yi) + seed;
double gaussianSource = (rand.getNoiseRaw(mashedSeed++) + 1) / 2;
int impulses = 0;
@@ -73,7 +72,7 @@ public class GaborNoiseSampler extends NoiseFunction {
}
private double gabor(double omega_0, double x, double y) {
return k * (FastMath.exp(-Math.PI * (a * a) * (x * x + y * y)) * fastCos(2 * Math.PI * f0 * (x * fastCos(omega_0) + y * fastSin(
return k * (Math.exp(-Math.PI * (a * a) * (x * x + y * y)) * MathUtil.cos(2 * Math.PI * f0 * (x * MathUtil.cos(omega_0) + y * MathUtil.sin(
omega_0))));
}
@@ -7,25 +7,15 @@
package com.dfsek.terra.addons.noise.samplers.noise;
import net.jafama.FastMath;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings("ManualMinMaxCalculation")
public abstract class NoiseFunction implements NoiseSampler {
// Hashing
protected static final int PRIME_X = 501125321;
protected static final int PRIME_Y = 1136930381;
protected static final int PRIME_Z = 1720413743;
static final int precision = 100;
static final int modulus = 360 * precision;
static final double[] sin = new double[360 * 100]; // lookup table
static {
for(int i = 0; i < sin.length; i++) {
sin[i] = (float) Math.sin((double) (i) / (precision));
}
}
protected double frequency = 0.02d;
protected long salt;
@@ -33,10 +23,6 @@ public abstract class NoiseFunction implements NoiseSampler {
this.salt = 0;
}
protected static int fastFloor(double f) {
return f >= 0 ? (int) f : (int) f - 1;
}
protected static int hash(int seed, int xPrimed, int yPrimed, int zPrimed) {
int hash = seed ^ xPrimed ^ yPrimed ^ zPrimed;
@@ -51,77 +37,6 @@ public abstract class NoiseFunction implements NoiseSampler {
return hash;
}
protected static int fastRound(double f) {
return f >= 0 ? (int) (f + 0.5f) : (int) (f - 0.5);
}
protected static double lerp(double a, double b, double t) {
return a + t * (b - a);
}
protected static double interpHermite(double t) {
return t * t * (3 - 2 * t);
}
protected static double interpQuintic(double t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
protected static double cubicLerp(double a, double b, double c, double d, double t) {
double p = (d - c) - (a - b);
return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b;
}
protected static double fastMin(double a, double b) {
return a < b ? a : b;
}
protected static double fastMax(double a, double b) {
return a > b ? a : b;
}
protected static double fastAbs(double f) {
return f < 0 ? -f : f;
}
protected static double fastSqrt(double f) {
return FastMath.sqrt(f);
}
protected static int fastCeil(double f) {
int i = (int) f;
if(i < f) i++;
return i;
}
/**
* Murmur64 hashing function
*
* @param h Input value
*
* @return Hashed value
*/
protected static long murmur64(long h) {
h ^= h >>> 33;
h *= 0xff51afd7ed558ccdL;
h ^= h >>> 33;
h *= 0xc4ceb9fe1a85ec53L;
h ^= h >>> 33;
return h;
}
protected static double fastSin(double a) {
return sinLookup((int) (a * precision + 0.5f));
}
protected static double fastCos(double a) {
return sinLookup((int) ((a + Math.PI / 2) * precision + 0.5f));
}
private static double sinLookup(int a) {
return a >= 0 ? sin[a % (modulus)] : -sin[-a % (modulus)];
}
public void setSalt(long salt) {
this.salt = salt;
}
@@ -8,6 +8,7 @@
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
public class BrownianMotionSampler extends FractalNoiseFunction {
@@ -23,7 +24,7 @@ public class BrownianMotionSampler extends FractalNoiseFunction {
for(int i = 0; i < octaves; i++) {
double noise = input.noise(seed++, x, y);
sum += noise * amp;
amp *= lerp(1.0, fastMin(noise + 1, 2) * 0.5, weightedStrength);
amp *= MathUtil.lerp(1.0, Math.min(noise + 1, 2) * 0.5, weightedStrength);
x *= lacunarity;
y *= lacunarity;
@@ -41,7 +42,7 @@ public class BrownianMotionSampler extends FractalNoiseFunction {
for(int i = 0; i < octaves; i++) {
double noise = input.noise(seed++, x, y, z);
sum += noise * amp;
amp *= lerp(1.0, (noise + 1) * 0.5, weightedStrength);
amp *= MathUtil.lerp(1.0, (noise + 1) * 0.5, weightedStrength);
x *= lacunarity;
y *= lacunarity;
@@ -25,7 +25,7 @@ public abstract class FractalNoiseFunction extends NoiseFunction {
}
protected void calculateFractalBounding() {
double gain = fastAbs(this.gain);
double gain = Math.abs(this.gain);
double amp = gain;
double ampFractal = 1.0;
for(int i = 1; i < octaves; i++) {
@@ -8,6 +8,7 @@
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
public class PingPongSampler extends FractalNoiseFunction {
@@ -35,7 +36,7 @@ public class PingPongSampler extends FractalNoiseFunction {
for(int i = 0; i < octaves; i++) {
double noise = pingPong((input.noise(seed++, x, y) + 1) * pingPongStrength);
sum += (noise - 0.5) * 2 * amp;
amp *= lerp(1.0, noise, weightedStrength);
amp *= MathUtil.lerp(1.0, noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
@@ -53,7 +54,7 @@ public class PingPongSampler extends FractalNoiseFunction {
for(int i = 0; i < octaves; i++) {
double noise = pingPong((input.noise(seed++, x, y, z) + 1) * pingPongStrength);
sum += (noise - 0.5) * 2 * amp;
amp *= lerp(1.0, noise, weightedStrength);
amp *= MathUtil.lerp(1.0, noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
@@ -8,6 +8,7 @@
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
public class RidgedFractalSampler extends FractalNoiseFunction {
@@ -22,9 +23,9 @@ public class RidgedFractalSampler extends FractalNoiseFunction {
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = fastAbs(input.noise(seed++, x, y));
double noise = Math.abs(input.noise(seed++, x, y));
sum += (noise * -2 + 1) * amp;
amp *= lerp(1.0, 1 - noise, weightedStrength);
amp *= MathUtil.lerp(1.0, 1 - noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
@@ -40,9 +41,9 @@ public class RidgedFractalSampler extends FractalNoiseFunction {
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = fastAbs(input.noise(seed++, x, y, z));
double noise = Math.abs(input.noise(seed++, x, y, z));
sum += (noise * -2 + 1) * amp;
amp *= lerp(1.0, 1 - noise, weightedStrength);
amp *= MathUtil.lerp(1.0, 1 - noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
@@ -7,6 +7,9 @@
package com.dfsek.terra.addons.noise.samplers.noise.random;
import com.dfsek.terra.api.util.MathUtil;
/**
* NoiseSampler implementation to produce random, uniformly distributed (white) noise.
*/
@@ -15,7 +18,7 @@ public class PositiveWhiteNoiseSampler extends WhiteNoiseSampler {
// Bits that when applied to the exponent/sign section of a double, produce a positive number with a power of 1.
public double getNoiseRaw(long seed) {
return (Double.longBitsToDouble((murmur64(seed) & 0x000fffffffffffffL) | POSITIVE_POW1) - 1.5) * 2;
return (Double.longBitsToDouble((MathUtil.murmur64(seed) & 0x000fffffffffffffL) | POSITIVE_POW1) - 1.5) * 2;
}
@Override
@@ -8,6 +8,7 @@
package com.dfsek.terra.addons.noise.samplers.noise.random;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
import com.dfsek.terra.api.util.MathUtil;
/**
@@ -24,18 +25,18 @@ public class WhiteNoiseSampler extends NoiseFunction {
long hashX = Double.doubleToRawLongBits(x) ^ seed;
long hashZ = Double.doubleToRawLongBits(y) ^ seed;
long hash = (((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed) + Double.doubleToRawLongBits(z);
return murmur64(hash);
return MathUtil.murmur64(hash);
}
public long randomBits(long seed, double x, double y) {
long hashX = Double.doubleToRawLongBits(x) ^ seed;
long hashZ = Double.doubleToRawLongBits(y) ^ seed;
long hash = ((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed;
return murmur64(hash);
return MathUtil.murmur64(hash);
}
public double getNoiseRaw(long seed) {
return (Double.longBitsToDouble((murmur64(seed) & 0x000fffffffffffffL) | POSITIVE_POW1) - 1.5) * 2;
return (Double.longBitsToDouble((MathUtil.murmur64(seed) & 0x000fffffffffffffL) | POSITIVE_POW1) - 1.5) * 2;
}
@Override
@@ -26,8 +26,8 @@ public class OpenSimplex2SSampler extends SimplexStyleSampler {
y += s;
int i = fastFloor(x);
int j = fastFloor(y);
int i = (int) Math.floor(x);
int j = (int) Math.floor(y);
double xi = x - i;
double yi = y - j;
@@ -131,9 +131,9 @@ public class OpenSimplex2SSampler extends SimplexStyleSampler {
z = r - z;
int i = fastFloor(x);
int j = fastFloor(y);
int k = fastFloor(z);
int i = (int) Math.floor(x);
int j = (int) Math.floor(y);
int k = (int) Math.floor(z);
double xi = x - i;
double yi = y - j;
double zi = z - k;
@@ -25,8 +25,8 @@ public class OpenSimplex2Sampler extends SimplexStyleSampler {
y += s;
int i = fastFloor(x);
int j = fastFloor(y);
int i = (int) Math.floor(x);
int j = (int) Math.floor(y);
double xi = x - i;
double yi = y - j;
@@ -85,9 +85,9 @@ public class OpenSimplex2Sampler extends SimplexStyleSampler {
z = r - z;
int i = fastRound(x);
int j = fastRound(y);
int k = fastRound(z);
int i = (int) Math.round(x);
int j = (int) Math.round(y);
int k = (int) Math.round(z);
double x0 = x - i;
double y0 = y - j;
double z0 = z - k;
@@ -7,6 +7,9 @@
package com.dfsek.terra.addons.noise.samplers.noise.simplex;
import com.dfsek.terra.api.util.MathUtil;
/**
* NoiseSampler implementation to provide Perlin Noise.
*/
@@ -14,34 +17,34 @@ public class PerlinSampler extends SimplexStyleSampler {
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x0 = fastFloor(x);
int y0 = fastFloor(y);
int x0 = (int) Math.floor(x);
int y0 = (int) Math.floor(y);
double xd0 = x - x0;
double yd0 = y - y0;
double xd1 = xd0 - 1;
double yd1 = yd0 - 1;
double xs = interpQuintic(xd0);
double ys = interpQuintic(yd0);
double xs = MathUtil.interpQuintic(xd0);
double ys = MathUtil.interpQuintic(yd0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
int x1 = x0 + PRIME_X;
int y1 = y0 + PRIME_Y;
double xf0 = lerp(gradCoord(seed, x0, y0, xd0, yd0), gradCoord(seed, x1, y0, xd1, yd0), xs);
double xf1 = lerp(gradCoord(seed, x0, y1, xd0, yd1), gradCoord(seed, x1, y1, xd1, yd1), xs);
double xf0 = MathUtil.lerp(gradCoord(seed, x0, y0, xd0, yd0), gradCoord(seed, x1, y0, xd1, yd0), xs);
double xf1 = MathUtil.lerp(gradCoord(seed, x0, y1, xd0, yd1), gradCoord(seed, x1, y1, xd1, yd1), xs);
return lerp(xf0, xf1, ys) * 1.4247691104677813;
return MathUtil.lerp(xf0, xf1, ys) * 1.4247691104677813;
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x0 = fastFloor(x);
int y0 = fastFloor(y);
int z0 = fastFloor(z);
int x0 = (int) Math.floor(x);
int y0 = (int) Math.floor(y);
int z0 = (int) Math.floor(z);
double xd0 = x - x0;
double yd0 = y - y0;
@@ -50,9 +53,9 @@ public class PerlinSampler extends SimplexStyleSampler {
double yd1 = yd0 - 1;
double zd1 = zd0 - 1;
double xs = interpQuintic(xd0);
double ys = interpQuintic(yd0);
double zs = interpQuintic(zd0);
double xs = MathUtil.interpQuintic(xd0);
double ys = MathUtil.interpQuintic(yd0);
double zs = MathUtil.interpQuintic(zd0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
@@ -61,14 +64,14 @@ public class PerlinSampler extends SimplexStyleSampler {
int y1 = y0 + PRIME_Y;
int z1 = z0 + PRIME_Z;
double xf00 = lerp(gradCoord(seed, x0, y0, z0, xd0, yd0, zd0), gradCoord(seed, x1, y0, z0, xd1, yd0, zd0), xs);
double xf10 = lerp(gradCoord(seed, x0, y1, z0, xd0, yd1, zd0), gradCoord(seed, x1, y1, z0, xd1, yd1, zd0), xs);
double xf01 = lerp(gradCoord(seed, x0, y0, z1, xd0, yd0, zd1), gradCoord(seed, x1, y0, z1, xd1, yd0, zd1), xs);
double xf11 = lerp(gradCoord(seed, x0, y1, z1, xd0, yd1, zd1), gradCoord(seed, x1, y1, z1, xd1, yd1, zd1), xs);
double xf00 = MathUtil.lerp(gradCoord(seed, x0, y0, z0, xd0, yd0, zd0), gradCoord(seed, x1, y0, z0, xd1, yd0, zd0), xs);
double xf10 = MathUtil.lerp(gradCoord(seed, x0, y1, z0, xd0, yd1, zd0), gradCoord(seed, x1, y1, z0, xd1, yd1, zd0), xs);
double xf01 = MathUtil.lerp(gradCoord(seed, x0, y0, z1, xd0, yd0, zd1), gradCoord(seed, x1, y0, z1, xd1, yd0, zd1), xs);
double xf11 = MathUtil.lerp(gradCoord(seed, x0, y1, z1, xd0, yd1, zd1), gradCoord(seed, x1, y1, z1, xd1, yd1, zd1), xs);
double yf0 = lerp(xf00, xf10, ys);
double yf1 = lerp(xf01, xf11, ys);
double yf0 = MathUtil.lerp(xf00, xf10, ys);
double yf1 = MathUtil.lerp(xf01, xf11, ys);
return lerp(yf0, yf1, zs) * 0.964921414852142333984375;
return MathUtil.lerp(yf0, yf1, zs) * 0.964921414852142333984375;
}
}
@@ -61,8 +61,8 @@ public class SimplexSampler extends SimplexStyleSampler {
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
double t = (x + y) * F2;
int i = fastFloor(x + t);
int j = fastFloor(y + t);
int i = (int) Math.floor(x + t);
int j = (int) Math.floor(y + t);
t = (i + j) * G2;
double X0 = i - t;
@@ -118,9 +118,9 @@ public class SimplexSampler extends SimplexStyleSampler {
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
double t = (x + y + z) * F3;
int i = fastFloor(x + t);
int j = fastFloor(y + t);
int k = fastFloor(z + t);
int i = (int) Math.floor(x + t);
int j = (int) Math.floor(y + t);
int k = (int) Math.floor(z + t);
t = (i + j + k) * G3;
double x0 = x - (i - t);
@@ -7,12 +7,15 @@
package com.dfsek.terra.addons.noise.samplers.noise.value;
import com.dfsek.terra.api.util.MathUtil;
public class ValueCubicSampler extends ValueStyleNoise {
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x1 = fastFloor(x);
int y1 = fastFloor(y);
int x1 = (int) Math.floor(x);
int y1 = (int) Math.floor(y);
double xs = x - x1;
double ys = y - y1;
@@ -26,14 +29,14 @@ public class ValueCubicSampler extends ValueStyleNoise {
int x3 = x1 + (PRIME_X << 1);
int y3 = y1 + (PRIME_Y << 1);
return cubicLerp(
cubicLerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), valCoord(seed, x2, y0), valCoord(seed, x3, y0),
return MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), valCoord(seed, x2, y0), valCoord(seed, x3, y0),
xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), valCoord(seed, x2, y1), valCoord(seed, x3, y1),
xs),
cubicLerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), valCoord(seed, x2, y1), valCoord(seed, x3, y1),
MathUtil.cubicLerp(valCoord(seed, x0, y2), valCoord(seed, x1, y2), valCoord(seed, x2, y2), valCoord(seed, x3, y2),
xs),
cubicLerp(valCoord(seed, x0, y2), valCoord(seed, x1, y2), valCoord(seed, x2, y2), valCoord(seed, x3, y2),
xs),
cubicLerp(valCoord(seed, x0, y3), valCoord(seed, x1, y3), valCoord(seed, x2, y3), valCoord(seed, x3, y3),
MathUtil.cubicLerp(valCoord(seed, x0, y3), valCoord(seed, x1, y3), valCoord(seed, x2, y3), valCoord(seed, x3, y3),
xs),
ys) * (1 / (1.5 * 1.5));
}
@@ -41,9 +44,9 @@ public class ValueCubicSampler extends ValueStyleNoise {
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x1 = fastFloor(x);
int y1 = fastFloor(y);
int z1 = fastFloor(z);
int x1 = (int) Math.floor(x);
int y1 = (int) Math.floor(y);
int z1 = (int) Math.floor(z);
double xs = x - x1;
double ys = y - y1;
@@ -63,45 +66,45 @@ public class ValueCubicSampler extends ValueStyleNoise {
int y3 = y1 + (PRIME_Y << 1);
int z3 = z1 + (PRIME_Z << 1);
return cubicLerp(
cubicLerp(
cubicLerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), valCoord(seed, x2, y0, z0),
return MathUtil.cubicLerp(
MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), valCoord(seed, x2, y0, z0),
valCoord(seed, x3, y0, z0), xs),
cubicLerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), valCoord(seed, x2, y1, z0),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), valCoord(seed, x2, y1, z0),
valCoord(seed, x3, y1, z0), xs),
cubicLerp(valCoord(seed, x0, y2, z0), valCoord(seed, x1, y2, z0), valCoord(seed, x2, y2, z0),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z0), valCoord(seed, x1, y2, z0), valCoord(seed, x2, y2, z0),
valCoord(seed, x3, y2, z0), xs),
cubicLerp(valCoord(seed, x0, y3, z0), valCoord(seed, x1, y3, z0), valCoord(seed, x2, y3, z0),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z0), valCoord(seed, x1, y3, z0), valCoord(seed, x2, y3, z0),
valCoord(seed, x3, y3, z0), xs),
ys),
cubicLerp(
cubicLerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), valCoord(seed, x2, y0, z1),
MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), valCoord(seed, x2, y0, z1),
valCoord(seed, x3, y0, z1), xs),
cubicLerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), valCoord(seed, x2, y1, z1),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), valCoord(seed, x2, y1, z1),
valCoord(seed, x3, y1, z1), xs),
cubicLerp(valCoord(seed, x0, y2, z1), valCoord(seed, x1, y2, z1), valCoord(seed, x2, y2, z1),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z1), valCoord(seed, x1, y2, z1), valCoord(seed, x2, y2, z1),
valCoord(seed, x3, y2, z1), xs),
cubicLerp(valCoord(seed, x0, y3, z1), valCoord(seed, x1, y3, z1), valCoord(seed, x2, y3, z1),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z1), valCoord(seed, x1, y3, z1), valCoord(seed, x2, y3, z1),
valCoord(seed, x3, y3, z1), xs),
ys),
cubicLerp(
cubicLerp(valCoord(seed, x0, y0, z2), valCoord(seed, x1, y0, z2), valCoord(seed, x2, y0, z2),
MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0, z2), valCoord(seed, x1, y0, z2), valCoord(seed, x2, y0, z2),
valCoord(seed, x3, y0, z2), xs),
cubicLerp(valCoord(seed, x0, y1, z2), valCoord(seed, x1, y1, z2), valCoord(seed, x2, y1, z2),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z2), valCoord(seed, x1, y1, z2), valCoord(seed, x2, y1, z2),
valCoord(seed, x3, y1, z2), xs),
cubicLerp(valCoord(seed, x0, y2, z2), valCoord(seed, x1, y2, z2), valCoord(seed, x2, y2, z2),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z2), valCoord(seed, x1, y2, z2), valCoord(seed, x2, y2, z2),
valCoord(seed, x3, y2, z2), xs),
cubicLerp(valCoord(seed, x0, y3, z2), valCoord(seed, x1, y3, z2), valCoord(seed, x2, y3, z2),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z2), valCoord(seed, x1, y3, z2), valCoord(seed, x2, y3, z2),
valCoord(seed, x3, y3, z2), xs),
ys),
cubicLerp(
cubicLerp(valCoord(seed, x0, y0, z3), valCoord(seed, x1, y0, z3), valCoord(seed, x2, y0, z3),
MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0, z3), valCoord(seed, x1, y0, z3), valCoord(seed, x2, y0, z3),
valCoord(seed, x3, y0, z3), xs),
cubicLerp(valCoord(seed, x0, y1, z3), valCoord(seed, x1, y1, z3), valCoord(seed, x2, y1, z3),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z3), valCoord(seed, x1, y1, z3), valCoord(seed, x2, y1, z3),
valCoord(seed, x3, y1, z3), xs),
cubicLerp(valCoord(seed, x0, y2, z3), valCoord(seed, x1, y2, z3), valCoord(seed, x2, y2, z3),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z3), valCoord(seed, x1, y2, z3), valCoord(seed, x2, y2, z3),
valCoord(seed, x3, y2, z3), xs),
cubicLerp(valCoord(seed, x0, y3, z3), valCoord(seed, x1, y3, z3), valCoord(seed, x2, y3, z3),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z3), valCoord(seed, x1, y3, z3), valCoord(seed, x2, y3, z3),
valCoord(seed, x3, y3, z3), xs),
ys),
zs) * (1 / (1.5 * 1.5 * 1.5));
@@ -7,37 +7,40 @@
package com.dfsek.terra.addons.noise.samplers.noise.value;
import com.dfsek.terra.api.util.MathUtil;
public class ValueSampler extends ValueStyleNoise {
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x0 = fastFloor(x);
int y0 = fastFloor(y);
int x0 = (int) Math.floor(x);
int y0 = (int) Math.floor(y);
double xs = interpHermite(x - x0);
double ys = interpHermite(y - y0);
double xs = MathUtil.interpHermite(x - x0);
double ys = MathUtil.interpHermite(y - y0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
int x1 = x0 + PRIME_X;
int y1 = y0 + PRIME_Y;
double xf0 = lerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), xs);
double xf1 = lerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), xs);
double xf0 = MathUtil.lerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), xs);
double xf1 = MathUtil.lerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), xs);
return lerp(xf0, xf1, ys);
return MathUtil.lerp(xf0, xf1, ys);
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x0 = fastFloor(x);
int y0 = fastFloor(y);
int z0 = fastFloor(z);
int x0 = (int) Math.floor(x);
int y0 = (int) Math.floor(y);
int z0 = (int) Math.floor(z);
double xs = interpHermite(x - x0);
double ys = interpHermite(y - y0);
double zs = interpHermite(z - z0);
double xs = MathUtil.interpHermite(x - x0);
double ys = MathUtil.interpHermite(y - y0);
double zs = MathUtil.interpHermite(z - z0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
@@ -46,14 +49,14 @@ public class ValueSampler extends ValueStyleNoise {
int y1 = y0 + PRIME_Y;
int z1 = z0 + PRIME_Z;
double xf00 = lerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), xs);
double xf10 = lerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), xs);
double xf01 = lerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), xs);
double xf11 = lerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), xs);
double xf00 = MathUtil.lerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), xs);
double xf10 = MathUtil.lerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), xs);
double xf01 = MathUtil.lerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), xs);
double xf11 = MathUtil.lerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), xs);
double yf0 = lerp(xf00, xf10, ys);
double yf1 = lerp(xf01, xf11, ys);
double yf0 = MathUtil.lerp(xf00, xf10, ys);
double yf1 = MathUtil.lerp(xf01, xf11, ys);
return lerp(yf0, yf1, zs);
return MathUtil.lerp(yf0, yf1, zs);
}
}
@@ -0,0 +1,13 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
version = version("1.0.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
api("com.dfsek", "paralithic", Versions.Libraries.paralithic)
}
tasks.named<ShadowJar>("shadowJar") {
relocate("com.dfsek.paralithic", "com.dfsek.terra.addons.numberpredicate.lib.paralithic")
}
@@ -0,0 +1,34 @@
package com.dfsek.terra.addons.numberpredicate;
import com.dfsek.paralithic.Expression;
import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
import java.util.function.DoublePredicate;
public class DoublePredicateLoader implements TypeLoader<DoublePredicate> {
@Override
public DoublePredicate load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
DepthTracker depthTracker) throws LoadException {
if (o instanceof String expressionString) {
Scope scope = new Scope();
scope.addInvocationVariable("value");
try {
Expression expression = new Parser().parse(expressionString, scope);
return d -> expression.evaluate(d) != 0; // Paralithic expressions treat '!= 0' as true
} catch(ParseException e) {
throw new LoadException("Failed to parse double predicate expression", e, depthTracker);
}
} else {
throw new LoadException("Double predicates must be defined as a string. E.g. 'value > 3'", depthTracker);
}
}
}
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2020-2021 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.numberpredicate;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.DoublePredicate;
import java.util.function.Supplier;
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.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
public class NumberPredicateAddon implements AddonInitializer {
@Inject
private Platform plugin;
@Inject
private BaseAddon addon;
@Override
public void initialize() {
plugin.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack().applyLoader(DoublePredicate.class, new DoublePredicateLoader()))
.priority(50)
.failThrough();
}
}
@@ -0,0 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
id: config-number-predicate
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.numberpredicate.NumberPredicateAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
@@ -2,10 +2,5 @@ version = version("1.0.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.ore.lib.jafama")
}
@@ -14,8 +14,13 @@ 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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OreAddon implements AddonInitializer {
private static final Logger logger = LoggerFactory.getLogger(OreAddon.class);
@Inject
private Platform platform;
@@ -29,5 +34,8 @@ public class OreAddon implements AddonInitializer {
.register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack().registerConfigType(new OreConfigType(), addon.key("ORE"), 1))
.failThrough();
if(platform.getTerraConfig().isDebugLog())
logger.warn("The ore-config addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the ore-config-v2 addon for future pack development instead.");
}
}
@@ -7,14 +7,14 @@
package com.dfsek.terra.addons.ore.ores;
import net.jafama.FastMath;
import java.util.BitSet;
import java.util.Map;
import java.util.Random;
import com.dfsek.terra.api.block.BlockType;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.util.MathUtil;
import com.dfsek.terra.api.util.Rotation;
import com.dfsek.terra.api.util.collection.MaterialSet;
import com.dfsek.terra.api.util.vector.Vector3Int;
@@ -41,57 +41,130 @@ public class VanillaOre implements Structure {
this.materials = materials;
}
protected static boolean shouldNotDiscard(Random random, double chance) {
if(chance <= 0.0F) {
return true;
} else if(chance >= 1.0F) {
return false;
} else {
return random.nextFloat() >= chance;
}
}
public static double lerp(double t, double v0, double v1) {
return v0 + t * (v1 - v0);
}
@Override
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
int centerX = location.getX();
int centerZ = location.getZ();
int centerY = location.getY();
float randomRadian = random.nextFloat() * (float) Math.PI;
double eigthSize = size / 8.0F;
// Place points to form a line segment
double startX = (double) location.getX() + MathUtil.sin(randomRadian) * eigthSize;
double endX = (double) location.getX() - MathUtil.sin(randomRadian) * eigthSize;
float f = random.nextFloat() * (float) Math.PI;
double startZ = (double) location.getZ() + MathUtil.cos(randomRadian) * eigthSize;
double endZ = (double) location.getZ() - MathUtil.cos(randomRadian) * eigthSize;
double d1 = centerX + 8 + FastMath.sin(f) * size / 8.0F;
double d2 = centerX + 8 - FastMath.sin(f) * size / 8.0F;
double d3 = centerZ + 8 + FastMath.cos(f) * size / 8.0F;
double d4 = centerZ + 8 - FastMath.cos(f) * size / 8.0F;
double startY = location.getY() + random.nextInt(3) - 2;
double endY = location.getY() + random.nextInt(3) - 2;
double d5 = centerY + random.nextInt(3) - 2D;
double d6 = centerY + random.nextInt(3) - 2D;
int sizeInt = (int) size;
double[] points = new double[sizeInt * 4];
for(int i = 0; i < size; i++) {
float iFactor = (float) i / (float) size;
double d10 = random.nextDouble() * size / 16.0D;
double d11 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0;
double d12 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0;
int xStart = FastMath.roundToInt(FastMath.floor(d1 + (d2 - d1) * iFactor - d11 / 2.0D));
int yStart = FastMath.roundToInt(FastMath.floor(d5 + (d6 - d5) * iFactor - d12 / 2.0D));
int zStart = FastMath.roundToInt(FastMath.floor(d3 + (d4 - d3) * iFactor - d11 / 2.0D));
int xEnd = FastMath.roundToInt(FastMath.floor(d1 + (d2 - d1) * iFactor + d11 / 2.0D));
int yEnd = FastMath.roundToInt(FastMath.floor(d5 + (d6 - d5) * iFactor + d12 / 2.0D));
int zEnd = FastMath.roundToInt(FastMath.floor(d3 + (d4 - d3) * iFactor + d11 / 2.0D));
for(int x = xStart; x <= xEnd; x++) {
double d13 = (x + 0.5D - (d1 + (d2 - d1) * iFactor)) / (d11 / 2.0D);
// Compute initial point positions and radius
for(int i = 0; i < sizeInt; ++i) {
float t = (float) i / (float) sizeInt;
double xt = lerp(t, startX, endX);
double yt = lerp(t, startY, endY);
double zt = lerp(t, startZ, endZ);
double roll = random.nextDouble() * size / 16.0;
// Taper radius closer to line ends
double radius = ((MathUtil.sin((float) Math.PI * t) + 1.0F) * roll + 1.0) / 2.0;
points[i * 4] = xt;
points[i * 4 + 1] = yt;
points[i * 4 + 2] = zt;
points[i * 4 + 3] = radius;
}
// Compare every point to every other point
for(int a = 0; a < sizeInt - 1; ++a) {
double radiusA = points[a * 4 + 3];
if(radiusA > 0.0) {
for(int b = a + 1; b < sizeInt; ++b) {
double radiusB = points[b * 4 + 3];
if(radiusB > 0.0) {
double dxt = points[a * 4] - points[b * 4];
double dyt = points[a * 4 + 1] - points[b * 4 + 1];
double dzt = points[a * 4 + 2] - points[b * 4 + 2];
double dRadius = radiusA - radiusB;
// If the radius difference is greater than the distance between the two points
if(dRadius * dRadius > dxt * dxt + dyt * dyt + dzt * dzt) {
// Set smaller of two radii to -1
if(dRadius > 0.0) {
points[b * 4 + 3] = -1.0;
} else {
points[a * 4 + 3] = -1.0;
}
}
}
}
}
}
int outset = (int) Math.ceil((size / 16.0F * 2.0F + 1.0F) / 2.0F);
int x = (int) (location.getX() - Math.ceil(eigthSize) - outset);
int y = location.getY() - 2 - outset;
int z = (int) (location.getZ() - Math.ceil(eigthSize) - outset);
int horizontalSize = (int) (2 * (Math.ceil(eigthSize) + outset));
int verticalSize = 2 * (2 + outset);
int sphereCount = 0;
BitSet visited = new BitSet(horizontalSize * verticalSize * horizontalSize);
// Generate a sphere at each point
for(int i = 0; i < sizeInt; ++i) {
double radius = points[i * 4 + 3];
if(radius > 0.0) {
double xt = points[i * 4];
double yt = points[i * 4 + 1];
double zt = points[i * 4 + 2];
if(d13 * d13 < 1.0D) {
for(int y = yStart; y <= yEnd; y++) {
double d14 = (y + 0.5D - (d5 + (d6 - d5) * iFactor)) / (d12 / 2.0D);
if(d13 * d13 + d14 * d14 < 1.0D) {
for(int z = zStart; z <= zEnd; z++) {
double d15 = (z + 0.5D - (d3 + (d4 - d3) * iFactor)) / (d11 / 2.0D);
if(y >= world.getMaxHeight() || y < world.getMinHeight()) continue;
BlockType block = world.getBlockState(x, y, z).getBlockType();
if((d13 * d13 + d14 * d14 + d15 * d15 < 1.0D) && getReplaceable().contains(block)) {
if(exposed > random.nextDouble() || !(world.getBlockState(x, y, z - 1).isAir() ||
world.getBlockState(x, y, z + 1).isAir() ||
world.getBlockState(x, y - 1, z).isAir() ||
world.getBlockState(x, y + 1, z).isAir() ||
world.getBlockState(x - 1, y, z).isAir() ||
world.getBlockState(x + 1, y, z).isAir())) {
world.setBlockState(x, y, z, getMaterial(block), isApplyGravity());
int xLowerBound = (int) Math.max(Math.floor(xt - radius), x);
int xUpperBound = (int) Math.max(Math.floor(xt + radius), xLowerBound);
int yLowerBound = (int) Math.max(Math.floor(yt - radius), y);
int yUpperBound = (int) Math.max(Math.floor(yt + radius), yLowerBound);
int zLowerBound = (int) Math.max(Math.floor(zt - radius), z);
int zUpperBound = (int) Math.max(Math.floor(zt + radius), zLowerBound);
// Iterate over coordinates within bounds
for(int xi = xLowerBound; xi <= xUpperBound; ++xi) {
double dx = ((double) xi + 0.5 - xt) / radius;
if(dx * dx < 1.0) {
for(int yi = yLowerBound; yi <= yUpperBound; ++yi) {
double dy = ((double) yi + 0.5 - yt) / radius;
if(dx * dx + dy * dy < 1.0) {
for(int zi = zLowerBound; zi <= zUpperBound; ++zi) {
double dz = ((double) zi + 0.5 - zt) / radius;
// If position is inside the sphere
if(dx * dx + dy * dy + dz * dz < 1.0 && !(yi < world.getMinHeight() || yi >= world.getMaxHeight())) {
int index = xi - x + (yi - y) * horizontalSize + (zi - z) * horizontalSize * verticalSize;
if(!visited.get(index)) { // Skip blocks that have already been visited
visited.set(index);
BlockType block = world.getBlockState(xi, yi, zi).getBlockType();
if(shouldPlace(block, random, world, xi, yi, zi)) {
world.setBlockState(xi, yi, zi, getMaterial(block), isApplyGravity());
++sphereCount;
break;
}
}
}
}
}
@@ -100,7 +173,23 @@ public class VanillaOre implements Structure {
}
}
}
return true;
return sphereCount > 0;
}
public boolean shouldPlace(BlockType type, Random random, WritableWorld world, int x, int y, int z) {
if(!getReplaceable().contains(type)) {
return false;
} else if(shouldNotDiscard(random, exposed)) {
return true;
} else {
return !(world.getBlockState(x, y, z - 1).isAir() ||
world.getBlockState(x, y, z + 1).isAir() ||
world.getBlockState(x, y - 1, z).isAir() ||
world.getBlockState(x, y + 1, z).isAir() ||
world.getBlockState(x - 1, y, z).isAir() ||
world.getBlockState(x + 1, y, z).isAir());
}
}
public BlockState getMaterial(BlockType replace) {
@@ -3,11 +3,4 @@ version = version("1.0.0")
dependencies {
api("com.googlecode.json-simple:json-simple:1.1.1")
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.structure.lib.jafama")
}
@@ -7,7 +7,6 @@
package com.dfsek.terra.addons.structure.structures.loot;
import net.jafama.FastMath;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@@ -62,12 +61,12 @@ public class Entry {
max = (long) ((JSONObject) loot).get("max");
min = (long) ((JSONObject) loot).get("min");
}
functions.add(new AmountFunction(FastMath.toIntExact(min), FastMath.toIntExact(max)));
functions.add(new AmountFunction(Math.toIntExact(min), Math.toIntExact(max)));
}
case "minecraft:set_damage", "set_damage" -> {
long maxDamage = (long) ((JSONObject) ((JSONObject) function).get("damage")).get("max");
long minDamage = (long) ((JSONObject) ((JSONObject) function).get("damage")).get("min");
functions.add(new DamageFunction(FastMath.toIntExact(minDamage), FastMath.toIntExact(maxDamage)));
functions.add(new DamageFunction(Math.toIntExact(minDamage), Math.toIntExact(maxDamage)));
}
case "minecraft:enchant_with_levels", "enchant_with_levels" -> {
long maxEnchant = (long) ((JSONObject) ((JSONObject) function).get("levels")).get("max");
@@ -76,7 +75,7 @@ public class Entry {
if(((JSONObject) function).containsKey("disabled_enchants"))
disabled = (JSONArray) ((JSONObject) function).get("disabled_enchants");
functions.add(
new EnchantFunction(FastMath.toIntExact(minEnchant), FastMath.toIntExact(maxEnchant), disabled, platform));
new EnchantFunction(Math.toIntExact(minEnchant), Math.toIntExact(maxEnchant), disabled, platform));
}
}
}
@@ -7,7 +7,6 @@
package com.dfsek.terra.addons.structure.structures.loot;
import net.jafama.FastMath;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@@ -37,16 +36,16 @@ public class Pool {
entries = new ProbabilityCollection<>();
Object amount = pool.get("rolls");
if(amount instanceof Long) {
max = FastMath.toIntExact((Long) amount);
min = FastMath.toIntExact((Long) amount);
max = Math.toIntExact((Long) amount);
min = Math.toIntExact((Long) amount);
} else {
max = FastMath.toIntExact((Long) ((JSONObject) amount).get("max"));
min = FastMath.toIntExact((Long) ((JSONObject) amount).get("min"));
max = Math.toIntExact((Long) ((JSONObject) amount).get("max"));
min = Math.toIntExact((Long) ((JSONObject) amount).get("min"));
}
for(Object entryJSON : (JSONArray) pool.get("entries")) {
Entry entry = new Entry((JSONObject) entryJSON, platform);
entries.add(entry, FastMath.toIntExact(entry.getWeight()));
entries.add(entry, Math.toIntExact(entry.getWeight()));
}
}
@@ -7,7 +7,6 @@
package com.dfsek.terra.addons.structure.structures.loot.functions;
import net.jafama.FastMath;
import org.json.simple.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -57,7 +56,7 @@ public class EnchantFunction implements LootFunction {
possible.add(ench);
}
}
int numEnchant = (r.nextInt((int) FastMath.abs(enchant)) / 10 + 1);
int numEnchant = (r.nextInt((int) Math.abs(enchant)) / 10 + 1);
Collections.shuffle(possible);
ItemMeta meta = original.getItemMeta();
iter:
@@ -68,12 +67,12 @@ public class EnchantFunction implements LootFunction {
}
int lvl = r.nextInt(1 + (int) (((enchant / 40 > 1) ? 1 : enchant / 40) * (chosen.getMaxLevel())));
try {
meta.addEnchantment(chosen, FastMath.max(lvl, 1));
meta.addEnchantment(chosen, Math.max(lvl, 1));
} catch(IllegalArgumentException e) {
LOGGER.warn(
"Attempted to enchant {} with {} at level {}, but an unexpected exception occurred! Usually this is caused by a " +
"misbehaving enchantment plugin.",
original.getType(), chosen, FastMath.max(lvl, 1));
original.getType(), chosen, Math.max(lvl, 1));
}
}
original.setItemMeta(meta);
+3 -3
View File
@@ -1,8 +1,8 @@
version = version("1.0.0")
version = version("1.0.1")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
}
@@ -4,8 +4,10 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.function.Supplier;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.addons.image.config.ColorLoader;
import com.dfsek.terra.addons.image.config.ColorLoader.ColorString;
import com.dfsek.terra.addons.image.config.ImageLibraryPackConfigTemplate;
import com.dfsek.terra.addons.image.config.noisesampler.ChannelNoiseSamplerTemplate;
import com.dfsek.terra.addons.image.config.noisesampler.DistanceTransformNoiseSamplerTemplate;
import com.dfsek.terra.addons.image.config.image.ImageTemplate;
@@ -15,9 +17,12 @@ import com.dfsek.terra.addons.image.config.colorsampler.image.SingleImageColorSa
import com.dfsek.terra.addons.image.config.colorsampler.image.TileImageColorSamplerTemplate;
import com.dfsek.terra.addons.image.config.colorsampler.mutate.RotateColorSamplerTemplate;
import com.dfsek.terra.addons.image.config.colorsampler.mutate.TranslateColorSamplerTemplate;
import com.dfsek.terra.addons.image.config.image.ImageTemplate;
import com.dfsek.terra.addons.image.config.image.StitchedImageTemplate;
import com.dfsek.terra.addons.image.config.noisesampler.ChannelNoiseSamplerTemplate;
import com.dfsek.terra.addons.image.config.noisesampler.DistanceTransformNoiseSamplerTemplate;
import com.dfsek.terra.addons.image.image.Image;
import com.dfsek.terra.addons.image.operator.DistanceTransform;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
@@ -52,6 +57,10 @@ public class ImageLibraryAddon implements AddonInitializer {
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.priority(10)
.then(event -> {
ImageLibraryPackConfigTemplate config = event.loadTemplate(new ImageLibraryPackConfigTemplate());
event.getPack().getContext().put(config);
})
.then(event -> {
ConfigPack pack = event.getPack();
CheckedRegistry<Supplier<ObjectTemplate<Image>>> imageRegistry = pack.getOrCreateRegistry(IMAGE_REGISTRY_KEY);
@@ -1,8 +1,8 @@
package com.dfsek.terra.addons.image.colorsampler.image;
import com.dfsek.terra.addons.image.image.Image;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.addons.image.colorsampler.image.transform.ImageTransformation;
import com.dfsek.terra.addons.image.image.Image;
public class SingleImageColorSampler implements ColorSampler {
@@ -1,10 +1,8 @@
package com.dfsek.terra.addons.image.colorsampler.image;
import net.jafama.FastMath;
import com.dfsek.terra.addons.image.image.Image;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.addons.image.colorsampler.image.transform.ImageTransformation;
import com.dfsek.terra.addons.image.image.Image;
public class TileImageColorSampler implements ColorSampler {
@@ -22,6 +20,6 @@ public class TileImageColorSampler implements ColorSampler {
public int apply(int x, int z) {
x = transformation.transformX(image, x);
z = transformation.transformZ(image, z);
return image.getRGB(FastMath.floorMod(x, image.getWidth()), FastMath.floorMod(z, image.getHeight()));
return image.getRGB(Math.floorMod(x, image.getWidth()), Math.floorMod(z, image.getHeight()));
}
}
@@ -1,8 +1,7 @@
package com.dfsek.terra.addons.image.colorsampler.mutate;
import net.jafama.FastMath;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.api.util.MathUtil;
public class RotateColorSampler implements ColorSampler {
@@ -29,7 +28,7 @@ public class RotateColorSampler implements ColorSampler {
else
rotationMethod = RotationMethod.RAD_ANY;
this.radians = FastMath.toRadians(degrees);
this.radians = Math.toRadians(degrees);
}
@Override
@@ -39,14 +38,14 @@ public class RotateColorSampler implements ColorSampler {
case DEG_90 -> -z;
case DEG_180 -> -x;
case DEG_270 -> z;
case RAD_ANY -> (int) (x * FastMath.cos(radians) - z * FastMath.sin(radians));
case RAD_ANY -> (int) (x * MathUtil.cos(radians) - z * MathUtil.sin(radians));
};
int rz = switch(rotationMethod) {
case DEG_0 -> z;
case DEG_90 -> x;
case DEG_180 -> -z;
case DEG_270 -> -x;
case RAD_ANY -> (int) (z * FastMath.cos(radians) + x * FastMath.sin(radians));
case RAD_ANY -> (int) (z * MathUtil.cos(radians) + x * MathUtil.sin(radians));
};
return sampler.apply(rx, rz);
}
@@ -0,0 +1,37 @@
package com.dfsek.terra.addons.image.config;
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
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;
import com.dfsek.terra.api.properties.Properties;
public class ImageLibraryPackConfigTemplate implements ConfigTemplate, Properties {
// TODO - These would be better as plugin wide config parameters in config.yml
@Value("images.cache.load-on-use")
@Description("If set to true, images will load into memory upon use rather than on pack load.")
@Default
private boolean loadOnUse = false;
@Value("images.cache.timeout")
@Description("How many seconds to keep images loaded in the image cache for. " +
"If set to a number greater than 0, images will be removed from memory if not used after the timeout, otherwise images will stay loaded in memory. " +
"Setting the timeout to greater than 0 will trade decreased memory consumption when not performing any image reads for a period of time for extra processing time required to perform cache lookups.")
@Default
private int cacheTimeout = 0;
public boolean loadOnUse() {
return loadOnUse;
}
public boolean unloadOnTimeout() {
return cacheTimeout > 0;
}
public int getCacheTimeout() {
return cacheTimeout;
}
}
@@ -4,9 +4,9 @@ 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.image.image.Image;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.addons.image.colorsampler.image.transform.Alignment;
import com.dfsek.terra.addons.image.image.Image;
public abstract class ImageColorSamplerTemplate implements ObjectTemplate<ColorSampler> {

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