Reformat code

This commit is contained in:
Zoë Gidiere 2023-11-02 18:47:36 -06:00
parent d696e4fd24
commit 81a96d6b76
224 changed files with 1156 additions and 1075 deletions

View File

@ -51,13 +51,13 @@ assignees: ""
<!-- You can fill out the different items by putting the correct value beside each cell. -->
| Name | Value |
|------------------------------|-------|
| Terra Version | <!-- Put your Terra version here. (remove the comment) -->
| Platform / Platform Version | <!-- Put your platform and platform version here. (remove the comment) (eg. Spigot, Fabric, Paper, etc.) (If you are using the Region generator, put that here instead) -->
| Any External Plugins or Mods | <!-- Put a list of all the plugins or mods you have installed here. (remove the comment) (Make sure to NOT include any new lines) -->
| Terra Packs In Use | <!-- Put a list of all the Terra packs you have installed here. (remove the comment) (Make sure to NOT include any new lines) (/te packs may be used to get a list) -->
| Terra Addons In Use | <!-- Put a list of all the Terra addons you have installed here. (remove the comment) (Make sure to NOT include any new lines) (/te addons may be used to get a list) -->
| Name | Value |
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Terra Version | <!-- Put your Terra version here. (remove the comment) -->
| Platform / Platform Version | <!-- Put your platform and platform version here. (remove the comment) (eg. Spigot, Fabric, Paper, etc.) (If you are using the Region generator, put that here instead) -->
| Any External Plugins or Mods | <!-- Put a list of all the plugins or mods you have installed here. (remove the comment) (Make sure to NOT include any new lines) -->
| Terra Packs In Use | <!-- Put a list of all the Terra packs you have installed here. (remove the comment) (Make sure to NOT include any new lines) (/te packs may be used to get a list) -->
| Terra Addons In Use | <!-- Put a list of all the Terra addons you have installed here. (remove the comment) (Make sure to NOT include any new lines) (/te addons may be used to get a list) -->
## Issue Description

View File

@ -1,11 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Which Issue Template do I Choose?
url: https://github.com/PolyhedralDev/Terra/wiki/How-To-Choose-An-Issue-Template
about: Click this if you don't know which issue template to select. This will help you make sure you choose the right one and provide enough information for us to help you.
- name: Terra Wiki
url: https://github.com/PolyhedralDev/Terra/wiki
about: Documentation for all things Terra.
- name: Join the Support Discord
url: https://discord.dfsek.com
about: If you have a basic support question, join the Discord instead.
- name: Which Issue Template do I Choose?
url: https://github.com/PolyhedralDev/Terra/wiki/How-To-Choose-An-Issue-Template
about: Click this if you don't know which issue template to select. This will help you make sure you choose the right one and provide enough information for us to help you.
- name: Terra Wiki
url: https://github.com/PolyhedralDev/Terra/wiki
about: Documentation for all things Terra.
- name: Join the Support Discord
url: https://discord.dfsek.com
about: If you have a basic support question, join the Discord instead.

View File

