Browse Source

moved noise library into jme3/terrain

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8959 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
bre..ns 13 years ago
parent
commit
8a9ec04e35
25 changed files with 2182 additions and 149 deletions
  1. 123 124
      engine/nbproject/project.properties
  2. 1 1
      engine/src/terrain/com/jme3/terrain/geomipmap/grid/FractalTileLoader.java
  3. 77 0
      engine/src/terrain/com/jme3/terrain/noise/Basis.java
  4. 134 0
      engine/src/terrain/com/jme3/terrain/noise/Color.java
  5. 44 0
      engine/src/terrain/com/jme3/terrain/noise/Filter.java
  6. 288 0
      engine/src/terrain/com/jme3/terrain/noise/ShaderUtils.java
  7. 111 0
      engine/src/terrain/com/jme3/terrain/noise/basis/FilteredBasis.java
  8. 127 0
      engine/src/terrain/com/jme3/terrain/noise/basis/ImprovedNoise.java
  9. 94 0
      engine/src/terrain/com/jme3/terrain/noise/basis/Noise.java
  10. 64 0
      engine/src/terrain/com/jme3/terrain/noise/basis/NoiseAggregator.java
  11. 100 0
      engine/src/terrain/com/jme3/terrain/noise/filter/AbstractFilter.java
  12. 154 0
      engine/src/terrain/com/jme3/terrain/noise/filter/HydraulicErodeFilter.java
  13. 102 0
      engine/src/terrain/com/jme3/terrain/noise/filter/IterativeFilter.java
  14. 113 0
      engine/src/terrain/com/jme3/terrain/noise/filter/OptimizedErode.java
  15. 98 0
      engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java
  16. 80 0
      engine/src/terrain/com/jme3/terrain/noise/filter/SmoothFilter.java
  17. 101 0
      engine/src/terrain/com/jme3/terrain/noise/filter/ThermalErodeFilter.java
  18. 57 0
      engine/src/terrain/com/jme3/terrain/noise/fractal/Fractal.java
  19. 142 0
      engine/src/terrain/com/jme3/terrain/noise/fractal/FractalSum.java
  20. 78 0
      engine/src/terrain/com/jme3/terrain/noise/modulator/CatRom2.java
  21. 36 0
      engine/src/terrain/com/jme3/terrain/noise/modulator/Modulator.java
  22. 34 0
      engine/src/terrain/com/jme3/terrain/noise/modulator/NoiseModulator.java
  23. 8 8
      engine/src/test/jme3test/terrain/TerrainFractalGridTest.java
  24. 8 8
      engine/src/test/jme3test/terrain/TerrainGridAlphaMapTest.java
  25. 8 8
      engine/src/test/jme3test/terrain/TerrainTestModifyHeight.java

+ 123 - 124
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

+ 1 - 1
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;
 
 /**
  *

+ 77 - 0
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:
+ * 
+ * <code>
+ * float value(float x, float y, float z) {
+ * 		return 0; // a flat noise with 0 value everywhere
+ * }
+ * </code>
+ * 
+ * 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);
+
+}

+ 134 - 0
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]);
+	}
+}

+ 44 - 0
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();
+}

+ 288 - 0
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;
+	}
+}

+ 111 - 0
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<Modulator> modulators = new ArrayList<Modulator>();
+	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;
+	}
+}

+ 127 - 0
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);
+	}
+
+}

+ 94 - 0
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<Modulator> modulators = new ArrayList<Modulator>();
+
+	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;
+	}
+}

+ 64 - 0
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);
+	}
+
+}

+ 100 - 0
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<Filter> preFilters = new ArrayList<Filter>();
+	protected List<Filter> postFilters = new ArrayList<Filter>();
+
+	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;
+	}
+
+}

+ 154 - 0
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;
+	}
+
+}

+ 102 - 0
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<Filter> preIterateFilters = new ArrayList<Filter>();
+	private List<Filter> postIterateFilters = new ArrayList<Filter>();
+	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;
+	}
+}

+ 113 - 0
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);
+	}
+
+}

+ 98 - 0
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;
+		}
+	}
+}

+ 80 - 0
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);
+	}
+}

+ 101 - 0
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;
+	}
+
+}

+ 57 - 0
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);
+
+}

+ 142 - 0
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() {
+
+	}
+
+}

+ 78 - 0
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<Integer, CatRom2> instances = new HashMap<Integer, CatRom2>();
+
+	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];
+	}
+}

+ 36 - 0
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);
+
+}

+ 34 - 0
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 {
+
+}

+ 8 - 8
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 {
 

+ 8 - 8
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 {
 

+ 8 - 8
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;
 
 /**
  *