aboutsummaryrefslogtreecommitdiff
path: root/engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java')
-rw-r--r--engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java98
1 files changed, 98 insertions, 0 deletions
diff --git a/engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java b/engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java
new file mode 100644
index 0000000..f510f90
--- /dev/null
+++ b/engine/src/terrain/com/jme3/terrain/noise/filter/PerturbFilter.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2011, Novyon Events
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Anthyon
+ */
+package com.jme3.terrain.noise.filter;
+
+import java.nio.FloatBuffer;
+import java.util.logging.Logger;
+
+import com.jme3.terrain.noise.ShaderUtils;
+import com.jme3.terrain.noise.fractal.FractalSum;
+
+public class PerturbFilter extends AbstractFilter {
+
+ private float magnitude;
+
+ @Override
+ public int getMargin(int size, int margin) {
+ margin = super.getMargin(size, margin);
+ return (int) Math.floor(this.magnitude * (margin + size) + margin);
+ }
+
+ public void setMagnitude(float magnitude) {
+ this.magnitude = magnitude;
+ }
+
+ public float getMagnitude() {
+ return this.magnitude;
+ }
+
+ @Override
+ public FloatBuffer filter(float sx, float sy, float base, FloatBuffer data, int workSize) {
+ float[] arr = data.array();
+ int origSize = (int) Math.ceil(workSize / (2 * this.magnitude + 1));
+ int offset = (workSize - origSize) / 2;
+ Logger.getLogger(PerturbFilter.class.getCanonicalName()).info(
+ "Found origSize : " + origSize + " and offset: " + offset + " for workSize : " + workSize + " and magnitude : "
+ + this.magnitude);
+ float[] retval = new float[workSize * workSize];
+ float[] perturbx = new FractalSum().setOctaves(8).setScale(5f).getBuffer(sx, sy, base, workSize).array();
+ float[] perturby = new FractalSum().setOctaves(8).setScale(5f).getBuffer(sx, sy, base + 1, workSize).array();
+ for (int y = 0; y < workSize; y++) {
+ for (int x = 0; x < workSize; x++) {
+ // Perturb our coordinates
+ float noisex = perturbx[y * workSize + x];
+ float noisey = perturby[y * workSize + x];
+
+ int px = (int) (origSize * noisex * this.magnitude);
+ int py = (int) (origSize * noisey * this.magnitude);
+
+ float c00 = arr[this.wrap(y - py, workSize) * workSize + this.wrap(x - px, workSize)];
+ float c01 = arr[this.wrap(y - py, workSize) * workSize + this.wrap(x + px, workSize)];
+ float c10 = arr[this.wrap(y + py, workSize) * workSize + this.wrap(x - px, workSize)];
+ float c11 = arr[this.wrap(y + py, workSize) * workSize + this.wrap(x + px, workSize)];
+
+ float c0 = ShaderUtils.mix(c00, c01, noisex);
+ float c1 = ShaderUtils.mix(c10, c11, noisex);
+ retval[y * workSize + x] = ShaderUtils.mix(c0, c1, noisey);
+ }
+ }
+ return FloatBuffer.wrap(retval);
+ }
+
+ private int wrap(int v, int size) {
+ if (v < 0) {
+ return v + size - 1;
+ } else if (v >= size) {
+ return v - size;
+ } else {
+ return v;
+ }
+ }
+}