From 8a9ec04e350319ebf73fbc4300e84a65604a44c1 Mon Sep 17 00:00:00 2001 From: "bre..ns" Date: Tue, 27 Dec 2011 23:51:32 +0000 Subject: [PATCH] moved noise library into jme3/terrain git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8959 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- engine/nbproject/project.properties | 247 ++++++++------- .../geomipmap/grid/FractalTileLoader.java | 2 +- .../terrain/com/jme3/terrain/noise/Basis.java | 77 +++++ .../terrain/com/jme3/terrain/noise/Color.java | 134 ++++++++ .../com/jme3/terrain/noise/Filter.java | 44 +++ .../com/jme3/terrain/noise/ShaderUtils.java | 288 ++++++++++++++++++ .../terrain/noise/basis/FilteredBasis.java | 111 +++++++ .../terrain/noise/basis/ImprovedNoise.java | 127 ++++++++ .../com/jme3/terrain/noise/basis/Noise.java | 94 ++++++ .../terrain/noise/basis/NoiseAggregator.java | 64 ++++ .../terrain/noise/filter/AbstractFilter.java | 100 ++++++ .../noise/filter/HydraulicErodeFilter.java | 154 ++++++++++ .../terrain/noise/filter/IterativeFilter.java | 102 +++++++ .../terrain/noise/filter/OptimizedErode.java | 113 +++++++ .../terrain/noise/filter/PerturbFilter.java | 98 ++++++ .../terrain/noise/filter/SmoothFilter.java | 80 +++++ .../noise/filter/ThermalErodeFilter.java | 101 ++++++ .../jme3/terrain/noise/fractal/Fractal.java | 57 ++++ .../terrain/noise/fractal/FractalSum.java | 142 +++++++++ .../jme3/terrain/noise/modulator/CatRom2.java | 78 +++++ .../terrain/noise/modulator/Modulator.java | 36 +++ .../noise/modulator/NoiseModulator.java | 34 +++ .../terrain/TerrainFractalGridTest.java | 16 +- .../terrain/TerrainGridAlphaMapTest.java | 16 +- .../terrain/TerrainTestModifyHeight.java | 16 +- 25 files changed, 2182 insertions(+), 149 deletions(-) create mode 100644 engine/src/terrain/com/jme3/terrain/noise/Basis.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/Color.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/Filter.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/ShaderUtils.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/basis/FilteredBasis.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/basis/ImprovedNoise.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/basis/Noise.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/basis/NoiseAggregator.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/filter/AbstractFilter.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/filter/HydraulicErodeFilter.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/filter/IterativeFilter.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/filter/OptimizedErode.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/filter/SmoothFilter.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/filter/ThermalErodeFilter.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/fractal/Fractal.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/fractal/FractalSum.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/modulator/CatRom2.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/modulator/Modulator.java create mode 100644 engine/src/terrain/com/jme3/terrain/noise/modulator/NoiseModulator.java diff --git a/engine/nbproject/project.properties b/engine/nbproject/project.properties index 5e5108019..ea78bae08 100644 --- a/engine/nbproject/project.properties +++ b/engine/nbproject/project.properties @@ -1,124 +1,123 @@ -annotation.processing.enabled=false -annotation.processing.enabled.in.editor=false -annotation.processing.run.all.processors=true -ant.customtasks.libs=JWSAntTasks -application.homepage=http://www.jmonkeyengine.com/ -application.title=jMonkeyEngine 3.0 -application.vendor=jMonkeyEngine -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/jMonkeyEngine3.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.src-test-data=src/test-data -includes=** -jar.archive.disabled=${jnlp.enabled} -jar.compress=true -jar.index=${jnlp.enabled} -javac.classpath=\ - ${libs.jogg.classpath}:\ - ${libs.jbullet.classpath}:\ - ${libs.lwjgl.classpath}:\ - ${libs.niftygui1.3.classpath}:\ - ${libs.jme3-test-data.classpath}:\ - ${libs.noise.classpath}:\ - ${libs.android.classpath}:\ - ${libs.bullet.classpath} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.processorpath=\ - ${javac.classpath} -javac.source=1.5 -javac.target=1.5 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir}:\ - ${libs.junit_4.classpath} -javadoc.additionalparam=-public -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle=jMonkeyEngine3 -jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" -jnlp.applet.class=jme3test.awt.AppHarness -jnlp.applet.height=300 -jnlp.applet.width=300 -jnlp.codebase.type=user -jnlp.codebase.user=http://jmonkeyengine.com/javawebstart/ -jnlp.descriptor=application -jnlp.enabled=false -jnlp.icon=/Users/normenhansen/Pictures/jme/icons/jme-logo48.png -jnlp.mixed.code=default -jnlp.offline-allowed=true -jnlp.signed=true -jnlp.signing=generated -jnlp.signing.alias= -jnlp.signing.keystore= -main.class=jme3test.TestChooser -manifest.file=MANIFEST.MF -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir}:\ - ${build.dir}/core:\ - ${build.dir}/plugins:\ - ${build.dir}/jogg:\ - ${build.dir}/desktop:\ - ${build.dir}/blender:\ - ${build.dir}/terrain:\ - ${build.dir}/jbullet:\ - ${build.dir}/bullet:\ - ${build.dir}/niftygui:\ - ${build.dir}/lwjgl:\ - ${build.dir}/android -run.jvmargs=-Xms128m -Xmx128m -XX:MaxDirectMemorySize=256M -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -src.android.dir=src/android -src.blender.dir=src/blender -src.bullet-common.dir=src/bullet-common -src.bullet-native.dir=src/bullet-native -src.bullet.dir=src/bullet -src.core-data.dir=src/core-data -src.core-plugins.dir=src/core-plugins -src.core.dir=src/core -src.desktop.dir=src/desktop -src.jbullet.dir=src/jbullet -src.jogg.dir=src/jogg -src.lwjgl.dir=src/lwjgl -src.networking.dir=src\\networking -src.niftygui.dir=src/niftygui -src.ogre.dir=src/ogre -src.terrain.dir=src/terrain -src.test.dir=src/test -src.tools.dir=src/tools -src.xml.dir=src/xml -test.test.dir=test +annotation.processing.enabled=false +annotation.processing.enabled.in.editor=false +annotation.processing.run.all.processors=true +ant.customtasks.libs=JWSAntTasks +application.homepage=http://www.jmonkeyengine.com/ +application.title=jMonkeyEngine 3.0 +application.vendor=jMonkeyEngine +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/jMonkeyEngine3.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.src-test-data=src/test-data +includes=** +jar.archive.disabled=${jnlp.enabled} +jar.compress=true +jar.index=${jnlp.enabled} +javac.classpath=\ + ${libs.jogg.classpath}:\ + ${libs.jbullet.classpath}:\ + ${libs.lwjgl.classpath}:\ + ${libs.niftygui1.3.classpath}:\ + ${libs.jme3-test-data.classpath}:\ + ${libs.android.classpath}:\ + ${libs.bullet.classpath} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam=-public +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle=jMonkeyEngine3 +jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api" +jnlp.applet.class=jme3test.awt.AppHarness +jnlp.applet.height=300 +jnlp.applet.width=300 +jnlp.codebase.type=user +jnlp.codebase.user=http://jmonkeyengine.com/javawebstart/ +jnlp.descriptor=application +jnlp.enabled=false +jnlp.icon=/Users/normenhansen/Pictures/jme/icons/jme-logo48.png +jnlp.mixed.code=default +jnlp.offline-allowed=true +jnlp.signed=true +jnlp.signing=generated +jnlp.signing.alias= +jnlp.signing.keystore= +main.class=jme3test.TestChooser +manifest.file=MANIFEST.MF +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${build.dir}/core:\ + ${build.dir}/plugins:\ + ${build.dir}/jogg:\ + ${build.dir}/desktop:\ + ${build.dir}/blender:\ + ${build.dir}/terrain:\ + ${build.dir}/jbullet:\ + ${build.dir}/bullet:\ + ${build.dir}/niftygui:\ + ${build.dir}/lwjgl:\ + ${build.dir}/android +run.jvmargs=-Xms128m -Xmx128m -XX:MaxDirectMemorySize=256M +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.android.dir=src/android +src.blender.dir=src/blender +src.bullet-common.dir=src/bullet-common +src.bullet-native.dir=src/bullet-native +src.bullet.dir=src/bullet +src.core-data.dir=src/core-data +src.core-plugins.dir=src/core-plugins +src.core.dir=src/core +src.desktop.dir=src/desktop +src.jbullet.dir=src/jbullet +src.jogg.dir=src/jogg +src.lwjgl.dir=src/lwjgl +src.networking.dir=src\\networking +src.niftygui.dir=src/niftygui +src.ogre.dir=src/ogre +src.terrain.dir=src/terrain +src.test.dir=src/test +src.tools.dir=src/tools +src.xml.dir=src/xml +test.test.dir=test diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/grid/FractalTileLoader.java b/engine/src/terrain/com/jme3/terrain/geomipmap/grid/FractalTileLoader.java index 4b2ed64e4..9eaa9a284 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/grid/FractalTileLoader.java +++ b/engine/src/terrain/com/jme3/terrain/geomipmap/grid/FractalTileLoader.java @@ -15,7 +15,7 @@ import com.jme3.terrain.heightmap.AbstractHeightMap; import com.jme3.terrain.heightmap.HeightMap; import java.io.IOException; import java.nio.FloatBuffer; -import org.novyon.noise.Basis; +import com.jme3.terrain.noise.Basis; /** * diff --git a/engine/src/terrain/com/jme3/terrain/noise/Basis.java b/engine/src/terrain/com/jme3/terrain/noise/Basis.java new file mode 100644 index 000000000..9f310f637 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/Basis.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise; + +import java.nio.FloatBuffer; + +import com.jme3.terrain.noise.basis.ImprovedNoise; +import com.jme3.terrain.noise.modulator.Modulator; + +/** + * Interface for - basically 3D - noise generation algorithms, based on the + * book: Texturing & Modeling - A Procedural Approach + * + * The main concept is to look at noise as a basis for generating fractals. + * Basis can be anything, like a simple: + * + * + * float value(float x, float y, float z) { + * return 0; // a flat noise with 0 value everywhere + * } + * + * + * or a more complex perlin noise ({@link ImprovedNoise} + * + * Fractals use these functions to generate a more complex result based on some + * frequency, roughness, etc values. + * + * Fractals themselves are implementing the Basis interface as well, opening + * an infinite range of results. + * + * @author Anthyon + * + * @since 2011 + * + */ +public interface Basis { + + public void init(); + + public Basis setScale(float scale); + + public float getScale(); + + public Basis addModulator(Modulator modulator); + + public float value(float x, float y, float z); + + public FloatBuffer getBuffer(float sx, float sy, float base, int size); + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/Color.java b/engine/src/terrain/com/jme3/terrain/noise/Color.java new file mode 100644 index 000000000..719c0ffee --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/Color.java @@ -0,0 +1,134 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise; + +/** + * Helper class for working with colors and gradients + * + * @author Anthyon + * + */ +public class Color { + + private final float[] rgba = new float[4]; + + public Color() {} + + public Color(final int r, final int g, final int b) { + this(r, g, b, 255); + } + + public Color(final int r, final int g, final int b, final int a) { + this.rgba[0] = (r & 255) / 256f; + this.rgba[1] = (g & 255) / 256f; + this.rgba[2] = (b & 255) / 256f; + this.rgba[3] = (a & 255) / 256f; + } + + public Color(final float r, final float g, final float b) { + this(r, g, b, 1); + } + + public Color(final float r, final float g, final float b, final float a) { + this.rgba[0] = ShaderUtils.clamp(r, 0, 1); + this.rgba[1] = ShaderUtils.clamp(g, 0, 1); + this.rgba[2] = ShaderUtils.clamp(b, 0, 1); + this.rgba[3] = ShaderUtils.clamp(a, 0, 1); + } + + public Color(final int h, final float s, final float b) { + this(h, s, b, 1); + } + + public Color(final int h, final float s, final float b, final float a) { + this.rgba[3] = a; + if (s == 0) { + // achromatic ( grey ) + this.rgba[0] = b; + this.rgba[1] = b; + this.rgba[2] = b; + return; + } + + float hh = h / 60.0f; + int i = ShaderUtils.floor(hh); + float f = hh - i; + float p = b * (1 - s); + float q = b * (1 - s * f); + float t = b * (1 - s * (1 - f)); + + if (i == 0) { + this.rgba[0] = b; + this.rgba[1] = t; + this.rgba[2] = p; + } else if (i == 1) { + this.rgba[0] = q; + this.rgba[1] = b; + this.rgba[2] = p; + } else if (i == 2) { + this.rgba[0] = p; + this.rgba[1] = b; + this.rgba[2] = t; + } else if (i == 3) { + this.rgba[0] = p; + this.rgba[1] = q; + this.rgba[2] = b; + } else if (i == 4) { + this.rgba[0] = t; + this.rgba[1] = p; + this.rgba[2] = b; + } else { + this.rgba[0] = b; + this.rgba[1] = p; + this.rgba[2] = q; + } + } + + public int toInteger() { + return 0x00000000 | (int) (this.rgba[3] * 256) << 24 | (int) (this.rgba[0] * 256) << 16 | (int) (this.rgba[1] * 256) << 8 + | (int) (this.rgba[2] * 256); + } + + public String toWeb() { + return Integer.toHexString(this.toInteger()); + } + + public Color toGrayscale() { + float v = (this.rgba[0] + this.rgba[1] + this.rgba[2]) / 3f; + return new Color(v, v, v, this.rgba[3]); + } + + public Color toSepia() { + float r = ShaderUtils.clamp(this.rgba[0] * 0.393f + this.rgba[1] * 0.769f + this.rgba[2] * 0.189f, 0, 1); + float g = ShaderUtils.clamp(this.rgba[0] * 0.349f + this.rgba[1] * 0.686f + this.rgba[2] * 0.168f, 0, 1); + float b = ShaderUtils.clamp(this.rgba[0] * 0.272f + this.rgba[1] * 0.534f + this.rgba[2] * 0.131f, 0, 1); + return new Color(r, g, b, this.rgba[3]); + } +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/Filter.java b/engine/src/terrain/com/jme3/terrain/noise/Filter.java new file mode 100644 index 000000000..1dca8bfbf --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/Filter.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise; + +import java.nio.FloatBuffer; + +public interface Filter { + public Filter addPreFilter(Filter filter); + + public Filter addPostFilter(Filter filter); + + public FloatBuffer doFilter(float sx, float sy, float base, FloatBuffer data, int size); + + public int getMargin(int size, int margin); + + public boolean isEnabled(); +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/ShaderUtils.java b/engine/src/terrain/com/jme3/terrain/noise/ShaderUtils.java new file mode 100644 index 000000000..d1c2f6e84 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/ShaderUtils.java @@ -0,0 +1,288 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; +import java.awt.image.WritableRaster; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * Helper class containing useful functions explained in the book: + * Texturing & Modeling - A Procedural Approach + * + * @author Anthyon + * + */ +public class ShaderUtils { + + public static final float[] i2c(final int color) { + return new float[] { (color & 0x00ff0000) / 256f, (color & 0x0000ff00) / 256f, (color & 0x000000ff) / 256f, + (color & 0xff000000) / 256f }; + } + + public static final int c2i(final float[] color) { + return (color.length == 4 ? (int) (color[3] * 256) : 0xff000000) | ((int) (color[0] * 256) << 16) | ((int) (color[1] * 256) << 8) + | (int) (color[2] * 256); + } + + public static final float mix(final float a, final float b, final float f) { + return (1 - f) * a + f * b; + } + + public static final Color mix(final Color a, final Color b, final float f) { + return new Color((int) ShaderUtils.clamp(ShaderUtils.mix(a.getRed(), b.getRed(), f), 0, 255), (int) ShaderUtils.clamp( + ShaderUtils.mix(a.getGreen(), b.getGreen(), f), 0, 255), (int) ShaderUtils.clamp( + ShaderUtils.mix(a.getBlue(), b.getBlue(), f), 0, 255)); + } + + public static final int mix(final int a, final int b, final float f) { + return (int) ((1 - f) * a + f * b); + } + + public static final float[] mix(final float[] c1, final float[] c2, final float f) { + return new float[] { ShaderUtils.mix(c1[0], c2[0], f), ShaderUtils.mix(c1[1], c2[1], f), ShaderUtils.mix(c1[2], c2[2], f) }; + } + + public static final float step(final float a, final float x) { + return x < a ? 0 : 1; + } + + public static final float boxstep(final float a, final float b, final float x) { + return ShaderUtils.clamp((x - a) / (b - a), 0, 1); + } + + public static final float pulse(final float a, final float b, final float x) { + return ShaderUtils.step(a, x) - ShaderUtils.step(b, x); + } + + public static final float clamp(final float x, final float a, final float b) { + return x < a ? a : x > b ? b : x; + } + + public static final float min(final float a, final float b) { + return a < b ? a : b; + } + + public static final float max(final float a, final float b) { + return a > b ? a : b; + } + + public static final float abs(final float x) { + return x < 0 ? -x : x; + } + + public static final float smoothstep(final float a, final float b, final float x) { + if (x < a) { + return 0; + } else if (x > b) { + return 1; + } + float xx = (x - a) / (b - a); + return xx * xx * (3 - 2 * xx); + } + + public static final float mod(final float a, final float b) { + int n = (int) (a / b); + float aa = a - n * b; + if (aa < 0) { + aa += b; + } + return aa; + } + + public static final int floor(final float x) { + return x > 0 ? (int) x : (int) x - 1; + } + + public static final float ceil(final float x) { + return (int) x + (x > 0 && x != (int) x ? 1 : 0); + } + + public static final float spline(float x, final float[] knot) { + float CR00 = -0.5f; + float CR01 = 1.5f; + float CR02 = -1.5f; + float CR03 = 0.5f; + float CR10 = 1.0f; + float CR11 = -2.5f; + float CR12 = 2.0f; + float CR13 = -0.5f; + float CR20 = -0.5f; + float CR21 = 0.0f; + float CR22 = 0.5f; + float CR23 = 0.0f; + float CR30 = 0.0f; + float CR31 = 1.0f; + float CR32 = 0.0f; + float CR33 = 0.0f; + + int span; + int nspans = knot.length - 3; + float c0, c1, c2, c3; /* coefficients of the cubic. */ + if (nspans < 1) {/* illegal */ + throw new RuntimeException("Spline has too few knots."); + } + /* Find the appropriate 4-point span of the spline. */ + x = ShaderUtils.clamp(x, 0, 1) * nspans; + span = (int) x; + if (span >= knot.length - 3) { + span = knot.length - 3; + } + x -= span; + /* Evaluate the span cubic at x using Horner’s rule. */ + c3 = CR00 * knot[span + 0] + CR01 * knot[span + 1] + CR02 * knot[span + 2] + CR03 * knot[span + 3]; + c2 = CR10 * knot[span + 0] + CR11 * knot[span + 1] + CR12 * knot[span + 2] + CR13 * knot[span + 3]; + c1 = CR20 * knot[span + 0] + CR21 * knot[span + 1] + CR22 * knot[span + 2] + CR23 * knot[span + 3]; + c0 = CR30 * knot[span + 0] + CR31 * knot[span + 1] + CR32 * knot[span + 2] + CR33 * knot[span + 3]; + return ((c3 * x + c2) * x + c1) * x + c0; + } + + public static final float[] spline(final float x, final float[][] knots) { + float[] retval = new float[knots.length]; + for (int i = 0; i < knots.length; i++) { + retval[i] = ShaderUtils.spline(x, knots[i]); + } + return retval; + } + + public static final float gammaCorrection(final float gamma, final float x) { + return (float) Math.pow(x, 1 / gamma); + } + + public static final float bias(final float b, final float x) { + return (float) Math.pow(x, Math.log(b) / Math.log(0.5)); + } + + public static final float gain(final float g, final float x) { + return x < 0.5 ? ShaderUtils.bias(1 - g, 2 * x) / 2 : 1 - ShaderUtils.bias(1 - g, 2 - 2 * x) / 2; + } + + public static final float sinValue(final float s, final float minFreq, final float maxFreq, final float swidth) { + float value = 0; + float cutoff = ShaderUtils.clamp(0.5f / swidth, 0, maxFreq); + float f; + for (f = minFreq; f < 0.5 * cutoff; f *= 2) { + value += Math.sin(2 * Math.PI * f * s) / f; + } + float fade = ShaderUtils.clamp(2 * (cutoff - f) / cutoff, 0, 1); + value += fade * Math.sin(2 * Math.PI * f * s) / f; + return value; + } + + public static final float length(final float x, final float y, final float z) { + return (float) Math.sqrt(x * x + y * y + z * z); + } + + public static final float[] rotate(final float[] v, final float[][] m) { + float x = v[0] * m[0][0] + v[1] * m[0][1] + v[2] * m[0][2]; + float y = v[0] * m[1][0] + v[1] * m[1][1] + v[2] * m[1][2]; + float z = v[0] * m[2][0] + v[1] * m[2][1] + v[2] * m[2][2]; + return new float[] { x, y, z }; + } + + public static final float[][] calcRotationMatrix(final float ax, final float ay, final float az) { + float[][] retval = new float[3][3]; + float cax = (float) Math.cos(ax); + float sax = (float) Math.sin(ax); + float cay = (float) Math.cos(ay); + float say = (float) Math.sin(ay); + float caz = (float) Math.cos(az); + float saz = (float) Math.sin(az); + + retval[0][0] = cay * caz; + retval[0][1] = -cay * saz; + retval[0][2] = say; + retval[1][0] = sax * say * caz + cax * saz; + retval[1][1] = -sax * say * saz + cax * caz; + retval[1][2] = -sax * cay; + retval[2][0] = -cax * say * caz + sax * saz; + retval[2][1] = cax * say * saz + sax * caz; + retval[2][2] = cax * cay; + + return retval; + } + + public static final float[] normalize(final float[] v) { + float l = ShaderUtils.length(v); + float[] r = new float[v.length]; + int i = 0; + for (float vv : v) { + r[i++] = vv / l; + } + return r; + } + + public static final float length(final float[] v) { + float s = 0; + for (float vv : v) { + s += vv * vv; + } + return (float) Math.sqrt(s); + } + + public static final ByteBuffer getImageDataFromImage(BufferedImage bufferedImage) { + WritableRaster wr; + DataBuffer db; + + BufferedImage bi = new BufferedImage(128, 64, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = bi.createGraphics(); + g.drawImage(bufferedImage, null, null); + bufferedImage = bi; + wr = bi.getRaster(); + db = wr.getDataBuffer(); + + DataBufferInt dbi = (DataBufferInt) db; + int[] data = dbi.getData(); + + ByteBuffer byteBuffer = ByteBuffer.allocateDirect(data.length * 4); + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + byteBuffer.asIntBuffer().put(data); + byteBuffer.flip(); + + return byteBuffer; + } + + public static float frac(float f) { + return f - ShaderUtils.floor(f); + } + + public static float[] floor(float[] fs) { + float[] retval = new float[fs.length]; + for (int i = 0; i < fs.length; i++) { + retval[i] = ShaderUtils.floor(fs[i]); + } + return retval; + } +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/basis/FilteredBasis.java b/engine/src/terrain/com/jme3/terrain/noise/basis/FilteredBasis.java new file mode 100644 index 000000000..53d0938ca --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/basis/FilteredBasis.java @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.basis; + +import java.nio.FloatBuffer; +import java.util.ArrayList; +import java.util.List; + +import com.jme3.terrain.noise.Basis; +import com.jme3.terrain.noise.filter.AbstractFilter; +import com.jme3.terrain.noise.modulator.Modulator; + +public class FilteredBasis extends AbstractFilter implements Basis { + + private Basis basis; + private List modulators = new ArrayList(); + private float scale; + + public FilteredBasis() {} + + public FilteredBasis(Basis basis) { + this.basis = basis; + } + + public Basis getBasis() { + return this.basis; + } + + public void setBasis(Basis basis) { + this.basis = basis; + } + + @Override + public FloatBuffer filter(float sx, float sy, float base, FloatBuffer data, int size) { + return data; + } + + @Override + public void init() { + this.basis.init(); + } + + @Override + public Basis setScale(float scale) { + this.scale = scale; + return this; + } + + @Override + public float getScale() { + return this.scale; + } + + @Override + public Basis addModulator(Modulator modulator) { + this.modulators.add(modulator); + return this; + } + + @Override + public float value(float x, float y, float z) { + throw new UnsupportedOperationException( + "Method value cannot be called on FilteredBasis and its descendants. Use getBuffer instead!"); + } + + @Override + public FloatBuffer getBuffer(float sx, float sy, float base, int size) { + int margin = this.getMargin(size, 0); + int workSize = size + 2 * margin; + FloatBuffer retval = this.basis.getBuffer(sx - margin, sy - margin, base, workSize); + return this.clip(this.doFilter(sx, sy, base, retval, workSize), workSize, size, margin); + } + + public FloatBuffer clip(FloatBuffer buf, int origSize, int newSize, int offset) { + FloatBuffer result = FloatBuffer.allocate(newSize * newSize); + + float[] orig = buf.array(); + for (int i = offset; i < offset + newSize; i++) { + result.put(orig, i * origSize + offset, newSize); + } + + return result; + } +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/basis/ImprovedNoise.java b/engine/src/terrain/com/jme3/terrain/noise/basis/ImprovedNoise.java new file mode 100644 index 000000000..9233ef87a --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/basis/ImprovedNoise.java @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.basis; + +import com.jme3.terrain.noise.ShaderUtils; + +// JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE - COPYRIGHT 2002 KEN PERLIN. +/** + * Perlin's default implementation of Improved Perlin Noise + * designed to work with Noise base + */ +public final class ImprovedNoise extends Noise { + + @Override + public void init() { + + } + + static public float noise(float x, float y, float z) { + int X = ShaderUtils.floor(x), // FIND UNIT CUBE THAT + Y = ShaderUtils.floor(y), // CONTAINS POINT. + Z = ShaderUtils.floor(z); + x -= X; // FIND RELATIVE X,Y,Z + y -= Y; // OF POINT IN CUBE. + z -= Z; + X = X & 255; + Y = Y & 255; + Z = Z & 255; + float u = ImprovedNoise.fade(x), // COMPUTE FADE CURVES + v = ImprovedNoise.fade(y), // FOR EACH OF X,Y,Z. + w = ImprovedNoise.fade(z); + int A = ImprovedNoise.p[X] + Y; + int AA = ImprovedNoise.p[A] + Z; + int AB = ImprovedNoise.p[A + 1] + Z; + int B = ImprovedNoise.p[X + 1] + Y; + int BA = ImprovedNoise.p[B] + Z; + int BB = ImprovedNoise.p[B + 1] + Z; + + return ImprovedNoise.lerp( + w, + ImprovedNoise.lerp( + v, + ImprovedNoise.lerp(u, ImprovedNoise.grad3(ImprovedNoise.p[AA], x, y, z), + ImprovedNoise.grad3(ImprovedNoise.p[BA], x - 1, y, z)), // BLENDED + ImprovedNoise.lerp(u, ImprovedNoise.grad3(ImprovedNoise.p[AB], x, y - 1, z), // RESULTS + ImprovedNoise.grad3(ImprovedNoise.p[BB], x - 1, y - 1, z))),// FROM + ImprovedNoise.lerp(v, + ImprovedNoise.lerp(u, ImprovedNoise.grad3(ImprovedNoise.p[AA + 1], x, y, z - 1), // CORNERS + ImprovedNoise.grad3(ImprovedNoise.p[BA + 1], x - 1, y, z - 1)), // OF + ImprovedNoise.lerp(u, ImprovedNoise.grad3(ImprovedNoise.p[AB + 1], x, y - 1, z - 1), + ImprovedNoise.grad3(ImprovedNoise.p[BB + 1], x - 1, y - 1, z - 1)))); + } + + static final float fade(final float t) { + return t * t * t * (t * (t * 6 - 15) + 10); + } + + static final float lerp(final float t, final float a, final float b) { + return a + t * (b - a); + } + + static float grad(final int hash, final float x, final float y, final float z) { + int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE + float u = h < 8 ? x : y, // INTO 12 GRADIENT DIRECTIONS. + v = h < 4 ? y : h == 12 || h == 14 ? x : z; + return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); + } + + static final float grad3(final int hash, final float x, final float y, final float z) { + int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE + return x * ImprovedNoise.GRAD3[h][0] + y * ImprovedNoise.GRAD3[h][1] + z * ImprovedNoise.GRAD3[h][2]; + } + + static final int p[] = new int[512], permutation[] = { 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, + 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, + 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, + 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, + 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, + 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, + 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, + 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, + 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, + 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 }; + + private static float[][] GRAD3 = new float[][] { { 1, 1, 0 }, { -1, 1, 0 }, { 1, -1, 0 }, { -1, -1, 0 }, { 1, 0, 1 }, { -1, 0, 1 }, + { 1, 0, -1 }, { -1, 0, -1 }, { 0, 1, 1 }, { 0, -1, 1 }, { 0, 1, -1 }, { 0, -1, -1 }, { 1, 0, -1 }, { -1, 0, -1 }, { 0, -1, 1 }, + { 0, 1, 1 } }; + + static { + for (int i = 0; i < 256; i++) { + ImprovedNoise.p[256 + i] = ImprovedNoise.p[i] = ImprovedNoise.permutation[i]; + } + } + + @Override + public float value(final float x, final float y, final float z) { + return ImprovedNoise.noise(this.scale * x, this.scale * y, this.scale * z); + } + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/basis/Noise.java b/engine/src/terrain/com/jme3/terrain/noise/basis/Noise.java new file mode 100644 index 000000000..c9de6f537 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/basis/Noise.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.basis; + +import java.nio.FloatBuffer; +import java.util.ArrayList; +import java.util.List; + +import com.jme3.terrain.noise.Basis; +import com.jme3.terrain.noise.modulator.Modulator; +import com.jme3.terrain.noise.modulator.NoiseModulator; + +/** + * Utility base class for Noise implementations + * + * @author Anthyon + * + */ +public abstract class Noise implements Basis { + + protected List modulators = new ArrayList(); + + protected float scale = 1.0f; + + @Override + public String toString() { + return this.getClass().getSimpleName(); + } + + @Override + public FloatBuffer getBuffer(float sx, float sy, float base, int size) { + FloatBuffer retval = FloatBuffer.allocate(size * size); + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + retval.put(this.modulate((sx + x) / size, (sy + y) / size, base)); + } + } + return retval; + } + + public float modulate(float x, float y, float z) { + float retval = this.value(x, y, z); + for (Modulator m : this.modulators) { + if (m instanceof NoiseModulator) { + retval = m.value(retval); + } + } + return retval; + } + + @Override + public Basis addModulator(Modulator modulator) { + this.modulators.add(modulator); + return this; + } + + @Override + public Basis setScale(float scale) { + this.scale = scale; + return this; + } + + @Override + public float getScale() { + return this.scale; + } +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/basis/NoiseAggregator.java b/engine/src/terrain/com/jme3/terrain/noise/basis/NoiseAggregator.java new file mode 100644 index 000000000..8a547a3b9 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/basis/NoiseAggregator.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.basis; + +import com.jme3.terrain.noise.Basis; + +/** + * A simple aggregator basis. Takes two basis functions and a rate and return + * some mixed values + * + * @author Anthyon + * + */ +public class NoiseAggregator extends Noise { + + private final float rate; + private final Basis a; + private final Basis b; + + public NoiseAggregator(final Basis a, final Basis b, final float rate) { + this.a = a; + this.b = b; + this.rate = rate; + } + + @Override + public void init() { + this.a.init(); + this.b.init(); + } + + @Override + public float value(final float x, final float y, final float z) { + return this.a.value(x, y, z) * (1 - this.rate) + this.rate * this.b.value(x, y, z); + } + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/filter/AbstractFilter.java b/engine/src/terrain/com/jme3/terrain/noise/filter/AbstractFilter.java new file mode 100644 index 000000000..4174ba974 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/filter/AbstractFilter.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.filter; + +import java.nio.FloatBuffer; +import java.util.ArrayList; +import java.util.List; + +import com.jme3.terrain.noise.Filter; + +public abstract class AbstractFilter implements Filter { + + protected List preFilters = new ArrayList(); + protected List postFilters = new ArrayList(); + + private boolean enabled = true; + + @Override + public Filter addPreFilter(Filter filter) { + this.preFilters.add(filter); + return this; + } + + @Override + public Filter addPostFilter(Filter filter) { + this.postFilters.add(filter); + return this; + } + + @Override + public FloatBuffer doFilter(float sx, float sy, float base, FloatBuffer data, int size) { + if (!this.isEnabled()) { + return data; + } + FloatBuffer retval = data; + for (Filter f : this.preFilters) { + retval = f.doFilter(sx, sy, base, retval, size); + } + retval = this.filter(sx, sy, base, retval, size); + for (Filter f : this.postFilters) { + retval = f.doFilter(sx, sy, base, retval, size); + } + return retval; + } + + public abstract FloatBuffer filter(float sx, float sy, float base, FloatBuffer buffer, int size); + + @Override + public int getMargin(int size, int margin) { + // TODO sums up all the margins from filters... maybe there's a more + // efficient algorithm + if (!this.isEnabled()) { + return margin; + } + for (Filter f : this.preFilters) { + margin = f.getMargin(size, margin); + } + for (Filter f : this.postFilters) { + margin = f.getMargin(size, margin); + } + return margin; + } + + @Override + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/filter/HydraulicErodeFilter.java b/engine/src/terrain/com/jme3/terrain/noise/filter/HydraulicErodeFilter.java new file mode 100644 index 000000000..13e2c5ea3 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/filter/HydraulicErodeFilter.java @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.filter; + +import java.nio.FloatBuffer; + +import com.jme3.terrain.noise.Basis; + +public class HydraulicErodeFilter extends AbstractFilter { + + private Basis waterMap; + private Basis sedimentMap; + private float Kr; + private float Ks; + private float Ke; + private float Kc; + private float T; + + public void setKc(float kc) { + this.Kc = kc; + } + + public void setKe(float ke) { + this.Ke = ke; + } + + public void setKr(float kr) { + this.Kr = kr; + } + + public void setKs(float ks) { + this.Ks = ks; + } + + public void setSedimentMap(Basis sedimentMap) { + this.sedimentMap = sedimentMap; + } + + public void setT(float t) { + this.T = t; + } + + public void setWaterMap(Basis waterMap) { + this.waterMap = waterMap; + } + + @Override + public int getMargin(int size, int margin) { + return super.getMargin(size, margin) + 1; + } + + @Override + public FloatBuffer filter(float sx, float sy, float base, FloatBuffer buffer, int workSize) { + float[] ga = buffer.array(); + // float[] wa = this.waterMap.getBuffer(sx, sy, base, workSize).array(); + // float[] sa = this.sedimentMap.getBuffer(sx, sy, base, + // workSize).array(); + float[] wt = new float[workSize * workSize]; + float[] st = new float[workSize * workSize]; + + int[] idxrel = { -workSize - 1, -workSize + 1, workSize - 1, workSize + 1 }; + + // step 1. water arrives and step 2. captures material + for (int y = 0; y < workSize; y++) { + for (int x = 0; x < workSize; x++) { + int idx = y * workSize + x; + float wtemp = this.Kr; // * wa[idx]; + float stemp = this.Ks; // * sa[idx]; + if (wtemp > 0) { + wt[idx] += wtemp; + if (stemp > 0) { + ga[idx] -= stemp * wt[idx]; + st[idx] += stemp * wt[idx]; + } + } + + // step 3. water is transported to it's neighbours + float a = ga[idx] + wt[idx]; + // float[] aj = new float[idxrel.length]; + float amax = 0; + int amaxidx = -1; + float ac = 0; + float dtotal = 0; + + for (int j = 0; j < idxrel.length; j++) { + if (idx + idxrel[j] > 0 && idx + idxrel[j] < workSize) { + float at = ga[idx + idxrel[j]] + wt[idx + idxrel[j]]; + if (a - at > a - amax) { + dtotal += at; + amax = at; + amaxidx = j; + ac++; + } + } + } + + float aa = (dtotal + a) / (ac + 1); + // for (int j = 0; j < idxrel.length; j++) { + // if (idx + idxrel[j] > 0 && idx + idxrel[j] < workSize && a - + // aj[j] > 0) { + if (amaxidx > -1) { + float dwj = Math.min(wt[idx], a - aa) * (a - amax) / dtotal; + float dsj = st[idx] * dwj / wt[idx]; + wt[idx] -= dwj; + st[idx] -= dsj; + wt[idx + idxrel[amaxidx]] += dwj; + st[idx + idxrel[amaxidx]] += dsj; + } + // } + + // step 4. water evaporates and deposits material + wt[idx] = wt[idx] * (1 - this.Ke); + if (wt[idx] < this.T) { + wt[idx] = 0; + } + float smax = this.Kc * wt[idx]; + if (st[idx] > smax) { + ga[idx] += st[idx] - smax; + st[idx] -= st[idx] - smax; + } + } + } + + return buffer; + } + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/filter/IterativeFilter.java b/engine/src/terrain/com/jme3/terrain/noise/filter/IterativeFilter.java new file mode 100644 index 000000000..3764256cb --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/filter/IterativeFilter.java @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.filter; + +import java.nio.FloatBuffer; +import java.util.ArrayList; +import java.util.List; + +import com.jme3.terrain.noise.Filter; + +public class IterativeFilter extends AbstractFilter { + + private int iterations; + + private List preIterateFilters = new ArrayList(); + private List postIterateFilters = new ArrayList(); + private Filter filter; + + @Override + public int getMargin(int size, int margin) { + if (!this.isEnabled()) { + return margin; + } + for (Filter f : this.preIterateFilters) { + margin = f.getMargin(size, margin); + } + margin = this.filter.getMargin(size, margin); + for (Filter f : this.postIterateFilters) { + margin = f.getMargin(size, margin); + } + return this.iterations * margin + super.getMargin(size, margin); + } + + public void setIterations(int iterations) { + this.iterations = iterations; + } + + public int getIterations() { + return this.iterations; + } + + public IterativeFilter addPostIterateFilter(Filter filter) { + this.postIterateFilters.add(filter); + return this; + } + + public IterativeFilter addPreIterateFilter(Filter filter) { + this.preIterateFilters.add(filter); + return this; + } + + public void setFilter(Filter filter) { + this.filter = filter; + } + + @Override + public FloatBuffer filter(float sx, float sy, float base, FloatBuffer data, int size) { + if (!this.isEnabled()) { + return data; + } + FloatBuffer retval = data; + + for (int i = 0; i < this.iterations; i++) { + for (Filter f : this.preIterateFilters) { + retval = f.doFilter(sx, sy, base, retval, size); + } + retval = this.filter.doFilter(sx, sy, base, retval, size); + for (Filter f : this.postIterateFilters) { + retval = f.doFilter(sx, sy, base, retval, size); + } + } + + return retval; + } +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/filter/OptimizedErode.java b/engine/src/terrain/com/jme3/terrain/noise/filter/OptimizedErode.java new file mode 100644 index 000000000..fc20da601 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/filter/OptimizedErode.java @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.filter; + +import java.nio.FloatBuffer; + +public class OptimizedErode extends AbstractFilter { + + private float talus; + private int radius; + + public OptimizedErode setRadius(int radius) { + this.radius = radius; + return this; + } + + public int getRadius() { + return this.radius; + } + + public OptimizedErode setTalus(float talus) { + this.talus = talus; + return this; + } + + public float getTalus() { + return this.talus; + } + + @Override + public int getMargin(int size, int margin) { + return super.getMargin(size, margin) + this.radius; + } + + @Override + public FloatBuffer filter(float sx, float sy, float base, FloatBuffer buffer, int size) { + float[] tmp = buffer.array(); + float[] retval = new float[tmp.length]; + + for (int y = this.radius + 1; y < size - this.radius; y++) { + for (int x = this.radius + 1; x < size - this.radius; x++) { + int idx = y * size + x; + float h = tmp[idx]; + + float horizAvg = 0; + int horizCount = 0; + float vertAvg = 0; + int vertCount = 0; + + boolean horizT = false; + boolean vertT = false; + + for (int i = 0; i >= -this.radius; i--) { + int idxV = (y + i) * size + x; + int idxVL = (y + i - 1) * size + x; + int idxH = y * size + x + i; + int idxHL = y * size + x + i - 1; + float hV = tmp[idxV]; + float hH = tmp[idxH]; + + if (Math.abs(h - hV) > this.talus && Math.abs(h - tmp[idxVL]) > this.talus || vertT) { + vertT = true; + } else { + if (Math.abs(h - hV) <= this.talus) { + vertAvg += hV; + vertCount++; + } + } + + if (Math.abs(h - hH) > this.talus && Math.abs(h - tmp[idxHL]) > this.talus || horizT) { + horizT = true; + } else { + if (Math.abs(h - hH) <= this.talus) { + horizAvg += hH; + horizCount++; + } + } + } + + retval[idx] = 0.5f * (vertAvg / (vertCount > 0 ? vertCount : 1) + horizAvg / (horizCount > 0 ? horizCount : 1)); + } + } + return FloatBuffer.wrap(retval); + } + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java b/engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java new file mode 100644 index 000000000..f510f9079 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.filter; + +import java.nio.FloatBuffer; +import java.util.logging.Logger; + +import com.jme3.terrain.noise.ShaderUtils; +import com.jme3.terrain.noise.fractal.FractalSum; + +public class PerturbFilter extends AbstractFilter { + + private float magnitude; + + @Override + public int getMargin(int size, int margin) { + margin = super.getMargin(size, margin); + return (int) Math.floor(this.magnitude * (margin + size) + margin); + } + + public void setMagnitude(float magnitude) { + this.magnitude = magnitude; + } + + public float getMagnitude() { + return this.magnitude; + } + + @Override + public FloatBuffer filter(float sx, float sy, float base, FloatBuffer data, int workSize) { + float[] arr = data.array(); + int origSize = (int) Math.ceil(workSize / (2 * this.magnitude + 1)); + int offset = (workSize - origSize) / 2; + Logger.getLogger(PerturbFilter.class.getCanonicalName()).info( + "Found origSize : " + origSize + " and offset: " + offset + " for workSize : " + workSize + " and magnitude : " + + this.magnitude); + float[] retval = new float[workSize * workSize]; + float[] perturbx = new FractalSum().setOctaves(8).setScale(5f).getBuffer(sx, sy, base, workSize).array(); + float[] perturby = new FractalSum().setOctaves(8).setScale(5f).getBuffer(sx, sy, base + 1, workSize).array(); + for (int y = 0; y < workSize; y++) { + for (int x = 0; x < workSize; x++) { + // Perturb our coordinates + float noisex = perturbx[y * workSize + x]; + float noisey = perturby[y * workSize + x]; + + int px = (int) (origSize * noisex * this.magnitude); + int py = (int) (origSize * noisey * this.magnitude); + + float c00 = arr[this.wrap(y - py, workSize) * workSize + this.wrap(x - px, workSize)]; + float c01 = arr[this.wrap(y - py, workSize) * workSize + this.wrap(x + px, workSize)]; + float c10 = arr[this.wrap(y + py, workSize) * workSize + this.wrap(x - px, workSize)]; + float c11 = arr[this.wrap(y + py, workSize) * workSize + this.wrap(x + px, workSize)]; + + float c0 = ShaderUtils.mix(c00, c01, noisex); + float c1 = ShaderUtils.mix(c10, c11, noisex); + retval[y * workSize + x] = ShaderUtils.mix(c0, c1, noisey); + } + } + return FloatBuffer.wrap(retval); + } + + private int wrap(int v, int size) { + if (v < 0) { + return v + size - 1; + } else if (v >= size) { + return v - size; + } else { + return v; + } + } +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/filter/SmoothFilter.java b/engine/src/terrain/com/jme3/terrain/noise/filter/SmoothFilter.java new file mode 100644 index 000000000..1c20c2451 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/filter/SmoothFilter.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.filter; + +import java.nio.FloatBuffer; + +public class SmoothFilter extends AbstractFilter { + + private int radius; + private float effect; + + public void setRadius(int radius) { + this.radius = radius; + } + + public int getRadius() { + return this.radius; + } + + public void setEffect(float effect) { + this.effect = effect; + } + + public float getEffect() { + return this.effect; + } + + @Override + public int getMargin(int size, int margin) { + return super.getMargin(size, margin) + this.radius; + } + + @Override + public FloatBuffer filter(float sx, float sy, float base, FloatBuffer buffer, int size) { + float[] data = buffer.array(); + float[] retval = new float[data.length]; + + for (int y = this.radius; y < size - this.radius; y++) { + for (int x = this.radius; x < size - this.radius; x++) { + int idx = y * size + x; + float n = 0; + for (int i = -this.radius; i < this.radius + 1; i++) { + for (int j = -this.radius; j < this.radius + 1; j++) { + n += data[(y + i) * size + x + j]; + } + } + retval[idx] = this.effect * n / (4 * this.radius * (this.radius + 1) + 1) + (1 - this.effect) * data[idx]; + } + } + + return FloatBuffer.wrap(retval); + } +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/filter/ThermalErodeFilter.java b/engine/src/terrain/com/jme3/terrain/noise/filter/ThermalErodeFilter.java new file mode 100644 index 000000000..2e496799e --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/filter/ThermalErodeFilter.java @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.filter; + +import java.nio.FloatBuffer; + +public class ThermalErodeFilter extends AbstractFilter { + + private float talus; + private float c; + + public ThermalErodeFilter setC(float c) { + this.c = c; + return this; + } + + public ThermalErodeFilter setTalus(float talus) { + this.talus = talus; + return this; + } + + @Override + public int getMargin(int size, int margin) { + return super.getMargin(size, margin) + 1; + } + + @Override + public FloatBuffer filter(float sx, float sy, float base, FloatBuffer buffer, int workSize) { + float[] ga = buffer.array(); + float[] sa = new float[workSize * workSize]; + + int[] idxrel = { -workSize - 1, -workSize + 1, workSize - 1, workSize + 1 }; + + for (int y = 0; y < workSize; y++) { + for (int x = 0; x < workSize; x++) { + int idx = y * workSize + x; + ga[idx] += sa[idx]; + sa[idx] = 0; + + float[] deltas = new float[idxrel.length]; + float deltaMax = this.talus; + float deltaTotal = 0; + + for (int j = 0; j < idxrel.length; j++) { + if (idx + idxrel[j] > 0 && idx + idxrel[j] < ga.length) { + float dj = ga[idx] - ga[idx + idxrel[j]]; + if (dj > this.talus) { + deltas[j] = dj; + deltaTotal += dj; + if (dj > deltaMax) { + deltaMax = dj; + } + } + } + } + + for (int j = 0; j < idxrel.length; j++) { + if (deltas[j] != 0) { + float d = this.c * (deltaMax - this.talus) * deltas[j] / deltaTotal; + if (d > ga[idx] + sa[idx]) { + d = ga[idx] + sa[idx]; + } + sa[idx] -= d; + sa[idx + idxrel[j]] += d; + } + deltas[j] = 0; + } + } + } + + return buffer; + } + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/fractal/Fractal.java b/engine/src/terrain/com/jme3/terrain/noise/fractal/Fractal.java new file mode 100644 index 000000000..9b5344717 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/fractal/Fractal.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.fractal; + +import com.jme3.terrain.noise.Basis; + +/** + * Interface for a general fractal basis. + * + * Takes any number of basis funcions to work with and a few common parameters + * for noise fractals + * + * @author Anthyon + * + */ +public interface Fractal extends Basis { + + public Fractal setOctaves(final float octaves); + + public Fractal setFrequency(final float frequency); + + public Fractal setRoughness(final float roughness); + + public Fractal setAmplitude(final float amplitude); + + public Fractal setLacunarity(final float lacunarity); + + public Fractal addBasis(Basis basis); + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/fractal/FractalSum.java b/engine/src/terrain/com/jme3/terrain/noise/fractal/FractalSum.java new file mode 100644 index 000000000..5fe5dcb4a --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/fractal/FractalSum.java @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.fractal; + +import com.jme3.terrain.noise.Basis; +import com.jme3.terrain.noise.ShaderUtils; +import com.jme3.terrain.noise.basis.ImprovedNoise; +import com.jme3.terrain.noise.basis.Noise; + +/** + * FractalSum is the simplest form of fractal functions summing up a few octaves + * of the noise value with an ever decreasing (0 < roughness < 1) amplitude + * + * lacunarity = 2.0f is the classical octave distance + * + * Note: though noise basis functions are generally designed to return value + * between -1..1, there sum can easily be made to extend out of this range. To + * handle this is up to the user. + * + * @author Anthyon + * + */ +public class FractalSum extends Noise implements Fractal { + + private Basis basis; + private float lacunarity; + private float amplitude; + private float roughness; + private float frequency; + private float octaves; + private int maxFreq; + + public FractalSum() { + this.basis = new ImprovedNoise(); + this.lacunarity = 2.124367f; + this.amplitude = 1.0f; + this.roughness = 0.6f; + this.frequency = 1f; + this.setOctaves(1); + } + + @Override + public float value(final float x, final float y, final float z) { + float total = 0; + + for (float f = this.frequency, a = this.amplitude; f < this.maxFreq; f *= this.lacunarity, a *= this.roughness) { + total += this.basis.value(this.scale * x * f, this.scale * y * f, this.scale * z * f) * a; + } + + return ShaderUtils.clamp(total, -1, 1); + } + + @Override + public Fractal addBasis(final Basis basis) { + this.basis = basis; + return this; + } + + public float getOctaves() { + return this.octaves; + } + + @Override + public Fractal setOctaves(final float octaves) { + this.octaves = octaves; + this.maxFreq = 1 << (int) octaves; + return this; + } + + public float getFrequency() { + return this.frequency; + } + + @Override + public Fractal setFrequency(final float frequency) { + this.frequency = frequency; + return this; + } + + public float getRoughness() { + return this.roughness; + } + + @Override + public Fractal setRoughness(final float roughness) { + this.roughness = roughness; + return this; + } + + public float getAmplitude() { + return this.amplitude; + } + + @Override + public Fractal setAmplitude(final float amplitude) { + this.amplitude = amplitude; + return this; + } + + public float getLacunarity() { + return this.lacunarity; + } + + @Override + public Fractal setLacunarity(final float lacunarity) { + this.lacunarity = lacunarity; + return this; + } + + @Override + public void init() { + + } + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/modulator/CatRom2.java b/engine/src/terrain/com/jme3/terrain/noise/modulator/CatRom2.java new file mode 100644 index 000000000..3f09c2996 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/modulator/CatRom2.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.modulator; + +import java.util.HashMap; +import java.util.Map; + +import com.jme3.terrain.noise.ShaderUtils; + +public class CatRom2 implements Modulator { + + private int sampleRate = 100; + + private final float[] table; + + private static Map instances = new HashMap(); + + public CatRom2(final int sampleRate) { + this.sampleRate = sampleRate; + this.table = new float[4 * sampleRate + 1]; + for (int i = 0; i < 4 * sampleRate + 1; i++) { + float x = i / (float) sampleRate; + x = (float) Math.sqrt(x); + if (x < 1) { + this.table[i] = 0.5f * (2 + x * x * (-5 + x * 3)); + } else { + this.table[i] = 0.5f * (4 + x * (-8 + x * (5 - x))); + } + } + } + + public static CatRom2 getInstance(final int sampleRate) { + if (!CatRom2.instances.containsKey(sampleRate)) { + CatRom2.instances.put(sampleRate, new CatRom2(sampleRate)); + } + return CatRom2.instances.get(sampleRate); + } + + @Override + public float value(final float... in) { + if (in[0] >= 4) { + return 0; + } + in[0] = in[0] * this.sampleRate + 0.5f; + int i = ShaderUtils.floor(in[0]); + if (i >= 4 * this.sampleRate + 1) { + return 0; + } + return this.table[i]; + } +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/modulator/Modulator.java b/engine/src/terrain/com/jme3/terrain/noise/modulator/Modulator.java new file mode 100644 index 000000000..28bfd1c92 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/modulator/Modulator.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.modulator; + +public interface Modulator { + + public float value(float... in); + +} diff --git a/engine/src/terrain/com/jme3/terrain/noise/modulator/NoiseModulator.java b/engine/src/terrain/com/jme3/terrain/noise/modulator/NoiseModulator.java new file mode 100644 index 000000000..38a3bd674 --- /dev/null +++ b/engine/src/terrain/com/jme3/terrain/noise/modulator/NoiseModulator.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2011, Novyon Events + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Anthyon + */ +package com.jme3.terrain.noise.modulator; + +public interface NoiseModulator extends Modulator { + +} diff --git a/engine/src/test/jme3test/terrain/TerrainFractalGridTest.java b/engine/src/test/jme3test/terrain/TerrainFractalGridTest.java index 60b6f07b6..499a8d60d 100644 --- a/engine/src/test/jme3test/terrain/TerrainFractalGridTest.java +++ b/engine/src/test/jme3test/terrain/TerrainFractalGridTest.java @@ -10,16 +10,16 @@ import com.jme3.terrain.geomipmap.TerrainGrid; import com.jme3.terrain.geomipmap.TerrainLodControl; import com.jme3.terrain.geomipmap.grid.FractalTileLoader; import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; +import com.jme3.terrain.noise.ShaderUtils; +import com.jme3.terrain.noise.basis.FilteredBasis; +import com.jme3.terrain.noise.filter.IterativeFilter; +import com.jme3.terrain.noise.filter.OptimizedErode; +import com.jme3.terrain.noise.filter.PerturbFilter; +import com.jme3.terrain.noise.filter.SmoothFilter; +import com.jme3.terrain.noise.fractal.FractalSum; +import com.jme3.terrain.noise.modulator.NoiseModulator; import com.jme3.texture.Texture; import com.jme3.texture.Texture.WrapMode; -import org.novyon.noise.ShaderUtils; -import org.novyon.noise.basis.FilteredBasis; -import org.novyon.noise.filter.IterativeFilter; -import org.novyon.noise.filter.OptimizedErode; -import org.novyon.noise.filter.PerturbFilter; -import org.novyon.noise.filter.SmoothFilter; -import org.novyon.noise.fractal.FractalSum; -import org.novyon.noise.modulator.NoiseModulator; public class TerrainFractalGridTest extends SimpleApplication { diff --git a/engine/src/test/jme3test/terrain/TerrainGridAlphaMapTest.java b/engine/src/test/jme3test/terrain/TerrainGridAlphaMapTest.java index 9399f5f44..6c45e7272 100644 --- a/engine/src/test/jme3test/terrain/TerrainGridAlphaMapTest.java +++ b/engine/src/test/jme3test/terrain/TerrainGridAlphaMapTest.java @@ -34,14 +34,14 @@ import com.jme3.texture.Texture.WrapMode; import java.io.File; import java.util.ArrayList; import java.util.List; -import org.novyon.noise.ShaderUtils; -import org.novyon.noise.basis.FilteredBasis; -import org.novyon.noise.filter.IterativeFilter; -import org.novyon.noise.filter.OptimizedErode; -import org.novyon.noise.filter.PerturbFilter; -import org.novyon.noise.filter.SmoothFilter; -import org.novyon.noise.fractal.FractalSum; -import org.novyon.noise.modulator.NoiseModulator; +import com.jme3.terrain.noise.ShaderUtils; +import com.jme3.terrain.noise.basis.FilteredBasis; +import com.jme3.terrain.noise.filter.IterativeFilter; +import com.jme3.terrain.noise.filter.OptimizedErode; +import com.jme3.terrain.noise.filter.PerturbFilter; +import com.jme3.terrain.noise.filter.SmoothFilter; +import com.jme3.terrain.noise.fractal.FractalSum; +import com.jme3.terrain.noise.modulator.NoiseModulator; public class TerrainGridAlphaMapTest extends SimpleApplication { diff --git a/engine/src/test/jme3test/terrain/TerrainTestModifyHeight.java b/engine/src/test/jme3test/terrain/TerrainTestModifyHeight.java index ef608f7b2..f813f0853 100644 --- a/engine/src/test/jme3test/terrain/TerrainTestModifyHeight.java +++ b/engine/src/test/jme3test/terrain/TerrainTestModifyHeight.java @@ -58,18 +58,18 @@ import com.jme3.terrain.geomipmap.grid.FractalTileLoader; import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; import com.jme3.terrain.heightmap.AbstractHeightMap; import com.jme3.terrain.heightmap.ImageBasedHeightMap; +import com.jme3.terrain.noise.ShaderUtils; +import com.jme3.terrain.noise.basis.FilteredBasis; +import com.jme3.terrain.noise.filter.IterativeFilter; +import com.jme3.terrain.noise.filter.OptimizedErode; +import com.jme3.terrain.noise.filter.PerturbFilter; +import com.jme3.terrain.noise.filter.SmoothFilter; +import com.jme3.terrain.noise.fractal.FractalSum; +import com.jme3.terrain.noise.modulator.NoiseModulator; import com.jme3.texture.Texture; import com.jme3.texture.Texture.WrapMode; import java.util.ArrayList; import java.util.List; -import org.novyon.noise.ShaderUtils; -import org.novyon.noise.basis.FilteredBasis; -import org.novyon.noise.filter.IterativeFilter; -import org.novyon.noise.filter.OptimizedErode; -import org.novyon.noise.filter.PerturbFilter; -import org.novyon.noise.filter.SmoothFilter; -import org.novyon.noise.fractal.FractalSum; -import org.novyon.noise.modulator.NoiseModulator; /** *