1 /**
2  * Copyright (c) 2011, Novyon Events
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * - Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * - Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * @author Anthyon
29  */
30 package com.jme3.terrain.noise.filter;
31 
32 import java.nio.FloatBuffer;
33 
34 public class ThermalErodeFilter extends AbstractFilter {
35 
36 	private float talus;
37 	private float c;
38 
setC(float c)39 	public ThermalErodeFilter setC(float c) {
40 		this.c = c;
41 		return this;
42 	}
43 
setTalus(float talus)44 	public ThermalErodeFilter setTalus(float talus) {
45 		this.talus = talus;
46 		return this;
47 	}
48 
49 	@Override
getMargin(int size, int margin)50 	public int getMargin(int size, int margin) {
51 		return super.getMargin(size, margin) + 1;
52 	}
53 
54 	@Override
filter(float sx, float sy, float base, FloatBuffer buffer, int workSize)55 	public FloatBuffer filter(float sx, float sy, float base, FloatBuffer buffer, int workSize) {
56 		float[] ga = buffer.array();
57 		float[] sa = new float[workSize * workSize];
58 
59 		int[] idxrel = { -workSize - 1, -workSize + 1, workSize - 1, workSize + 1 };
60 
61 		for (int y = 0; y < workSize; y++) {
62 			for (int x = 0; x < workSize; x++) {
63 				int idx = y * workSize + x;
64 				ga[idx] += sa[idx];
65 				sa[idx] = 0;
66 
67 				float[] deltas = new float[idxrel.length];
68 				float deltaMax = this.talus;
69 				float deltaTotal = 0;
70 
71 				for (int j = 0; j < idxrel.length; j++) {
72 					if (idx + idxrel[j] > 0 && idx + idxrel[j] < ga.length) {
73 						float dj = ga[idx] - ga[idx + idxrel[j]];
74 						if (dj > this.talus) {
75 							deltas[j] = dj;
76 							deltaTotal += dj;
77 							if (dj > deltaMax) {
78 								deltaMax = dj;
79 							}
80 						}
81 					}
82 				}
83 
84 				for (int j = 0; j < idxrel.length; j++) {
85 					if (deltas[j] != 0) {
86 						float d = this.c * (deltaMax - this.talus) * deltas[j] / deltaTotal;
87 						if (d > ga[idx] + sa[idx]) {
88 							d = ga[idx] + sa[idx];
89 						}
90 						sa[idx] -= d;
91 						sa[idx + idxrel[j]] += d;
92 					}
93 					deltas[j] = 0;
94 				}
95 			}
96 		}
97 
98 		return buffer;
99 	}
100 
101 }
102