From e1711b5d03958888f3bbab89f49424ff51a811f2 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Fri, 12 Nov 2021 15:52:50 -0500 Subject: [PATCH] CNG Image map support --- .../engine/object/IrisGeneratorStyle.java | 15 ++++++ .../volmit/iris/engine/object/IrisImage.java | 16 +++++- .../iris/engine/object/IrisImageMap.java | 27 +++++++--- .../volmit/iris/util/noise/ImageNoise.java | 49 +++++++++++++++++++ 4 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/volmit/iris/util/noise/ImageNoise.java diff --git a/src/main/java/com/volmit/iris/engine/object/IrisGeneratorStyle.java b/src/main/java/com/volmit/iris/engine/object/IrisGeneratorStyle.java index 017c3a4dd..7caba6ea0 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisGeneratorStyle.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisGeneratorStyle.java @@ -28,6 +28,7 @@ import com.volmit.iris.engine.object.annotations.Snippet; import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.noise.ExpressionNoise; +import com.volmit.iris.util.noise.ImageNoise; import com.volmit.iris.util.stream.ProceduralStream; import lombok.AllArgsConstructor; import lombok.Data; @@ -52,6 +53,8 @@ public class IrisGeneratorStyle { @Desc("Instead of using the style property, use a custom expression to represent this style.") @RegistryListResource(IrisExpression.class) private String expression = null; + @Desc("Use an Image map instead of a generated value") + private IrisImageMap imageMap = null; @MinNumber(0.00001) @Desc("The Output multiplier. Only used if parent is fracture.") private double multiplier = 1; @@ -90,6 +93,18 @@ public class IrisGeneratorStyle { } } + else if(getImageMap() != null) + { + CNG cng = new CNG(rng, new ImageNoise(data, getImageMap()), 1D, 1).bake().scale(1D/zoom).pow(exponent).bake(); + cng.setTrueFracturing(axialFracturing); + + if (fracture != null) { + cng.fractureWith(fracture.create(rng.nextParallelRNG(2934), data), fracture.getMultiplier()); + } + + return cng; + } + CNG cng = style.create(rng).bake().scale(1D / zoom).pow(exponent).bake(); cng.setTrueFracturing(axialFracturing); diff --git a/src/main/java/com/volmit/iris/engine/object/IrisImage.java b/src/main/java/com/volmit/iris/engine/object/IrisImage.java index f09d1488a..431faf6c6 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisImage.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisImage.java @@ -28,9 +28,19 @@ import java.awt.image.BufferedImage; public class IrisImage extends IrisRegistrant { private BufferedImage image; + public int getWidth() + { + return image.getWidth(); + } + + public int getHeight() + { + return image.getHeight(); + } + public int getRawValue(int x, int z) { - if(x >= w || z >= h || x < 0 || z < 0) + if(x >= getWidth() || z >= getHeight() || x < 0 || z < 0) { return 0; } @@ -40,7 +50,7 @@ public class IrisImage extends IrisRegistrant { public double getValue(IrisImageChannel channel, int x, int z) { - int color = getRawValue(x + (image.getWidth()/2), z + (image.getHeight()/2)); + int color = getRawValue(x, z); switch(channel) { @@ -87,6 +97,8 @@ public class IrisImage extends IrisRegistrant { return color; } } + + return color; } public IrisImage() diff --git a/src/main/java/com/volmit/iris/engine/object/IrisImageMap.java b/src/main/java/com/volmit/iris/engine/object/IrisImageMap.java index 54c774839..57b2961d2 100644 --- a/src/main/java/com/volmit/iris/engine/object/IrisImageMap.java +++ b/src/main/java/com/volmit/iris/engine/object/IrisImageMap.java @@ -32,6 +32,7 @@ import com.volmit.iris.engine.object.annotations.Snippet; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.interpolation.InterpolationMethod; +import com.volmit.iris.util.interpolation.IrisInterpolation; import com.volmit.iris.util.math.RNG; import lombok.AllArgsConstructor; import lombok.Data; @@ -56,21 +57,35 @@ public class IrisImageMap { @Desc("The interpolation method if the coordinateScale is greater than 1. This blends the image into noise. For nearest neighbor, use NONE.") private InterpolationMethod interpolationMethod = InterpolationMethod.BILINEAR_STARCAST_6; - @Desc("The color of the sky, top half of sky. (hex format)") - private IrisImageChannel channel = IrisImageChannel.COMPOSITE_HSB; + @Desc("The channel of the image to read from. This basically converts image data into a number betwen 0 to 1 per pixel using a certain 'channel/filter'") + private IrisImageChannel channel = IrisImageChannel.COMPOSITE_ADD_HSB; @Desc("Invert the channel input") private boolean inverted = false; + @Desc("Tile the image coordinates") + private boolean tiled = false; + + @Desc("Center 0,0 to the center of the image instead of the top left.") + private boolean centered = true; + private AtomicCache imageCache = new AtomicCache(); public double getNoise(IrisData data, int x, int z) { IrisImage i = imageCache.aquire(() -> data.getImageLoader().load(image)); + return IrisInterpolation.getNoise(interpolationMethod, x, z, coordinateScale, (xx,zz) -> rawNoise(i, xx, zz)); + } - if(coordinateScale <= 1) - { - return i.getImage - } + private double rawNoise(IrisImage i, double x, double z) + { + x /= coordinateScale; + z /= coordinateScale; + x = isTiled() ? x % i.getWidth() : x; + z = isTiled() ? z % i.getHeight() : z; + x = isCentered() ? x + ((i.getWidth() / 2D) * coordinateScale) : x; + z = isCentered() ? z + ((i.getHeight() / 2D) * coordinateScale) : z; + double v = i.getValue(getChannel(), (int)(x/coordinateScale), (int)(z/coordinateScale)); + return isInverted() ? 1D - v : v; } } diff --git a/src/main/java/com/volmit/iris/util/noise/ImageNoise.java b/src/main/java/com/volmit/iris/util/noise/ImageNoise.java new file mode 100644 index 000000000..138e53c5c --- /dev/null +++ b/src/main/java/com/volmit/iris/util/noise/ImageNoise.java @@ -0,0 +1,49 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.noise; + +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.engine.object.IrisExpression; +import com.volmit.iris.engine.object.IrisImageMap; +import com.volmit.iris.util.math.RNG; + +public class ImageNoise implements NoiseGenerator { + private final IrisImageMap expression; + private final IrisData data; + + public ImageNoise(IrisData data, IrisImageMap expression) { + this.data = data; + this.expression = expression; + } + + @Override + public double noise(double x) { + return noise(x, 0); + } + + @Override + public double noise(double x, double z) { + return expression.getNoise(data, (int) x, (int)z); + } + + @Override + public double noise(double x, double y, double z) { + return noise(x, y, 0); + } +}