-
Notifications
You must be signed in to change notification settings - Fork 0
/
noise.cpp
187 lines (167 loc) · 6.07 KB
/
noise.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include <stdlib.h>
#define MOD 0xff
static int permut[256];
static const char gradient[32][4] =
{
{ 1, 1, 1, 0}, { 1, 1, 0, 1}, { 1, 0, 1, 1}, { 0, 1, 1, 1},
{ 1, 1, -1, 0}, { 1, 1, 0, -1}, { 1, 0, 1, -1}, { 0, 1, 1, -1},
{ 1, -1, 1, 0}, { 1, -1, 0, 1}, { 1, 0, -1, 1}, { 0, 1, -1, 1},
{ 1, -1, -1, 0}, { 1, -1, 0, -1}, { 1, 0, -1, -1}, { 0, 1, -1, -1},
{-1, 1, 1, 0}, {-1, 1, 0, 1}, {-1, 0, 1, 1}, { 0, -1, 1, 1},
{-1, 1, -1, 0}, {-1, 1, 0, -1}, {-1, 0, 1, -1}, { 0, -1, 1, -1},
{-1, -1, 1, 0}, {-1, -1, 0, 1}, {-1, 0, -1, 1}, { 0, -1, -1, 1},
{-1, -1, -1, 0}, {-1, -1, 0, -1}, {-1, 0, -1, -1}, { 0, -1, -1, -1},
};
void InitNoise (void)
{
unsigned int i = 0;
while (i < 256)
permut[i++] = rand () & MOD;
}
/*
** Function finding out the gradient corresponding to the coordinates
*/
static int Indice (const int i,
const int j,
const int k,
const int l)
{
return (permut[(l + permut[(k + permut[(j + permut[i & MOD])
& MOD])
& MOD])
& MOD]
& 0x1f);
}
/*
** Functions computing the dot product of the vector and the gradient
*/
static float Prod (const float a, const char b)
{
if (b > 0)
return a;
if (b < 0)
return -a;
return 0;
}
static float Dot_prod (const float x1, const char x2,
const float y1, const char y2,
const float z1, const char z2,
const float t1, const char t2)
{
return (Prod (x1, x2) + Prod (y1, y2) + Prod (z1, z2) + Prod (t1, t2));
}
/*
** Functions computing interpolations
*/
static float Spline5 (const float state)
{
/*
** Enhanced spline :
** (3x^2 + 2x^3) is not as good as (6x^5 - 15x^4 + 10x^3)
*/
const float sqr = state * state;
return state * sqr * (6 * sqr - 15 * state + 10);
}
static float Linear (const float start,
const float end,
const float state)
{
return start + (end - start) * state;
}
/*
** Noise function, returning the Perlin Noise at a given point
*/
float Noise (const float x,
const float y,
const float z,
const float t)
{
/* The unit hypercube containing the point */
const int x1 = (int) (x > 0 ? x : x - 1);
const int y1 = (int) (y > 0 ? y : y - 1);
const int z1 = (int) (z > 0 ? z : z - 1);
const int t1 = (int) (t > 0 ? t : t - 1);
const int x2 = x1 + 1;
const int y2 = y1 + 1;
const int z2 = z1 + 1;
const int t2 = t1 + 1;
/* The 16 corresponding gradients */
const char * g0000 = gradient[Indice (x1, y1, z1, t1)];
const char * g0001 = gradient[Indice (x1, y1, z1, t2)];
const char * g0010 = gradient[Indice (x1, y1, z2, t1)];
const char * g0011 = gradient[Indice (x1, y1, z2, t2)];
const char * g0100 = gradient[Indice (x1, y2, z1, t1)];
const char * g0101 = gradient[Indice (x1, y2, z1, t2)];
const char * g0110 = gradient[Indice (x1, y2, z2, t1)];
const char * g0111 = gradient[Indice (x1, y2, z2, t2)];
const char * g1000 = gradient[Indice (x2, y1, z1, t1)];
const char * g1001 = gradient[Indice (x2, y1, z1, t2)];
const char * g1010 = gradient[Indice (x2, y1, z2, t1)];
const char * g1011 = gradient[Indice (x2, y1, z2, t2)];
const char * g1100 = gradient[Indice (x2, y2, z1, t1)];
const char * g1101 = gradient[Indice (x2, y2, z1, t2)];
const char * g1110 = gradient[Indice (x2, y2, z2, t1)];
const char * g1111 = gradient[Indice (x2, y2, z2, t2)];
/* The 16 vectors */
const float dx1 = x - x1;
const float dx2 = x - x2;
const float dy1 = y - y1;
const float dy2 = y - y2;
const float dz1 = z - z1;
const float dz2 = z - z2;
const float dt1 = t - t1;
const float dt2 = t - t2;
/* The 16 dot products */
const float b0000 = Dot_prod(dx1, g0000[0], dy1, g0000[1],
dz1, g0000[2], dt1, g0000[3]);
const float b0001 = Dot_prod(dx1, g0001[0], dy1, g0001[1],
dz1, g0001[2], dt2, g0001[3]);
const float b0010 = Dot_prod(dx1, g0010[0], dy1, g0010[1],
dz2, g0010[2], dt1, g0010[3]);
const float b0011 = Dot_prod(dx1, g0011[0], dy1, g0011[1],
dz2, g0011[2], dt2, g0011[3]);
const float b0100 = Dot_prod(dx1, g0100[0], dy2, g0100[1],
dz1, g0100[2], dt1, g0100[3]);
const float b0101 = Dot_prod(dx1, g0101[0], dy2, g0101[1],
dz1, g0101[2], dt2, g0101[3]);
const float b0110 = Dot_prod(dx1, g0110[0], dy2, g0110[1],
dz2, g0110[2], dt1, g0110[3]);
const float b0111 = Dot_prod(dx1, g0111[0], dy2, g0111[1],
dz2, g0111[2], dt2, g0111[3]);
const float b1000 = Dot_prod(dx2, g1000[0], dy1, g1000[1],
dz1, g1000[2], dt1, g1000[3]);
const float b1001 = Dot_prod(dx2, g1001[0], dy1, g1001[1],
dz1, g1001[2], dt2, g1001[3]);
const float b1010 = Dot_prod(dx2, g1010[0], dy1, g1010[1],
dz2, g1010[2], dt1, g1010[3]);
const float b1011 = Dot_prod(dx2, g1011[0], dy1, g1011[1],
dz2, g1011[2], dt2, g1011[3]);
const float b1100 = Dot_prod(dx2, g1100[0], dy2, g1100[1],
dz1, g1100[2], dt1, g1100[3]);
const float b1101 = Dot_prod(dx2, g1101[0], dy2, g1101[1],
dz1, g1101[2], dt2, g1101[3]);
const float b1110 = Dot_prod(dx2, g1110[0], dy2, g1110[1],
dz2, g1110[2], dt1, g1110[3]);
const float b1111 = Dot_prod(dx2, g1111[0], dy2, g1111[1],
dz2, g1111[2], dt2, g1111[3]);
/* Then the interpolations, down to the result */
const float idx1 = Spline5 (dx1);
const float idy1 = Spline5 (dy1);
const float idz1 = Spline5 (dz1);
const float idt1 = Spline5 (dt1);
const float b111 = Linear (b1110, b1111, idt1);
const float b110 = Linear (b1100, b1101, idt1);
const float b101 = Linear (b1010, b1011, idt1);
const float b100 = Linear (b1000, b1001, idt1);
const float b011 = Linear (b0110, b0111, idt1);
const float b010 = Linear (b0100, b0101, idt1);
const float b001 = Linear (b0010, b0011, idt1);
const float b000 = Linear (b0000, b0001, idt1);
const float b11 = Linear (b110, b111, idz1);
const float b10 = Linear (b100, b101, idz1);
const float b01 = Linear (b010, b011, idz1);
const float b00 = Linear (b000, b001, idz1);
const float b1 = Linear (b10, b11, idy1);
const float b0 = Linear (b00, b01, idy1);
return Linear (b0, b1, idx1);
}