home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / RTrace 1.0 / source / shadtext.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-28  |  22.6 KB  |  804 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Copyright (c) 1988, 1992 Antonio Costa, INESC-Norte.
  3.  * All rights reserved.
  4.  *
  5.  * Code, ideas or suggestions were taken from the following people:
  6.  *
  7.  *  Roman Kuchkuda      - basic ray tracer
  8.  *  Mark VandeWettering - MTV ray tracer
  9.  *  Augusto Sousa       - overall, shading model
  10.  *  Craig Kolb          - textures
  11.  *  David Buck          - textures
  12.  *
  13.  * Redistribution and use in source and binary forms are permitted
  14.  * provided that the above copyright notice and this paragraph are
  15.  * duplicated in all such forms and that any documentation,
  16.  * advertising materials, and other materials related to such
  17.  * distribution and use acknowledge that the software was developed
  18.  * by Antonio Costa, at INESC-Norte. The name of the author and
  19.  * INESC-Norte may not be used to endorse or promote products derived
  20.  * from this software without specific prior written permission.
  21.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  22.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  23.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  24.  */
  25. #include "defs.h"
  26. #include "extern.h"
  27.  
  28. /**********************************************************************
  29.  *    RAY TRACING - Shade texture - Version 8.0.0                     *
  30.  *                                                                    *
  31.  *    MADE BY    : Antonio Costa, INESC-Norte, October 1991           *
  32.  *    MODIFIED BY: Antonio Costa, INESC-Norte, September 1992         *
  33.  **********************************************************************/
  34.  
  35. /***** Textures *****/
  36. #define ADJUST(color)\
  37. do {\
  38.   (color).r = MIN(1.0, MAX(0.0, (color).r));\
  39.   (color).g = MIN(1.0, MAX(0.0, (color).g));\
  40.   (color).b = MIN(1.0, MAX(0.0, (color).b));\
  41. } while (0)
  42.  
  43. #define SCALE(color, red, green, blue)\
  44. do {\
  45.   (color).r *= 2.0 * (red);\
  46.   (color).g *= 2.0 * (green);\
  47.   (color).b *= 2.0 * (blue);\
  48.   ADJUST(color);\
  49. } while (0)
  50.  
  51. static void
  52. interpolate(t, colors, color)
  53.   real            t;
  54.   rgb_ptr         colors, color;
  55. {
  56.   REG int         i1, i2;
  57.   REG real        t1, t2;
  58.   if (t < 0.0)
  59.   {
  60.     STRUCT_ASSIGN(*color, colors[0]);
  61.     return;
  62.   }
  63.   if (t >= 1.0)
  64.   {
  65.     STRUCT_ASSIGN(*color, colors[255]);
  66.     return;
  67.   }
  68.   t1 = t * 256.0;
  69.   i1 = (int) t1;
  70.   if (i1 < 255)
  71.     i2 = SUCC(i1);
  72.   else
  73.   {
  74.     i1 = 255;
  75.     i2 = 0;
  76.   }
  77.   t1 = FRAC(t1);
  78.   t2 = 1.0 - t1;
  79.   color->r = t1 * colors[i1].r + t2 * colors[i2].r;
  80.   color->g = t1 * colors[i1].g + t2 * colors[i2].g;
  81.   color->b = t1 * colors[i1].b + t2 * colors[i2].b;
  82. }
  83. static void
  84. checker_texture(position, normal, old_surface, texture)
  85.   xyz_ptr         position, normal;
  86.   surface_ptr     old_surface;
  87.   texture_ptr     texture;
  88. {
  89.   int             x, y, z;
  90.   checker_ptr     checker;
  91.  
  92.   checker = (checker_ptr) texture->data;
  93.   x = position->x > 0.0 ? (int) position->x : (int) (1.0 - position->x);
  94.   y = position->y > 0.0 ? (int) position->y : (int) (1.0 - position->y);
  95.   z = position->z > 0.0 ? (int) position->z : (int) (1.0 - position->z);
  96.   if (ODD(x + y + z))
  97.     STRUCT_ASSIGN(*old_surface, *(surface[checker->surface_id]));
  98. }
  99. static void
  100. blotch_texture(position, normal, old_surface, texture)
  101.   xyz_ptr         position, normal;
  102.   surface_ptr     old_surface;
  103.   texture_ptr     texture;
  104. {
  105.   real            t;
  106.   blotch_ptr      blotch;
  107.  
  108.   blotch = (blotch_ptr) texture->data;
  109.   t = black_noise(position);
  110.   if (t > blotch->scale)
  111.   {
  112.     t = (t - blotch->scale) / (1.0 - blotch->scale);
  113.     old_surface->color.r = old_surface->color.r * (1.0 - t) +
  114.       surface[blotch->surface_id]->color.r * t;
  115.     old_surface->color.g = old_surface->color.g * (1.0 - t) +
  116.       surface[blotch->surface_id]->color.g * t;
  117.     old_surface->color.b = old_surface->color.b * (1.0 - t) +
  118.       surface[blotch->surface_id]->color.b * t;
  119.     ADJUST(old_surface->color);
  120.   }
  121. }
  122. static void
  123. bump_texture(position, normal, old_surface, texture)
  124.   xyz_ptr         position, normal;
  125.   surface_ptr     old_surface;
  126.   texture_ptr     texture;
  127. {
  128.   xyz_struct      p;
  129.   bump_ptr        bump;
  130.  
  131.   bump = (bump_ptr) texture->data;
  132.   black_noise2(position, &p);
  133.   normal->x += p.x * bump->scale;
  134.   normal->y += p.y * bump->scale;
  135.   normal->z += p.z * bump->scale;
  136.   NORMALIZE(*normal);
  137. }
  138. static void
  139. marble_texture(position, normal, old_surface, texture)
  140.   xyz_ptr         position, normal;
  141.   surface_ptr     old_surface;
  142.   texture_ptr     texture;
  143. {
  144.   real            t;
  145.   rgb_struct      color;
  146.   marble_ptr      marble;
  147.  
  148.   marble = (marble_ptr) texture->data;
  149.   t = marble_noise(position);
  150.   if (marble->color != NULL)
  151.   {
  152.     interpolate(t, marble->color, &color);
  153.     SCALE(old_surface->color, color.r, color.g, color.b);
  154.     return;
  155.   }
  156.   SCALE(old_surface->color, t, t, t);
  157. }
  158. static void
  159. fbm_texture(position, normal, old_surface, texture)
  160.   xyz_ptr         position, normal;
  161.   surface_ptr     old_surface;
  162.   texture_ptr     texture;
  163. {
  164.   real            t;
  165.   rgb_struct      color;
  166.   fbm_ptr         fbm;
  167.  
  168.   fbm = (fbm_ptr) texture->data;
  169.   t = fbm_noise(position, fbm->omega, fbm->lambda, fbm->octaves);
  170.   if (t < fbm->threshold)
  171.     t = fbm->offset;
  172.   else
  173.     t = fbm->offset + fbm->scale * (t - fbm->threshold);
  174.   if (fbm->color != NULL)
  175.   {
  176.     interpolate(t, fbm->color, &color);
  177.     SCALE(old_surface->color, color.r, color.g, color.b);
  178.     return;
  179.   }
  180.   SCALE(old_surface->color, t, t, t);
  181. }
  182. static void
  183. fbm_bump_texture(position, normal, old_surface, texture)
  184.   xyz_ptr         position, normal;
  185.   surface_ptr     old_surface;
  186.   texture_ptr     texture;
  187. {
  188.   xyz_struct      p;
  189.   fbm_bump_ptr    fbm_bump;
  190.  
  191.   fbm_bump = (fbm_bump_ptr) texture->data;
  192.   fbm_noise2(position, fbm_bump->omega, fbm_bump->lambda, fbm_bump->octaves,
  193.              &p);
  194.   normal->x += (p.x + fbm_bump->offset) * fbm_bump->scale;
  195.   normal->y += (p.y + fbm_bump->offset) * fbm_bump->scale;
  196.   normal->z += (p.z + fbm_bump->offset) * fbm_bump->scale;
  197.   NORMALIZE(*normal);
  198. }
  199. static void
  200. wood_texture(position, normal, old_surface, texture)
  201.   xyz_ptr         position, normal;
  202.   surface_ptr     old_surface;
  203.   texture_ptr     texture;
  204. {
  205.   REG real        r, g, b;
  206.   REG real        brown_layer, green_layer;
  207.   real            brown_noise, green_noise, green0_noise;
  208.   real            chaos, t;
  209.   wood_ptr        wood;
  210.  
  211.   wood = (wood_ptr) texture->data;
  212.   chaos = chaos_noise(position, 7);
  213.   t = SIN(SIN(8.0 * chaos + 7.0 * position->x + 3.0 * position->y));
  214.   green_layer = ABS(t);
  215.   brown_layer = green_layer;
  216.   t = ABS(SIN(40.0 * chaos + 50.0 * position->z));
  217.   brown_noise = 0.7 * t + 0.3;
  218.   green_noise = 0.2 * t + 0.8;
  219.   green0_noise = 0.15 * t + 0.85;
  220.   g = POWER(ABS(brown_layer), 0.3);
  221.   brown_layer = POWER(0.5 * (brown_layer + 1.0), 0.6) * brown_noise;
  222.   green_layer = POWER(0.5 * (green_layer + 1.0), 0.6) * green_noise;
  223.   r = ((wood->color.r + wood->color.b) * 0.5 * brown_layer +
  224.        wood->color.g * green_layer) * g;
  225.   b = ((wood->color.r + wood->color.b) * 0.25 * brown_layer +
  226.        wood->color.g * green_layer) * g;
  227.   g *= MAX(brown_layer, green_layer) * green0_noise;
  228.   SCALE(old_surface->color, r, g, b);
  229. }
  230. static void
  231. round_texture(position, normal, old_surface, texture)
  232.   xyz_ptr         position, normal;
  233.   surface_ptr     old_surface;
  234.   texture_ptr     texture;
  235. {
  236.   real            k1, k2;
  237.   xyz_struct      u, v;
  238.   round_ptr       round;
  239.  
  240.   round = (round_ptr) texture->data;
  241.   if (round->scale < ROUNDOFF)
  242.     return;
  243.   v.x = 0.0;
  244.   v.y = 1.0;
  245.   v.z = 0.0;
  246.   if (ABS(DOT_PRODUCT(*normal, v)) > 1.0 - ROUNDOFF)
  247.   {
  248.     v.x = 1.0;
  249.     v.y = 0.0;
  250.   }
  251.   CROSS_PRODUCT(u, *normal, v);
  252.   NORMALIZE(u);
  253.   CROSS_PRODUCT(v, u, *normal);
  254.   k1 = black_noise(position) * 2.0 - 1.0;
  255.   position->x += k1;
  256.   position->y += k1;
  257.   position->z += k1;
  258.   k2 = black_noise(position) * 2.0 - 1.0;
  259.   k2 *= SQRT(1.0 - SQR(k1)) * round->scale;
  260.   k1 *= round->scale;
  261.   normal->x += k1 * u.x + k2 * v.x;
  262.   normal->y += k1 * u.y + k2 * v.y;
  263.   normal->z += k1 * u.z + k2 * v.z;
  264.   NORMALIZE(*normal);
  265. }
  266. static void
  267. bozo_texture(position, normal, old_surface, texture)
  268.   xyz_ptr         position, normal;
  269.   surface_ptr     old_surface;
  270.   texture_ptr     texture;
  271. {
  272.   REG real        t;
  273.   xyz_struct      temp;
  274.   rgb_struct      color;
  275.   bozo_ptr        bozo;
  276.  
  277.   bozo = (bozo_ptr) texture->data;
  278.   if (bozo->turbulence > ROUNDOFF)
  279.   {
  280.     turbulence2(position, &temp);
  281.     position->x += temp.x * bozo->turbulence;
  282.     position->y += temp.y * bozo->turbulence;
  283.     position->z += temp.z * bozo->turbulence;
  284.   }
  285.   t = black_noise(position);
  286.   if (bozo->color != NULL)
  287.   {
  288.     interpolate(t, bozo->color, &color);
  289.     SCALE(old_surface->color, color.r, color.g, color.b);
  290.     return;
  291.   }
  292.   if (t < 0.4)
  293.   {
  294.     SCALE(old_surface->color, 1.0, 1.0, 1.0);
  295.     return;
  296.   }
  297.   if (t < 0.6)
  298.   {
  299.     SCALE(old_surface->color, 0.5, 1.0, 0.5);
  300.     return;
  301.   }
  302.   if (t < 0.8)
  303.   {
  304.     SCALE(old_surface->color, 0.5, 0.5, 1.0);
  305.     return;
  306.   }
  307.   SCALE(old_surface->color, 1.0, 0.5, 0.5);
  308. }
  309. static void
  310. ripples_texture(position, normal, old_surface, texture)
  311.   xyz_ptr         position, normal;
  312.   surface_ptr     old_surface;
  313.   texture_ptr     texture;
  314. {
  315.   int             i;
  316.   REG real        k, l, t;
  317.   xyz_struct      temp;
  318.   ripples_ptr     ripples;
  319.  
  320.   ripples = (ripples_ptr) texture->data;
  321.   k = ripples->scale / (real) WAVES_MAX;
  322.   for (i = 0; i < WAVES_MAX; POSINC(i))
  323.   {
  324.     temp.x = position->x - wave.source[i].x;
  325.     temp.y = position->y - wave.source[i].y;
  326.     temp.z = position->z - wave.source[i].z;
  327.     l = LENGTH(temp);
  328.     if (l < ROUNDOFF)
  329.       l = 1.0;
  330.     t = l * ripples->frequency + ripples->phase;
  331.     t = cycloidal(t) * k / l;
  332.     normal->x += temp.x * t;
  333.     normal->y += temp.y * t;
  334.     normal->z += temp.z * t;
  335.   }
  336.   NORMALIZE(*normal);
  337. }
  338. static void
  339. waves_texture(position, normal, old_surface, texture)
  340.   xyz_ptr         position, normal;
  341.   surface_ptr     old_surface;
  342.   texture_ptr     texture;
  343. {
  344.   int             i;
  345.   REG real        k, l, t;
  346.   xyz_struct      temp;
  347.   waves_ptr       waves;
  348.  
  349.   waves = (waves_ptr) texture->data;
  350.   k = waves->scale / (real) WAVES_MAX;
  351.   for (i = 0; i < WAVES_MAX; POSINC(i))
  352.   {
  353.     temp.x = position->x - wave.source[i].x;
  354.     temp.y = position->y - wave.source[i].y;
  355.     temp.z = position->z - wave.source[i].z;
  356.     l = LENGTH(temp);
  357.     if (l < ROUNDOFF)
  358.       l = 1.0;
  359.     t = l * waves->frequency * wave.frequency[i] + waves->phase;
  360.     t = cycloidal(t) * k * wave.frequency[i] / l;
  361.     normal->x += temp.x * t;
  362.     normal->y += temp.y * t;
  363.     normal->z += temp.z * t;
  364.   }
  365.   NORMALIZE(*normal);
  366. }
  367. static void
  368. spotted_texture(position, normal, old_surface, texture)
  369.   xyz_ptr         position, normal;
  370.   surface_ptr     old_surface;
  371.   texture_ptr     texture;
  372. {
  373.   REG real        t;
  374.   rgb_struct      color;
  375.   spotted_ptr     spotted;
  376.  
  377.   spotted = (spotted_ptr) texture->data;
  378.   t = black_noise(position);
  379.   if (spotted->color != NULL)
  380.   {
  381.     interpolate(t, spotted->color, &color);
  382.     SCALE(old_surface->color, color.r, color.g, color.b);
  383.     return;
  384.   }
  385.   SCALE(old_surface->color, t, t, t);
  386. }
  387. static void
  388. dents_texture(position, normal, old_surface, texture)
  389.   xyz_ptr         position, normal;
  390.   surface_ptr     old_surface;
  391.   texture_ptr     texture;
  392. {
  393.   REG real        t;
  394.   xyz_struct      temp;
  395.   dents_ptr       dents;
  396.  
  397.   dents = (dents_ptr) texture->data;
  398.   t = black_noise(position) * dents->scale;
  399.   black_noise2(position, &temp);
  400.   normal->x += temp.x * t;
  401.   normal->y += temp.y * t;
  402.   normal->z += temp.z * t;
  403.   NORMALIZE(*normal);
  404. }
  405. static void
  406. agate_texture(position, normal, old_surface, texture)
  407.   xyz_ptr         position, normal;
  408.   surface_ptr     old_surface;
  409.   texture_ptr     texture;
  410. {
  411.   REG real        t, hue;
  412.   rgb_struct      color;
  413.   agate_ptr       agate;
  414.  
  415.   agate = (agate_ptr) texture->data;
  416.   t = (cycloidal(1.3 * turbulence(position) + 1.1 * position->z) + 1.0) * 0.5;
  417.   t = POWER(t, 0.77);
  418.   if (agate->color != NULL)
  419.   {
  420.     interpolate(t, agate->color, &color);
  421.     SCALE(old_surface->color, color.r, color.g, color.b);
  422.     return;
  423.   }
  424.   hue = 1.0 - t;
  425.   if (t < 0.5)
  426.   {
  427.     SCALE(old_surface->color, 1.0 - t / 10.0, 1.0 - t / 5.0, hue);
  428.     return;
  429.   }
  430.   if (t < 0.6)
  431.   {
  432.     SCALE(old_surface->color, 0.9, 0.7, hue);
  433.     return;
  434.   }
  435.   SCALE(old_surface->color, 0.6 + hue, 0.3 + hue, hue);
  436. }
  437. static void
  438. wrinkles_texture(position, normal, old_surface, texture)
  439.   xyz_ptr         position, normal;
  440.   surface_ptr     old_surface;
  441.   texture_ptr     texture;
  442. {
  443.   int             i;
  444.   REG real        scale;
  445.   xyz_struct      r, p, value;
  446.   wrinkles_ptr    wrinkles;
  447.  
  448.   wrinkles = (wrinkles_ptr) texture->data;
  449.   black_noise2(position, &r);
  450.   scale = 2.0;
  451.   for (i = 1; i < 10; POSINC(i))
  452.   {
  453.     p.x = position->x * scale;
  454.     p.y = position->y * scale;
  455.     p.z = position->z * scale;
  456.     black_noise2(&p, &value);
  457.     r.x += ABS(value.x / scale);
  458.     r.y += ABS(value.y / scale);
  459.     r.z += ABS(value.z / scale);
  460.     scale *= 2.0;
  461.   }
  462.   normal->x += r.x * wrinkles->scale;
  463.   normal->y += r.y * wrinkles->scale;
  464.   normal->z += r.z * wrinkles->scale;
  465.   NORMALIZE(*normal);
  466. }
  467. static void
  468. granite_texture(position, normal, old_surface, texture)
  469.   xyz_ptr         position, normal;
  470.   surface_ptr     old_surface;
  471.   texture_ptr     texture;
  472. {
  473.   int             i;
  474.   REG real        t, scale;
  475.   xyz_struct      p;
  476.   rgb_struct      color;
  477.   granite_ptr     granite;
  478.  
  479.   granite = (granite_ptr) texture->data;
  480.   t = 0.0;
  481.   scale = 2.0;
  482.   for (i = 0; i < 6; POSINC(i))
  483.   {
  484.     p.x = position->x * scale * 4.0;
  485.     p.y = position->y * scale * 4.0;
  486.     p.z = position->z * scale * 4.0;
  487.     t += black_noise(&p) / scale;
  488.     scale *= 2.0;
  489.   }
  490.   if (granite->color != NULL)
  491.   {
  492.     interpolate(t, granite->color, &color);
  493.     SCALE(old_surface->color, color.r, color.g, color.b);
  494.     return;
  495.   }
  496.   SCALE(old_surface->color, t, t, t);
  497. }
  498. static void
  499. gradient_texture(position, normal, old_surface, texture)
  500.   xyz_ptr         position, normal;
  501.   surface_ptr     old_surface;
  502.   texture_ptr     texture;
  503. {
  504.   REG real        t;
  505.   xyz_struct      temp;
  506.   rgb_struct      color;
  507.   gradient_ptr    gradient;
  508.  
  509.   gradient = (gradient_ptr) texture->data;
  510.   if (gradient->turbulence > ROUNDOFF)
  511.   {
  512.     turbulence2(position, &temp);
  513.     position->x += temp.x * gradient->turbulence;
  514.     position->y += temp.y * gradient->turbulence;
  515.     position->z += temp.z * gradient->turbulence;
  516.   }
  517.   t = 0.0;
  518.   if (ABS(gradient->direction.x) > ROUNDOFF)
  519.     t += FRAC(gradient->direction.x * position->x);
  520.   if (ABS(gradient->direction.y) > ROUNDOFF)
  521.     t += FRAC(gradient->direction.y * position->y);
  522.   if (ABS(gradient->direction.z) > ROUNDOFF)
  523.     t += FRAC(gradient->direction.z * position->z);
  524.   t = FRAC(t);
  525.  
  526.   if (gradient->color != NULL)
  527.   {
  528.     interpolate(t, gradient->color, &color);
  529.     SCALE(old_surface->color, color.r, color.g, color.b);
  530.     return;
  531.   }
  532.   SCALE(old_surface->color, t, t, t);
  533. }
  534. static void
  535. image_map_texture(position, normal, old_surface, texture)
  536.   xyz_ptr         position, normal;
  537.   surface_ptr     old_surface;
  538.   texture_ptr     texture;
  539. {
  540.   REG unsigned char value;
  541.   REG long        u, v, offset;
  542.   xyz_struct      temp;
  543.   image_map_ptr   image_map;
  544.  
  545.   image_map = (image_map_ptr) texture->data;
  546.   if (image_map->turbulence > ROUNDOFF)
  547.   {
  548.     turbulence2(position, &temp);
  549.     position->x += temp.x * image_map->turbulence;
  550.     position->y += temp.y * image_map->turbulence;
  551.     position->z += temp.z * image_map->turbulence;
  552.   }
  553.   switch (image_map->u)
  554.   {
  555.   case X_AXIS:
  556.     if (image_map->once AND((position->x < 0.0) OR(position->x > 1.0)))
  557.       return;
  558.     u = (long) ((1.0 - FRAC(position->x)) * (real) (image_map->width));
  559.     break;
  560.   case Y_AXIS:
  561.     if (image_map->once AND((position->y < 0.0) OR(position->y > 1.0)))
  562.       return;
  563.     u = (long) ((1.0 - FRAC(position->y)) * (real) (image_map->width));
  564.     break;
  565.   case Z_AXIS:
  566.     if (image_map->once AND((position->z < 0.0) OR(position->z > 1.0)))
  567.       return;
  568.     u = (long) ((1.0 - FRAC(position->z)) * (real) (image_map->width));
  569.     break;
  570.   }
  571.   switch (image_map->v)
  572.   {
  573.   case X_AXIS:
  574.     if (image_map->once AND((position->x < 0.0) OR(position->x > 1.0)))
  575.       return;
  576.     v = (long) ((1.0 - FRAC(position->x)) * (real) (image_map->height));
  577.     break;
  578.   case Y_AXIS:
  579.     if (image_map->once AND((position->y < 0.0) OR(position->y > 1.0)))
  580.       return;
  581.     v = (long) ((1.0 - FRAC(position->y)) * (real) (image_map->height));
  582.     break;
  583.   case Z_AXIS:
  584.     if (image_map->once AND((position->z < 0.0) OR(position->z > 1.0)))
  585.       return;
  586.     v = (long) ((1.0 - FRAC(position->z)) * (real) (image_map->height));
  587.     break;
  588.   }
  589.   if ((u < 0) OR(u >= (long) image_map->width)
  590.       OR(v < 0) OR(v >= (long) image_map->height))
  591.   { 
  592.     /* ToDo: fix this. A one pixel error sometimes occurs in middle axis of a sphere.  
  593.      * Bad distance is returned by intersec.c and this causes test to fail and image 
  594.      * to abort. I have verified that it occurs even in non-image mapping but all that
  595.      * happens is that the pixel is set to the background color.  This only seems to 
  596.      * occur on the MAC (anyone else see this on other systems?). -- reid.
  597.      * ===> to see the error, enable this test <===
  598.     runtime_abort("bad 2D MAPPING COORDINATES");
  599.      */
  600.     u = 0;
  601.     v = 0;
  602.   }
  603.  
  604.   /* The PPM input_output_format is 1, while PIC input_output_format is 0.
  605.    * This moves the offset to one less byte if we have PPM files. 
  606.    */
  607.   offset = (v * (long) (image_map->width) + u) * 3 + 4 - output_format;
  608.  
  609.   SEEK(image_map->image, offset);
  610.   if (IO_status != IO_OK)
  611.     runtime_abort("unable to seek IMAGE");
  612.   READ_CHAR(image_map->image, value);
  613.   old_surface->color.r = (real) (value) / 255.0;
  614.   READ_CHAR(image_map->image, value);
  615.   old_surface->color.g = (real) (value) / 255.0;
  616.   READ_CHAR(image_map->image, value);
  617.   old_surface->color.b = (real) (value) / 255.0;
  618. }
  619. static void
  620. gloss_texture(position, normal, old_surface, texture)
  621.   xyz_ptr         position, normal;
  622.   surface_ptr     old_surface;
  623.   texture_ptr     texture;
  624. {
  625.   REG real        t1, t2;
  626.   gloss_ptr       gloss;
  627.  
  628.   gloss = (gloss_ptr) texture->data;
  629.   t1 = black_noise(position) * gloss->scale;
  630.   t2 = 1.0 - t1;
  631.   old_surface->specular.r += old_surface->diffuse.r * t1;
  632.   old_surface->specular.g += old_surface->diffuse.g * t1;
  633.   old_surface->specular.b += old_surface->diffuse.b * t1;
  634.   old_surface->diffuse.r *= t2;
  635.   old_surface->diffuse.g *= t2;
  636.   old_surface->diffuse.b *= t2;
  637.   old_surface->phong_factor = 1.0 + 1000.0 * t1;
  638. }
  639. static void
  640. bump3_texture(position, normal, old_position, texture)
  641.   xyz_ptr         position, normal, old_position;
  642.   texture_ptr     texture;
  643. {
  644.   xyz_struct      p, n, u, v, p1, p2, p3, p4;
  645.   bump3_ptr       bump3;
  646.  
  647.   bump3 = (bump3_ptr) texture->data;
  648.   if (bump3->scale < ROUNDOFF)
  649.     return;
  650.   v.x = 0.0;
  651.   v.y = 1.0;
  652.   v.z = 0.0;
  653.   if (ABS(DOT_PRODUCT(*normal, v)) > 1.0 - ROUNDOFF)
  654.   {
  655.     v.x = 1.0;
  656.     v.y = 0.0;
  657.   }
  658.   CROSS_PRODUCT(u, *normal, v);
  659.   NORMALIZE(u);
  660.   CROSS_PRODUCT(v, u, *normal);
  661.   u.x *= bump3->size;
  662.   u.y *= bump3->size;
  663.   u.z *= bump3->size;
  664.   v.x *= bump3->size;
  665.   v.y *= bump3->size;
  666.   v.z *= bump3->size;
  667.   STRUCT_ASSIGN(p, *position);
  668.   black_noise2(position, &n);
  669.   position->x += n.x * bump3->scale;
  670.   position->y += n.y * bump3->scale;
  671.   position->z += n.z * bump3->scale;
  672.   old_position->x += n.x * bump3->scale;
  673.   old_position->y += n.y * bump3->scale;
  674.   old_position->z += n.z * bump3->scale;
  675.   p1.x = p.x + v.x;
  676.   p1.y = p.y + v.y;
  677.   p1.z = p.z + v.z;
  678.   black_noise2(&p1, &n);
  679.   p1.x += n.x * bump3->scale - position->x;
  680.   p1.y += n.y * bump3->scale - position->y;
  681.   p1.z += n.z * bump3->scale - position->z;
  682.   p2.x = p.x + u.x;
  683.   p2.y = p.y + u.y;
  684.   p2.z = p.z + u.z;
  685.   black_noise2(&p2, &n);
  686.   p2.x += n.x * bump3->scale - position->x;
  687.   p2.y += n.y * bump3->scale - position->y;
  688.   p2.z += n.z * bump3->scale - position->z;
  689.   p3.x = p.x - v.x;
  690.   p3.y = p.y - v.y;
  691.   p3.z = p.z - v.z;
  692.   black_noise2(&p3, &n);
  693.   p3.x += n.x * bump3->scale - position->x;
  694.   p3.y += n.y * bump3->scale - position->y;
  695.   p3.z += n.z * bump3->scale - position->z;
  696.   p4.x = p.x - u.x;
  697.   p4.y = p.y - u.y;
  698.   p4.z = p.z - u.z;
  699.   black_noise2(&p4, &n);
  700.   p4.x += n.x * bump3->scale - position->x;
  701.   p4.y += n.y * bump3->scale - position->y;
  702.   p4.z += n.z * bump3->scale - position->z;
  703.   CROSS_PRODUCT(*normal, p1, p2);
  704.   CROSS_PRODUCT(n, p2, p3);
  705.   normal->x += n.x;
  706.   normal->y += n.y;
  707.   normal->z += n.z;
  708.   CROSS_PRODUCT(n, p3, p4);
  709.   normal->x += n.x;
  710.   normal->y += n.y;
  711.   normal->z += n.z;
  712.   CROSS_PRODUCT(n, p4, p1);
  713.   normal->x += n.x;
  714.   normal->y += n.y;
  715.   normal->z += n.z;
  716.   NORMALIZE(*normal);
  717. }
  718. /***** End of textures *****/
  719. void
  720. surface_texture(old_position, normal, old_surface, texture)
  721.   xyz_ptr         old_position, normal;
  722.   surface_ptr     old_surface;
  723.   texture_ptr     texture;
  724. {
  725.   xyz_struct      position, temp;
  726.  
  727.   STRUCT_ASSIGN(position, *old_position);
  728.   /* Apply texture(s) */
  729.   for (; texture != NULL; texture = (texture_ptr) texture->next)
  730.   {
  731.     if (texture->transf != NULL)
  732.     {
  733.       /* Transform position */
  734.       STRUCT_ASSIGN(temp, position);
  735.       transform(texture->transf, &temp, &position);
  736.     }
  737.     switch (texture->type)
  738.     {
  739.     case NULL_TYPE:
  740.       break;
  741.     case CHECKER_TYPE:
  742.       checker_texture(&position, normal, old_surface, texture);
  743.       break;
  744.     case BLOTCH_TYPE:
  745.       blotch_texture(&position, normal, old_surface, texture);
  746.       break;
  747.     case BUMP_TYPE:
  748.       bump_texture(&position, normal, old_surface, texture);
  749.       break;
  750.     case MARBLE_TYPE:
  751.       marble_texture(&position, normal, old_surface, texture);
  752.       break;
  753.     case FBM_TYPE:
  754.       fbm_texture(&position, normal, old_surface, texture);
  755.       break;
  756.     case FBM_BUMP_TYPE:
  757.       fbm_bump_texture(&position, normal, old_surface, texture);
  758.       break;
  759.     case WOOD_TYPE:
  760.       wood_texture(&position, normal, old_surface, texture);
  761.       break;
  762.     case ROUND_TYPE:
  763.       round_texture(&position, normal, old_surface, texture);
  764.       break;
  765.     case BOZO_TYPE:
  766.       bozo_texture(&position, normal, old_surface, texture);
  767.       break;
  768.     case RIPPLES_TYPE:
  769.       ripples_texture(&position, normal, old_surface, texture);
  770.       break;
  771.     case WAVES_TYPE:
  772.       waves_texture(&position, normal, old_surface, texture);
  773.       break;
  774.     case SPOTTED_TYPE:
  775.       spotted_texture(&position, normal, old_surface, texture);
  776.       break;
  777.     case DENTS_TYPE:
  778.       dents_texture(&position, normal, old_surface, texture);
  779.       break;
  780.     case AGATE_TYPE:
  781.       agate_texture(&position, normal, old_surface, texture);
  782.       break;
  783.     case WRINKLES_TYPE:
  784.       wrinkles_texture(&position, normal, old_surface, texture);
  785.       break;
  786.     case GRANITE_TYPE:
  787.       granite_texture(&position, normal, old_surface, texture);
  788.       break;
  789.     case GRADIENT_TYPE:
  790.       gradient_texture(&position, normal, old_surface, texture);
  791.       break;
  792.     case IMAGE_MAP_TYPE:
  793.       image_map_texture(&position, normal, old_surface, texture);
  794.       break;
  795.     case GLOSS_TYPE:
  796.       gloss_texture(&position, normal, old_surface, texture);
  797.       break;
  798.     case BUMP3_TYPE:
  799.       bump3_texture(&position, normal, old_position, texture);
  800.       break;
  801.     }
  802.   }
  803. }
  804.