git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8959 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
d6124d3489
commit
8a9ec04e35
@ -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); |
||||||
|
|
||||||
|
} |
@ -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]); |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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); |
||||||
|
|
||||||
|
} |
@ -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() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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]; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
|
||||||
|
} |
@ -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 { |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue