1 /* OpenSceneGraph example, osgshaders.
2 *
3 *  Permission is hereby granted, free of charge, to any person obtaining a copy
4 *  of this software and associated documentation files (the "Software"), to deal
5 *  in the Software without restriction, including without limitation the rights
6 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 *  copies of the Software, and to permit persons to whom the Software is
8 *  furnished to do so, subject to the following conditions:
9 *
10 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16 *  THE SOFTWARE.
17 */
18 
19 /************************************************************************
20  *                                                                      *
21  *                   Copyright (C) 2002  3Dlabs Inc. Ltd.               *
22  *                                                                      *
23  ************************************************************************/
24 
25 #include <math.h>
26 #include <stdlib.h>
27 
28 /* Coherent noise function over 1, 2 or 3 dimensions */
29 /* (copyright Ken Perlin) */
30 
31 #define MAXB 0x100
32 #define N 0x1000
33 #define NP 12   /* 2^N */
34 #define NM 0xfff
35 
36 #define s_curve(t) ( t * t * (3. - 2. * t) )
37 #define lerp(t, a, b) ( a + t * (b - a) )
38 #define setup(i,b0,b1,r0,r1)\
39         t = vec[i] + N;\
40         b0 = ((int)t) & BM;\
41         b1 = (b0+1) & BM;\
42         r0 = t - (int)t;\
43         r1 = r0 - 1.;
44 #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
45 #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
46 
47 static void initNoise(void);
48 
49 static int p[MAXB + MAXB + 2];
50 static double g3[MAXB + MAXB + 2][3];
51 static double g2[MAXB + MAXB + 2][2];
52 static double g1[MAXB + MAXB + 2];
53 
54 int start;
55 int B;
56 int BM;
57 
58 
SetNoiseFrequency(int frequency)59 void SetNoiseFrequency(int frequency)
60 {
61         start = 1;
62         B = frequency;
63         BM = B-1;
64 }
65 
noise1(double arg)66 double noise1(double arg)
67 {
68    int bx0, bx1;
69    double rx0, rx1, sx, t, u, v, vec[1];
70 
71    vec[0] = arg;
72    if (start) {
73       start = 0;
74       initNoise();
75    }
76 
77    setup(0,bx0,bx1,rx0,rx1);
78 
79    sx = s_curve(rx0);
80    u = rx0 * g1[ p[ bx0 ] ];
81    v = rx1 * g1[ p[ bx1 ] ];
82 
83    return(lerp(sx, u, v));
84 }
85 
noise2(double vec[2])86 double noise2(double vec[2])
87 {
88    int bx0, bx1, by0, by1, b00, b10, b01, b11;
89    double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
90    int i, j;
91 
92    if (start) {
93       start = 0;
94       initNoise();
95    }
96 
97    setup(0, bx0,bx1, rx0,rx1);
98    setup(1, by0,by1, ry0,ry1);
99 
100    i = p[ bx0 ];
101    j = p[ bx1 ];
102 
103    b00 = p[ i + by0 ];
104    b10 = p[ j + by0 ];
105    b01 = p[ i + by1 ];
106    b11 = p[ j + by1 ];
107 
108    sx = s_curve(rx0);
109    sy = s_curve(ry0);
110 
111    q = g2[ b00 ] ; u = at2(rx0,ry0);
112    q = g2[ b10 ] ; v = at2(rx1,ry0);
113    a = lerp(sx, u, v);
114 
115    q = g2[ b01 ] ; u = at2(rx0,ry1);
116    q = g2[ b11 ] ; v = at2(rx1,ry1);
117    b = lerp(sx, u, v);
118 
119    return lerp(sy, a, b);
120 }
121 
noise3(double vec[3])122 double noise3(double vec[3])
123 {
124    int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
125    double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
126    int i, j;
127 
128    if (start) {
129       start = 0;
130       initNoise();
131    }
132 
133    setup(0, bx0,bx1, rx0,rx1);
134    setup(1, by0,by1, ry0,ry1);
135    setup(2, bz0,bz1, rz0,rz1);
136 
137    i = p[ bx0 ];
138    j = p[ bx1 ];
139 
140    b00 = p[ i + by0 ];
141    b10 = p[ j + by0 ];
142    b01 = p[ i + by1 ];
143    b11 = p[ j + by1 ];
144 
145    t  = s_curve(rx0);
146    sy = s_curve(ry0);
147    sz = s_curve(rz0);
148 
149    q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
150    q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
151    a = lerp(t, u, v);
152 
153    q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
154    q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
155    b = lerp(t, u, v);
156 
157    c = lerp(sy, a, b);
158 
159    q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
160    q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
161    a = lerp(t, u, v);
162 
163    q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
164    q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
165    b = lerp(t, u, v);
166 
167    d = lerp(sy, a, b);
168 
169    //fprintf(stderr, "%f\n", lerp(sz, c, d));
170 
171    return lerp(sz, c, d);
172 }
173 
normalize2(double v[2])174 void normalize2(double v[2])
175 {
176    double s;
177 
178    s = sqrt(v[0] * v[0] + v[1] * v[1]);
179    v[0] = v[0] / s;
180    v[1] = v[1] / s;
181 }
182 
normalize3(double v[3])183 void normalize3(double v[3])
184 {
185    double s;
186 
187    s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
188    v[0] = v[0] / s;
189    v[1] = v[1] / s;
190    v[2] = v[2] / s;
191 }
192 
initNoise(void)193 void initNoise(void)
194 {
195    int i, j, k;
196 
197    srand(30757);
198    for (i = 0 ; i < B ; i++) {
199       p[i] = i;
200       g1[i] = (double)((rand() % (B + B)) - B) / B;
201 
202       for (j = 0 ; j < 2 ; j++)
203          g2[i][j] = (double)((rand() % (B + B)) - B) / B;
204       normalize2(g2[i]);
205 
206       for (j = 0 ; j < 3 ; j++)
207          g3[i][j] = (double)((rand() % (B + B)) - B) / B;
208       normalize3(g3[i]);
209    }
210 
211    while (--i) {
212       k = p[i];
213       p[i] = p[j = rand() % B];
214       p[j] = k;
215    }
216 
217    for (i = 0 ; i < B + 2 ; i++) {
218       p[B + i] = p[i];
219       g1[B + i] = g1[i];
220       for (j = 0 ; j < 2 ; j++)
221          g2[B + i][j] = g2[i][j];
222       for (j = 0 ; j < 3 ; j++)
223          g3[B + i][j] = g3[i][j];
224    }
225 }
226 
227 /* --- My harmonic summing functions - PDB --------------------------*/
228 
229 /*
230    In what follows "alpha" is the weight when the sum is formed.
231    Typically it is 2, As this approaches 1 the function is noisier.
232    "beta" is the harmonic scaling/spacing, typically 2.
233 */
234 
PerlinNoise1D(double x,double alpha,double beta,int n)235 double PerlinNoise1D(double x,double alpha,double beta,int n)
236 {
237    int i;
238    double val,sum = 0;
239    double p,scale = 1;
240 
241    p = x;
242    for (i=0;i<n;i++) {
243       val = noise1(p);
244       sum += val / scale;
245       scale *= alpha;
246       p *= beta;
247    }
248    return(sum);
249 }
250 
PerlinNoise2D(double x,double y,double alpha,double beta,int n)251 double PerlinNoise2D(double x,double y,double alpha,double beta,int n)
252 {
253    int i;
254    double val,sum = 0;
255    double p[2],scale = 1;
256 
257    p[0] = x;
258    p[1] = y;
259    for (i=0;i<n;i++) {
260       val = noise2(p);
261       sum += val / scale;
262       scale *= alpha;
263       p[0] *= beta;
264       p[1] *= beta;
265    }
266    return(sum);
267 }
268 
PerlinNoise3D(double x,double y,double z,double alpha,double beta,int n)269 double PerlinNoise3D(double x,double y,double z,double alpha,double beta,int n)
270 {
271    int i;
272    double val,sum = 0;
273    double p[3],scale = 1;
274 
275    p[0] = x;
276    p[1] = y;
277    p[2] = z;
278    for (i=0;i<n;i++) {
279       val = noise3(p);
280       sum += val / scale;
281       scale *= alpha;
282       p[0] *= beta;
283       p[1] *= beta;
284       p[2] *= beta;
285    }
286    return(sum);
287 }
288