home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / atomart.tar.gz / atomart.tar / texture.c < prev    next >
C/C++ Source or Header  |  1990-06-28  |  4KB  |  251 lines

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include "atomart.h"
  4. #include "macro.h"
  5. #include "gram.h"
  6.  
  7. extern float    randtable[];
  8. extern float    noise();
  9. extern void    Vnoise();
  10.  
  11. extern attr    *astackp;
  12.  
  13. static    noise_inited = 0;
  14.  
  15. /*
  16.  * turbulence
  17.  *
  18.  *    Accumulate a 3D noise function over octaves octaves, scaling
  19.  *    each by 1 / f
  20.  */
  21. float
  22. turbulence(pos, octaves)
  23.     vector    *pos;
  24.     int    octaves;
  25. {
  26.     float    scale, t, f;
  27.     vector    p;
  28.     int    i;
  29.  
  30.     scale = f = 1.0;
  31.     t = 0.0;
  32.  
  33.     for (i = 0; i < octaves; i++) {
  34.         p.x = pos->x * f;
  35.         p.y = pos->y * f;
  36.         p.z = pos->z * f;
  37.         t += fabs(noise(&p) * scale);
  38.         f *= 2;
  39.         scale *= 0.5;
  40.     }
  41.  
  42.     return(t);
  43. }
  44.  
  45. /*
  46.  * marble
  47.  *
  48.  *     Does marble texture.
  49.  */
  50. void
  51. marble(o, txt, l, n, pcol, type)
  52.     object  *o;
  53.     texture *txt;
  54.     vector  *l, *n;
  55.     pixel   *pcol;
  56.     int     type;
  57. {
  58.     float    x;
  59.     vector    loc, tmp;
  60.  
  61.         totexture(txt, loc, *l);
  62.     
  63.     x = txt->var[0] * loc.x + txt->var[1] * turbulence(&loc, txt->octaves);
  64.     x = 0.5 * (1.0 + sin(x));
  65.  
  66.     x = pow((double)x, (double)txt->var[2]);
  67.     
  68.     texturec(txt, pcol, &loc, n, type, x);
  69. }
  70.  
  71. /*
  72.  * wood
  73.  *
  74.  *     Does wood texture.
  75.  */
  76. void
  77. wood(o, txt, l, n, pcol, type)
  78.     object  *o;
  79.     texture *txt;
  80.     vector  *l, *n;
  81.     pixel   *pcol;
  82.     int     type;
  83. {
  84.     float    x;
  85.     vector    loc, tmp;
  86.     
  87.         totexture(txt, loc, *l);
  88.  
  89.     x = sqrt(loc.x * loc.x + loc.y * loc.y);
  90.     x *= txt->var[0];
  91.     x += txt->var[1] * turbulence(&loc, txt->octaves);
  92.     x = 0.5 * (1.0 + sin(x));
  93.     x = pow((double)x, (double)txt->var[2]);
  94.     
  95.     texturec(txt, pcol, &loc, n, type, x);
  96. }
  97.  
  98.  
  99. /*
  100.  * bumpy
  101.  *
  102.  *     Does a bumpy texture.
  103.  */
  104. void
  105. bumpy(o, txt, l, n, pcol, type)
  106.     object  *o;
  107.     texture *txt;
  108.     vector  *l, *n;
  109.     pixel   *pcol;
  110.     int     type;
  111. {
  112.     vector    amp, loc, tmp;
  113.     
  114.         totexture(txt, loc, *l);
  115.  
  116.     Vnoise(&loc, &);
  117.  
  118.     n->x += amp.x * txt->var[0];
  119.     n->y += amp.y * txt->var[1];
  120.     n->z += amp.z * txt->var[2];
  121.  
  122.     normalise(*n);
  123. }
  124.  
  125. /*
  126.  * texturec
  127.  *
  128.  *    compute the color for a textured surface.
  129.  */
  130. texturec(txt, pcol, l, n, type, x)
  131.     texture    *txt;
  132.     pixel    *pcol;
  133.     vector    *l, *n;
  134.     int    type;
  135.     float    x;
  136. {
  137.     int    i;
  138.  
  139.     if (txt->map == (char *)NULL) {
  140.         /*
  141.          * It's a variation of the base color.
  142.          */
  143.         if (x < 0.0)
  144.             x = 0.0;
  145.         if (x > 1.0)
  146.             x = 1.0;
  147.  
  148.         pcol->r = (1.0 - x) * pcol->r + x * txt->blendcolour.r;
  149.         pcol->g = (1.0 - x) * pcol->g + x * txt->blendcolour.g;
  150.         pcol->b = (1.0 - x) * pcol->b + x * txt->blendcolour.b;
  151.     } else {
  152.         i = fabs(x) * txt->pixw;
  153.         if (i < 0)
  154.             i = 0;
  155.         if (i > txt->pixw)
  156.             i = txt->pixw;
  157.  
  158.         i *= 3;
  159.  
  160.         pcol->r = (unsigned char)txt->map[i] / 255.0;
  161.         pcol->g = (unsigned char)txt->map[i + 1] / 255.0;
  162.         pcol->b = (unsigned char)txt->map[i + 2] / 255.0;
  163.     }
  164. }
  165.  
  166. /*
  167.  * textureinit
  168.  *
  169.  *    initialise the function pointers and fields for a texture pattern. 
  170.  */
  171. tlist *
  172. textureinit(name, d)
  173.     char    *name;
  174.     details    *d;
  175. {
  176.     tlist        *tl;
  177.     char        buf[128];
  178.     details        *ld;
  179.  
  180.     if (!noise_inited) {
  181.         init_noise();
  182.         noise_inited = 1;
  183.     }
  184.  
  185.     tl = (tlist *)smalloc(sizeof(tlist));
  186.     tl->txt.refset = FALSE;
  187.  
  188.     if (strcmp(name, "marble") == 0) 
  189.         tl->txtcol = marble;
  190.     else if (strcmp(name, "wood") == 0) 
  191.         tl->txtcol = wood;
  192.     else if (strcmp(name, "bumpy") == 0) 
  193.         tl->txtcol = bumpy;
  194.     else if (strcmp(name, "tile") == 0)     /* different for each object */
  195.         tl->txtcol = (void (*)())NULL;
  196.     else {
  197.         sprintf(buf, "atomart: unknown procedural texture %s.\n", name);
  198.         fatal(buf);
  199.     }
  200.  
  201.     tl->txt.map = (char *)NULL;
  202.     tl->txt.octaves = 6;
  203.  
  204.     cp3x3(tl->txt.mat, astackp->m);
  205.  
  206.     tl->txt.trans.x = astackp->m[3][0];
  207.     tl->txt.trans.y = astackp->m[3][1];
  208.     tl->txt.trans.z = astackp->m[3][2];
  209.  
  210.     tl->txt.scales = astackp->scales;
  211.  
  212.     tl->txt.scalew = 1.0;
  213.     tl->txt.scaleh = 1.0;
  214.  
  215.     while (d != (details *)NULL) {
  216.         switch (d->type) {
  217.         case MAP:
  218.             readascmap(&tl->txt, d->u.s);
  219.             break;
  220.         case RANGE:
  221.             tl->txt.octaves = d->u.f;
  222.             break;
  223.         case BLENDCOLOR:
  224.             tl->txt.blendcolour.r = d->u.v.x;
  225.             tl->txt.blendcolour.g = d->u.v.y;
  226.             tl->txt.blendcolour.b = d->u.v.z;
  227.             break;
  228.         case SCALEFACTORS:
  229.             tl->txt.var[0] = d->u.v.x;
  230.             tl->txt.var[1] = d->u.v.y;
  231.             tl->txt.var[2] = d->u.v.z;
  232.             break;
  233.         case VORTFILE:
  234.             tileinit(&tl->txt, d->u.s, 1.0, 1.0);
  235.             break;
  236.         case SIZE:
  237.             tl->txt.scalew /= d->u.v.x;
  238.             tl->txt.scaleh /= d->u.v.y;
  239.             break;
  240.         default:
  241.             warning("atomart: illegal field in procedural texture ignored.\n");
  242.         }
  243.         ld = d;
  244.         d = d->nxt;
  245.         free(ld);
  246.     }
  247.  
  248.     return(tl);
  249. }
  250.  
  251.