00001
00002
00003
00004
00005
00006
00007 #define MODULE_TEXTUR2
00008
00009
00010
00011
00012
00013
00014
00015 #include "render.h"
00016
00017 #define MINX -10000
00018 #define MINY MINX
00019 #define MINZ MINX
00020
00021 #define max_noise 10
00022 #define NRIPPLES 10
00023 #define MAXSIZE 267
00024 #define RNDMASK 0x7FFF
00025 #define RNDDIVISOR (double) RNDMASK
00026 #define NUMBER_OF_WAVES 10
00027 #define SINTABSIZE 1000
00028 #define EPSILON (double) 0.00001
00029
00030 #define FLOOR(x) ((x) >= 0.0 ? floor(x) : (0.0 - floor(0.0 - (x)) - 1.0))
00031 #define FABS(x) ((x) < 0.0 ? (0.0 - x) : (x))
00032 #define SCURVE(a) ((a)*(a)*(3.0-2.0*(a)))
00033 #define REALSCALE ( 2.0 / 65535.0 )
00034 #define Hash3d(a,b,c) hashTable[(int)(hashTable[(int)( \
00035 hashTable[(int)((a) & 0xfffL)] ^ ((b) & 0xfffL))] ^ ((c) & 0xfffL))]
00036 #define INCRSUM(m,s,x,y,z) ((s)*(RTable[m]*0.5+RTable[m+1]*(x) \
00037 + RTable[m+2]*(y) + RTable[m+3]*(z)))
00038
00039 vector Wave_Sources[NUMBER_OF_WAVES];
00040 double Rip_Freq=10000.0;
00041
00042 static vector ripple_o[NRIPPLES];
00043 static double ripple_l[NRIPPLES],ripple_h[NRIPPLES];
00044 static unsigned short noise_table[max_noise+1][max_noise+1][max_noise+1];
00045
00046 static double sintab [SINTABSIZE];
00047 static double frequency[NUMBER_OF_WAVES];
00048 static double RTable[MAXSIZE];
00049 static short *hashTable=NULL;
00050 static unsigned short crctab[256] =
00051 {
00052 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
00053 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
00054 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
00055 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
00056 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
00057 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
00058 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
00059 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
00060 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
00061 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
00062 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
00063 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
00064 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
00065 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
00066 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
00067 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
00068 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
00069 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
00070 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
00071 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
00072 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
00073 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
00074 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
00075 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
00076 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
00077 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
00078 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
00079 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
00080 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
00081 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
00082 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
00083 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
00084 };
00085
00086 static short InitRTable(void);
00087 static short InitTextureTable(void);
00088 static int RTableNoise(vector v);
00089 static int Crc16(char *buf, int count);
00090 static void InitialiseSimpleNoise(void);
00091 static double SimpleNoise(double x, double y, double z);
00092
00093 void FreeTextureHashTable(void){
00094 if(hashTable != NULL)X__Free(hashTable);
00095 hashTable=NULL;
00096 return;
00097 }
00098
00099 short InitialiseNoise(void){
00100 register int i = 0;
00101 InitialiseSimpleNoise();
00102 if(InitRTable() == FAIL)return FAIL;
00103 for (i = 0 ; i < SINTABSIZE ; i++)
00104 sintab[i] = sin(i/(double)SINTABSIZE * (3.14159265359 * 2.0));
00105 for (i = 0 ; i < NUMBER_OF_WAVES ; i++){
00106 Dnoise2(Wave_Sources[i], (double) i, 0.0, 0.0);
00107 normalize(Wave_Sources[i]);
00108 frequency[i] = (rand() & RNDMASK) / RNDDIVISOR + 0.01;
00109 }
00110 return OK;
00111 }
00112
00113 static short InitRTable(void){
00114 int i;
00115 vector rp;
00116 if(InitTextureTable() == FAIL)return FAIL;
00117 for (i = 0; i < MAXSIZE; i++){
00118 rp[0] = rp[1] = rp[2] = (double)i;
00119 RTable[i] = (unsigned int) RTableNoise(rp) * REALSCALE - 1.0;
00120 }
00121 return OK;
00122 }
00123
00124 static short InitTextureTable(void){
00125 int i, j, temp;
00126 srand(0);
00127 if((hashTable = (short int *) X__Malloc(4096*sizeof(short int))) == NULL)
00128 return FAIL;
00129 for (i = 0; i < 4096; i++)
00130 hashTable[i] = i;
00131 for (i = 4095; i >= 0; i--)
00132 {
00133 j = rand() % 4096;
00134 temp = hashTable[i];
00135 hashTable[i] = hashTable[j];
00136 hashTable[j] = temp;
00137 }
00138 return OK;
00139 }
00140
00141 static int RTableNoise(vector v){
00142 v[0] *= .12345;
00143 v[1] *= .12345;
00144 v[2] *= .12345;
00145 return (Crc16((char *) v, sizeof(vector)));
00146 }
00147
00148 static int Crc16(char *buf, int count){
00149 register unsigned short crc = 0;
00150 while (count--)
00151 crc = (crc >> 8) ^ crctab[ (unsigned char) (crc ^ *buf++) ];
00152 return ((int) crc);
00153 }
00154
00155 void Snoise2(double x, double y, double z, double *r){
00156 register long ix, iy, iz, jx, jy, jz;
00157 double sx, sy, sz, tx, ty, tz;
00158 double sum;
00159 short m;
00160
00161 x -= MINX;
00162 y -= MINY;
00163 z -= MINZ;
00164
00165 ix = (long)x; iy = (long)y; iz = (long)z;
00166 jx = ix + 1; jy = iy + 1; jz = iz + 1;
00167 sx = SCURVE(x - ix); sy = SCURVE(y - iy); sz = SCURVE(z - iz);
00168
00169 tx = 1.0 - sx; ty = 1.0 - sy; tz = 1.0 - sz;
00170
00171
00172
00173 m = Hash3d( ix, iy, iz ) & 0xFF;
00174 sum = INCRSUM(m,(tx*ty*tz),(x-ix),(y-iy),(z-iz));
00175 m = Hash3d( jx, iy, iz ) & 0xFF;
00176 sum += INCRSUM(m,(sx*ty*tz),(x-jx),(y-iy),(z-iz));
00177 m = Hash3d( ix, jy, iz ) & 0xFF;
00178 sum += INCRSUM(m,(tx*sy*tz),(x-ix),(y-jy),(z-iz));
00179 m = Hash3d( jx, jy, iz ) & 0xFF;
00180 sum += INCRSUM(m,(sx*sy*tz),(x-jx),(y-jy),(z-iz));
00181 m = Hash3d( ix, iy, jz ) & 0xFF;
00182 sum += INCRSUM(m,(tx*ty*sz),(x-ix),(y-iy),(z-jz));
00183 m = Hash3d( jx, iy, jz ) & 0xFF;
00184 sum += INCRSUM(m,(sx*ty*sz),(x-jx),(y-iy),(z-jz));
00185 m = Hash3d( ix, jy, jz ) & 0xFF;
00186 sum += INCRSUM(m,(tx*sy*sz),(x-ix),(y-jy),(z-jz));
00187 m = Hash3d( jx, jy, jz ) & 0xFF;
00188 sum += INCRSUM(m,(sx*sy*sz),(x-jx),(y-jy),(z-jz));
00189 sum = sum + 0.5;
00190 if (sum < 0.0)
00191 sum = 0.0;
00192 if (sum > 1.0)
00193 sum = 1.0;
00194 *r = sum;
00195 return;
00196 }
00197
00198 void Dnoise2(vector result, double x, double y, double z){
00199 register long ix, iy, iz, jx, jy, jz;
00200 double px, py, pz, s;
00201 double sx, sy, sz, tx, ty, tz;
00202 short m;
00203
00204 x -= MINX;
00205 y -= MINY;
00206 z -= MINZ;
00207
00208 ix = (long)x; iy = (long)y; iz = (long)z;
00209 jx = ix+1; jy = iy + 1; jz = iz + 1;
00210 sx = SCURVE(x - ix); sy = SCURVE(y - iy); sz = SCURVE(z - iz);
00211
00212 tx = 1.0 - sx; ty = 1.0 - sy; tz = 1.0 - sz;
00213 m = Hash3d( ix, iy, iz ) & 0xFF;
00214 px = x-ix; py = y-iy; pz = z-iz;
00215 s = tx*ty*tz;
00216 result[0] = INCRSUM(m,s,px,py,pz);
00217 result[1] = INCRSUM(m+4,s,px,py,pz);
00218 result[2] = INCRSUM(m+8,s,px,py,pz);
00219 m = Hash3d( jx, iy, iz ) & 0xFF;
00220 px = x-jx;
00221 s = sx*ty*tz;
00222 result[0] += INCRSUM(m,s,px,py,pz);
00223 result[1] += INCRSUM(m+4,s,px,py,pz);
00224 result[2] += INCRSUM(m+8,s,px,py,pz);
00225 m = Hash3d( jx, jy, iz ) & 0xFF;
00226 py = y-jy;
00227 s = sx*sy*tz;
00228 result[0] += INCRSUM(m,s,px,py,pz);
00229 result[1] += INCRSUM(m+4,s,px,py,pz);
00230 result[2] += INCRSUM(m+8,s,px,py,pz);
00231 m = Hash3d( ix, jy, iz ) & 0xFF;
00232 px = x-ix;
00233 s = tx*sy*tz;
00234 result[0] += INCRSUM(m,s,px,py,pz);
00235 result[1] += INCRSUM(m+4,s,px,py,pz);
00236 result[2] += INCRSUM(m+8,s,px,py,pz);
00237 m = Hash3d( ix, jy, jz ) & 0xFF;
00238 pz = z-jz;
00239 s = tx*sy*sz;
00240 result[0] += INCRSUM(m,s,px,py,pz);
00241 result[1] += INCRSUM(m+4,s,px,py,pz);
00242 result[2] += INCRSUM(m+8,s,px,py,pz);
00243 m = Hash3d( jx, jy, jz ) & 0xFF;
00244 px = x-jx;
00245 s = sx*sy*sz;
00246 result[0] += INCRSUM(m,s,px,py,pz);
00247 result[1] += INCRSUM(m+4,s,px,py,pz);
00248 result[2] += INCRSUM(m+8,s,px,py,pz);
00249 m = Hash3d( jx, iy, jz ) & 0xFF;
00250 py = y-iy;
00251 s = sx*ty*sz;
00252 result[0] += INCRSUM(m,s,px,py,pz);
00253 result[1] += INCRSUM(m+4,s,px,py,pz);
00254 result[2] += INCRSUM(m+8,s,px,py,pz);
00255 m = Hash3d( ix, iy, jz ) & 0xFF;
00256 px = x-ix;
00257 s = tx*ty*sz;
00258 result[0] += INCRSUM(m,s,px,py,pz);
00259 result[1] += INCRSUM(m+4,s,px,py,pz);
00260 result[2] += INCRSUM(m+8,s,px,py,pz);
00261 }
00262
00263 void STurbulence(double x, double y, double z, double *r){
00264 register double pixelSize = 0.1;
00265 register double t = 0.0;
00266 register double scale;
00267 double value;
00268 for (scale = 1.0 ; scale > pixelSize ; scale *= 0.5) {
00269 Snoise2(x/scale, y/scale, z/scale, &value);
00270 t += FABS (value) * scale;
00271 }
00272 *r=t;
00273 return;
00274 }
00275
00276 void DTurbulence(vector result, double x, double y, double z){
00277 register double pixelSize = 0.01;
00278 register double scale;
00279 vector value;
00280 result[0] = 0.0;
00281 result[1] = 0.0;
00282 result[2] = 0.0;
00283 value[0] = value[1] = value[2] = 0.0;
00284 for (scale = 1.0 ; scale > pixelSize ; scale *= 0.5) {
00285 Dnoise2(value, x/scale, y/scale, z/scale);
00286 result[0] += value[0] * scale;
00287 result[1] += value[1] * scale;
00288 result[2] += value[2] * scale;
00289 }
00290 }
00291
00292 void Cycloidal(double value, double *r){
00293 if (value >= 0.0)
00294 *r = (sintab [(int)((value - floor (value)) * SINTABSIZE)]);
00295 else
00296 *r = (0.0 - sintab [(int)((0.0 - (value + floor (0.0 - value)))
00297 * SINTABSIZE)]);
00298 return;
00299 }
00300
00301 static void InitialiseSimpleNoise(void){
00302 long x,y,z,xx,yy,zz;
00303 for(x=0;x<=max_noise;x++)
00304 for(y=0;y<=max_noise;y++)
00305 for(z=0;z<=max_noise;z++){
00306 noise_table[x][y][z]=(unsigned short)rand();
00307 if(x == max_noise)xx=0;
00308 else xx=x;
00309 if(y == max_noise)yy=0;
00310 else yy=y;
00311 if(z == max_noise)zz=0;
00312 else zz=z;
00313 noise_table[x][y][z]=noise_table[xx][yy][zz];
00314 }
00315 }
00316
00317 static double SimpleNoise(double x, double y, double z){
00318 long ix,iy,iz,n;
00319 double ox,oy,oz,n00,n01,n10,n11,n0,n1;
00320 ix=((long)x+30000)%max_noise;
00321 iy=((long)y+30000)%max_noise;
00322 iz=((long)z+30000)%max_noise;
00323 ox=x-floor(x); oy=y-floor(y); oz=z-floor(z);
00324 n=noise_table[ix][iy][iz];
00325 n00=n+ox*(noise_table[ix+1][iy][iz]-n);
00326 n=noise_table[ix][iy][iz+1];
00327 n01=n+ox*(noise_table[ix+1][iy][iz+1]-n);
00328 n=noise_table[ix][iy+1][iz];
00329 n10=n+ox*(noise_table[ix+1][iy+1][iz]-n);
00330 n=noise_table[ix][iy+1][iz+1];
00331 n11=n+ox*(noise_table[ix+1][iy+1][iz+1]-n);
00332 n0=n00+oy*(n10-n00);
00333 n1=n01+oy*(n11-n01);
00334 return (n0+oz*(n1-n0))*3.052e-5;
00335 }
00336
00338
00339 double Triangle_Wave(double value){
00340 register double offset;
00341 if (value >= 0.0) offset = value - floor(value);
00342 else offset = value - (-1.0 - floor(FABS(value)));
00343 if (offset >= 0.5) return (2.0 * (1.0 - offset));
00344 else return (2.0 * offset);
00345 }
00346
00347 static void bozo_grain(double alpha, double beta, double gamma, double *color,
00348 unsigned char *txcol, double turb, double zscale){
00349 double noise;
00350 vector BozoTurbulence;
00351 double x,y,z,fraction;
00352 x=alpha; y=beta; z=gamma;
00353 z = z*zscale;
00354 x=alpha; y=beta; z=gamma;
00355 if (turb != 0.0)
00356 {
00357 DTurbulence (BozoTurbulence, x, y, z);
00358 x += BozoTurbulence[0] * turb;
00359 y += BozoTurbulence[1] * turb;
00360 z += BozoTurbulence[2] * turb;
00361 }
00362 Snoise2 (x, y, z, &noise);
00363 if (noise < 0.5)return;
00364 else if (noise < 0.6) {
00365 fraction=(noise - 0.5)/(0.6 - 0.5);
00366 color[0] = color[0] + fraction*(255.0 - color[0]);
00367 color[1] = color[1] + fraction*(255.0 - color[1]);
00368 color[2] = color[2] + fraction*(255.0 - color[2]);
00369 }
00370 else {
00371 fraction=1.0 - 0.5*(noise - 0.6)/(1.0 - 0.6);
00372 color[0] = fraction*255.0;
00373 color[1] = fraction*255.0;
00374 color[2] = fraction*255.0;
00375 }
00376 return;
00377 }
00378
00379 static void wood_grain2(double alpha, double beta, double gamma,
00380 double *color,
00381 unsigned char *txcol, double turb){
00382 double x,y,z,noise,length;
00383 vector WoodTurbulence,point;
00384 x=alpha,y=beta,z=gamma;
00385 x *= 10.0; y *= 10.0; z *= 10.0;
00386 DTurbulence (WoodTurbulence,x,y,z);
00387 Cycloidal((x + WoodTurbulence[0])*turb, &point[0]);
00388 Cycloidal((y + WoodTurbulence[1])*turb, &point[1]);
00389 point[2] = 0.0;
00390 point[0] += x;
00391 point[1] += y;
00392 point[2] += z;
00393 length=R_length(point);
00394 noise = Triangle_Wave(length);
00395 if(noise > 0.6){
00396 color[0] = (double)txcol[0];
00397 color[1] = (double)txcol[1];
00398 color[2] = (double)txcol[2];
00399 }
00400 return;
00401 }
00402
00403 static void waves2(double alpha, double beta, double gamma,
00404 vector Vector, double Frequency, double Phase, double Bump_Amount){
00405 double x,y,z;
00406 register int i;
00407 vector point;
00408 register double length, scalar, index;
00409 double sinValue ;
00410 x=alpha; y=beta; z=gamma;
00411 x *= .030; y *= .030; z=0;
00412 for (i = 0 ; i < NUMBER_OF_WAVES ; i++) {
00413 point[0] = x;
00414 point[1] = y;
00415 point[2] = z;
00416 vecsub(point, Wave_Sources[i], point);
00417 length=dot(point, point);
00418 if (length == 0.0)length = 1.0;
00419 length = sqrt(length);
00420 index = (length * Frequency * frequency[i]) + Phase;
00421 Cycloidal (index, &sinValue);
00422 scalar = sinValue * Bump_Amount / frequency[i];
00423 vecscale(scalar/length/(double)NUMBER_OF_WAVES,point,point);
00424 vecsum(Vector, point, Vector);
00425 }
00426 normalize(Vector);
00427 }
00428
00429 static void spotted_grain(double alpha, double beta, double gamma,
00430 double *color, unsigned char *txcol){
00431 double x,y,z;
00432 double noise;
00433 x=alpha,y=beta; z=gamma;
00434 Snoise2(x,y,z,&noise);
00435 color[0] += (noise*255);
00436 color[1] += (noise*255);
00437 color[2] += (noise*255);
00438 return;
00439 }
00440
00441 static void agate_grain(double alpha, double beta, double gamma,
00442 double *color, unsigned char *txcol){
00443 double x,y,z,r;
00444 double noise, hue;
00445 x=alpha; y=beta; z=gamma;
00446 STurbulence(x,y,z,&r);
00447 Cycloidal(1.3 * r + 1.1 * z, &noise);
00448 noise += 1;
00449 noise *= 0.5;
00450 noise = pow(noise, 0.77);
00451 hue = 1.0 - noise;
00452 if (noise < 0.5)
00453 {
00454 color[0] += (1.0 - (noise / 10))*255;
00455 color[1] += (1.0 - (noise / 5))*255;
00456 color[2] += hue*255;
00457 }
00458 else if (noise < 0.6)
00459 {
00460 color[0] += 0.9*255;
00461 color[1] += 0.7*255;
00462 color[2] += hue*255;
00463 }
00464 else
00465 {
00466 color[0] += (0.6 + hue)*255;
00467 color[1] += (0.3 + hue)*255;
00468 color[2] += hue*255;
00469 }
00470 return;
00471 }
00472
00473 static double new_bumpy(double alpha, double beta, double gamma,double Bump_Amount, vector normal){
00474 double x,y,z;
00475 vector result;
00476 x=alpha; y=beta; z=gamma;
00477 Dnoise2(result,x*10.0,y*10.0,z*10.0);
00478 Bump_Amount *= 2.0;
00479 VECSCALE(Bump_Amount,result,result)
00480 vecsum(normal,result,normal);
00481 normalize(normal);
00482 return 0.0;
00483 }
00484
00485 static double dents(double alpha, double beta, double gamma, double Bump_Amount, vector normal){
00486 double x,y,z,noise;
00487 vector result;
00488 x=alpha; y=beta; z=gamma;
00489 x *= 10.0; y *= 10.0; z *= 10.0;
00490 Snoise2(x,y,z,&noise);
00491 noise=noise*noise*noise*Bump_Amount*2.0;
00492 Dnoise2(result,x,y,z);
00493 vecscale(noise,result,result);
00494 vecsum(normal,result,normal);
00495 normalize(normal);
00496 return 0.0;
00497 }
00498
00499 static double wrinkles(double alpha, double beta, double gamma, double Bump_Amount, vector normal){
00500 double x,y,z;
00501 register int i;
00502 register double scale = 1.0;
00503 vector result, value;
00504 x=alpha; y=beta; z=gamma;
00505 result[0] = 0.0;
00506 result[1] = 0.0;
00507 result[2] = 0.0;
00508 x *= 10.0; y *= 10.0; z *= 10.0;
00509 for (i = 0; i < 10 ; scale *= 2.0, i++){
00510 Dnoise2(value, x * scale, y * scale, z * scale);
00511 result[0] += FABS (value[0] / scale);
00512 result[1] += FABS (value[1] / scale);
00513 result[2] += FABS (value[2] / scale);
00514 }
00515 vecscale(Bump_Amount*2.0,result,result);
00516 vecsum(normal,result,normal);
00517 normalize(normal);
00518 return 0.0;
00519 }
00520
00521
00522
00523
00524
00525 static void granite_grain(double alpha, double beta, double gamma,
00526 double *color, unsigned char *txcol){
00527 double x,y,z,temp;
00528 register int i;
00529 register double noise = 0.0, freq = 1.0;
00530 x=alpha; y=beta; z=gamma;
00531 for (i = 0; i < 6 ; freq *= 2.0, i++) {
00532 Snoise2 (x * 4 * freq, y * 4 * freq, z * 4 * freq, &temp);
00533 temp = 0.5 - temp;
00534 temp = FABS(temp);
00535 noise += temp / freq;
00536 }
00537 color[0] *= noise;
00538 color[1] *= noise;
00539 color[2] *= noise;
00540 return;
00541 }
00542
00543 static void marble_grain(double alpha, double beta, double gamma,
00544 double *color, unsigned char *txcol){
00545 vector noisevec;
00546 double i,sinval;
00547 alpha *= 20;
00548 beta *= 20;
00549 gamma *= 10;
00550 Dnoise2(noisevec,alpha,beta,gamma);
00551 i = fabs(noisevec[0]*0.5 - 0.25) +
00552 fabs(noisevec[1]*0.5 - 0.125) +
00553 fabs(noisevec[2]*0.5 - 0.0626);
00554 if(i < 0.0)i=0.0;
00555 if(i > 0.999)i=0.999;
00556 i=sin(gamma*1.0+i*2.0)*0.5 + 0.5;
00557 #if 0
00558 double d,dd,i;
00559 alpha *= 20;
00560 beta *= 20;
00561 gamma *= 10;
00562 d=30000+beta*5+17*SimpleNoise(alpha,beta,gamma);
00563 dd=(double)(((long)floor(d))%17);
00564
00565 if(dd < 2)i=0.7+0.2*SimpleNoise(alpha,beta,gamma);
00566
00567 else if(dd < 5 || dd >= 10){
00568 d=fabs(d-floor(d/17)*17-10.5)*0.1538462;
00569 i=0.4+0.3*d+0.2*SimpleNoise(alpha,beta,gamma);
00570 }
00571 else i=0.2+0.2*SimpleNoise(alpha,beta,gamma);
00572 #endif
00573 color[0]=(double)txcol[0]*i+color[0]*(1.0-i);
00574 color[1]=(double)txcol[1]*i+color[1]*(1.0-i);
00575 color[2]=(double)txcol[2]*i+color[2]*(1.0-i);
00576 }
00577
00578 static void fire_grain(double alpha, double beta, double gamma,
00579 double *color, unsigned char *txcol){
00580 vector noisevec;
00581 double i;
00582 alpha *= 10;
00583 beta *= 10;
00584 gamma *= 10;
00585 Dnoise2(noisevec,alpha,beta,gamma);
00586 i = fabs(noisevec[0]*0.5 - 0.25) +
00587 fabs(noisevec[1]*0.5 - 0.125) +
00588 fabs(noisevec[2]*0.5 - 0.0626);
00589
00590 if(i < 0.0)i=0.0;
00591 if(i > 0.999)i=0.999;
00592 color[0]=(double)txcol[0]*i+color[0]*(1.0-i);
00593 color[1]=(double)txcol[1]*i+color[1]*(1.0-i);
00594 color[2]=(double)txcol[2]*i+color[2]*(1.0-i);
00595 }
00596
00597
00598 static double aztec_bumpy(double a1, double b1, double g1, double bumpyness, vector n){
00599 double alpha,beta,gamma,i1,i2,i3,c;
00600 short j1,j2,j3;
00601 vector v1,v2;
00602 vector unitx={1.0,0.0,0.0};
00603 vector unity={0.0,1.0,0.0};
00604 gamma =g1;
00605 c = 2.0*bumpyness;
00606 alpha = a1*10;
00607 beta = b1*10;
00608 gamma *= 30;
00609 j1=SimpleNoise(alpha,beta,gamma)*10;
00610 j2=SimpleNoise(alpha+0.15,beta,gamma)*10;
00611 j3=SimpleNoise(alpha,beta+0.15,gamma)*10;
00612 if(j1%2)i1=0; else i1=0.3;
00613 if(j2%2)i2=0; else i2=0.3;
00614 if(j3%2)i3=0; else i3=0.3;
00615 vecscale((i2-i1)*c,unitx,v1);
00616 vecscale((i3-i1)*c,unity,v2);
00617 vecsum(n,v1,n);
00618 vecsum(n,v2,n);
00619 normalize(n);
00620 return 0.0;
00621 }
00622
00623 static void blend_grain(double alpha, double beta, double gamma,
00624 double *color,unsigned char *txcol){
00625 gamma=(gamma-floor(gamma))*2;
00626 if(gamma <= 1.0){
00627 color[0]=color[0] + ((double)txcol[0] - color[0])*gamma;
00628 color[1]=color[1] + ((double)txcol[1] - color[1])*gamma;
00629 color[2]=color[2] + ((double)txcol[2] - color[2])*gamma;
00630 }
00631 else{
00632 gamma -= 1.0;
00633 color[0]=(double)txcol[0] + (color[0] - (double)txcol[0])*gamma;
00634 color[1]=(double)txcol[1] + (color[1] - (double)txcol[1])*gamma;
00635 color[2]=(double)txcol[2] + (color[2] - (double)txcol[2])*gamma;
00636 }
00637 }
00638
00639 void init_ripples(void){
00640 vector v1,v2,vy;
00641 double rn,rn1,rn2;
00642 short j;
00643 Rip_Freq=10000.0;
00644 veccopy(Ground.dy,vy);
00645 normalize(vy);
00646 vecscale(Ground.lengthx,vy,vy);
00647 vecsum(Ground.p,Ground.dx,ripple_o[0]); ripple_l[0]=Ground.lengthy;
00648 ripple_h[0]=Ground.height*0.4;
00649 vecsum(Ground.p,vy,ripple_o[1]); ripple_l[1]=Ground.lengthy;
00650 ripple_h[1]=Ground.height*0.4;
00651 if(NRIPPLES > 2)for(j=2;j<NRIPPLES;j++){
00652 rn1 = (double)(rand())/32767.0 * 10;
00653 rn2 = (double)(rand())/32767.0 * 10;
00654 vecscale(rn1,Ground.dx,v1);
00655 vecscale(rn2,vy,v2);
00656 vecsum(Ground.p,v1,v1);
00657 vecsum(v1,v2,ripple_o[j]);
00658 rn = 0.01 + (double)(rand())/32767.0;
00659 ripple_l[j]=Ground.lengthy*rn;
00660 ripple_h[j]=Ground.height*0.4;
00661 }
00662 }
00663
00664 void calcripple(vector point, vector wave_centre,
00665 double wave_propagate,double wave_wavelength,
00666 double wave_drag, double wave_amplitude,
00667 vector ripple){
00668 double riprad,temp1,temp2,temp3;
00669 long iriprad;
00670 vecsub(point,wave_centre,ripple);
00671 normalize(ripple);
00672 temp1 = wave_centre[0] - point[0];
00673 temp2 = wave_centre[1] - point[1];
00674 temp3 = wave_centre[2] - point[2];
00675
00676 temp1 = temp1 * temp1;
00677 temp2 = temp2 * temp2;
00678 temp3 = temp3 * temp3;
00679
00680 riprad = (double)sqrt(temp1 + temp2 + temp3);
00681
00682
00683
00684
00685 riprad += wave_propagate * wave_wavelength;
00686 riprad /= wave_wavelength;
00687
00688 iriprad = (long) riprad;
00689 if (iriprad & 1) {
00690 ripple[0] = -ripple[0];
00691 ripple[1] = -ripple[1];
00692 ripple[2] = -ripple[2];
00693 }
00694 riprad -= (double) iriprad;
00695 riprad -= 0.5;
00696 if (riprad < 0.0) riprad = -riprad;
00697 riprad = 0.5 - riprad;
00698
00699 riprad *= wave_amplitude;
00700 vecscale(riprad,ripple,ripple);
00701 }
00702
00703 void Ocean(vector p0, vector Groundn, vector gn){
00704 int j;
00705 vector ripple;
00706 veccopy(Groundn,gn);
00707 for(j=0;j<NRIPPLES;j++){
00708 calcripple(p0,ripple_o[j],wave_phase,ripple_l[j],
00709 1.0,ripple_h[j],ripple);
00710 vecsum(ripple,gn,gn);
00711 }
00712 if(normalize(gn))veccopy(Groundn,gn);
00713 }
00714
00715
00716 BOOL GetInternalTexture(matl *Mat,double alpha, double beta, double gamma,
00717 long textID, vector p, vector n, long obj, face *f,
00718 double *colors, double *colort,
00719 long *flag_trans, double tr, double *tr1,
00720 long trace_relection_depth,long trace_refraction_depth,
00721 long refractive_flag){
00722 double c;
00723 vector d;
00724 long t;
00725 unsigned char tExco[3]={128,128,0};
00726 unsigned char fParam=128;
00727 BOOL fullsat=FALSE;
00728 VECCOPY(Mat->texco,tExco)
00729 fParam=Mat->params[0];
00730 if(textID == 1){
00731 wood_grain2(alpha,beta,gamma,colors,tExco,0.078125);
00732 }
00733 else if(textID == 7)new_bumpy (alpha,beta,gamma,(double)fParam*SHSCALE,n);
00734 else if(textID == 8)aztec_bumpy(alpha,beta,gamma,(double)fParam*SHSCALE,n);
00735 else if(textID == 13)dents (alpha,beta,gamma,(double)fParam*SHSCALE,n);
00736 else if(textID == 9)wrinkles (alpha,beta,gamma,(double)fParam*SHSCALE,n);
00737 else if(textID == 2){
00738 marble_grain(alpha,beta,gamma,colors,tExco);
00739 }
00740 else if(textID == 12){
00741 bozo_grain(alpha,beta,gamma,colors,tExco,
00742 (double)(fParam)*7.8125e-3,
00743
00744 (double)(128)*0.375);
00745 fullsat=TRUE;
00746 }
00747 else if(textID == 3){
00748 granite_grain(alpha,beta,gamma,colors,tExco);
00749 }
00750 if(textID == 4){
00751 alpha=(alpha-floor(alpha));
00752 gamma=(gamma-floor(gamma));
00753 beta =(beta-floor(beta));
00754 if(beta > 0.95){
00755 colors[0]=(double)tExco[0];
00756 colors[1]=(double)tExco[1];
00757 colors[2]=(double)tExco[2];
00758 }
00759 else if((gamma > 0.95 || (gamma > 0.45 && gamma < 0.5)) ||
00760 (gamma < 0.5 && ( (alpha > 0.45 && alpha < 0.5) || alpha > 0.95) ) ||
00761 (gamma > 0.5 && ((alpha > 0.25 && alpha < 0.3) ||
00762 (alpha > 0.7 && alpha < 0.75)))
00763 ){
00764 colors[0]=(double)tExco[0];
00765 colors[1]=(double)tExco[1];
00766 colors[2]=(double)tExco[2];
00767 }
00768 }
00769 else if(textID == 5){
00770 fullsat=TRUE;
00771 }
00772 else if(textID == 6){
00773 fire_grain(alpha,beta,gamma,colors,tExco);
00774 fullsat=TRUE;
00775 }
00776 else if(textID == 10){
00777 spotted_grain(alpha,beta,gamma,colors,tExco);
00778 }
00779 else if(textID == 11){
00780 agate_grain(alpha,beta,gamma,colors,tExco);
00781 }
00782 else if(textID == 14){
00783 blend_grain(alpha,beta,gamma,colors,tExco);
00784 }
00785 #if 0
00786 else if(trace_refractions && textID == 15){
00787 c=(double)((p[0]*p[0]) + (p[1]*p[1]) + (p[2]*p[2]));
00788 c=sqrt(c);
00789 VECSCALE((1.0/c),p,d)
00790 trace_REFR_ray(p,d,n,obj,f,(double)BIGP,colort,
00791 trace_relection_depth,trace_refraction_depth,
00792 refractive_flag);
00793 *flag_trans=1;
00794 *tr1=1.0-tr;
00795 }
00796 else if(trace_reflections && textID == 16){
00797 waves2(alpha,beta,gamma,n,Rip_Freq,wave_phase,
00798 (double)fParam * 0.000390625);
00799 c=(double)((p[0]*p[0]) + (p[1]*p[1]) + (p[2]*p[2]));
00800 c=sqrt(c);
00801 VECSCALE((1.0/c),p,d)
00802 trace_REFR_ray(p,d,n,obj,f,(double)BIGP,colort,
00803 trace_relection_depth,trace_refraction_depth,
00804 refractive_flag);
00805
00806 *flag_trans=1;
00807 *tr1=1.0-tr;
00808 }
00809 #endif
00810 return fullsat;
00811 }