TEXTURES.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX Modelling, Animation and Rendering Package
00003 -- */
00004 
00005 // file textures.c
00006 
00007 #define MODULE_TEXTUR2
00008 
00009 /* surface shaders - most code scavanged from elsewhere and adapted     */
00010 /* by converting to the approporate geometry                            */
00011 /* Perlins SIGGRAPH 86 paper textures are very evident                  */
00012 /* The CLOUD texture is called BOZO   see Perlin + DKB trace            */
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    /* ensures the values are positive. */
00161    x -= MINX;
00162    y -= MINY;
00163    z -= MINZ;
00164    /* its equivalent integer lattice point. */
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    /* the complement values of sx,sy,sz */
00169    tx = 1.0 - sx; ty = 1.0 - sy; tz = 1.0 - sz;
00170    /*
00171     *  interpolate!
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;          /* range at this point -0.5 - 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    /* ensures the values are positive. */
00204    x -= MINX;
00205    y -= MINY;
00206    z -= MINZ;
00207    /* its equivalent integer lattice point. */
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    /* the complement values of sx,sy,sz */
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;      /* basic colour */
00364    else if (noise < 0.6) {      /* blend to white */
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 {                       /* blend to grey */
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);             /* "white (1.0) * noise" */
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);             /* displace "normal" */
00481    normalize(normal);                        /* 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);             /* displace "normal" */
00495    normalize(normal);                        /* 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);   /* * 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);             /* displace "normal" */
00517    normalize(normal);                        /* normalize normal! */
00518    return 0.0;
00519 }
00520 
00521 /*
00522    Granite - union of the "spotted" and the "dented" textures,
00523    using a 1/f fractal noise function for color values.
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;                  /* "white (1.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 /* if(dd < 4)i=0.7+0.2*SimpleNoise(alpha,beta,gamma);    original */
00565  if(dd < 2)i=0.7+0.2*SimpleNoise(alpha,beta,gamma);
00566 /* else if(dd < 9 || dd >= 12){                    original */
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  //i=fabs(noisevec[0]*0.5 - 0.25);
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); /* x vector length in y direction */
00647   vecsum(Ground.p,Ground.dx,ripple_o[0]);  ripple_l[0]=Ground.lengthy;
00648   ripple_h[0]=Ground.height*0.4;  /* 0.4  is a good height */
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); /* unit vector pointing away from wave centre */
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;  /* square it */
00677     temp2 = temp2 * temp2;  /* square it */
00678     temp3 = temp3 * temp3;  /* square it */
00679 
00680     riprad = (double)sqrt(temp1 + temp2 + temp3);  /* distance from centre to point */
00681 /* distance damping */
00682 /*    if (wave_drag < 1.01) damper = 1.0;
00683 **    else damper = min(1.0,wave_drag/riprad);
00684 */
00685     riprad += wave_propagate * wave_wavelength;  /* move it */
00686     riprad /= wave_wavelength;  /* scale half-wave crest to 0..1 */
00687 
00688     iriprad = (long) riprad;
00689     if (iriprad & 1)  {/* negate it */
00690       ripple[0] = -ripple[0];
00691       ripple[1] = -ripple[1];
00692       ripple[2] = -ripple[2];
00693       }
00694     riprad -= (double) iriprad;  /* just get fraction 0..1 */
00695     riprad -= 0.5;  /* scale to -0.5 .. +0.5 */
00696     if (riprad < 0.0) riprad = -riprad;  /* absolute value */
00697     riprad  = 0.5 - riprad;  /* invert */
00698 /*    riprad *= damper; */
00699     riprad *= wave_amplitude;
00700     vecscale(riprad,ripple,ripple);  /* scale bend */
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){/* wood finish */
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){/* marble finish */
00738    marble_grain(alpha,beta,gamma,colors,tExco);
00739  }
00740  else if(textID == 12){ /* cloudy  */
00741    bozo_grain(alpha,beta,gamma,colors,tExco,
00742              (double)(fParam)*7.8125e-3,
00743 //             (double)(f->matsp)*0.375);
00744              (double)(128)*0.375);
00745    fullsat=TRUE;
00746  }
00747  else if(textID == 3){ /* granite  */
00748    granite_grain(alpha,beta,gamma,colors,tExco);
00749  }
00750  if(textID == 4){   /* BRICK */  
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){ /* luminous */
00770    fullsat=TRUE;
00771  }
00772  else if(textID == 6){ /* FIRE */ 
00773    fire_grain(alpha,beta,gamma,colors,tExco);
00774    fullsat=TRUE;
00775  }
00776  else if(textID == 10){ /* spotted  */
00777    spotted_grain(alpha,beta,gamma,colors,tExco);
00778  }
00779  else if(textID == 11){ /* agate  */
00780    agate_grain(alpha,beta,gamma,colors,tExco);
00781  }
00782  else if(textID == 14){/* blend finish */
00783    blend_grain(alpha,beta,gamma,colors,tExco);
00784  }
00785 #if 0
00786  else if(trace_refractions && textID == 15){/* refractive glass */  // THESE last two have been
00787    c=(double)((p[0]*p[0]) + (p[1]*p[1]) + (p[2]*p[2]));             // temporarily removed
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;// tr=1.0;
00794    *tr1=1.0-tr;
00795  }
00796  else if(trace_reflections && textID == 16){
00797   waves2(alpha,beta,gamma,n,Rip_Freq,wave_phase,         /* 0.2 is max   */
00798                 (double)fParam * 0.000390625);/* 0.02 is good */
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;// tr=1.0;
00807    *tr1=1.0-tr;
00808  }
00809 #endif 
00810  return fullsat;
00811 }

Generated on Sun Apr 27 14:20:13 2014 for OpenFX by  doxygen 1.5.6