• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 package com.jme3.scene.plugins.blender.textures;
33 
34 import com.jme3.math.FastMath;
35 import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
36 import com.jme3.scene.plugins.blender.BlenderContext;
37 import com.jme3.scene.plugins.blender.file.Structure;
38 import com.jme3.scene.plugins.blender.textures.TextureGeneratorMusgrave.MusgraveData;
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.io.ObjectInputStream;
42 import java.util.HashMap;
43 import java.util.Map;
44 import java.util.logging.Level;
45 import java.util.logging.Logger;
46 
47 /**
48  * This generator is responsible for creating various noises used to create
49  * generated textures loaded from blender.
50  * It derives from AbstractBlenderHelper but is not stored in blender context.
51  * It is only used by TextureHelper.
52  * @author Marcin Roguski (Kaelthas)
53  */
54 /*package*/ class NoiseGenerator extends AbstractBlenderHelper {
55     private static final Logger LOGGER = Logger.getLogger(NoiseGenerator.class.getName());
56 
57     // flag
58     protected static final int TEX_COLORBAND = 1;
59     protected static final int TEX_FLIPBLEND = 2;
60     protected static final int TEX_NEGALPHA = 4;
61     protected static final int TEX_CHECKER_ODD = 8;
62     protected static final int TEX_CHECKER_EVEN = 16;
63     protected static final int TEX_PRV_ALPHA = 32;
64     protected static final int TEX_PRV_NOR = 64;
65     protected static final int TEX_REPEAT_XMIR = 128;
66     protected static final int TEX_REPEAT_YMIR = 256;
67     protected static final int TEX_FLAG_MASK = TEX_COLORBAND | TEX_FLIPBLEND | TEX_NEGALPHA | TEX_CHECKER_ODD | TEX_CHECKER_EVEN | TEX_PRV_ALPHA | TEX_PRV_NOR | TEX_REPEAT_XMIR | TEX_REPEAT_YMIR;
68 
69     // tex->stype
70     protected static final int TEX_PLASTIC = 0;
71     protected static final int TEX_WALLIN = 1;
72     protected static final int TEX_WALLOUT = 2;
73 
74     // musgrave stype
75     protected static final int TEX_MFRACTAL = 0;
76     protected static final int TEX_RIDGEDMF = 1;
77     protected static final int TEX_HYBRIDMF = 2;
78     protected static final int TEX_FBM = 3;
79     protected static final int TEX_HTERRAIN = 4;
80 
81     // keyblock->type
82     protected static final int KEY_LINEAR = 0;
83     protected static final int KEY_CARDINAL = 1;
84     protected static final int KEY_BSPLINE = 2;
85 
86     // CONSTANTS (read from file)
87     protected static float[] hashpntf;
88     protected static short[] hash;
89     protected static float[] hashvectf;
90     protected static short[] p;
91     protected static float[][] g;
92 
93     /**
94      * Constructor. Stores the blender version number and loads the constants needed for computations.
95      * @param blenderVersion
96      *        the number of blender version
97      */
NoiseGenerator(String blenderVersion)98     public NoiseGenerator(String blenderVersion) {
99         super(blenderVersion, false);
100         this.loadConstants();
101     }
102 
103     /**
104      * This method loads the constants needed for computations. They are exactly like the ones the blender uses. Each
105      * deriving class should override this method and load its own constraints. Be carefult with overriding though, if
106      * an exception will be thrown the class will not be instantiated.
107      */
loadConstants()108     protected void loadConstants() {
109         InputStream is = NoiseGenerator.class.getResourceAsStream("noiseconstants.dat");
110         try {
111             ObjectInputStream ois = new ObjectInputStream(is);
112             hashpntf = (float[]) ois.readObject();
113             hash = (short[]) ois.readObject();
114             hashvectf = (float[]) ois.readObject();
115             p = (short[]) ois.readObject();
116             g = (float[][]) ois.readObject();
117         } catch (IOException e) {
118             LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
119         } catch (ClassNotFoundException e) {
120             assert false : "Constants' classes should be arrays of primitive types, so they are ALWAYS known!";
121         } finally {
122             if (is != null) {
123                 try {
124                     is.close();
125                 } catch (IOException e) {
126                     LOGGER.log(Level.WARNING, e.getLocalizedMessage());
127                 }
128             }
129         }
130     }
131 
132     protected static Map<Integer, NoiseFunction> noiseFunctions = new HashMap<Integer, NoiseFunction>();
133     static {
NoiseFunction()134         noiseFunctions.put(Integer.valueOf(0), new NoiseFunction() {
135         	// originalBlenderNoise
136             @Override
137             public float execute(float x, float y, float z) {
138                 return NoiseFunctions.originalBlenderNoise(x, y, z);
139             }
140 
141             @Override
142             public float executeSigned(float x, float y, float z) {
143                 return 2.0f * NoiseFunctions.originalBlenderNoise(x, y, z) - 1.0f;
144             }
145         });
NoiseFunction()146         noiseFunctions.put(Integer.valueOf(1), new NoiseFunction() {
147         	// orgPerlinNoise
148             @Override
149             public float execute(float x, float y, float z) {
150                 return 0.5f + 0.5f * NoiseFunctions.noise3Perlin(x, y, z);
151             }
152 
153             @Override
154             public float executeSigned(float x, float y, float z) {
155                 return NoiseFunctions.noise3Perlin(x, y, z);
156             }
157         });
NoiseFunction()158         noiseFunctions.put(Integer.valueOf(2), new NoiseFunction() {
159         	// newPerlin
160             @Override
161             public float execute(float x, float y, float z) {
162                 return 0.5f + 0.5f * NoiseFunctions.newPerlin(x, y, z);
163             }
164 
165             @Override
166             public float executeSigned(float x, float y, float z) {
167                 return this.execute(x, y, z);
168             }
169         });
NoiseFunction()170         noiseFunctions.put(Integer.valueOf(3), new NoiseFunction() {
171         	// voronoi_F1
172             @Override
173             public float execute(float x, float y, float z) {
174                 float[] da = new float[4], pa = new float[12];
175                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
176                 return da[0];
177             }
178 
179             @Override
180             public float executeSigned(float x, float y, float z) {
181                 float[] da = new float[4], pa = new float[12];
182                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
183                 return 2.0f * da[0] - 1.0f;
184             }
185         });
NoiseFunction()186         noiseFunctions.put(Integer.valueOf(4), new NoiseFunction() {
187         	// voronoi_F2
188             @Override
189             public float execute(float x, float y, float z) {
190                 float[] da = new float[4], pa = new float[12];
191                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
192                 return da[1];
193             }
194 
195             @Override
196             public float executeSigned(float x, float y, float z) {
197                 float[] da = new float[4], pa = new float[12];
198                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
199                 return 2.0f * da[1] - 1.0f;
200             }
201         });
NoiseFunction()202         noiseFunctions.put(Integer.valueOf(5), new NoiseFunction() {
203         	// voronoi_F3
204             @Override
205             public float execute(float x, float y, float z) {
206                 float[] da = new float[4], pa = new float[12];
207                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
208                 return da[2];
209             }
210 
211             @Override
212             public float executeSigned(float x, float y, float z) {
213                 float[] da = new float[4], pa = new float[12];
214                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
215                 return 2.0f * da[2] - 1.0f;
216             }
217         });
NoiseFunction()218         noiseFunctions.put(Integer.valueOf(6), new NoiseFunction() {
219         	// voronoi_F4
220             @Override
221             public float execute(float x, float y, float z) {
222                 float[] da = new float[4], pa = new float[12];
223                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
224                 return da[3];
225             }
226 
227             @Override
228             public float executeSigned(float x, float y, float z) {
229                 float[] da = new float[4], pa = new float[12];
230                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
231                 return 2.0f * da[3] - 1.0f;
232             }
233         });
NoiseFunction()234         noiseFunctions.put(Integer.valueOf(7), new NoiseFunction() {
235         	// voronoi_F1F2
236             @Override
237             public float execute(float x, float y, float z) {
238                 float[] da = new float[4], pa = new float[12];
239                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
240                 return da[1] - da[0];
241             }
242 
243             @Override
244             public float executeSigned(float x, float y, float z) {
245                 float[] da = new float[4], pa = new float[12];
246                 NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
247                 return 2.0f * (da[1] - da[0]) - 1.0f;
248             }
249         });
NoiseFunction()250         noiseFunctions.put(Integer.valueOf(8), new NoiseFunction() {
251         	// voronoi_Cr
252             @Override
253             public float execute(float x, float y, float z) {
254                 float t = 10 * noiseFunctions.get(Integer.valueOf(7)).execute(x, y, z);// voronoi_F1F2
255                 return t > 1.0f ? 1.0f : t;
256             }
257 
258             @Override
259             public float executeSigned(float x, float y, float z) {
260                 float t = 10.0f * noiseFunctions.get(Integer.valueOf(7)).execute(x, y, z);// voronoi_F1F2
261                 return t > 1.0f ? 1.0f : 2.0f * t - 1.0f;
262             }
263         });
NoiseFunction()264         noiseFunctions.put(Integer.valueOf(14), new NoiseFunction() {
265         	// cellNoise
266             @Override
267             public float execute(float x, float y, float z) {
268                 int xi = (int) Math.floor(x);
269                 int yi = (int) Math.floor(y);
270                 int zi = (int) Math.floor(z);
271                 long n = xi + yi * 1301 + zi * 314159;
272                 n ^= n << 13;
273                 return (n * (n * n * 15731 + 789221) + 1376312589) / 4294967296.0f;
274             }
275 
276             @Override
277             public float executeSigned(float x, float y, float z) {
278                 return 2.0f * this.execute(x, y, z) - 1.0f;
279             }
280         });
281     }
282     /** Distance metrics for voronoi. e parameter only used in Minkovsky. */
283     protected static Map<Integer, DistanceFunction> distanceFunctions = new HashMap<Integer, NoiseGenerator.DistanceFunction>();
284 
285     static {
DistanceFunction()286         distanceFunctions.put(Integer.valueOf(0), new DistanceFunction() {
287         	// real distance
288             @Override
289             public float execute(float x, float y, float z, float e) {
290                 return (float) Math.sqrt(x * x + y * y + z * z);
291             }
292         });
DistanceFunction()293         distanceFunctions.put(Integer.valueOf(1), new DistanceFunction() {
294         	// distance squared
295             @Override
296             public float execute(float x, float y, float z, float e) {
297                 return x * x + y * y + z * z;
298             }
299         });
DistanceFunction()300         distanceFunctions.put(Integer.valueOf(2), new DistanceFunction() {
301         	// manhattan/taxicab/cityblock distance
302             @Override
303             public float execute(float x, float y, float z, float e) {
304                 return FastMath.abs(x) + FastMath.abs(y) + FastMath.abs(z);
305             }
306         });
DistanceFunction()307         distanceFunctions.put(Integer.valueOf(3), new DistanceFunction() {
308         	// Chebychev
309             @Override
310             public float execute(float x, float y, float z, float e) {
311                 x = FastMath.abs(x);
312                 y = FastMath.abs(y);
313                 z = FastMath.abs(z);
314                 float t = x > y ? x : y;
315                 return z > t ? z : t;
316             }
317         });
DistanceFunction()318         distanceFunctions.put(Integer.valueOf(4), new DistanceFunction() {
319         	// Minkovsky, preset exponent 0.5 (MinkovskyH)
320             @Override
321             public float execute(float x, float y, float z, float e) {
322                 float d = (float) (Math.sqrt(FastMath.abs(x)) + Math.sqrt(FastMath.abs(y)) + Math.sqrt(FastMath.abs(z)));
323                 return d * d;
324             }
325         });
DistanceFunction()326         distanceFunctions.put(Integer.valueOf(5), new DistanceFunction() {
327         	// Minkovsky, preset exponent 0.25 (Minkovsky4)
328             @Override
329             public float execute(float x, float y, float z, float e) {
330                 x *= x;
331                 y *= y;
332                 z *= z;
333                 return (float) Math.sqrt(Math.sqrt(x * x + y * y + z * z));
334             }
335         });
DistanceFunction()336         distanceFunctions.put(Integer.valueOf(6), new DistanceFunction() {
337         	// Minkovsky, general case
338             @Override
339             public float execute(float x, float y, float z, float e) {
340                 return (float) Math.pow(Math.pow(FastMath.abs(x), e) + Math.pow(FastMath.abs(y), e) + Math.pow(FastMath.abs(z), e), 1.0f / e);
341             }
342         });
343     }
344 
345     protected static Map<Integer, MusgraveFunction> musgraveFunctions = new HashMap<Integer, NoiseGenerator.MusgraveFunction>();
346     static {
MusgraveFunction()347         musgraveFunctions.put(Integer.valueOf(TEX_MFRACTAL), new MusgraveFunction() {
348 
349             @Override
350             public float execute(MusgraveData musgraveData, float x, float y, float z) {
351                 float rmd, value = 1.0f, pwr = 1.0f, pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
352                 NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
353                 if (abstractNoiseFunc == null) {
354                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
355                 }
356 
357                 for (int i = 0; i < (int) musgraveData.octaves; ++i) {
358                     value *= pwr * abstractNoiseFunc.executeSigned(x, y, z) + 1.0f;
359                     pwr *= pwHL;
360                     x *= musgraveData.lacunarity;
361                     y *= musgraveData.lacunarity;
362                     z *= musgraveData.lacunarity;
363                 }
364                 rmd = (float) (musgraveData.octaves - Math.floor(musgraveData.octaves));
365                 if (rmd != 0.0f) {
366                     value *= rmd * abstractNoiseFunc.executeSigned(x, y, z) * pwr + 1.0f;
367                 }
368                 return value;
369             }
370         });
MusgraveFunction()371         musgraveFunctions.put(Integer.valueOf(TEX_RIDGEDMF), new MusgraveFunction() {
372 
373             @Override
374             public float execute(MusgraveData musgraveData, float x, float y, float z) {
375                 float result, signal, weight;
376                 float pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
377                 float pwr = pwHL;
378 
379                 NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
380                 if (abstractNoiseFunc == null) {
381                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
382                 }
383 
384                 signal = musgraveData.offset - FastMath.abs(abstractNoiseFunc.executeSigned(x, y, z));
385                 signal *= signal;
386                 result = signal;
387                 weight = 1.0f;
388 
389                 for (int i = 1; i < (int) musgraveData.octaves; ++i) {
390                     x *= musgraveData.lacunarity;
391                     y *= musgraveData.lacunarity;
392                     z *= musgraveData.lacunarity;
393                     weight = signal * musgraveData.gain;
394                     if (weight > 1.0f) {
395                         weight = 1.0f;
396                     } else if (weight < 0.0) {
397                         weight = 0.0f;
398                     }
399                     signal = musgraveData.offset - FastMath.abs(abstractNoiseFunc.executeSigned(x, y, z));
400                     signal *= signal;
401                     signal *= weight;
402                     result += signal * pwr;
403                     pwr *= pwHL;
404                 }
405                 return result;
406             }
407         });
MusgraveFunction()408         musgraveFunctions.put(Integer.valueOf(TEX_HYBRIDMF), new MusgraveFunction() {
409 
410             @Override
411             public float execute(MusgraveData musgraveData, float x, float y, float z) {
412                 float result, signal, weight, rmd;
413                 float pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
414                 float pwr = pwHL;
415                 NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
416                 if (abstractNoiseFunc == null) {
417                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
418                 }
419 
420                 result = abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset;
421                 weight = musgraveData.gain * result;
422                 x *= musgraveData.lacunarity;
423                 y *= musgraveData.lacunarity;
424                 z *= musgraveData.lacunarity;
425 
426                 for (int i = 1; weight > 0.001f && i < (int) musgraveData.octaves; ++i) {
427                     if (weight > 1.0f) {
428                         weight = 1.0f;
429                     }
430                     signal = (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr;
431                     pwr *= pwHL;
432                     result += weight * signal;
433                     weight *= musgraveData.gain * signal;
434                     x *= musgraveData.lacunarity;
435                     y *= musgraveData.lacunarity;
436                     z *= musgraveData.lacunarity;
437                 }
438 
439                 rmd = musgraveData.octaves - (float) Math.floor(musgraveData.octaves);
440                 if (rmd != 0.0f) {
441                     result += rmd * (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr;
442                 }
443                 return result;
444             }
445         });
MusgraveFunction()446         musgraveFunctions.put(Integer.valueOf(TEX_FBM), new MusgraveFunction() {
447 
448             @Override
449             public float execute(MusgraveData musgraveData, float x, float y, float z) {
450                 float rmd, value = 0.0f, pwr = 1.0f, pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
451 
452                 NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
453                 if (abstractNoiseFunc == null) {
454                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
455                 }
456 
457                 for (int i = 0; i < (int) musgraveData.octaves; ++i) {
458                     value += abstractNoiseFunc.executeSigned(x, y, z) * pwr;
459                     pwr *= pwHL;
460                     x *= musgraveData.lacunarity;
461                     y *= musgraveData.lacunarity;
462                     z *= musgraveData.lacunarity;
463                 }
464 
465                 rmd = (float) (musgraveData.octaves - Math.floor(musgraveData.octaves));
466                 if (rmd != 0.f) {
467                     value += rmd * abstractNoiseFunc.executeSigned(x, y, z) * pwr;
468                 }
469                 return value;
470             }
471         });
MusgraveFunction()472         musgraveFunctions.put(Integer.valueOf(TEX_HTERRAIN), new MusgraveFunction() {
473 
474             @Override
475             public float execute(MusgraveData musgraveData, float x, float y, float z) {
476                 float value, increment, rmd;
477                 float pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
478                 float pwr = pwHL;
479                 NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
480                 if (abstractNoiseFunc == null) {
481                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
482                 }
483 
484                 value = musgraveData.offset + abstractNoiseFunc.executeSigned(x, y, z);
485                 x *= musgraveData.lacunarity;
486                 y *= musgraveData.lacunarity;
487                 z *= musgraveData.lacunarity;
488 
489                 for (int i = 1; i < (int) musgraveData.octaves; ++i) {
490                     increment = (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr * value;
491                     value += increment;
492                     pwr *= pwHL;
493                     x *= musgraveData.lacunarity;
494                     y *= musgraveData.lacunarity;
495                     z *= musgraveData.lacunarity;
496                 }
497 
498                 rmd = musgraveData.octaves - (float) Math.floor(musgraveData.octaves);
499                 if (rmd != 0.0) {
500                     increment = (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr * value;
501                     value += rmd * increment;
502                 }
503                 return value;
504             }
505         });
506     }
507 
508     public static class NoiseFunctions {
noise(float x, float y, float z, float noiseSize, int noiseDepth, int noiseBasis, boolean isHard)509     	public static float noise(float x, float y, float z, float noiseSize, int noiseDepth, int noiseBasis, boolean isHard) {
510     		NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noiseBasis));
511     		if (abstractNoiseFunc == null) {
512 	            abstractNoiseFunc = noiseFunctions.get(0);
513 	            noiseBasis = 0;
514 	        }
515 
516     		if (noiseBasis == 0) {
517     			++x;
518 	            ++y;
519 	            ++z;
520 	        }
521 
522 	        if (noiseSize != 0.0) {
523 	            noiseSize = 1.0f / noiseSize;
524 	            x *= noiseSize;
525 	            y *= noiseSize;
526 	            z *= noiseSize;
527 	        }
528 	        float result = abstractNoiseFunc.execute(x, y, z);
529 	        return isHard ? Math.abs(2.0f * result - 1.0f) : result;
530     	}
531 
turbulence(float x, float y, float z, float noiseSize, int noiseDepth, int noiseBasis, boolean isHard)532     	public static float turbulence(float x, float y, float z, float noiseSize, int noiseDepth, int noiseBasis, boolean isHard) {
533     		NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noiseBasis));
534     		if (abstractNoiseFunc == null) {
535 	            abstractNoiseFunc = noiseFunctions.get(0);
536 	            noiseBasis = 0;
537 	        }
538 
539     		if (noiseBasis == 0) {
540 	            ++x;
541 	            ++y;
542 	            ++z;
543 	        }
544 	        if (noiseSize != 0.0) {
545 	            noiseSize = 1.0f / noiseSize;
546 	            x *= noiseSize;
547 	            y *= noiseSize;
548 	            z *= noiseSize;
549 	        }
550 
551 	        float sum = 0, t, amp = 1, fscale = 1;
552 	        for (int i = 0; i <= noiseDepth; ++i, amp *= 0.5, fscale *= 2) {
553 	            t = abstractNoiseFunc.execute(fscale * x, fscale * y, fscale * z);
554 	            if (isHard) {
555 	                t = FastMath.abs(2.0f * t - 1.0f);
556 	            }
557 	            sum += t * amp;
558 	        }
559 
560 	        sum *= (float) (1 << noiseDepth) / (float) ((1 << noiseDepth + 1) - 1);
561 	        return sum;
562     	}
563 
564     	/**
565          * Not 'pure' Worley, but the results are virtually the same. Returns distances in da and point coords in pa
566          */
voronoi(float x, float y, float z, float[] da, float[] pa, float distanceExponent, int distanceType)567         public static void voronoi(float x, float y, float z, float[] da, float[] pa, float distanceExponent, int distanceType) {
568             float xd, yd, zd, d, p[] = new float[3];
569 
570             DistanceFunction distanceFunc = distanceFunctions.get(Integer.valueOf(distanceType));
571             if (distanceFunc == null) {
572                 distanceFunc = distanceFunctions.get(Integer.valueOf(0));
573             }
574 
575             int xi = (int) FastMath.floor(x);
576             int yi = (int) FastMath.floor(y);
577             int zi = (int) FastMath.floor(z);
578             da[0] = da[1] = da[2] = da[3] = 1e10f;
579             for (int i = xi - 1; i <= xi + 1; ++i) {
580                 for (int j = yi - 1; j <= yi + 1; ++j) {
581                     for (int k = zi - 1; k <= zi + 1; ++k) {
582                         NoiseMath.hash(i, j, k, p);
583                         xd = x - (p[0] + i);
584                         yd = y - (p[1] + j);
585                         zd = z - (p[2] + k);
586                         d = distanceFunc.execute(xd, yd, zd, distanceExponent);
587                         if (d < da[0]) {
588                             da[3] = da[2];
589                             da[2] = da[1];
590                             da[1] = da[0];
591                             da[0] = d;
592                             pa[9] = pa[6];
593                             pa[10] = pa[7];
594                             pa[11] = pa[8];
595                             pa[6] = pa[3];
596                             pa[7] = pa[4];
597                             pa[8] = pa[5];
598                             pa[3] = pa[0];
599                             pa[4] = pa[1];
600                             pa[5] = pa[2];
601                             pa[0] = p[0] + i;
602                             pa[1] = p[1] + j;
603                             pa[2] = p[2] + k;
604                         } else if (d < da[1]) {
605                             da[3] = da[2];
606                             da[2] = da[1];
607                             da[1] = d;
608                             pa[9] = pa[6];
609                             pa[10] = pa[7];
610                             pa[11] = pa[8];
611                             pa[6] = pa[3];
612                             pa[7] = pa[4];
613                             pa[8] = pa[5];
614                             pa[3] = p[0] + i;
615                             pa[4] = p[1] + j;
616                             pa[5] = p[2] + k;
617                         } else if (d < da[2]) {
618                             da[3] = da[2];
619                             da[2] = d;
620                             pa[9] = pa[6];
621                             pa[10] = pa[7];
622                             pa[11] = pa[8];
623                             pa[6] = p[0] + i;
624                             pa[7] = p[1] + j;
625                             pa[8] = p[2] + k;
626                         } else if (d < da[3]) {
627                             da[3] = d;
628                             pa[9] = p[0] + i;
629                             pa[10] = p[1] + j;
630                             pa[11] = p[2] + k;
631                         }
632                     }
633                 }
634             }
635         }
636 
637         // instead of adding another permutation array, just use hash table defined above
newPerlin(float x, float y, float z)638         public static float newPerlin(float x, float y, float z) {
639             int A, AA, AB, B, BA, BB;
640             float floorX = (float) Math.floor(x), floorY = (float) Math.floor(y), floorZ = (float) Math.floor(z);
641             int intX = (int) floorX & 0xFF, intY = (int) floorY & 0xFF, intZ = (int) floorZ & 0xFF;
642             x -= floorX;
643             y -= floorY;
644             z -= floorZ;
645             //computing fading curves
646             floorX = NoiseMath.npfade(x);
647             floorY = NoiseMath.npfade(y);
648             floorZ = NoiseMath.npfade(z);
649             A = hash[intX] + intY;
650             AA = hash[A] + intZ;
651             AB = hash[A + 1] + intZ;
652             B = hash[intX + 1] + intY;
653             BA = hash[B] + intZ;
654             BB = hash[B + 1] + intZ;
655             return  NoiseMath.lerp(floorZ, NoiseMath.lerp(floorY, NoiseMath.lerp(floorX, NoiseMath.grad(hash[AA], x, y, z),
656             		NoiseMath.grad(hash[BA], x - 1, y, z)),
657             		NoiseMath.lerp(floorX, NoiseMath.grad(hash[AB], x, y - 1, z),
658             		NoiseMath.grad(hash[BB], x - 1, y - 1, z))),
659             		NoiseMath.lerp(floorY, NoiseMath.lerp(floorX, NoiseMath.grad(hash[AA + 1], x, y, z - 1),
660             		NoiseMath.grad(hash[BA + 1], x - 1, y, z - 1)),
661             		NoiseMath.lerp(floorX, NoiseMath.grad(hash[AB + 1], x, y - 1, z - 1),
662             		NoiseMath.grad(hash[BB + 1], x - 1, y - 1, z - 1))));
663         }
664 
noise3Perlin(float x, float y, float z)665         public static float noise3Perlin(float x, float y, float z) {
666             float t = x + 10000.0f;
667             int bx0 = (int) t & 0xFF;
668             int bx1 = bx0 + 1 & 0xFF;
669             float rx0 = t - (int) t;
670             float rx1 = rx0 - 1.0f;
671 
672             t = y + 10000.0f;
673             int by0 = (int) t & 0xFF;
674             int by1 = by0 + 1 & 0xFF;
675             float ry0 = t - (int) t;
676             float ry1 = ry0 - 1.0f;
677 
678             t = z + 10000.0f;
679             int bz0 = (int) t & 0xFF;
680             int bz1 = bz0 + 1 & 0xFF;
681             float rz0 = t - (int) t;
682             float rz1 = rz0 - 1.0f;
683 
684             int i = p[bx0];
685             int j = p[bx1];
686 
687             int b00 = p[i + by0];
688             int b10 = p[j + by0];
689             int b01 = p[i + by1];
690             int b11 = p[j + by1];
691 
692             float sx = NoiseMath.surve(rx0);
693             float sy = NoiseMath.surve(ry0);
694             float sz = NoiseMath.surve(rz0);
695 
696             float[] q = g[b00 + bz0];
697             float u = NoiseMath.at(rx0, ry0, rz0, q);
698             q = g[b10 + bz0];
699             float v = NoiseMath.at(rx1, ry0, rz0, q);
700             float a = NoiseMath.lerp(sx, u, v);
701 
702             q = g[b01 + bz0];
703             u = NoiseMath.at(rx0, ry1, rz0, q);
704             q = g[b11 + bz0];
705             v = NoiseMath.at(rx1, ry1, rz0, q);
706             float b = NoiseMath.lerp(sx, u, v);
707 
708             float c = NoiseMath.lerp(sy, a, b);
709 
710             q = g[b00 + bz1];
711             u = NoiseMath.at(rx0, ry0, rz1, q);
712             q = g[b10 + bz1];
713             v = NoiseMath.at(rx1, ry0, rz1, q);
714             a = NoiseMath.lerp(sx, u, v);
715 
716             q = g[b01 + bz1];
717             u = NoiseMath.at(rx0, ry1, rz1, q);
718             q = g[b11 + bz1];
719             v = NoiseMath.at(rx1, ry1, rz1, q);
720             b = NoiseMath.lerp(sx, u, v);
721 
722             float d = NoiseMath.lerp(sy, a, b);
723             return 1.5f * NoiseMath.lerp(sz, c, d);
724         }
725 
originalBlenderNoise(float x, float y, float z)726         public static float originalBlenderNoise(float x, float y, float z) {
727             float n = 0.5f;
728 
729             int ix = (int) Math.floor(x);
730             int iy = (int) Math.floor(y);
731             int iz = (int) Math.floor(z);
732 
733             float ox = x - ix;
734             float oy = y - iy;
735             float oz = z - iz;
736 
737             float jx = ox - 1;
738             float jy = oy - 1;
739             float jz = oz - 1;
740 
741             float cn1 = ox * ox;
742             float cn2 = oy * oy;
743             float cn3 = oz * oz;
744             float cn4 = jx * jx;
745             float cn5 = jy * jy;
746             float cn6 = jz * jz;
747 
748             cn1 = 1.0f - 3.0f * cn1 + 2.0f * cn1 * ox;
749             cn2 = 1.0f - 3.0f * cn2 + 2.0f * cn2 * oy;
750             cn3 = 1.0f - 3.0f * cn3 + 2.0f * cn3 * oz;
751             cn4 = 1.0f - 3.0f * cn4 - 2.0f * cn4 * jx;
752             cn5 = 1.0f - 3.0f * cn5 - 2.0f * cn5 * jy;
753             cn6 = 1.0f - 3.0f * cn6 - 2.0f * cn6 * jz;
754             float[] cn = new float[] {cn1 * cn2 * cn3, cn1 * cn2 * cn6, cn1 * cn5 * cn3, cn1 * cn5 * cn6,
755 					  cn4 * cn2 * cn3, cn4 * cn2 * cn6, cn4 * cn5 * cn3, cn4 * cn5 * cn6,};
756 
757             int b00 = hash[hash[ix & 0xFF] + (iy & 0xFF)];
758             int b01 = hash[hash[ix & 0xFF] + (iy + 1 & 0xFF)];
759             int b10 = hash[hash[ix + 1 & 0xFF] + (iy & 0xFF)];
760             int b11 = hash[hash[ix + 1 & 0xFF] + (iy + 1 & 0xFF)];
761             int[] b1 = new int[] {b00, b00, b01, b01, b10, b10, b11, b11};
762 
763             int[] b2 = new int[] {iz & 0xFF, iz + 1 & 0xFF};
764 
765             float[] xFactor = new float[] {ox, ox, ox, ox, jx, jx, jx, jx};
766             float[] yFactor = new float[] {oy, oy, jy, jy, oy, oy, jy, jy};
767             float[] zFactor = new float[] {oz, jz, oz, jz, oz, jz, oz, jz};
768 
769             for(int i=0;i<8;++i) {
770             	int hIndex = 3 * hash[b1[i] + b2[i%2]];
771             	n += cn[i] * (hashvectf[hIndex] * xFactor[i] + hashvectf[hIndex + 1] * yFactor[i] + hashvectf[hIndex + 2] * zFactor[i]);
772             }
773 
774             if (n < 0.0f) {
775                 n = 0.0f;
776             } else if (n > 1.0f) {
777                 n = 1.0f;
778             }
779             return n;
780         }
781     }
782 
783     /**
784      * This class is abstract to the noise functions computations. It has two methods. One calculates the Signed (with
785      * 'S' at the end) and the other Unsigned value.
786      * @author Marcin Roguski (Kaelthas)
787      */
788     interface NoiseFunction {
789 
790         /**
791          * This method calculates the unsigned value of the noise.
792          * @param x
793          *        the x texture coordinate
794          * @param y
795          *        the y texture coordinate
796          * @param z
797          *        the z texture coordinate
798          * @return value of the noise
799          */
execute(float x, float y, float z)800         float execute(float x, float y, float z);
801 
802         /**
803          * This method calculates the signed value of the noise.
804          * @param x
805          *        the x texture coordinate
806          * @param y
807          *        the y texture coordinate
808          * @param z
809          *        the z texture coordinate
810          * @return value of the noise
811          */
executeSigned(float x, float y, float z)812         float executeSigned(float x, float y, float z);
813     }
814 
815     public static class NoiseMath {
lerp(float t, float a, float b)816     	public static float lerp(float t, float a, float b) {
817             return a + t * (b - a);
818         }
819 
npfade(float t)820     	public static float npfade(float t) {
821             return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
822         }
823 
grad(int hash, float x, float y, float z)824     	public static float grad(int hash, float x, float y, float z) {
825             int h = hash & 0x0F;
826             float u = h < 8 ? x : y, v = h < 4 ? y : h == 12 || h == 14 ? x : z;
827             return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
828         }
829 
830     	public static float surve(float t) {
831             return t * t * (3.0f - 2.0f * t);
832         }
833 
834     	public static float at(float x, float y, float z, float[] q) {
835             return x * q[0] + y * q[1] + z * q[2];
836         }
837 
838     	public static void hash(int x, int y, int z, float[] result) {
839             result[0] = hashpntf[3 * hash[hash[hash[z & 0xFF] + y & 0xFF] + x & 0xFF]];
840             result[1] = hashpntf[3 * hash[hash[hash[z & 0xFF] + y & 0xFF] + x & 0xFF] + 1];
841             result[2] = hashpntf[3 * hash[hash[hash[z & 0xFF] + y & 0xFF] + x & 0xFF] + 2];
842         }
843     }
844 
845     @Override
846     public boolean shouldBeLoaded(Structure structure, BlenderContext blenderContext) {
847     	return true;
848     }
849 
850     /**
851      * This interface is used for distance calculation classes. Distance metrics for voronoi. e parameter only used in
852      * Minkovsky.
853      */
854     interface DistanceFunction {
855 
856         /**
857          * This method calculates the distance for voronoi algorithms.
858          * @param x
859          *        the x coordinate
860          * @param y
861          *        the y coordinate
862          * @param z
863          *        the z coordinate
864          * @param e
865          *        this parameter used in Monkovsky (no idea what it really is ;)
866          * @return
867          */
868         float execute(float x, float y, float z, float e);
869     }
870 
871     interface MusgraveFunction {
872 
873         float execute(MusgraveData musgraveData, float x, float y, float z);
874     }
875 }
876