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.basis;
31 
32 import com.jme3.terrain.noise.ShaderUtils;
33 
34 // JAVA REFERENCE IMPLEMENTATION OF IMPROVED NOISE - COPYRIGHT 2002 KEN PERLIN.
35 /**
36  * Perlin's default implementation of Improved Perlin Noise
37  * designed to work with Noise base
38  */
39 public final class ImprovedNoise extends Noise {
40 
41 	@Override
init()42 	public void init() {
43 
44 	}
45 
noise(float x, float y, float z)46 	static public float noise(float x, float y, float z) {
47 		int X = ShaderUtils.floor(x), // FIND UNIT CUBE THAT
48 		Y = ShaderUtils.floor(y), // CONTAINS POINT.
49 		Z = ShaderUtils.floor(z);
50 		x -= X; // FIND RELATIVE X,Y,Z
51 		y -= Y; // OF POINT IN CUBE.
52 		z -= Z;
53 		X = X & 255;
54 		Y = Y & 255;
55 		Z = Z & 255;
56 		float u = ImprovedNoise.fade(x), // COMPUTE FADE CURVES
57 		v = ImprovedNoise.fade(y), // FOR EACH OF X,Y,Z.
58 		w = ImprovedNoise.fade(z);
59 		int A = ImprovedNoise.p[X] + Y;
60 		int AA = ImprovedNoise.p[A] + Z;
61 		int AB = ImprovedNoise.p[A + 1] + Z;
62 		int B = ImprovedNoise.p[X + 1] + Y;
63 		int BA = ImprovedNoise.p[B] + Z;
64 		int BB = ImprovedNoise.p[B + 1] + Z;
65 
66 		return ImprovedNoise.lerp(
67 				w,
68 				ImprovedNoise.lerp(
69 						v,
70 						ImprovedNoise.lerp(u, ImprovedNoise.grad3(ImprovedNoise.p[AA], x, y, z),
71 								ImprovedNoise.grad3(ImprovedNoise.p[BA], x - 1, y, z)), // BLENDED
72 						ImprovedNoise.lerp(u, ImprovedNoise.grad3(ImprovedNoise.p[AB], x, y - 1, z), // RESULTS
73 								ImprovedNoise.grad3(ImprovedNoise.p[BB], x - 1, y - 1, z))),// FROM
74 				ImprovedNoise.lerp(v,
75 						ImprovedNoise.lerp(u, ImprovedNoise.grad3(ImprovedNoise.p[AA + 1], x, y, z - 1), // CORNERS
76 								ImprovedNoise.grad3(ImprovedNoise.p[BA + 1], x - 1, y, z - 1)), // OF
77 						ImprovedNoise.lerp(u, ImprovedNoise.grad3(ImprovedNoise.p[AB + 1], x, y - 1, z - 1),
78 								ImprovedNoise.grad3(ImprovedNoise.p[BB + 1], x - 1, y - 1, z - 1))));
79 	}
80 
fade(final float t)81 	static final float fade(final float t) {
82 		return t * t * t * (t * (t * 6 - 15) + 10);
83 	}
84 
lerp(final float t, final float a, final float b)85 	static final float lerp(final float t, final float a, final float b) {
86 		return a + t * (b - a);
87 	}
88 
grad(final int hash, final float x, final float y, final float z)89 	static float grad(final int hash, final float x, final float y, final float z) {
90 		int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
91 		float u = h < 8 ? x : y, // INTO 12 GRADIENT DIRECTIONS.
92 		v = h < 4 ? y : h == 12 || h == 14 ? x : z;
93 		return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
94 	}
95 
96 	static final float grad3(final int hash, final float x, final float y, final float z) {
97 		int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
98 		return x * ImprovedNoise.GRAD3[h][0] + y * ImprovedNoise.GRAD3[h][1] + z * ImprovedNoise.GRAD3[h][2];
99 	}
100 
101 	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,
102 			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,
103 			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,
104 			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,
105 			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,
106 			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,
107 			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,
108 			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,
109 			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,
110 			93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 };
111 
112 	private static float[][] GRAD3 = new float[][] { { 1, 1, 0 }, { -1, 1, 0 }, { 1, -1, 0 }, { -1, -1, 0 }, { 1, 0, 1 }, { -1, 0, 1 },
113 			{ 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 },
114 			{ 0, 1, 1 } };
115 
116 	static {
117 		for (int i = 0; i < 256; i++) {
118 			ImprovedNoise.p[256 + i] = ImprovedNoise.p[i] = ImprovedNoise.permutation[i];
119 		}
120 	}
121 
122 	@Override
123 	public float value(final float x, final float y, final float z) {
124 		return ImprovedNoise.noise(this.scale * x, this.scale * y, this.scale * z);
125 	}
126 
127 }
128