@ -7,32 +7,32 @@ versionProjects(":platforms", version("6.4.0"))
allprojects {
group = "com.dfsek.terra"
configureCompilation()
configureDependencies()
configurePublishing()
tasks.withType<JavaCompile>().configureEach {
options.isFork = true
options.isIncremental = true
}
tasks.withType<Test>().configureEach {
useJUnitPlatform()
maxHeapSize = "2G"
ignoreFailures = false
failFast = true
maxParallelForks = (Runtime.getRuntime().availableProcessors() - 1).takeIf { it > 0 } ?: 1
reports.html.required.set(false)
reports.junitXml.required.set(false)
}
tasks.withType<Copy>().configureEach {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.withType<Jar>().configureEach {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
@ -45,11 +45,11 @@ afterEvaluate {
project(":platforms:bukkit:common").configureDistribution()
forSubProjects(":common:addons") {
apply(plugin = "com.github.johnrengelman.shadow")
tasks.named("build") {
finalizedBy(tasks.named("shadowJar"))
}
dependencies {
"compileOnly"(project(":common:api"))
"testImplementation"(project(":common:api"))

View File

@ -17,8 +17,8 @@ repositories {
dependencies {
//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("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.5.6")
implementation("org.ow2.asm", "asm", "9.5")
implementation("org.ow2.asm", "asm-tree", "9.5")
implementation("com.dfsek.tectonic", "common", "4.2.0")

View File

@ -88,7 +88,8 @@ fun Project.configureDistribution() {
val jar = getJarTask().archiveFileName.get()
resources.computeIfAbsent(
if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "addons/bootstrap"
else "addons") { ArrayList() }.add(jar)
else "addons"
) { ArrayList() }.add(jar)
}
val options = DumperOptions()
@ -109,7 +110,7 @@ fun Project.configureDistribution() {
FileWriter(manifest).use {
yaml.dump(resources, it)
}
}
}

View File

@ -56,7 +56,8 @@ object Versions {
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"

View File

@ -1,14 +1,14 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: biome-provider-extrusion
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.extrusion.BiomeExtrusionAddon"
- "com.dfsek.terra.addons.biome.extrusion.BiomeExtrusionAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
depends:
biome-query-api: "1.+"
biome-query-api: "1.+"

View File

@ -58,15 +58,19 @@ public class ImageBiomeProviderAddon implements AddonInitializer {
providerRegistry.register(addon.key("IMAGE"), ImageProviderTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry = event.getPack().getOrCreateRegistry(
BIOME_COLOR_CONVERTER_REGISTRY_KEY);
CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry =
event.getPack().getOrCreateRegistry(
BIOME_COLOR_CONVERTER_REGISTRY_KEY);
biomeColorConverterRegistry.register(addon.key("EXACT"), ExactBiomeColorConverterTemplate::new);
biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestBiomeColorConverterTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<Biome>>>> biomeColorMappingRegistry = event.getPack().getOrCreateRegistry(
BIOME_COLOR_MAPPING_REGISTRY_KEY);
biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"), () -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class), b -> b));
CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<Biome>>>> biomeColorMappingRegistry =
event.getPack().getOrCreateRegistry(
BIOME_COLOR_MAPPING_REGISTRY_KEY);
biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"),
() -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class),
b -> b));
biomeColorMappingRegistry.register(addon.key("MAP"), DefinedBiomeColorMappingTemplate::new);
})
.failThrough();

View File

@ -8,7 +8,7 @@ import com.dfsek.terra.api.world.biome.Biome;
public class ClosestBiomeColorConverterTemplate extends ClosestColorConverterTemplate<Biome> {
@Value("match")
private ColorMapping<Biome> match;

View File

@ -12,19 +12,19 @@ public class ExactBiomeColorConverterTemplate extends ExactColorConverterTemplat
@Value("match")
private ColorMapping<Biome> match;
@Value("else")
private Biome fallback;
@Value("ignore-alpha")
@Default
private boolean ignoreAlpha = true;
@Override
protected ColorMapping<Biome> getMapping() {
return match;
}
@Override
protected Biome getFallback() {
return fallback;

View File

@ -1,14 +1,14 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: biome-provider-image-v2
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.image.v2.ImageBiomeProviderAddon"
- "com.dfsek.terra.addons.biome.image.v2.ImageBiomeProviderAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
depends:
library-image: "1.+"
library-image: "1.+"

View File

@ -27,11 +27,9 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class ImageBiomeProviderAddon implements AddonInitializer {
private static final Logger logger = LoggerFactory.getLogger(ImageBiomeProviderAddon.class);
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
};
private static final Logger logger = LoggerFactory.getLogger(ImageBiomeProviderAddon.class);
@Inject
private Platform platform;
@ -51,6 +49,8 @@ public class ImageBiomeProviderAddon implements AddonInitializer {
})
.failThrough();
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.");
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.");
}
}

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: biome-provider-image
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.image.ImageBiomeProviderAddon"
- "com.dfsek.terra.addons.biome.image.ImageBiomeProviderAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -6,7 +6,7 @@ of "stages" to apply "mutations" to a 2D grid of biomes.
Version 2 is a re-implementation of the original addon with the primary goal of providing
consistent scaling for noise relative to the world
(See https://github.com/PolyhedralDev/Terra/issues/264 for more details), and has been
included as a separate addon to maintain parity with packs utilizing the first version.
included as a separate addon to maintain parity with packs utilizing the first version.
This addon registers the `PIPELINE` biome provider type, and all associated
configurations.

View File

@ -38,7 +38,7 @@ public class PipelineBiomeProvider implements BiomeProvider {
this.biomeChunkCache = Caffeine.newBuilder()
.maximumSize(64)
.build(pipeline::generateChunk);
Set<PipelineBiome> biomeSet = new HashSet<>();
pipeline.getSource().getBiomes().forEach(biomeSet::add);
Iterable<PipelineBiome> result = biomeSet;
@ -49,7 +49,7 @@ public class PipelineBiomeProvider implements BiomeProvider {
Iterable<PipelineBiome> finalResult = result;
result.forEach(pipelineBiome -> {
if(pipelineBiome.isPlaceholder()) {
StringBuilder biomeList = new StringBuilder("\n");
StreamSupport.stream(finalResult.spliterator(), false)
.sorted(Comparator.comparing(StringIdentifiable::getID))
@ -60,7 +60,8 @@ public class PipelineBiomeProvider implements BiomeProvider {
.append(delegate.getClass().getCanonicalName())
.append('\n'));
throw new IllegalArgumentException("Biome Pipeline leaks placeholder biome \"" + pipelineBiome.getID() +
"\". Ensure there is a stage to guarantee replacement of the placeholder biome. Biomes: " +
"\". Ensure there is a stage to guarantee replacement of the placeholder biome. " +
"Biomes: " +
biomeList);
}
this.biomes.add(pipelineBiome.getBiome());
@ -73,7 +74,7 @@ public class PipelineBiomeProvider implements BiomeProvider {
}
public Biome getBiome(int x, int z, long seed) {
x += mutator.noise(seed + 1, x, z) * noiseAmp;
z += mutator.noise(seed + 2, x, z) * noiseAmp;

View File

@ -7,8 +7,6 @@ import com.dfsek.terra.api.world.biome.Biome;
public interface PipelineBiome extends StringIdentifiable {
Biome getBiome();
static PipelineBiome placeholder(String id) {
return new PlaceholderPipelineBiome(id);
}
@ -21,6 +19,8 @@ public interface PipelineBiome extends StringIdentifiable {
return SelfPipelineBiome.INSTANCE;
}
Biome getBiome();
Set<String> getTags();
default boolean isPlaceholder() {

View File

@ -10,7 +10,7 @@ final class SelfPipelineBiome implements PipelineBiome {
public static final SelfPipelineBiome INSTANCE = new SelfPipelineBiome();
private SelfPipelineBiome() {
}
@Override

View File

@ -33,24 +33,20 @@ public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
Larger values are quadratically faster, but produce lower quality results.
For example, a value of 3 would sample every 3 blocks.""")
protected @Meta int resolution = 1;
@Value("pipeline.source")
@Description("The Biome Source to use for initial population of biomes.")
private @Meta Source source;
@Value("pipeline.stages")
@Description("A list of pipeline stages to apply to the result of #source")
private @Meta List<@Meta Stage> stages;
@Value("blend.sampler")
@Default
@Description("A sampler to use for blending the edges of biomes via domain warping.")
protected @Meta NoiseSampler blendSampler = NoiseSampler.zero();
@Value("blend.amplitude")
@Default
@Description("The amplitude at which to perform blending.")
protected @Meta double blendAmplitude = 0d;
@Value("pipeline.source")
@Description("The Biome Source to use for initial population of biomes.")
private @Meta Source source;
@Value("pipeline.stages")
@Description("A list of pipeline stages to apply to the result of #source")
private @Meta List<@Meta Stage> stages;
@Override
public BiomeProvider get() {

View File

@ -11,10 +11,10 @@ import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
public class BiomeChunkImpl implements BiomeChunk {
private PipelineBiome[][] biomes;
private final SeededVector worldOrigin;
private final int chunkOriginArrayIndex;
private final int worldCoordinateScale;
private PipelineBiome[][] biomes;
public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) {
@ -43,7 +43,8 @@ public class BiomeChunkImpl implements BiomeChunk {
for(int gridZ = 0; gridZ < gridSize; gridZ++) {
int xIndex = gridOrigin + gridX * gridInterval;
int zIndex = gridOrigin + gridZ * gridInterval;
biomes[xIndex][zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex), zIndexToWorldCoordinate(zIndex));
biomes[xIndex][zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex),
zIndexToWorldCoordinate(zIndex));
}
}
@ -79,21 +80,6 @@ public class BiomeChunkImpl implements BiomeChunk {
}
}
@Override
public PipelineBiome get(int xInChunk, int zInChunk) {
int xIndex = xInChunk + chunkOriginArrayIndex;
int zIndex = zInChunk + chunkOriginArrayIndex;
return biomes[xIndex][zIndex];
}
private int xIndexToWorldCoordinate(int xIndex) {
return (worldOrigin.x() + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
private int zIndexToWorldCoordinate(int zIndex) {
return (worldOrigin.z() + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
protected static int initialSizeToArraySize(int expanderCount, int initialSize) {
int size = initialSize;
for(int i = 0; i < expanderCount; i++) {
@ -117,8 +103,8 @@ public class BiomeChunkImpl implements BiomeChunk {
int gridOrigin = 0;
int expansionsApplied = 0;
int gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied);
for (Stage stage : stages) {
if (stage instanceof Expander) {
for(Stage stage : stages) {
if(stage instanceof Expander) {
expansionsApplied++;
gridInterval = calculateGridInterval(totalExpanderCount, expansionsApplied);
}
@ -143,6 +129,21 @@ public class BiomeChunkImpl implements BiomeChunk {
return 1 << (totalExpansions - expansionsApplied);
}
@Override
public PipelineBiome get(int xInChunk, int zInChunk) {
int xIndex = xInChunk + chunkOriginArrayIndex;
int zIndex = zInChunk + chunkOriginArrayIndex;
return biomes[xIndex][zIndex];
}
private int xIndexToWorldCoordinate(int xIndex) {
return (worldOrigin.x() + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
private int zIndexToWorldCoordinate(int zIndex) {
return (worldOrigin.z() + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
}
private SeededVector getOrigin() {
return worldOrigin;
}
@ -160,7 +161,8 @@ public class BiomeChunkImpl implements BiomeChunk {
private final int zIndex;
private final PipelineBiome[][] lookupArray;
private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex, PipelineBiome[][] lookupArray) {
private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex,
PipelineBiome[][] lookupArray) {
this.chunk = chunk;
this.gridInterval = gridInterval;
this.gridX = gridX;

View File

@ -36,18 +36,18 @@ public class PipelineImpl implements Pipeline {
int chunkOriginArrayIndex;
int chunkSize;
int initialSize = 1;
while (true) {
while(true) {
arraySize = BiomeChunkImpl.initialSizeToArraySize(expanderCount, initialSize);
chunkOriginArrayIndex = BiomeChunkImpl.calculateChunkOriginArrayIndex(expanderCount, stages);
chunkSize = BiomeChunkImpl.calculateChunkSize(arraySize, chunkOriginArrayIndex, expanderCount);
if (chunkSize > 1 && arraySize >= idealChunkArraySize) break;
if(chunkSize > 1 && arraySize >= idealChunkArraySize) break;
initialSize++;
}
this.arraySize = arraySize;
this.chunkOriginArrayIndex = chunkOriginArrayIndex;
this.chunkSize = chunkSize;
logger.debug("Initialized a new biome pipeline:");
logger.debug("Array size: {} (Target: {})", arraySize, idealChunkArraySize);
logger.debug("Internal array origin: {}", chunkOriginArrayIndex);

View File

@ -16,21 +16,21 @@ public class FractalExpander implements Expander {
@Override
public PipelineBiome fillBiome(BiomeChunkImpl.ViewPoint viewPoint) {
int xMod2 = viewPoint.gridX() % 2;
int zMod2 = viewPoint.gridZ() % 2;
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
if (xMod2 == 1 && zMod2 == 0) { // Pick one of 2 neighbors on X axis randomly
if(xMod2 == 1 && zMod2 == 0) { // Pick one of 2 neighbors on X axis randomly
return roll > 0 ? viewPoint.getRelativeBiome(-1, 0) : viewPoint.getRelativeBiome(1, 0);
} else if (xMod2 == 0 && zMod2 == 1) { // Pick one of 2 neighbors on Z axis randomly
} else if(xMod2 == 0 && zMod2 == 1) { // Pick one of 2 neighbors on Z axis randomly
return roll > 0 ? viewPoint.getRelativeBiome(0, -1) : viewPoint.getRelativeBiome(0, 1);
} else { // Pick one of 4 corners randomly
return roll > 0 ?
roll > 0.25 ? viewPoint.getRelativeBiome(-1, 1) : viewPoint.getRelativeBiome(1, 1) :
roll > 0.25 ? viewPoint.getRelativeBiome(-1, 1) : viewPoint.getRelativeBiome(1, 1) :
roll > -0.25 ? viewPoint.getRelativeBiome(-1, -1) : viewPoint.getRelativeBiome(1, -1);
}
}

View File

@ -38,7 +38,7 @@ public class BorderListStage implements Stage {
this.replaceDefault = replaceDefault;
this.defaultReplace = defaultReplace;
this.replace = replace;
List<Vector2Int> points = new ArrayList<>();
for(int x = -1; x <= 1; x++) {
for(int z = -1; z <= 1; z++) {
@ -68,10 +68,11 @@ public class BorderListStage implements Stage {
if(current != null && current.getTags().contains(border)) {
if(replace.containsKey(center)) {
PipelineBiome replacement = replace.get(center).get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
viewPoint.worldSeed());
viewPoint.worldSeed());
return replacement.isSelf() ? center : replacement;
}
PipelineBiome replacement = replaceDefault.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
PipelineBiome replacement = replaceDefault.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
viewPoint.worldSeed());
return replacement.isSelf() ? center : replacement;
}
}

View File

@ -34,7 +34,7 @@ public class SmoothStage implements Stage {
boolean vert = Objects.equals(top, bottom);
boolean horiz = Objects.equals(left, right);
if(vert && horiz) {
return roll > 0 ?
roll > 0.25 ? left : right :

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: biome-provider-pipeline-v2
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.pipeline.v2.BiomePipelineAddon"
- "com.dfsek.terra.addons.biome.pipeline.v2.BiomePipelineAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -41,15 +41,13 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
public class BiomePipelineAddon implements AddonInitializer {
private static final Logger logger = LoggerFactory.getLogger(BiomePipelineAddon.class);
public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
};
private static final Logger logger = LoggerFactory.getLogger(BiomePipelineAddon.class);
@Inject
private Platform platform;
@ -91,6 +89,8 @@ public class BiomePipelineAddon implements AddonInitializer {
});
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.");
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.");
}
}

View File

@ -80,11 +80,11 @@ public class BiomePipelineProvider implements BiomeProvider {
public Biome getBiome(int x, int z, long seed) {
x += mutator.noise(seed + 1, x, z) * noiseAmp;
z += mutator.noise(seed + 2, x, z) * noiseAmp;
x /= resolution;
z /= resolution;
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(),
@ -119,7 +119,7 @@ public class BiomePipelineProvider implements BiomeProvider {
}
return false;
}
@Override
public int hashCode() {
int code = x;

View File

@ -10,7 +10,7 @@ final class SelfDelegate implements BiomeDelegate {
public static final SelfDelegate INSTANCE = new SelfDelegate();
private SelfDelegate() {
}
@Override

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: biome-provider-pipeline
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.pipeline.BiomePipelineAddon"
- "com.dfsek.terra.addons.biome.pipeline.BiomePipelineAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: biome-provider-single
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.single.SingleBiomeProviderAddon"
- "com.dfsek.terra.addons.biome.single.SingleBiomeProviderAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -33,12 +33,12 @@ public class BiomeQueryAPIAddon implements AddonInitializer {
.getPack()
.getRegistry(Biome.class)
.entries();
BiomeTagFlattener flattener = new BiomeTagFlattener(biomes
.stream()
.flatMap(biome -> biome.getTags().stream())
.toList());
biomes.forEach(biome -> biome.getContext().put(BIOME_TAG_KEY, new BiomeTagHolder(biome, flattener)));
})
.global();

View File

@ -8,7 +8,7 @@ import com.dfsek.terra.api.world.biome.Biome;
public final class BiomeQueries {
private BiomeQueries() {
}
public static Predicate<Biome> has(String tag) {

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: biome-query-api
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.query.BiomeQueryAPIAddon"
- "com.dfsek.terra.addons.biome.query.BiomeQueryAPIAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -47,7 +47,7 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
event.getPack().applyLoader(SlantHolder.CalculationMethod.class,
(type, o, loader, depthTracker) -> SlantHolder.CalculationMethod.valueOf((String) o));
NoiseChunkGeneratorPackConfigTemplate config = event.loadTemplate(new NoiseChunkGeneratorPackConfigTemplate());
event.getPack().getContext().put(config);
@ -68,10 +68,13 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
.register(addon, ConfigurationLoadEvent.class)
.then(event -> {
if(event.is(Biome.class)) {
NoiseChunkGeneratorPackConfigTemplate config = event.getPack().getContext().get(NoiseChunkGeneratorPackConfigTemplate.class);
NoiseChunkGeneratorPackConfigTemplate config = event.getPack().getContext().get(
NoiseChunkGeneratorPackConfigTemplate.class);
event.getLoadedObject(Biome.class).getContext().put(paletteInfoPropertyKey,
event.load(new BiomePaletteTemplate(platform, config.getSlantCalculationMethod())).get());
event.load(new BiomePaletteTemplate(platform,
config.getSlantCalculationMethod()))
.get());
event.getLoadedObject(Biome.class).getContext().put(noisePropertiesPropertyKey,
event.load(new BiomeNoiseConfigTemplate()).get());
}

View File

@ -12,7 +12,7 @@ public class ThreadLocalNoiseHolder {
if(holder.init && holder.y == y && holder.z == z && holder.x == x && holder.seed == seed) {
return holder.noise;
}
double noise = sampler.noise(seed, x, y, z);
holder.noise = noise;
holder.x = x;

View File

@ -27,26 +27,22 @@ import com.dfsek.terra.api.world.chunk.generation.util.Palette;
public class BiomePaletteTemplate implements ObjectTemplate<BiomePaletteInfo> {
private final Platform platform;
private final SlantHolder.CalculationMethod slantCalculationMethod;
@Value("slant")
@Default
@Description("The slant palettes to use in this biome.")
private @Meta List<SlantHolder.@Meta Layer> slantLayers = Collections.emptyList();
@Value("slant-depth")
@Default
@Description("The maximum depth at which to apply a slant palette.")
private @Meta int slantDepth = Integer.MAX_VALUE;
@Value("palette")
@Description("The palettes to use in this biome.")
private @Meta List<@Meta Map<@Meta Palette, @Meta Integer>> palettes;
@Value("ocean.level")
@Description("Sea level in this biome. Defaults to zero")
@Default
private @Meta int seaLevel = 0;
@Value("ocean.palette")
@Description("The palette to use for the ocean in this biome. Defaults to a blank palette.")
@Default
@ -56,13 +52,10 @@ public class BiomePaletteTemplate implements ObjectTemplate<BiomePaletteInfo> {
return platform.getWorldHandle().air();
}
};
@Value("carving.update-palette")
@Default
private @Meta boolean updatePalette = false;
private final SlantHolder.CalculationMethod slantCalculationMethod;
public BiomePaletteTemplate(Platform platform, SlantHolder.CalculationMethod slantCalculationMethod) {
this.platform = platform;
this.slantCalculationMethod = slantCalculationMethod;

View File

@ -145,7 +145,7 @@ public class ChunkInterpolator {
*/
public double getNoise(double x, double y, double z) {
return interpGrid[reRange(((int) x) / 4, 3)][(Math.max(Math.min(((int) y), max), min) - min) / 4][reRange(((int) z) / 4,
3)].trilerp(
3)].trilerp(
(x % 4) / 4, (y % 4) / 4, (z % 4) / 4);
}

View File

@ -24,15 +24,6 @@ public class PaletteHolder {
this.offset = offset;
}
public Palette getPalette(int y) {
int index = y + offset;
return index >= 0
? index < palettes.length
? palettes[index]
: palettes[palettes.length - 1]
: palettes[0];
}
public static PaletteHolder of(List<Map<Palette, Integer>> palettes) {
PaletteHolderBuilder builder = new PaletteHolderBuilder();
for(Map<Palette, Integer> layer : palettes) {
@ -43,6 +34,16 @@ public class PaletteHolder {
return builder.build();
}
public Palette getPalette(int y) {
int index = y + offset;
return index >= 0
? index < palettes.length
? palettes[index]
: palettes[palettes.length - 1]
: palettes[0];
}
private static class PaletteHolderBuilder {
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();

View File

@ -23,7 +23,8 @@ public class MultipleSlantHolder extends SlantHolderImpl {
MultipleSlantHolder(List<SlantHolder.Layer> slant, int slantDepth, CalculationMethod calculationMethod) {
super(slantDepth, calculationMethod);
NavigableMap<Double, PaletteHolder> layers = new TreeMap<>(slant.stream().collect(Collectors.toMap(SlantHolder.Layer::threshold, SlantHolder.Layer::palette)));
NavigableMap<Double, PaletteHolder> layers = new TreeMap<>(
slant.stream().collect(Collectors.toMap(SlantHolder.Layer::threshold, SlantHolder.Layer::palette)));
Stream<Double> thresholds = layers.keySet().stream();
double slantThreshold = floorToThreshold ?
thresholds.min(Double::compare).orElseThrow() :

View File

@ -9,89 +9,6 @@ import com.dfsek.terra.api.util.vector.Vector3;
public interface SlantHolder {
static SlantHolder of(List<SlantHolder.Layer> layers, int slantDepth, CalculationMethod calculationMethod) {
if(layers.isEmpty()) {
return EMPTY;
} else if(layers.size() == 1) {
return new SingleSlantHolder(layers.get(0), slantDepth, calculationMethod);
}
return new MultipleSlantHolder(layers, slantDepth, calculationMethod);
}
double calculateSlant(Sampler3D sampler, double x, double y, double z);
boolean isAboveDepth(int depth);
boolean isInSlantThreshold(double slant);
PaletteHolder getPalette(double slant);
record Layer(PaletteHolder palette, double threshold) {
}
enum CalculationMethod {
DotProduct {
private static final Vector3 DOT_PRODUCT_DIRECTION = Vector3.of(0, 1, 0);
private static final Vector3[] DOT_PRODUCT_SAMPLE_POINTS = {
Vector3.of(0, 0, -DERIVATIVE_DIST),
Vector3.of(0, 0, DERIVATIVE_DIST),
Vector3.of(0, -DERIVATIVE_DIST, 0),
Vector3.of(0, DERIVATIVE_DIST, 0),
Vector3.of(-DERIVATIVE_DIST, 0, 0),
Vector3.of(DERIVATIVE_DIST, 0, 0)
};
@Override
public double slant(Sampler3D sampler, double x, double y, double z) {
Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0);
for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) {
var scalar = -sampler.sample(x+point.getX(), y+point.getY(), z+point.getZ());
normalApproximation.add(point.mutable().multiply(scalar));
}
return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize());
}
@Override
public boolean floorToThreshold() {
return false;
}
},
Derivative {
@Override
public double slant(Sampler3D sampler, double x, double y, double z) {
double baseSample = sampler.sample(x, y, z);
double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
return Math.sqrt(((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
}
@Override
public boolean floorToThreshold() {
return true;
}
};
private static final double DERIVATIVE_DIST = 0.55;
public abstract double slant(Sampler3D sampler, double x, double y, double z);
/*
* Controls whether palettes should be applied before or after their respective thresholds.
*
* If true, slant values will map to the palette of the next floor threshold, otherwise they
* will map to the ceiling.
*/
public abstract boolean floorToThreshold();
}
SlantHolder EMPTY = new SlantHolder() {
@Override
public double calculateSlant(Sampler3D sampler, double x, double y, double z) {
@ -113,4 +30,90 @@ public interface SlantHolder {
throw new UnsupportedOperationException("Empty holder cannot return a palette");
}
};
static SlantHolder of(List<SlantHolder.Layer> layers, int slantDepth, CalculationMethod calculationMethod) {
if(layers.isEmpty()) {
return EMPTY;
} else if(layers.size() == 1) {
return new SingleSlantHolder(layers.get(0), slantDepth, calculationMethod);
}
return new MultipleSlantHolder(layers, slantDepth, calculationMethod);
}
double calculateSlant(Sampler3D sampler, double x, double y, double z);
boolean isAboveDepth(int depth);
boolean isInSlantThreshold(double slant);
PaletteHolder getPalette(double slant);
enum CalculationMethod {
DotProduct {
private static final Vector3 DOT_PRODUCT_DIRECTION = Vector3.of(0, 1, 0);
private static final Vector3[] DOT_PRODUCT_SAMPLE_POINTS = {
Vector3.of(0, 0, -DERIVATIVE_DIST),
Vector3.of(0, 0, DERIVATIVE_DIST),
Vector3.of(0, -DERIVATIVE_DIST, 0),
Vector3.of(0, DERIVATIVE_DIST, 0),
Vector3.of(-DERIVATIVE_DIST, 0, 0),
Vector3.of(DERIVATIVE_DIST, 0, 0)
};
@Override
public double slant(Sampler3D sampler, double x, double y, double z) {
Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0);
for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) {
var scalar = -sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ());
normalApproximation.add(point.mutable().multiply(scalar));
}
return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize());
}
@Override
public boolean floorToThreshold() {
return false;
}
},
Derivative {
@Override
public double slant(Sampler3D sampler, double x, double y, double z) {
double baseSample = sampler.sample(x, y, z);
double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
return Math.sqrt(
((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
}
@Override
public boolean floorToThreshold() {
return true;
}
};
private static final double DERIVATIVE_DIST = 0.55;
public abstract double slant(Sampler3D sampler, double x, double y, double z);
/*
* Controls whether palettes should be applied before or after their respective thresholds.
*
* If true, slant values will map to the palette of the next floor threshold, otherwise they
* will map to the ceiling.
*/
public abstract boolean floorToThreshold();
}
record Layer(PaletteHolder palette, double threshold) {
}
}

View File

@ -4,11 +4,9 @@ import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
public abstract class SlantHolderImpl implements SlantHolder {
private final SlantHolder.CalculationMethod calculationMethod;
private final int slantDepth;
protected final boolean floorToThreshold;
private final SlantHolder.CalculationMethod calculationMethod;
private final int slantDepth;
protected SlantHolderImpl(int slantDepth, CalculationMethod calculationMethod) {
this.floorToThreshold = calculationMethod.floorToThreshold();

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: chunk-generator-noise-3d
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.chunkgenerator.NoiseChunkGenerator3DAddon"
- "com.dfsek.terra.addons.chunkgenerator.NoiseChunkGenerator3DAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -28,7 +28,7 @@ public class AddonsCommandAddon implements AddonInitializer {
.register(addon, CommandRegistrationEvent.class)
.then(event -> {
CommandManager<CommandSender> manager = event.getCommandManager();
manager.command(
manager.commandBuilder("addons", ArgumentDescription.of("List installed Terra addons"))
.permission("terra.addons")
@ -51,9 +51,9 @@ public class AddonsCommandAddon implements AddonInitializer {
.handler(context -> {
BaseAddon addon = context.get("addon");
StringBuilder addonInfo = new StringBuilder("Addon ").append(addon.getID()).append('\n');
addonInfo.append("Version: ").append(addon.getVersion().getFormatted()).append('\n');
addonInfo.append("Dependencies:\n");
addon.getDependencies().forEach((id, versions) -> addonInfo
.append(" - ")

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: command-addons
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.commands.addons.AddonsCommandAddon"
- "com.dfsek.terra.addons.commands.addons.AddonsCommandAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -33,7 +33,7 @@ public class PacksCommandAddon implements AddonInitializer {
.register(addon, CommandRegistrationEvent.class)
.then(event -> {
CommandManager<CommandSender> manager = event.getCommandManager();
manager.command(
manager.commandBuilder("packs", ArgumentDescription.of("List installed config packs"))
.permission("terra.packs")
@ -54,10 +54,10 @@ public class PacksCommandAddon implements AddonInitializer {
.handler(context -> {
ConfigPack pack = context.get("pack");
StringBuilder packInfo = new StringBuilder("Pack ").append(pack.getID()).append('\n');
packInfo.append("Version: ").append(pack.getVersion().getFormatted()).append('\n');
packInfo.append("Author: ").append(pack.getAuthor()).append('\n');
packInfo.append("Addon Dependencies:\n");
pack.addons().forEach((id, versions) -> packInfo
.append(" - ")

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: command-packs
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.commands.packs.PacksCommandAddon"
- "com.dfsek.terra.addons.commands.packs.PacksCommandAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: command-profiler
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.commands.profiler.ProfilerCommandAddon"
- "com.dfsek.terra.addons.commands.profiler.ProfilerCommandAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -41,7 +41,7 @@ public class StructureCommandAddon implements AddonInitializer {
.register(addon, CommandRegistrationEvent.class)
.then(event -> {
CommandManager<CommandSender> manager = event.getCommandManager();
manager.command(
manager.commandBuilder("structures", ArgumentDescription.of("Manage or generate structures"))
.literal("generate")

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: command-structures
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.commands.structure.StructureCommandAddon"
- "com.dfsek.terra.addons.commands.structure.StructureCommandAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-biome
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.biome.BiomeAddon"
- "com.dfsek.terra.addons.biome.BiomeAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -50,7 +50,7 @@ public class DistributorAddon implements AddonInitializer {
CheckedRegistry<Supplier<ObjectTemplate<Distributor>>> distributorRegistry = event
.getPack()
.getOrCreateRegistry(DISTRIBUTOR_TOKEN);
distributorRegistry.register(addon.key("SAMPLER"), SamplerDistributorTemplate::new);
distributorRegistry.register(addon.key("POINTS"), PointSetDistributorTemplate::new);
distributorRegistry.register(addon.key("PADDED_GRID"), PaddedGridDistributorTemplate::new);
@ -59,7 +59,7 @@ public class DistributorAddon implements AddonInitializer {
distributorRegistry.register(addon.key("XOR"), XorDistributorTemplate::new);
distributorRegistry.register(addon.key("YES"), YesDistributorTemplate::new);
distributorRegistry.register(addon.key("NO"), NoDistributorTemplate::new);
event.getPack()
.applyLoader(Point.class, PointTemplate::new);
})

View File

@ -1,15 +1,15 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-distributors
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.feature.distributor.DistributorAddon"
- "com.dfsek.terra.addons.feature.distributor.DistributorAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
depends:
config-feature: "1.+"
generation-stage-feature: "1.+"
config-feature: "1.+"
generation-stage-feature: "1.+"

View File

@ -1,14 +1,14 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-feature
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.feature.FeatureAddon"
- "com.dfsek.terra.addons.feature.FeatureAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
depends:
generation-stage-feature: "1.+"
generation-stage-feature: "1.+"

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-flora
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.flora.FloraAddon"
- "com.dfsek.terra.addons.flora.FloraAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -63,16 +63,16 @@ public class LocatorAddon implements AddonInitializer {
CheckedRegistry<Supplier<ObjectTemplate<Locator>>> locatorRegistry = event.getPack().getOrCreateRegistry(LOCATOR_TOKEN);
locatorRegistry.register(addon.key("SURFACE"), SurfaceLocatorTemplate::new);
locatorRegistry.register(addon.key("TOP"), TopLocatorTemplate::new);
locatorRegistry.register(addon.key("RANDOM"), RandomLocatorTemplate::new);
locatorRegistry.register(addon.key("GAUSSIAN_RANDOM"), GaussianRandomLocatorTemplate::new);
locatorRegistry.register(addon.key("PATTERN"), PatternLocatorTemplate::new);
locatorRegistry.register(addon.key("ADJACENT_PATTERN"), AdjacentPatternLocatorTemplate::new);
locatorRegistry.register(addon.key("SAMPLER"), SamplerLocatorTemplate::new);
locatorRegistry.register(addon.key("SAMPLER_3D"), Sampler3DLocatorTemplate::new);
locatorRegistry.register(addon.key("AND"), AndLocatorTemplate::new);
locatorRegistry.register(addon.key("OR"), OrLocatorTemplate::new);
locatorRegistry.register(addon.key("XOR"), XorLocatorTemplate::new);
@ -83,7 +83,7 @@ public class LocatorAddon implements AddonInitializer {
patternRegistry.register(addon.key("MATCH_SOLID"), SolidMatchPatternTemplate::new);
patternRegistry.register(addon.key("MATCH"), SingleBlockMatchPatternTemplate::new);
patternRegistry.register(addon.key("MATCH_SET"), BlockSetMatchPatternTemplate::new);
patternRegistry.register(addon.key("AND"), AndPatternTemplate::new);
patternRegistry.register(addon.key("OR"), OrPatternTemplate::new);
patternRegistry.register(addon.key("XOR"), XorPatternTemplate::new);

View File

@ -1,15 +1,15 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-locators
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.feature.locator.LocatorAddon"
- "com.dfsek.terra.addons.feature.locator.LocatorAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
depends:
config-feature: "1.+"
generation-stage-feature: "1.+"
config-feature: "1.+"
generation-stage-feature: "1.+"

View File

@ -95,7 +95,7 @@ public class NoiseAddon implements AddonInitializer {
.applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::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);
noiseRegistry.register(addon.key("CLAMP"), ClampNormalizerTemplate::new);
@ -103,53 +103,54 @@ public class NoiseAddon implements AddonInitializer {
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);
noiseRegistry.register(addon.key("DOMAIN_WARP"), DomainWarpTemplate::new);
noiseRegistry.register(addon.key("FBM"), BrownianMotionTemplate::new);
noiseRegistry.register(addon.key("PING_PONG"), PingPongTemplate::new);
noiseRegistry.register(addon.key("RIDGED"), RidgedFractalTemplate::new);
noiseRegistry.register(addon.key("OPEN_SIMPLEX_2"), () -> new SimpleNoiseTemplate(OpenSimplex2Sampler::new));
noiseRegistry.register(addon.key("OPEN_SIMPLEX_2S"), () -> new SimpleNoiseTemplate(OpenSimplex2SSampler::new));
noiseRegistry.register(addon.key("PERLIN"), () -> new SimpleNoiseTemplate(PerlinSampler::new));
noiseRegistry.register(addon.key("SIMPLEX"), () -> new SimpleNoiseTemplate(SimplexSampler::new));
noiseRegistry.register(addon.key("GABOR"), GaborNoiseTemplate::new);
noiseRegistry.register(addon.key("VALUE"), () -> new SimpleNoiseTemplate(ValueSampler::new));
noiseRegistry.register(addon.key("VALUE_CUBIC"), () -> new SimpleNoiseTemplate(ValueCubicSampler::new));
noiseRegistry.register(addon.key("CELLULAR"), CellularNoiseTemplate::new);
noiseRegistry.register(addon.key("WHITE_NOISE"), () -> new SimpleNoiseTemplate(WhiteNoiseSampler::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));
noiseRegistry.register(addon.key("MUL"), () -> new BinaryArithmeticTemplate<>(MultiplicationSampler::new));
noiseRegistry.register(addon.key("DIV"), () -> new BinaryArithmeticTemplate<>(DivisionSampler::new));
noiseRegistry.register(addon.key("MAX"), () -> new BinaryArithmeticTemplate<>(MaxSampler::new));
noiseRegistry.register(addon.key("MIN"), () -> new BinaryArithmeticTemplate<>(MinSampler::new));
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));
noiseRegistry.register(addon.key("EXPRESSION_NORMALIZER"),
() -> new ExpressionNormalizerTemplate(packSamplers, packFunctions));
NoiseConfigPackTemplate template = event.loadTemplate(new NoiseConfigPackTemplate());
packSamplers.putAll(template.getSamplers());
packFunctions.putAll(template.getFunctions());

View File

@ -27,6 +27,6 @@ public class TranslateSamplerTemplate extends SamplerTemplate<TranslateSampler>
@Override
public NoiseSampler get() {
return new TranslateSampler(sampler, x, y ,z);
return new TranslateSampler(sampler, x, y, z);
}
}

View File

@ -41,15 +41,18 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers, Map<String, FunctionTemplate> globalFunctions) {
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);
var mergedFunctions = new HashMap<>(globalFunctions);
mergedFunctions.putAll(functions);
var mergedSamplers = new HashMap<>(globalSamplers);
mergedSamplers.putAll(samplers);
try {
return new ExpressionFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars);
} catch(ParseException e) {

View File

@ -45,15 +45,18 @@ public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionN
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
public ExpressionNormalizerTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers, Map<String, FunctionTemplate> globalFunctions) {
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);
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) {

View File

@ -28,18 +28,14 @@ public class CubicSpline {
}
}
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
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
} 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];
@ -48,7 +44,7 @@ public class CubicSpline {
double toLeft = toValues[pointIdx];
double toRight = toValues[pointIdx + 1];
double gradientLeft = gradients[pointIdx];
double gradientLeft = gradients[pointIdx];
double gradientRight = gradients[pointIdx + 1];
double fromDelta = fromRight - fromLeft;
@ -56,7 +52,8 @@ public class CubicSpline {
double t = (in - fromLeft) / fromDelta;
return lerp(t, toLeft, toRight) + t * (1.0F - t) * lerp(t, gradientLeft * fromDelta - toDelta, -gradientRight * fromDelta + toDelta);
return lerp(t, toLeft, toRight) + t * (1.0F - t) * lerp(t, gradientLeft * fromDelta - toDelta,
-gradientRight * fromDelta + toDelta);
}
}
@ -64,10 +61,10 @@ public class CubicSpline {
int left = 0;
int right = values.length;
int idx = right - left;
while (idx > 0) {
while(idx > 0) {
int halfDelta = idx / 2;
int mid = left + halfDelta;
if (targetValue < values[mid]) {
if(targetValue < values[mid]) {
idx = halfDelta;
} else {
left = mid + 1;
@ -76,6 +73,11 @@ public class CubicSpline {
}
return left;
}
public double apply(double in) {
return calculate(in, fromValues, toValues, gradients);
}
public record Point(double from, double to, double gradient) implements Comparable<Point> {

View File

@ -14,10 +14,11 @@ import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
public class FunctionUtil {
private FunctionUtil() {}
private FunctionUtil() { }
public static Map<String, Function> convertFunctionsAndSamplers(Map<String, FunctionTemplate> functions,
Map<String, DimensionApplicableNoiseSampler> samplers) throws ParseException {
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()));

View File

@ -20,14 +20,30 @@ public class DistanceSampler extends NoiseFunction {
this.radius = radius;
this.distanceAtRadius = distance2d(distanceFunction, radius, 0); // distance2d and distance3d should return the same value
}
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);
};
}
@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;
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);
if(normalize) return Math.min(((2 * dist) / distanceAtRadius) - 1, 1);
return dist;
}
@ -38,26 +54,10 @@ public class DistanceSampler extends NoiseFunction {
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);
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,

View File

@ -17,11 +17,10 @@ public class GaborNoiseSampler extends NoiseFunction {
private double a = 0.1;
private double f0 = 0.625;
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 = Math.exp(-impulsesPerCell);
private double impulsesPerKernel = 64d;
private double omega0 = Math.PI * 0.25;
private boolean isotropic = true;
@ -72,8 +71,9 @@ public class GaborNoiseSampler extends NoiseFunction {
}
private double gabor(double omega_0, double x, double y) {
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))));
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))));
}
public void setA(double a) {

View File

@ -15,7 +15,7 @@ public abstract class NoiseFunction implements NoiseSampler {
protected static final int PRIME_X = 501125321;
protected static final int PRIME_Y = 1136930381;
protected static final int PRIME_Z = 1720413743;
protected double frequency = 0.02d;
protected long salt;

View File

@ -33,11 +33,11 @@ public class ValueCubicSampler extends ValueStyleNoise {
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),
xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2), valCoord(seed, x1, y2), valCoord(seed, x2, y2), valCoord(seed, x3, y2),
xs),
xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3), valCoord(seed, x1, y3), valCoord(seed, x2, y3), valCoord(seed, x3, y3),
xs),
xs),
ys) * (1 / (1.5 * 1.5));
}
@ -69,43 +69,43 @@ public class ValueCubicSampler extends ValueStyleNoise {
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),
valCoord(seed, x3, y0, z0), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), valCoord(seed, x2, y1, z0),
valCoord(seed, x3, y1, z0), xs),
valCoord(seed, x3, y1, z0), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z0), valCoord(seed, x1, y2, z0), valCoord(seed, x2, y2, z0),
valCoord(seed, x3, y2, z0), xs),
valCoord(seed, x3, y2, z0), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z0), valCoord(seed, x1, y3, z0), valCoord(seed, x2, y3, z0),
valCoord(seed, x3, y3, z0), xs),
valCoord(seed, x3, y3, z0), xs),
ys),
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),
valCoord(seed, x3, y0, z1), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), valCoord(seed, x2, y1, z1),
valCoord(seed, x3, y1, z1), xs),
valCoord(seed, x3, y1, z1), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z1), valCoord(seed, x1, y2, z1), valCoord(seed, x2, y2, z1),
valCoord(seed, x3, y2, z1), xs),
valCoord(seed, x3, y2, z1), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z1), valCoord(seed, x1, y3, z1), valCoord(seed, x2, y3, z1),
valCoord(seed, x3, y3, z1), xs),
valCoord(seed, x3, y3, z1), xs),
ys),
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),
valCoord(seed, x3, y0, z2), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z2), valCoord(seed, x1, y1, z2), valCoord(seed, x2, y1, z2),
valCoord(seed, x3, y1, z2), xs),
valCoord(seed, x3, y1, z2), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z2), valCoord(seed, x1, y2, z2), valCoord(seed, x2, y2, z2),
valCoord(seed, x3, y2, z2), xs),
valCoord(seed, x3, y2, z2), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z2), valCoord(seed, x1, y3, z2), valCoord(seed, x2, y3, z2),
valCoord(seed, x3, y3, z2), xs),
valCoord(seed, x3, y3, z2), xs),
ys),
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),
valCoord(seed, x3, y0, z3), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z3), valCoord(seed, x1, y1, z3), valCoord(seed, x2, y1, z3),
valCoord(seed, x3, y1, z3), xs),
valCoord(seed, x3, y1, z3), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z3), valCoord(seed, x1, y2, z3), valCoord(seed, x2, y2, z3),
valCoord(seed, x3, y2, z3), xs),
valCoord(seed, x3, y2, z3), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z3), valCoord(seed, x1, y3, z3), valCoord(seed, x2, y3, z3),
valCoord(seed, x3, y3, z3), xs),
valCoord(seed, x3, y3, z3), xs),
ys),
zs) * (1 / (1.5 * 1.5 * 1.5));
}

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-noise-function
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.noise.NoiseAddon"
- "com.dfsek.terra.addons.noise.NoiseAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -18,7 +18,7 @@ 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) {
if(o instanceof String expressionString) {
Scope scope = new Scope();
scope.addInvocationVariable("value");
try {

View File

@ -16,6 +16,7 @@ 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

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-number-predicate
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.numberpredicate.NumberPredicateAddon"
- "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
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -167,6 +167,7 @@ public class VanillaOre implements Structure {
return blockCount > 0;
}
public BlockState getMaterial(BlockType replace) {
return materials.getOrDefault(replace, material);
}

View File

@ -15,6 +15,7 @@ import static com.dfsek.terra.addons.ore.utils.VanillaOreUtils.shouldPlace;
public class VanillaScatteredOre extends VanillaOre {
protected final int spread;
public VanillaScatteredOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity, double exposed,
Map<BlockType, BlockState> materials, int spread) {
super(material, size, replaceable, applyGravity, exposed, materials);
@ -30,9 +31,9 @@ public class VanillaScatteredOre extends VanillaOre {
for(int j = 0; j < i; ++j) {
this.setPos(mutable, random, location, Math.min(j, spread));
BlockType block = world.getBlockState(mutable).getBlockType();
if (shouldPlace(getReplaceable(), block, exposed, random, world, mutable.getX(), mutable.getY(), mutable.getZ())) {
world.setBlockState(mutable, getMaterial(block), isApplyGravity());
}
if(shouldPlace(getReplaceable(), block, exposed, random, world, mutable.getX(), mutable.getY(), mutable.getZ())) {
world.setBlockState(mutable, getMaterial(block), isApplyGravity());
}
}
return true;
@ -48,6 +49,6 @@ public class VanillaScatteredOre extends VanillaOre {
}
private int getSpread(Random random, int spread) {
return Math.round((random.nextFloat() - random.nextFloat()) * (float)spread);
return Math.round((random.nextFloat() - random.nextFloat()) * (float) spread);
}
}

View File

@ -18,7 +18,8 @@ public class VanillaOreUtils {
}
}
public static boolean shouldPlace(MaterialSet replaceable, BlockType type, Double exposed, Random random, WritableWorld world, int x, int y, int z) {
public static boolean shouldPlace(MaterialSet replaceable, BlockType type, Double exposed, Random random, WritableWorld world, int x,
int y, int z) {
if(!replaceable.contains(type)) {
return false;
} else if(shouldNotDiscard(random, exposed)) {

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-ore
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.ore.OreAddon"
- "com.dfsek.terra.addons.ore.OreAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-palette
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.palette.PaletteAddon"
- "com.dfsek.terra.addons.palette.PaletteAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: config-structure
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.structure.StructureAddon"
- "com.dfsek.terra.addons.structure.StructureAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -66,7 +66,7 @@ public class FeatureGenerationAddon implements AddonInitializer {
.then(event -> {
if(event.is(Biome.class)) {
DynamicTemplate.Builder templateBuilder = DynamicTemplate.builder();
List<FeatureGenerationStage> featureGenerationStages = new ArrayList<>();
event.getPack().getStages().forEach(stage -> {
if(stage instanceof FeatureGenerationStage featureGenerationStage) {
@ -80,13 +80,13 @@ public class FeatureGenerationAddon implements AddonInitializer {
.build());
}
});
DynamicTemplate template = event.load(templateBuilder.build());
Map<FeatureGenerationStage, List<Feature>> features = new HashMap<>();
featureGenerationStages.forEach(stage -> features.put(stage, template.get(stage.getID(), List.class)));
event.getLoadedObject(Biome.class).getContext().put(biomeFeaturesKey, new BiomeFeatures(features));
}
})

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: generation-stage-feature
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.generation.feature.FeatureGenerationAddon"
- "com.dfsek.terra.addons.generation.feature.FeatureGenerationAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: generation-stage-structure
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.generation.structure.StructureGenerationAddon"
- "com.dfsek.terra.addons.generation.structure.StructureGenerationAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -1,12 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
- Terra contributors
id: language-yaml
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.yaml.YamlAddon"
- "com.dfsek.terra.addons.yaml.YamlAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License

View File

@ -2,7 +2,6 @@ version = version("1.0.1")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
}

View File

@ -84,6 +84,6 @@ public class ImageLibraryAddon implements AddonInitializer {
colorSamplerRegistry.register(addon.key("COLOR"), ConstantColorSamplerTemplate::new);
colorSamplerRegistry.register(addon.key("ROTATE"), RotateColorSamplerTemplate::new);
colorSamplerRegistry.register(addon.key("TRANSLATE"), TranslateColorSamplerTemplate::new);
});
});
}
}

View File

@ -6,6 +6,7 @@ public interface ColorSampler {
/**
* @param x World x coordinate
* @param z World z coordinate
*
* @return Integer representing a web color
*/
int apply(int x, int z);

View File

@ -10,7 +10,7 @@ public enum Alignment implements ImageTransformation {
public int transformX(Image image, int x) {
return x;
}
@Override
public int transformZ(Image image, int z) {
return z;
@ -21,7 +21,7 @@ public enum Alignment implements ImageTransformation {
public int transformX(Image image, int x) {
return x + image.getWidth() / 2;
}
@Override
public int transformZ(Image image, int z) {
return z + image.getHeight() / 2;

View File

@ -3,6 +3,7 @@ package com.dfsek.terra.addons.image.colorsampler.mutate;
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
import com.dfsek.terra.api.util.MathUtil;
public class RotateColorSampler implements ColorSampler {
private final ColorSampler sampler;
@ -15,15 +16,15 @@ public class RotateColorSampler implements ColorSampler {
this.sampler = sampler;
double normalizedDegrees = degrees % 360.0;
if (normalizedDegrees < 0) normalizedDegrees += 360.0;
if(normalizedDegrees < 0) normalizedDegrees += 360.0;
if (normalizedDegrees == 0.0)
if(normalizedDegrees == 0.0)
rotationMethod = RotationMethod.DEG_0;
else if (normalizedDegrees == 90.0)
else if(normalizedDegrees == 90.0)
rotationMethod = RotationMethod.DEG_90;
else if (normalizedDegrees == 180.0)
else if(normalizedDegrees == 180.0)
rotationMethod = RotationMethod.DEG_180;
else if (normalizedDegrees == 270.0)
else if(normalizedDegrees == 270.0)
rotationMethod = RotationMethod.DEG_270;
else
rotationMethod = RotationMethod.RAD_ANY;

View File

@ -28,28 +28,24 @@ public class ColorLoader implements TypeLoader<ColorString> {
this.argb = parse(string);
}
public int getColor() {
return argb;
}
private static int parse(String string) throws IllegalArgumentException {
if (string.length() == 0)
if(string.length() == 0)
throw new IllegalArgumentException("Empty string cannot be parsed as a valid color");
String[] split = string.split(",");
if (split.length == 1)
if(split.length == 1)
return parseHex(string);
else if (split.length == 3)
else if(split.length == 3)
return parseChannels("255", split[0], split[1], split[2]);
else if (split.length == 4)
else if(split.length == 4)
return parseChannels(split[0], split[1], split[2], split[3]);
else
throw new IllegalArgumentException("Invalid channels provided, required format RED,GREEN,BLUE or ALPHA,RED,GREEN,BLUE");
}
private static int parseHex(String hex) throws IllegalArgumentException {
if (hex.startsWith("#"))
if(hex.startsWith("#"))
hex = hex.substring(1);
int alpha = 255;
@ -71,7 +67,7 @@ public class ColorLoader implements TypeLoader<ColorString> {
blue = Integer.parseInt(hex.substring(4, 6), 16);
return ColorUtil.argbValidated(alpha, red, green, blue);
} catch (NumberFormatException e) {
} catch(NumberFormatException e) {
throw new IllegalArgumentException("Failed to parse hex color", e);
}
}
@ -84,9 +80,13 @@ public class ColorLoader implements TypeLoader<ColorString> {
int b = Integer.decode(blue);
return ColorUtil.argbValidated(a, r, g, b);
} catch (NumberFormatException e) {
} catch(NumberFormatException e) {
throw new IllegalArgumentException("Invalid channel value", e);
}
}
public int getColor() {
return argb;
}
}
}

View File

@ -7,6 +7,7 @@ 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
@ -17,8 +18,10 @@ public class ImageLibraryPackConfigTemplate implements ConfigTemplate, Propertie
@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.")
"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;

View File

@ -9,7 +9,7 @@ import com.dfsek.terra.addons.image.colorsampler.image.SingleImageColorSampler;
public class SingleImageColorSamplerTemplate extends ImageColorSamplerTemplate {
@Value("outside-sampler")
private ColorSampler fallback;
@Override
public ColorSampler get() {
return new SingleImageColorSampler(image, fallback, alignment);

View File

@ -5,7 +5,7 @@ import com.dfsek.terra.addons.image.colorsampler.image.TileImageColorSampler;
public class TileImageColorSamplerTemplate extends ImageColorSamplerTemplate {
@Override
public ColorSampler get() {
return new TileImageColorSampler(image, alignment);

View File

@ -16,6 +16,6 @@ public class TranslateColorSamplerTemplate extends MutateColorSamplerTemplate {
@Override
public ColorSampler get() {
return new TranslateColorSampler(sampler, translateX, translateZ);
return new TranslateColorSampler(sampler, translateX, translateZ);
}
}

View File

@ -27,12 +27,12 @@ record ImageCache(LoadingCache<String, Image> cache) implements Properties {
ImageCache images;
if(!pack.getContext().has(ImageCache.class)) {
var cacheBuilder = Caffeine.newBuilder();
if (config.unloadOnTimeout()) cacheBuilder.expireAfterAccess(config.getCacheTimeout(), TimeUnit.SECONDS);
if(config.unloadOnTimeout()) cacheBuilder.expireAfterAccess(config.getCacheTimeout(), TimeUnit.SECONDS);
images = new ImageCache(cacheBuilder.build(s -> loadImage(s, files)));
pack.getContext().put(images);
} else images = pack.getContext().get(ImageCache.class);
if (config.loadOnUse()) {
if(config.loadOnUse()) {
if(config.unloadOnTimeout()) { // Grab directly from cache if images are to unload on timeout
return new SuppliedImage(() -> images.cache.get(path));
} else {

View File

@ -12,13 +12,11 @@ import com.dfsek.terra.api.config.Loader;
public class ImageTemplate implements ObjectTemplate<Image> {
private final Loader files;
private final ConfigPack pack;
@Value("path")
private String path;
private final Loader files;
private final ConfigPack pack;
public ImageTemplate(Loader files, ConfigPack pack) {
this.files = files;
this.pack = pack;

View File

@ -15,24 +15,19 @@ import com.dfsek.terra.api.config.Loader;
public class StitchedImageTemplate implements ObjectTemplate<Image>, ValidatedConfigTemplate {
private final Loader files;
private final ConfigPack pack;
@Value("path-format")
private String path;
@Value("rows")
private int rows;
@Value("columns")
private int cols;
@Value("zero-indexed")
@Default
private boolean zeroIndexed = false;
private final Loader files;
private final ConfigPack pack;
public StitchedImageTemplate(Loader files, ConfigPack pack) {
this.files = files;
this.pack = pack;
@ -54,13 +49,13 @@ public class StitchedImageTemplate implements ObjectTemplate<Image>, ValidatedCo
}
private String getFormattedPath(int row, int column) {
if (!zeroIndexed) {
if(!zeroIndexed) {
row++;
column++;
}
return path.replaceFirst("\\{row}", String.valueOf(row)).replaceFirst("\\{column}", String.valueOf(column));
}
@Override
public boolean validate() throws ValidationException {
if(!path.contains("{row}"))

View File

@ -69,6 +69,7 @@ public class DistanceTransformNoiseSamplerTemplate implements ObjectTemplate<Noi
@Override
public NoiseSampler get() {
return new DistanceTransform.Noise(new DistanceTransform(image, channel, threshold, clampToEdge, costFunction, invertThreshold), normalization);
return new DistanceTransform.Noise(new DistanceTransform(image, channel, threshold, clampToEdge, costFunction, invertThreshold),
normalization);
}
}

View File

@ -4,17 +4,18 @@ import java.util.Map;
import com.dfsek.terra.addons.image.util.ColorUtil;
public class ClosestMatchColorConverter<T> implements ColorConverter<T> {
private final Map<Integer, T> map;
private final Integer[] colors;
public ClosestMatchColorConverter(Map<Integer, T> map) {
this.map = map;
this.colors = map.keySet().toArray(new Integer[0]);
}
@Override
public T apply(int color) {
int closest = 0;
@ -32,7 +33,7 @@ public class ClosestMatchColorConverter<T> implements ColorConverter<T> {
}
return map.get(closest);
}
@Override
public Iterable<T> getEntries() {
return map.values();

View File

@ -16,7 +16,7 @@ public class ExactColorConverter<T> implements ColorConverter<T> {
private final boolean ignoreAlpha;
public ExactColorConverter(Map<Integer, T> map, T fallback, boolean ignoreAlpha) {
if (ignoreAlpha) {
if(ignoreAlpha) {
map = MapUtil.mapKeys(map, ColorUtil::zeroAlpha);
}
this.map = map;
@ -26,7 +26,7 @@ public class ExactColorConverter<T> implements ColorConverter<T> {
@Override
public T apply(int color) {
if (ignoreAlpha) {
if(ignoreAlpha) {
color = ColorUtil.zeroAlpha(color);
}
T lookup = map.get(color);

View File

@ -30,7 +30,8 @@ public class BiomeDefinedColorMapping<T> implements ColorMapping<T> {
if(!output.containsKey(color)) {
output.put(color, biome);
} else {
throw new IllegalArgumentException(String.format("Biome %s has same color as %s: %x", biome.getID(), output.get(color).getID(), color));
throw new IllegalArgumentException(
String.format("Biome %s has same color as %s: %x", biome.getID(), output.get(color).getID(), color));
}
}));
return output.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> converter.apply(e.getValue())));

View File

@ -40,7 +40,7 @@ public class StitchedImage implements Image {
}
private int getColumn(int x) {
for(int i = columnOffsets.length-1; i > 0; i--) {
for(int i = columnOffsets.length - 1; i > 0; i--) {
if(x >= columnOffsets[i])
return i;
}
@ -48,7 +48,7 @@ public class StitchedImage implements Image {
}
private int getRow(int y) {
for(int i = rowOffsets.length-1; i > 0; i--) {
for(int i = rowOffsets.length - 1; i > 0; i--) {
if(y >= rowOffsets[i])
return i;
}
@ -59,7 +59,7 @@ public class StitchedImage implements Image {
public int getRGB(int x, int y) {
int row = getRow(y);
int column = getColumn(x);
return images[row][column].getRGB(x-columnOffsets[column], y-rowOffsets[row]);
return images[row][column].getRGB(x - columnOffsets[column], y - rowOffsets[row]);
}
@Override

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.addons.image.image;
import java.util.function.Supplier;
public class SuppliedImage implements Image {
private final Supplier<Image> imageSupplier;

View File

@ -16,21 +16,20 @@ import static com.dfsek.terra.addons.image.util.MathUtil.lerp;
*/
public class DistanceTransform {
private static final double MAX_DISTANCE_CAP = 10_000_000; // Arbitrarily large value, doubtful someone would
private final double[][] distances;
/**
* Size bounds matching the provided image.
*/
private final int width, height;
/**
* Min and max distances of the distance computation. These may change after {@link #normalize(Normalization)} calls.
*/
private double minDistance, maxDistance;
private static final double MAX_DISTANCE_CAP = 10_000_000; // Arbitrarily large value, doubtful someone would
// ever use an image large enough to exceed this.
public DistanceTransform(Image image, Channel channel, int threshold, boolean clampToMaxEdgeDistance, CostFunction costFunction, boolean invertThreshold) {
// ever use an image large enough to exceed this.
public DistanceTransform(Image image, Channel channel, int threshold, boolean clampToMaxEdgeDistance, CostFunction costFunction,
boolean invertThreshold) {
// Construct binary image based on threshold value
boolean[][] binaryImage = new boolean[image.getWidth()][image.getHeight()];
for(int x = 0; x < image.getWidth(); x++) {
@ -47,17 +46,17 @@ public class DistanceTransform {
binaryImageEdge[x][y] = false;
else
// If cell borders any false cell
binaryImageEdge[x][y] = x > 0 && !binaryImage[x-1][y] ||
y > 0 && !binaryImage[x][y-1] ||
x < image.getWidth ()-1 && !binaryImage[x+1][y] ||
y < image.getHeight()-1 && !binaryImage[x][y+1];
binaryImageEdge[x][y] = x > 0 && !binaryImage[x - 1][y] ||
y > 0 && !binaryImage[x][y - 1] ||
x < image.getWidth() - 1 && !binaryImage[x + 1][y] ||
y < image.getHeight() - 1 && !binaryImage[x][y + 1];
}
}
double[][] function = new double[image.getWidth()][image.getHeight()];
for(int x = 0; x < image.getWidth(); x++) {
for(int y = 0; y < image.getHeight(); y++) {
function[x][y] = switch (costFunction) {
function[x][y] = switch(costFunction) {
case Channel -> ColorUtil.getChannel(image.getRGB(x, y), channel);
case Threshold -> binaryImage[x][y] ? MAX_DISTANCE_CAP : 0;
case ThresholdEdge, ThresholdEdgeSigned -> binaryImageEdge[x][y] ? 0 : MAX_DISTANCE_CAP;
@ -80,11 +79,11 @@ public class DistanceTransform {
double max = Double.NEGATIVE_INFINITY;
for(int x = 0; x < image.getWidth(); x++) {
max = Math.max(max, distances[x][0]);
max = Math.max(max, distances[x][image.getHeight()-1]);
max = Math.max(max, distances[x][image.getHeight() - 1]);
}
for(int y = 0; y < image.getHeight(); y++) {
max = Math.max(max, distances[0][y]);
max = Math.max(max, distances[image.getWidth()-1][y]);
max = Math.max(max, distances[image.getWidth() - 1][y]);
}
// Clamp to that largest value
for(int x = 0; x < image.getWidth(); x++) {
@ -93,7 +92,7 @@ public class DistanceTransform {
}
}
}
this.width = image.getWidth();
this.height = image.getHeight();
@ -122,28 +121,28 @@ public class DistanceTransform {
private double[] calculateDistance1D(double[] f) {
double[] d = new double[f.length];
int[] v = new int[f.length];
double[] z = new double[f.length+1];
double[] z = new double[f.length + 1];
int k = 0;
v[0] = 0;
z[0] = Integer.MIN_VALUE;
z[1] = Integer.MAX_VALUE;
for(int q = 1; q <= f.length-1; q++) {
double s = ((f[q]+Math.pow(q, 2))-(f[v[k]]+Math.pow(v[k], 2)))/(2*q-2*v[k]);
while (s <= z[k]) {
for(int q = 1; q <= f.length - 1; q++) {
double s = ((f[q] + Math.pow(q, 2)) - (f[v[k]] + Math.pow(v[k], 2))) / (2 * q - 2 * v[k]);
while(s <= z[k]) {
k--;
s = ((f[q]+Math.pow(q, 2))-(f[v[k]]+Math.pow(v[k], 2)))/(2*q-2*v[k]);
s = ((f[q] + Math.pow(q, 2)) - (f[v[k]] + Math.pow(v[k], 2))) / (2 * q - 2 * v[k]);
}
k++;
v[k] = q;
z[k] = s;
z[k+1] = Integer.MAX_VALUE;
z[k + 1] = Integer.MAX_VALUE;
}
k = 0;
for(int q = 0; q <= f.length-1; q++) {
while(z[k+1] < q)
for(int q = 0; q <= f.length - 1; q++) {
while(z[k + 1] < q)
k++;
d[q] = Math.pow(q-v[k], 2) + f[v[k]];
d[q] = Math.pow(q - v[k], 2) + f[v[k]];
}
return d;
}
@ -164,9 +163,9 @@ public class DistanceTransform {
yield lerp(distances[x][y], minDistance, -1, maxDistance, 1);
} else {
if(d > 0) {
yield Math.pow(d/maxDistance, 2);
yield Math.pow(d / maxDistance, 2);
} else if(d < 0) {
yield -Math.pow(d/minDistance, 2);
yield -Math.pow(d / minDistance, 2);
} else {
yield 0;
}
@ -198,6 +197,7 @@ public class DistanceTransform {
ThresholdEdgeSigned,
}
public enum Normalization {
/**
* Return the raw calculated distances.
@ -217,21 +217,22 @@ public class DistanceTransform {
SmoothPreserveZero,
}
public static class Noise implements NoiseSampler {
private final DistanceTransform transform;
public Noise(DistanceTransform transform, Normalization normalization) {
this.transform = transform;
transform.normalize(normalization);
}
@Override
public double noise(long seed, double x, double y) {
if(x<0 || y<0 || x>=transform.width || y>=transform.height) return transform.minDistance;
if(x < 0 || y < 0 || x >= transform.width || y >= transform.height) return transform.minDistance;
return transform.distances[(int) Math.floor(x)][(int) Math.floor(y)];
}
@Override
public double noise(long seed, double x, double y, double z) {
return noise(seed, x, z);

View File

@ -5,7 +5,7 @@ package com.dfsek.terra.addons.image.util;
*/
public class ColorUtil {
private ColorUtil() {}
private ColorUtil() { }
public static int distance(int a, int b) {
return Math.abs(getRed(a) - getRed(b)) +
@ -17,6 +17,7 @@ public class ColorUtil {
* Returns the red channel value of a given ARGB color value.
*
* @param argb the ARGB color value to extract the red channel value from
*
* @return the red channel value of the given ARGB color value, in the range 0-255
*/
public static int getRed(int argb) {
@ -27,6 +28,7 @@ public class ColorUtil {
* Returns the green channel value of a given ARGB color value.
*
* @param argb the ARGB color value to extract the green channel value from
*
* @return the green channel value of the given ARGB color value, in the range 0-255
*/
public static int getGreen(int argb) {
@ -37,6 +39,7 @@ public class ColorUtil {
* Returns the blue channel value of a given ARGB color value.
*
* @param argb the ARGB color value to extract the blue channel value from
*
* @return the blue channel value of the given ARGB color value, in the range 0-255
*/
public static int getBlue(int argb) {
@ -47,6 +50,7 @@ public class ColorUtil {
* Returns the alpha channel value of a given ARGB color value.
*
* @param argb the ARGB color value to extract the blue channel value from
*
* @return the alpha channel value of the given ARGB color value, in the range 0-255
*/
public static int getAlpha(int argb) {
@ -57,6 +61,7 @@ public class ColorUtil {
* Returns the grayscale value of a given ARGB color value.
*
* @param argb the ARGB color value to convert to grayscale
*
* @return the grayscale value of the given ARGB color value, in the range 0-255
*/
public static int getGrayscale(int argb) {
@ -66,8 +71,9 @@ public class ColorUtil {
/**
* Returns the value of the specified channel for a given ARGB color value.
*
* @param argb the ARGB color value to extract the channel value from
* @param argb the ARGB color value to extract the channel value from
* @param channel the channel to extract the value from
*
* @return the value of the specified channel for the given ARGB color value, in the range 0-255
*/
public static int getChannel(int argb, Channel channel) {
@ -78,6 +84,7 @@ public class ColorUtil {
* Sets the red channel value of a given ARGB color value to zero.
*
* @param argb the ARGB color value to zero the red channel of
*
* @return the resulting ARGB color value with the red channel set to zero
*/
public static int zeroRed(int argb) {
@ -88,6 +95,7 @@ public class ColorUtil {
* Sets the green channel value of a given ARGB color value to zero.
*
* @param argb the ARGB color value to zero the green channel of
*
* @return the resulting ARGB color value with the green channel set to zero
*/
public static int zeroGreen(int argb) {
@ -98,6 +106,7 @@ public class ColorUtil {
* Sets the blue channel value of a given ARGB color value to zero.
*
* @param argb the ARGB color value to zero the blue channel of
*
* @return the resulting ARGB color value with the blue channel set to zero
*/
public static int zeroBlue(int argb) {
@ -109,6 +118,7 @@ public class ColorUtil {
* This is the same as setting the color to fully transparent.
*
* @param argb the ARGB color value to zero the alpha channel of
*
* @return the resulting ARGB color value with the alpha channel set to zero
*/
public static int zeroAlpha(int argb) {
@ -120,6 +130,7 @@ public class ColorUtil {
* This is the same as setting the color to black, while preserving the alpha.
*
* @param argb the ARGB color value to zero the color channel of
*
* @return the resulting ARGB color value with the color channels set to zero
*/
public static int zeroGrayscale(int argb) {
@ -129,8 +140,9 @@ public class ColorUtil {
/**
* Sets the specified channel value of a given ARGB color value to zero.
*
* @param argb the ARGB color value to zero the specified channel of
* @param argb the ARGB color value to zero the specified channel of
* @param channel the channel to zero the value of
*
* @return the resulting ARGB color value with the specified channel value set to zero
*/
public static int zeroChannel(int argb, Channel channel) {
@ -141,6 +153,7 @@ public class ColorUtil {
* Multiply the RGB channels of a given ARGB color value by its alpha channel value.
*
* @param argb the ARGB color value to premultiply the RGB channels of
*
* @return the resulting premultiplied ARGB color value
*/
public static int premultiply(int argb) {
@ -155,9 +168,10 @@ public class ColorUtil {
* Returns an ARGB color value with the specified values for alpha, red, green, and blue channels.
*
* @param alpha the alpha value, between 0 and 255, to set in the ARGB color value
* @param red the red value, between 0 and 255, to set in the ARGB color value
* @param red the red value, between 0 and 255, to set in the ARGB color value
* @param green the green value, between 0 and 255, to set in the ARGB color value
* @param blue the blue value, between 0 and 255, to set in the ARGB color value
* @param blue the blue value, between 0 and 255, to set in the ARGB color value
*
* @return the resulting ARGB color value with the specified values for alpha, red, green, and blue channels
*/
public static int argb(int alpha, int red, int green, int blue) {
@ -169,17 +183,19 @@ public class ColorUtil {
* after validating that each channel value is in the range 0-255.
*
* @param alpha the alpha value, between 0 and 255, to set in the ARGB color value
* @param red the red value, between 0 and 255, to set in the ARGB color value
* @param red the red value, between 0 and 255, to set in the ARGB color value
* @param green the green value, between 0 and 255, to set in the ARGB color value
* @param blue the blue value, between 0 and 255, to set in the ARGB color value
* @param blue the blue value, between 0 and 255, to set in the ARGB color value
*
* @return the resulting ARGB color value with the specified values for alpha, red, green, and blue channels
*
* @throws IllegalArgumentException if any channel value is outside the range 0-255
*/
public static int argbValidated(int alpha, int red, int green, int blue) throws IllegalArgumentException {
if (alpha < 0 || alpha > 255 ||
red < 0 || red > 255 ||
green < 0 || green > 255 ||
blue < 0 || blue > 255
if(alpha < 0 || alpha > 255 ||
red < 0 || red > 255 ||
green < 0 || green > 255 ||
blue < 0 || blue > 255
) throw new IllegalArgumentException("Channel values must be in range 0-255");
return argb(alpha, red, green, blue);
}
@ -189,6 +205,7 @@ public class ColorUtil {
* for the red, green, and blue channels.
*
* @param alpha the alpha channel value to set in the ARGB color value
*
* @return the resulting ARGB color value
*/
public static int argbAlpha(int alpha) { return alpha << 24; }
@ -198,6 +215,7 @@ public class ColorUtil {
* for the alpha, green, and blue channels.
*
* @param red the red channel value to set in the ARGB color value
*
* @return the resulting ARGB color value
*/
public static int argbRed(int red) { return red << 16; }
@ -207,6 +225,7 @@ public class ColorUtil {
* for the alpha, red, and blue channels.
*
* @param green the green channel value to set in the ARGB color value
*
* @return the resulting ARGB color value
*/
public static int argbGreen(int green) { return green << 8; }
@ -216,6 +235,7 @@ public class ColorUtil {
* for the alpha, red, and green channels.
*
* @param blue the blue channel value to set in the ARGB color value
*
* @return the resulting ARGB color value
*/
public static int argbBlue(int blue) { return blue; }
@ -224,6 +244,7 @@ public class ColorUtil {
* Returns an ARGB color value with the specified grayscale value for all four channels.
*
* @param value the grayscale value to set in all four channels of the ARGB color value
*
* @return the resulting ARGB color value with the specified grayscale value for all four channels
*/
public static int argbGrayscale(int value) { return argb(value, value, value, value); }
@ -234,7 +255,7 @@ public class ColorUtil {
public int from(int argb) {
return getRed(argb);
}
@Override
public int zero(int argb) {
return zeroRed(argb);
@ -250,7 +271,7 @@ public class ColorUtil {
public int from(int argb) {
return getGreen(argb);
}
@Override
public int zero(int argb) {
return zeroGreen(argb);
@ -266,7 +287,7 @@ public class ColorUtil {
public int from(int argb) {
return getBlue(argb);
}
@Override
public int zero(int argb) {
return zeroBlue(argb);
@ -282,7 +303,7 @@ public class ColorUtil {
public int from(int argb) {
return getGrayscale(argb);
}
@Override
public int zero(int argb) {
return zeroGrayscale(argb);
@ -298,7 +319,7 @@ public class ColorUtil {
public int from(int argb) {
return getAlpha(argb);
}
@Override
public int zero(int argb) {
return zeroAlpha(argb);

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