00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "perlin.h"
00022
00023
00024 namespace NUM
00025 {
00026
00027 template<typename T>void NoiseGenerator_Perlin<T>::_init()
00028 {
00029 int i,j;
00030
00031 for(i=0 ; i<B ; i++)
00032 {
00033 p[i] = i;
00034
00035
00036 g1[i] = (T)((rand() & (2*B-1)) - B) / B;
00037
00038 for(j=0 ; j<2 ; j++)
00039 g2[i][j] = (T)((rand() & (2*B-1)) - B) / B;
00040
00041
00042
00043 T s = T(1.0)/hypot(g2[i][0],g2[i][1]);
00044 g2[i][0] *= s;
00045 g2[i][1] *= s;
00046
00047 for(j=0 ; j<3 ; j++)
00048 g3[i][j] = (T)((rand() & (2*B-1)) - B) / B;
00049
00050
00051
00052 s = T(1.0)/sqrt(sqr(g3[i][0]) + sqr(g3[i][1]) + sqr(g3[i][2]));
00053 g3[i][0] *= s;
00054 g3[i][1] *= s;
00055 g3[i][2] *= s;
00056 }
00057
00058
00059 while(--i)
00060 {
00061 int k = p[i];
00062
00063 p[i] = p[j = rand() & (B-1)];
00064 p[j] = k;
00065 }
00066
00067 for(i = 0 ; i < B + 2 ; i++)
00068 {
00069 p[B + i] = p[i];
00070 g1[B + i] = g1[i];
00071 for(j=0 ; j<2 ; j++)
00072 g2[B + i][j] = g2[i][j];
00073 for(j=0 ; j<3 ; j++)
00074 g3[B + i][j] = g3[i][j];
00075 }
00076 }
00077
00078
00079 #define s_curve(t) ( t * t * (T(3.0) - T(2.0) * t) )
00080
00081 #define lerp(t, a, b) ( a + t * (b - a) )
00082
00083 #define setup(i,b0,b1,r0,r1)\
00084 t = vc[i] + N;\
00085 b0 = ((int)t) & (B-1);\
00086 b1 = (b0+1) & (B-1);\
00087 r0 = t - (int)t;\
00088 r1 = r0 - 1.;
00089
00090
00091 template<typename T>T NoiseGenerator_Perlin<T>::noise1(T arg) const
00092 {
00093 int bx0, bx1;
00094 T rx0, rx1, sx, t, u, v, vc[1];
00095
00096 vc[0] = arg;
00097
00098 setup(0, bx0,bx1, rx0,rx1);
00099
00100 sx = s_curve(rx0);
00101
00102 u = rx0 * g1[ p[ bx0 ] ];
00103 v = rx1 * g1[ p[ bx1 ] ];
00104
00105 return lerp(sx, u, v);
00106 }
00107
00108
00109 template<typename T>T NoiseGenerator_Perlin<T>::noise2(const T *vc) const
00110 {
00111 int bx0, bx1, by0, by1, b00, b10, b01, b11;
00112 T rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v;
00113 const T *q;
00114 register int i, j;
00115
00116
00117
00118
00119
00120 t = vc[0] + N;
00121 bx0 = ((int)t) & (B-1);
00122 bx1 = (bx0+1) & (B-1);
00123 rx0 = t - (int)t;
00124 rx1 = rx0 - T(1.0);
00125
00126 t = vc[1] + N;
00127 by0 = ((int)t) & (B-1);
00128 by1 = (by0+1) & (B-1);
00129 ry0 = t - (int)t;
00130 ry1 = ry0 - T(1.0);
00131
00132 i = p[ bx0 ];
00133 j = p[ bx1 ];
00134
00135 b00 = p[ i + by0 ];
00136 b10 = p[ j + by0 ];
00137 b01 = p[ i + by1 ];
00138 b11 = p[ j + by1 ];
00139
00140 sx = s_curve(rx0);
00141 sy = s_curve(ry0);
00142
00143 #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
00144
00145 q = g2[ b00 ] ; u = at2(rx0,ry0);
00146 q = g2[ b10 ] ; v = at2(rx1,ry0);
00147 a = lerp(sx, u, v);
00148
00149 q = g2[ b01 ] ; u = at2(rx0,ry1);
00150 q = g2[ b11 ] ; v = at2(rx1,ry1);
00151 b = lerp(sx, u, v);
00152
00153 return T(lerp(sy, a, b));
00154 }
00155
00156
00157 template<typename T>T NoiseGenerator_Perlin<T>::noise3(const T *vc) const
00158 {
00159 int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
00160 T rx0, rx1, ry0, ry1, rz0, rz1, sy, sz, a, b, c, d, t, u, v;
00161 const T *q;
00162 register int i, j;
00163
00164
00165
00166
00167 t = vc[0] + N;
00168 bx0 = ((int)t) & (B-1);
00169 bx1 = (bx0+1) & (B-1);
00170 rx0 = t - (int)t;
00171 rx1 = rx0 - T(1.0);
00172
00173 t = vc[1] + N;
00174 by0 = ((int)t) & (B-1);
00175 by1 = (by0+1) & (B-1);
00176 ry0 = t - (int)t;
00177 ry1 = ry0 - T(1.0);
00178
00179 t = vc[2] + N;
00180 bz0 = ((int)t) & (B-1);
00181 bz1 = (bz0+1) & (B-1);
00182 rz0 = t - (int)t;
00183 rz1 = rz0 - T(1.0);
00184
00185 i = p[ bx0 ];
00186 j = p[ bx1 ];
00187
00188 b00 = p[ i + by0 ];
00189 b10 = p[ j + by0 ];
00190 b01 = p[ i + by1 ];
00191 b11 = p[ j + by1 ];
00192
00193 t = s_curve(rx0);
00194 sy = s_curve(ry0);
00195 sz = s_curve(rz0);
00196
00197 #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
00198
00199 q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
00200 q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
00201 a = lerp(t, u, v);
00202
00203 q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
00204 q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
00205 b = lerp(t, u, v);
00206
00207 c = lerp(sy, a, b);
00208
00209 q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
00210 q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
00211 a = lerp(t, u, v);
00212
00213 q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
00214 q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
00215 b = lerp(t, u, v);
00216
00217 d = lerp(sy, a, b);
00218
00219 return T(lerp(sz, c, d));
00220 }
00221
00222
00223 void _NoiseGenerator_PerlinInstantiationDummy()
00224 {
00225 {
00226 NoiseGenerator_Perlin<dbl> p;
00227 p.noise1(0);
00228 p.noise2(NULL);
00229 p.noise3(NULL);
00230 }
00231 {
00232 NoiseGenerator_Perlin<flt> p;
00233 p.noise1(0);
00234 p.noise2(NULL);
00235 p.noise3(NULL);
00236 }
00237 }
00238
00239 }