CNG Image map support

This commit is contained in:
cyberpwn 2021-11-12 15:52:50 -05:00
parent 28ef4a0b2b
commit e1711b5d03
4 changed files with 99 additions and 8 deletions

View File

@ -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);

View File

@ -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()

View File

@ -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<IrisImage> imageCache = new AtomicCache<IrisImage>();
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;
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}
}