home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / povsrc31.zip / texture.c < prev    next >
C/C++ Source or Header  |  2001-02-02  |  40KB  |  1,766 lines

  1. /****************************************************************************
  2. *                texture.c
  3. *
  4. *  This module implements texturing functions such as noise, turbulence and
  5. *  texture transformation functions. The actual texture routines are in the
  6. *  files pigment.c & normal.c.
  7. *  The noise function used here is the one described by Ken Perlin in
  8. *  "Hypertexture", SIGGRAPH '89 Conference Proceedings page 253.
  9. *
  10. *  from Persistence of Vision(tm) Ray Tracer
  11. *  Copyright 1996,1999 Persistence of Vision Team
  12. *---------------------------------------------------------------------------
  13. *  NOTICE: This source code file is provided so that users may experiment
  14. *  with enhancements to POV-Ray and to port the software to platforms other
  15. *  than those supported by the POV-Ray Team.  There are strict rules under
  16. *  which you are permitted to use this file.  The rules are in the file
  17. *  named POVLEGAL.DOC which should be distributed with this file.
  18. *  If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  19. *  Team Coordinator by email to team-coord@povray.org or visit us on the web at
  20. *  http://www.povray.org. The latest version of POV-Ray may be found at this site.
  21. *
  22. * This program is based on the popular DKB raytracer version 2.12.
  23. * DKBTrace was originally written by David K. Buck.
  24. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  25. *
  26. *****************************************************************************/
  27.  
  28. /*
  29.    Some texture ideas garnered from SIGGRAPH '85 Volume 19 Number 3, 
  30.    "An Image Synthesizer" By Ken Perlin.
  31.    Further Ideas Garnered from "The RenderMan Companion" (Addison Wesley)
  32. */
  33.  
  34. #include "frame.h"
  35. #include "povray.h"
  36. #include "vector.h"
  37. #include "povproto.h"
  38. #include "texture.h"
  39. #include "image.h"
  40. #include "matrices.h"
  41. #include "normal.h"
  42. #include "pigment.h"
  43.  
  44. /*****************************************************************************
  45. * Local preprocessor defines
  46. ******************************************************************************/
  47.  
  48. /* Ridiculously large scaling values */
  49.  
  50. #define MINX (-10000)
  51. #define MINY MINX
  52. #define MINZ MINX
  53.  
  54.   /* YS feb 1 2001
  55.           Fixed sin_wave and scallop_wave bug
  56. #define SINTABSIZE 1000
  57.   see cycloidal() for more info
  58. */
  59. #define REALSCALE (2.0 / 65535.0)
  60.  
  61. #define SCURVE(a) ((a)*(a)*(3.0-2.0*(a)))
  62.  
  63. /*****************************************************************************
  64. * Local typedefs
  65. ******************************************************************************/
  66.  
  67.  
  68.  
  69. /*****************************************************************************
  70. * Local variables
  71. ******************************************************************************/
  72.  
  73.   /* YS feb 1 2001
  74.           Fixed sin_wave and scallop_wave bug
  75.   see cycloidal() for more info
  76. static DBL *sintab;
  77. */
  78. unsigned int Number_Of_Waves = 10;    /* dmf */
  79. DBL *frequency;                       /* dmf */
  80. VECTOR *Wave_Sources;                 /* dmf */
  81.  
  82. short *hashTable;
  83.  
  84. DBL RTable[267] =
  85. {
  86.          -1,    0.604974,   -0.937102,    0.414115,    0.576226,  -0.0161593,
  87.    0.432334,    0.103685,    0.590539,   0.0286412,     0.46981,    -0.84622,
  88.  -0.0734112,   -0.304097,    -0.40206,   -0.210132,   -0.919127,    0.652033,
  89.    -0.83151,   -0.183948,   -0.671107,    0.852476,    0.043595,   -0.404532,
  90.     0.75494,   -0.335653,    0.618433,    0.605707,    0.708583,   -0.477195,
  91.    0.899474,    0.490623,    0.221729,   -0.400381,   -0.853727,   -0.932586,
  92.    0.659113,    0.961303,    0.325948,   -0.750851,    0.842466,    0.734401,
  93.   -0.649866,    0.394491,   -0.466056,   -0.434073,    0.109026,   0.0847028,
  94.   -0.738857,    0.241505,     0.16228,    -0.71426,   -0.883665,   -0.150408,
  95.    -0.90396,   -0.686549,   -0.785214,    0.488548,   0.0246433,    0.142473,
  96.   -0.602136,    0.375845, -0.00779736,    0.498955,   -0.268147,    0.856382,
  97.   -0.386007,   -0.596094,   -0.867735,   -0.570977,   -0.914366,     0.28896,
  98.    0.672206,   -0.233783,     0.94815,    0.895262,    0.343252,   -0.173388,
  99.   -0.767971,   -0.314748,    0.824308,   -0.342092,    0.721431,    -0.24004,
  100.    -0.63653,    0.553277,    0.376272,    0.158984,   -0.452659,    0.396323,
  101.   -0.420676,   -0.454154,    0.122179,    0.295857,   0.0664225,   -0.202075,
  102.   -0.724788,    0.453513,    0.224567,   -0.908812,    0.176349,   -0.320516,
  103.   -0.697139,    0.742702,   -0.900786,    0.471489,   -0.133532,    0.119127,
  104.   -0.889769,    -0.23183,   -0.669673,   -0.046891,   -0.803433,   -0.966735,
  105.    0.475578,   -0.652644,   0.0112459,   -0.730007,    0.128283,    0.145647,
  106.   -0.619318,    0.272023,    0.392966,    0.646418,  -0.0207675,   -0.315908,
  107.    0.480797,    0.535668,   -0.250172,    -0.83093,   -0.653773,   -0.443809,
  108.    0.119982,   -0.897642,     0.89453,    0.165789,    0.633875,   -0.886839,
  109.    0.930877,   -0.537194,    0.587732,    0.722011,   -0.209461,  -0.0424659,
  110.   -0.814267,   -0.919432,    0.280262,    -0.66302,   -0.558099,   -0.537469,
  111.   -0.598779,    0.929656,   -0.170794,   -0.537163,    0.312581,    0.959442,
  112.    0.722652,    0.499931,    0.175616,   -0.534874,   -0.685115,    0.444999,
  113.     0.17171,    0.108202,   -0.768704,   -0.463828,    0.254231,    0.546014,
  114.    0.869474,    0.875212,   -0.944427,    0.130724,   -0.110185,    0.312184,
  115.    -0.33138,   -0.629206,   0.0606546,    0.722866,  -0.0979477,    0.821561,
  116.   0.0931258,   -0.972808,   0.0318151,   -0.867033,   -0.387228,    0.280995,
  117.   -0.218189,   -0.539178,   -0.427359,   -0.602075,    0.311971,    0.277974,
  118.    0.773159,    0.592493,  -0.0331884,   -0.630854,   -0.269947,    0.339132,
  119.    0.581079,    0.209461,   -0.317433,   -0.284993,    0.181323,    0.341634,
  120.    0.804959,   -0.229572,   -0.758907,   -0.336721,    0.605463,   -0.991272,
  121.  -0.0188754,   -0.300191,    0.368307,   -0.176135,     -0.3832,   -0.749569,
  122.     0.62356,   -0.573938,    0.278309,   -0.971313,    0.839994,   -0.830686,
  123.    0.439078,     0.66128,    0.694514,   0.0565042,     0.54342,   -0.438804,
  124.  -0.0228428,   -0.687068,    0.857267,    0.301991,   -0.494255,   -0.941039,
  125.    0.775509,    0.410575,   -0.362081,   -0.671534,   -0.348379,    0.932433,
  126.    0.886442,    0.868681,   -0.225666,   -0.062211,  -0.0976425,   -0.641444,
  127.   -0.848112,    0.724697,    0.473503,    0.998749,    0.174701,    0.559625,
  128.   -0.029099,   -0.337392,   -0.958129,   -0.659785,    0.236042,   -0.246937,
  129.    0.659449,   -0.027512,    0.821897,   -0.226215,   0.0181735,    0.500481,
  130.   -0.420127,   -0.427878,    0.566186
  131. };
  132.  
  133. static unsigned long int next_rand = 1;
  134.  
  135.  
  136.  
  137. /*****************************************************************************
  138. * Static functions
  139. ******************************************************************************/
  140.  
  141. static void InitTextureTable (void);
  142. static TEXTURE *Copy_Materials (TEXTURE *Old);
  143.  
  144.  
  145. /*****************************************************************************
  146. *
  147. * FUNCTION
  148. *
  149. *   Initialize_Noise()
  150. *
  151. * INPUT
  152. *   
  153. * OUTPUT
  154. *
  155. * RETURNS
  156. *   
  157. * AUTHOR
  158. *
  159. *   POV-Ray Team
  160. *   
  161. * DESCRIPTION
  162. *
  163. * CHANGES
  164. *
  165. ******************************************************************************/
  166.  
  167. void Initialize_Noise()
  168. {
  169.   register unsigned int i;
  170.   VECTOR point;
  171.  
  172.   InitTextureTable();
  173.  
  174.   /* YS feb 1 2001
  175.           Fixed sin_wave and scallop_wave bug
  176.       see cycloidal() for more info
  177.   sintab = (DBL *)POV_MALLOC(SINTABSIZE * sizeof(DBL), "sine table");
  178. */
  179.   /* dmf */
  180.   frequency = (DBL *)POV_MALLOC(Number_Of_Waves * sizeof(DBL), "wave frequency table: use lower Number_Of_Waves");
  181.  
  182.   /* dmf */
  183.   Wave_Sources = (VECTOR *)POV_MALLOC(Number_Of_Waves * sizeof(VECTOR), "wave sources table: use lower Number_Of_Waves");
  184.  
  185.   /* YS feb 1 2001
  186.           Fixed sin_wave and scallop_wave bug
  187.       see cycloidal() for more info
  188.   for (i = 0 ; i < SINTABSIZE ; i++)
  189.   {
  190.     sintab[i] = sin((DBL)i / SINTABSIZE * TWO_M_PI);
  191.   }
  192. */
  193.   for (i = 0 ; i < Number_Of_Waves ; i++)
  194.   {
  195.     Make_Vector(point,(DBL)i,0.0,0.0);
  196.     DNoise(point, point);
  197.     VNormalize(Wave_Sources[i], point);
  198.     frequency[i] = FRAND() + 0.01;
  199.   }
  200. }
  201.  
  202.  
  203.  
  204. /*****************************************************************************
  205. *
  206. * FUNCTION
  207. *
  208. *   InitTextureTable()
  209. *
  210. * INPUT
  211. *
  212. * OUTPUT
  213. *
  214. * RETURNS
  215. *
  216. * AUTHOR
  217. *
  218. *   POV-Ray Team
  219. *
  220. * DESCRIPTION
  221. *
  222. * CHANGES
  223. *
  224. ******************************************************************************/
  225.  
  226. static void InitTextureTable()
  227. {
  228.   short int i, j, temp;
  229.  
  230.   POV_SRAND(0);
  231.  
  232.   hashTable = (short int *)POV_MALLOC(4096*sizeof(short int), "hash table");
  233.  
  234.   for (i = 0; i < 4096; i++)
  235.   {
  236.     hashTable[i] = i;
  237.   }
  238.  
  239.   for (i = 4095; i >= 0; i--)
  240.   {
  241.     j = POV_RAND() % 4096;
  242.     temp = hashTable[i];
  243.     hashTable[i] = hashTable[j];
  244.     hashTable[j] = temp;
  245.   }
  246. }
  247.  
  248.  
  249.  
  250. /*****************************************************************************
  251. *
  252. * FUNCTION
  253. *
  254. *   Free_Noise_Tables()
  255. *
  256. * INPUT
  257. *   
  258. * OUTPUT
  259. *   
  260. * RETURNS
  261. *   
  262. * AUTHOR
  263. *
  264. *   POV-Ray Team
  265. *   
  266. * DESCRIPTION
  267. *
  268. * CHANGES
  269. *
  270. ******************************************************************************/
  271.  
  272. void Free_Noise_Tables()
  273. {
  274.   /* YS feb 1 2001
  275.           Fixed sin_wave and scallop_wave bug
  276.       see cycloidal() for more info
  277.   */
  278.    if (frequency != NULL) 
  279.   {
  280. /*    POV_FREE(sintab);*/
  281.     POV_FREE(hashTable);
  282.     POV_FREE(frequency);
  283.     POV_FREE(Wave_Sources);
  284.     
  285. /*    sintab       = NULL;*/
  286.     hashTable    = NULL;
  287.     frequency    = NULL;
  288.     Wave_Sources = NULL;
  289.   }
  290. }
  291.  
  292.  
  293.  
  294. /*****************************************************************************
  295. *
  296. * FUNCTION
  297. *
  298. *   Noise
  299. *
  300. * INPUT
  301. *
  302. *   EPoint -- 3-D point at which noise is evaluated
  303. *
  304. * OUTPUT
  305. *   
  306. * RETURNS
  307. *
  308. *   DBL noise value
  309. *   
  310. * AUTHOR
  311. *
  312. *   Robert Skinner based on Ken Perlin
  313. *   
  314. * DESCRIPTION
  315. *
  316. * CHANGES
  317. *   Modified by AAC to ensure uniformly distributed clamped values
  318. *   between 0 and 1.0...
  319. *
  320. ******************************************************************************/
  321. #ifdef NoiseTranslateFixPatch
  322. DBL Noise(VECTOR EPoint)
  323. {
  324.   DBL x, y, z;
  325.   DBL *mp;
  326.   long ix, iy, iz, jx, jy, jz, tmp;
  327.   int ixiy_hash, ixjy_hash, jxiy_hash, jxjy_hash;
  328.   
  329.   DBL sx, sy, sz, tx, ty, tz;
  330.   DBL sum = 0.0;
  331.   
  332.   DBL x_ix, x_jx, y_iy, y_jy, z_iz, z_jz, txty, sxty, txsy, sxsy;
  333.   
  334.   x = EPoint[X];
  335.   y = EPoint[Y];
  336.   z = EPoint[Z];
  337.   
  338.   /* its equivalent integer lattice point. */
  339.   /* ix = (long)x; iy = (long)y; iz = (long)z; */
  340.                 /* JB fix for the range problem */
  341.   tmp = (x>=0)?(long)x:(long)(x-(1-EPSILON));
  342.   ix = (tmp-MINX)&0xFFF;
  343.   x_ix = x-tmp;
  344.     
  345.   tmp = (y>=0)?(long)y:(long)(y-(1-EPSILON));
  346.   iy = (tmp-MINY)&0xFFF;
  347.   y_iy = y-tmp;
  348.   
  349.   tmp = (z>=0)?(long)z:(long)(z-(1-EPSILON));
  350.   iz = (tmp-MINZ)&0xFFF;
  351.   z_iz = z-tmp;
  352.  
  353.   jx = (ix+1)&0xFFF; jy = (iy+1)&0xFFF; jz = (iz+1)&0xFFF;
  354.   
  355.   x_jx = x_ix-1; y_jy = y_iy-1; z_jz = z_iz-1;
  356.  
  357.   sx = SCURVE(x_ix); sy = SCURVE(y_iy); sz = SCURVE(z_iz);
  358.   
  359.   /* the complement values of sx,sy,sz */
  360.   tx = 1 - sx; ty = 1 - sy; tz = 1 - sz;
  361.   
  362.   /*
  363.    *  interpolate!
  364.    */
  365.   txty = tx * ty;
  366.   sxty = sx * ty;
  367.   txsy = tx * sy;
  368.   sxsy = sx * sy;
  369.   ixiy_hash = Hash2d(ix, iy);
  370.   jxiy_hash = Hash2d(jx, iy);
  371.   ixjy_hash = Hash2d(ix, jy);
  372.   jxjy_hash = Hash2d(jx, jy);
  373.   
  374.   mp = &RTable[(int) Hash1d(ixiy_hash, iz) & 0xFF];
  375.   sum = INCRSUMP(mp, (txty*tz), x_ix, y_iy, z_iz);
  376.   
  377.   mp = &RTable[(int) Hash1d(jxiy_hash, iz) & 0xFF];
  378.   sum += INCRSUMP(mp, (sxty*tz), x_jx, y_iy, z_iz);
  379.   
  380.   mp = &RTable[(int) Hash1d(ixjy_hash, iz) & 0xFF];
  381.   sum += INCRSUMP(mp, (txsy*tz), x_ix, y_jy, z_iz);
  382.   
  383.   mp = &RTable[(int) Hash1d(jxjy_hash, iz) & 0xFF];
  384.   sum += INCRSUMP(mp, (sxsy*tz), x_jx, y_jy, z_iz);
  385.   
  386.   mp = &RTable[(int) Hash1d(ixiy_hash, jz) & 0xFF];
  387.   sum += INCRSUMP(mp, (txty*sz), x_ix, y_iy, z_jz);
  388.   
  389.   mp = &RTable[(int) Hash1d(jxiy_hash, jz) & 0xFF];
  390.   sum += INCRSUMP(mp, (sxty*sz), x_jx, y_iy, z_jz);
  391.  
  392.   mp = &RTable[(int) Hash1d(ixjy_hash, jz) & 0xFF];
  393.   sum += INCRSUMP(mp, (txsy*sz), x_ix, y_jy, z_jz);
  394.   
  395.   mp = &RTable[(int) Hash1d(jxjy_hash, jz) & 0xFF];
  396.   sum += INCRSUMP(mp, (sxsy*sz), x_jx, y_jy, z_jz);
  397.   
  398. #ifdef DNoiseFixPatch
  399.   if(opts.unofficialVersion>=50)
  400.   {
  401.     /* details of range here:
  402.     Min, max: -1.05242, 0.988997
  403.     Mean: -0.0191481, Median: -0.535493, Std Dev: 0.256828
  404.  
  405.     We want to chage it to as close to [0,1] as possible.
  406.     */
  407.     sum += 1.05242;
  408.     sum *= 0.48985582;
  409.  
  410.     if (sum < 0.0)
  411.       sum = 0.0;
  412.     if (sum > 1.0)
  413.       sum = 1.0;
  414.   }
  415.   else
  416.   {
  417. #endif
  418.   sum = sum + 0.5;                     /* range at this point -0.5 - 0.5... */
  419.   
  420.   if (sum < 0.0)
  421.     sum = 0.0;
  422.   if (sum > 1.0)
  423.     sum = 1.0;
  424. #ifdef DNoiseFixPatch
  425.   }
  426. #endif
  427.   
  428.   return (sum);
  429. }
  430. #else
  431. DBL Noise(VECTOR EPoint)
  432. {
  433.   DBL x, y, z;
  434.   DBL *mp;
  435.   long ix, iy, iz, jx, jy, jz;
  436.   int ixiy_hash, ixjy_hash, jxiy_hash, jxjy_hash;
  437.   
  438.   DBL sx, sy, sz, tx, ty, tz;
  439.   DBL sum;
  440.   
  441.   DBL x_ix, x_jx, y_iy, y_jy, z_iz, z_jz, txty, sxty, txsy, sxsy;
  442.   
  443.   Increase_Counter(stats[Calls_To_Noise]);
  444.   
  445.   x = EPoint[X]-MINX;
  446.   y = EPoint[Y]-MINY;
  447.   z = EPoint[Z]-MINZ;
  448.   
  449.   /* its equivalent integer lattice point. */
  450.   ix = (long)x; iy = (long)y; iz = (long)z;
  451.   jx = ix + 1; jy = iy + 1; jz = iz + 1;
  452.   
  453.   sx = SCURVE(x - ix); sy = SCURVE(y - iy); sz = SCURVE(z - iz);
  454.   
  455.   /* the complement values of sx,sy,sz */
  456.   tx = 1.0 - sx; ty = 1.0 - sy; tz = 1.0 - sz;
  457.   
  458.   /*
  459.   *  interpolate!
  460.   */
  461.   x_ix = x - ix;
  462.   x_jx = x - jx;
  463.   y_iy = y - iy;
  464.   y_jy = y - jy;
  465.   z_iz = z - iz;
  466.   z_jz = z - jz;
  467.   txty = tx * ty;
  468.   sxty = sx * ty;
  469.   txsy = tx * sy;
  470.   sxsy = sx * sy;
  471.   ixiy_hash = Hash2d(ix, iy);
  472.   jxiy_hash = Hash2d(jx, iy);
  473.   ixjy_hash = Hash2d(ix, jy);
  474.   jxjy_hash = Hash2d(jx, jy);
  475.   
  476.   mp = &RTable[(int) Hash1d(ixiy_hash, iz) & 0xFF];
  477.   sum = INCRSUMP(mp, (txty*tz), x_ix, y_iy, z_iz);
  478.   
  479.   mp = &RTable[(int) Hash1d(jxiy_hash, iz) & 0xFF];
  480.   sum += INCRSUMP(mp, (sxty*tz), x_jx, y_iy, z_iz);
  481.   
  482.   mp = &RTable[(int) Hash1d(ixjy_hash, iz) & 0xFF];
  483.   sum += INCRSUMP(mp, (txsy*tz), x_ix, y_jy, z_iz);
  484.   
  485.   mp = &RTable[(int) Hash1d(jxjy_hash, iz) & 0xFF];
  486.   sum += INCRSUMP(mp, (sxsy*tz), x_jx, y_jy, z_iz);
  487.   
  488.   mp = &RTable[(int) Hash1d(ixiy_hash, jz) & 0xFF];
  489.   sum += INCRSUMP(mp, (txty*sz), x_ix, y_iy, z_jz);
  490.   
  491.   mp = &RTable[(int) Hash1d(jxiy_hash, jz) & 0xFF];
  492.   sum += INCRSUMP(mp, (sxty*sz), x_jx, y_iy, z_jz);
  493.  
  494.   mp = &RTable[(int) Hash1d(ixjy_hash, jz) & 0xFF];
  495.   sum += INCRSUMP(mp, (txsy*sz), x_ix, y_jy, z_jz);
  496.   
  497.   mp = &RTable[(int) Hash1d(jxjy_hash, jz) & 0xFF];
  498.   sum += INCRSUMP(mp, (sxsy*sz), x_jx, y_jy, z_jz);
  499.   
  500. #ifdef DNoiseFixPatch
  501.   if(opts.unofficialVersion>=50)
  502.   {
  503.     /* details of range here:
  504.     Min, max: -1.05242, 0.988997
  505.     Mean: -0.0191481, Median: -0.535493, Std Dev: 0.256828
  506.  
  507.     We want to chage it to as close to [0,1] as possible.
  508.     */
  509.     sum += 1.05242;
  510.     sum *= 0.48985582;
  511.  
  512.     if (sum < 0.0)
  513.       sum = 0.0;
  514.     if (sum > 1.0)
  515.       sum = 1.0;
  516.   }
  517.   else
  518.   {
  519. #endif
  520.   sum = sum + 0.5;                     /* range at this point -0.5 - 0.5... */
  521.   
  522.   if (sum < 0.0)
  523.     sum = 0.0;
  524.   if (sum > 1.0)
  525.     sum = 1.0;
  526. #ifdef DNoiseFixPatch
  527.   }
  528. #endif
  529.   
  530.   return (sum);
  531. }
  532.  
  533. #endif
  534.  
  535. /*****************************************************************************
  536. *
  537. * FUNCTION
  538. *
  539. *   DNoise
  540. *
  541. * INPUT
  542. *
  543. *   EPoint -- 3-D point at which noise is evaluated
  544. *   
  545. * OUTPUT
  546. *
  547. *   VECTOR result
  548. *   
  549. * RETURNS
  550. *   
  551. * AUTHOR
  552. *
  553. *   Robert Skinner based on Ken Perlin
  554. *   
  555. * DESCRIPTION
  556. *   Vector-valued version of "Noise"
  557. *
  558. * CHANGES
  559. *   Modified by AAC to ensure uniformly distributed clamped values
  560. *   between 0 and 1.0...
  561. *
  562. ******************************************************************************/
  563. #ifdef NoiseTranslateFixPatch
  564. void DNoise(VECTOR result, VECTOR EPoint)
  565. {
  566.   DBL x, y, z;
  567.   DBL *mp;
  568.   long ix, iy, iz, jx, jy, jz, tmp;
  569.   int ixiy_hash, ixjy_hash, jxiy_hash, jxjy_hash;
  570.   DBL x_ix, x_jx, y_iy, y_jy, z_iz, z_jz;
  571.   DBL s;
  572.   DBL sx, sy, sz, tx, ty, tz;
  573.   DBL txty, sxty, txsy, sxsy;
  574.   
  575.   Increase_Counter(stats[Calls_To_DNoise]);
  576.   
  577.   x = EPoint[X];
  578.   y = EPoint[Y];
  579.   z = EPoint[Z];
  580.   
  581.   /* its equivalent integer lattice point. */
  582.   /*ix = (long)x; iy = (long)y; iz = (long)z;
  583.   x_ix = x - ix; y_iy = y - iy; z_iz = z - iz;*/
  584.                 /* JB fix for the range problem */
  585.   tmp = (x>=0)?(long)x:(long)(x-(1-EPSILON));
  586.   ix = (tmp-MINX)&0xFFF;
  587.   x_ix = x-tmp;
  588.     
  589.   tmp = (y>=0)?(long)y:(long)(y-(1-EPSILON));
  590.   iy = (tmp-MINY)&0xFFF;
  591.   y_iy = y-tmp;
  592.   
  593.   tmp = (z>=0)?(long)z:(long)(z-(1-EPSILON));
  594.   iz = (tmp-MINZ)&0xFFF;
  595.   z_iz = z-tmp;
  596.  
  597.   jx = (ix + 1)&0xFFF; jy = (iy + 1)&0xFFF; jz = (iz + 1)&0xFFF;
  598.   
  599.   x_jx = x_ix-1; y_jy = y_iy-1; z_jz = z_iz-1;
  600.  
  601.   sx = SCURVE(x_ix); sy = SCURVE(y_iy); sz = SCURVE(z_iz);
  602.  
  603.   /* the complement values of sx,sy,sz */
  604.   tx = 1 - sx; ty = 1 - sy; tz = 1 - sz;
  605.   
  606.   /*
  607.    *  interpolate!
  608.    */
  609.   txty = tx * ty;
  610.   sxty = sx * ty;
  611.   txsy = tx * sy;
  612.   sxsy = sx * sy;
  613.   ixiy_hash = Hash2d(ix, iy);
  614.   jxiy_hash = Hash2d(jx, iy);
  615.   ixjy_hash = Hash2d(ix, jy);
  616.   jxjy_hash = Hash2d(jx, jy);
  617.   
  618.   mp = &RTable[(int) Hash1d(ixiy_hash, iz) & 0xFF];
  619.   s = txty*tz;
  620.   result[X] = INCRSUMP(mp, s, x_ix, y_iy, z_iz);
  621.   mp += 4;
  622.   result[Y] = INCRSUMP(mp, s, x_ix, y_iy, z_iz);
  623.   mp += 4;
  624.   result[Z] = INCRSUMP(mp, s, x_ix, y_iy, z_iz);
  625.   
  626.   mp = &RTable[(int) Hash1d(jxiy_hash, iz) & 0xFF];
  627.   s = sxty*tz;
  628.   result[X] += INCRSUMP(mp, s, x_jx, y_iy, z_iz);
  629.   mp += 4;
  630.   result[Y] += INCRSUMP(mp, s, x_jx, y_iy, z_iz);
  631.   mp += 4;
  632.   result[Z] += INCRSUMP(mp, s, x_jx, y_iy, z_iz);
  633.   
  634.   mp = &RTable[(int) Hash1d(jxjy_hash, iz) & 0xFF];
  635.   s = sxsy*tz;
  636.   result[X] += INCRSUMP(mp, s, x_jx, y_jy, z_iz);
  637.   mp += 4;
  638.   result[Y] += INCRSUMP(mp, s, x_jx, y_jy, z_iz);
  639.   mp += 4;
  640.   result[Z] += INCRSUMP(mp, s, x_jx, y_jy, z_iz);
  641.   
  642.   mp = &RTable[(int) Hash1d(ixjy_hash, iz) & 0xFF];
  643.   s = txsy*tz;
  644.   result[X] += INCRSUMP(mp, s, x_ix, y_jy, z_iz);
  645.   mp += 4;
  646.   result[Y] += INCRSUMP(mp, s, x_ix, y_jy, z_iz);
  647.   mp += 4;
  648.   result[Z] += INCRSUMP(mp, s, x_ix, y_jy, z_iz);
  649.   
  650.   mp = &RTable[(int) Hash1d(ixjy_hash, jz) & 0xFF];
  651.   s = txsy*sz;
  652.   result[X] += INCRSUMP(mp, s, x_ix, y_jy, z_jz);
  653.   mp += 4;
  654.   result[Y] += INCRSUMP(mp, s, x_ix, y_jy, z_jz);
  655.   mp += 4;
  656.   result[Z] += INCRSUMP(mp, s, x_ix, y_jy, z_jz);
  657.   
  658.   mp = &RTable[(int) Hash1d(jxjy_hash, jz) & 0xFF];
  659.   s = sxsy*sz;
  660.   result[X] += INCRSUMP(mp, s, x_jx, y_jy, z_jz);
  661.   mp += 4;
  662.   result[Y] += INCRSUMP(mp, s, x_jx, y_jy, z_jz);
  663.   mp += 4;
  664.   result[Z] += INCRSUMP(mp, s, x_jx, y_jy, z_jz);
  665.   
  666.   mp = &RTable[(int) Hash1d(jxiy_hash, jz) & 0xFF];
  667.   s = sxty*sz;
  668.   result[X] += INCRSUMP(mp, s, x_jx, y_iy, z_jz);
  669.   mp += 4;
  670.   result[Y] += INCRSUMP(mp, s, x_jx, y_iy, z_jz);
  671.   mp += 4;
  672.   result[Z] += INCRSUMP(mp, s, x_jx, y_iy, z_jz);
  673.   
  674.   mp = &RTable[(int) Hash1d(ixiy_hash, jz) & 0xFF];
  675.   s = txty*sz;
  676.   result[X] += INCRSUMP(mp, s, x_ix, y_iy, z_jz);
  677.   mp += 4;
  678.   result[Y] += INCRSUMP(mp, s, x_ix, y_iy, z_jz);
  679.   mp += 4;
  680.   result[Z] += INCRSUMP(mp, s, x_ix, y_iy, z_jz);
  681. }
  682. #else
  683. void DNoise(VECTOR result, VECTOR EPoint)
  684. {
  685.   DBL x, y, z;
  686.   DBL *mp;
  687.   long ix, iy, iz, jx, jy, jz;
  688.   int ixiy_hash, ixjy_hash, jxiy_hash, jxjy_hash;
  689.   DBL px, py, pz, s;
  690.   DBL sx, sy, sz, tx, ty, tz;
  691.   DBL txty, sxty, txsy, sxsy;
  692.   
  693.   Increase_Counter(stats[Calls_To_DNoise]);
  694.   
  695.   x = EPoint[X]-MINX;
  696.   y = EPoint[Y]-MINY;
  697.   z = EPoint[Z]-MINZ;
  698.   
  699.   /* its equivalent integer lattice point. */
  700.   ix = (long)x; iy = (long)y; iz = (long)z;
  701.   jx = ix + 1; jy = iy + 1; jz = iz + 1;
  702.   
  703.   sx = SCURVE(x - ix); sy = SCURVE(y - iy); sz = SCURVE(z - iz);
  704.   
  705.   /* the complement values of sx,sy,sz */
  706.   tx = 1.0 - sx; ty = 1.0 - sy; tz = 1.0 - sz;
  707.   
  708.   /*
  709.   *  interpolate!
  710.   */
  711.   txty = tx * ty;
  712.   sxty = sx * ty;
  713.   txsy = tx * sy;
  714.   sxsy = sx * sy;
  715.   ixiy_hash = Hash2d(ix, iy);
  716.   jxiy_hash = Hash2d(jx, iy);
  717.   ixjy_hash = Hash2d(ix, jy);
  718.   jxjy_hash = Hash2d(jx, jy);
  719.   
  720.   mp = &RTable[(int) Hash1d(ixiy_hash, iz) & 0xFF];
  721.   px = x - ix;  py = y - iy;  pz = z - iz;
  722.   s = txty*tz;
  723.   result[X] = INCRSUMP(mp, s, px, py, pz);
  724.   mp += 4;
  725.   result[Y] = INCRSUMP(mp, s, px, py, pz);
  726.   mp += 4;
  727.   result[Z] = INCRSUMP(mp, s, px, py, pz);
  728.   
  729.   mp = &RTable[(int) Hash1d(jxiy_hash, iz) & 0xFF];
  730.   px = x - jx;
  731.   s = sxty*tz;
  732.   result[X] += INCRSUMP(mp, s, px, py, pz);
  733.   mp += 4;
  734.   result[Y] += INCRSUMP(mp, s, px, py, pz);
  735.   mp += 4;
  736.   result[Z] += INCRSUMP(mp, s, px, py, pz);
  737.   
  738.   mp = &RTable[(int) Hash1d(jxjy_hash, iz) & 0xFF];
  739.   py = y - jy;
  740.   s = sxsy*tz;
  741.   result[X] += INCRSUMP(mp, s, px, py, pz);
  742.   mp += 4;
  743.   result[Y] += INCRSUMP(mp, s, px, py, pz);
  744.   mp += 4;
  745.   result[Z] += INCRSUMP(mp, s, px, py, pz);
  746.   
  747.   mp = &RTable[(int) Hash1d(ixjy_hash, iz) & 0xFF];
  748.   px = x - ix;
  749.   s = txsy*tz;
  750.   result[X] += INCRSUMP(mp, s, px, py, pz);
  751.   mp += 4;
  752.   result[Y] += INCRSUMP(mp, s, px, py, pz);
  753.   mp += 4;
  754.   result[Z] += INCRSUMP(mp, s, px, py, pz);
  755.   
  756.   mp = &RTable[(int) Hash1d(ixjy_hash, jz) & 0xFF];
  757.   pz = z - jz;
  758.   s = txsy*sz;
  759.   result[X] += INCRSUMP(mp, s, px, py, pz);
  760.   mp += 4;
  761.   result[Y] += INCRSUMP(mp, s, px, py, pz);
  762.   mp += 4;
  763.   result[Z] += INCRSUMP(mp, s, px, py, pz);
  764.   
  765.   mp = &RTable[(int) Hash1d(jxjy_hash, jz) & 0xFF];
  766.   px = x - jx;
  767.   s = sxsy*sz;
  768.   result[X] += INCRSUMP(mp, s, px, py, pz);
  769.   mp += 4;
  770.   result[Y] += INCRSUMP(mp, s, px, py, pz);
  771.   mp += 4;
  772.   result[Z] += INCRSUMP(mp, s, px, py, pz);
  773.   
  774.   mp = &RTable[(int) Hash1d(jxiy_hash, jz) & 0xFF];
  775.   py = y - iy;
  776.   s = sxty*sz;
  777.   result[X] += INCRSUMP(mp, s, px, py, pz);
  778.   mp += 4;
  779.   result[Y] += INCRSUMP(mp, s, px, py, pz);
  780.   mp += 4;
  781.   result[Z] += INCRSUMP(mp, s, px, py, pz);
  782.   
  783.   mp = &RTable[(int) Hash1d(ixiy_hash, jz) & 0xFF];
  784.   px = x - ix;
  785.   s = txty*sz;
  786.   result[X] += INCRSUMP(mp, s, px, py, pz);
  787.   mp += 4;
  788.   result[Y] += INCRSUMP(mp, s, px, py, pz);
  789.   mp += 4;
  790.   result[Z] += INCRSUMP(mp, s, px, py, pz);
  791. }
  792. #endif
  793.  
  794.  
  795. /*****************************************************************************
  796. *
  797. * FUNCTION
  798. *
  799. *   Turbulence
  800. *
  801. * INPUT
  802. *
  803. *   EPoint -- Point at which turb is evaluated.
  804. *   Turb   -- Parameters for fbm calculations.
  805. *   
  806. * OUTPUT
  807. *   
  808. * RETURNS
  809. *
  810. *   DBL result
  811. *   
  812. * AUTHOR
  813. *
  814. *   POV-Ray Team
  815. *
  816. * DESCRIPTION   : Computes a Fractal Brownian Motion turbulence value
  817. *                 using repeated calls to a Perlin Noise function.
  818. *
  819. * CHANGES
  820. *   ??? ???? : Updated with varible Octaves, Lambda, & Omega by [DMF]
  821. *
  822. ******************************************************************************/
  823.  
  824. DBL Turbulence(VECTOR EPoint,TURB *Turb)
  825. {
  826.   int i;
  827.   DBL Lambda, Omega, l, o, value;
  828.   VECTOR temp;
  829.   int Octaves=Turb->Octaves;
  830.   
  831.   value = Noise(EPoint);
  832.  
  833.   l = Lambda = Turb->Lambda;
  834.   o = Omega  = Turb->Omega;
  835.  
  836.   for (i = 2; i <= Octaves; i++)
  837.   {
  838.     VScale(temp,EPoint,l);
  839.     value += o * Noise(temp);
  840.     if (i < Octaves)
  841.     {
  842.       l *= Lambda;
  843.       o *= Omega;
  844.     }
  845.   }
  846.   return (value);
  847. }
  848.  
  849.  
  850.  
  851. /*****************************************************************************
  852. *
  853. * FUNCTION
  854. *
  855. *   DTurbulence
  856. *
  857. * INPUT
  858. *
  859. *   EPoint -- Point at which turb is evaluated.
  860. *   Turb   -- Parameters for fmb calculations.
  861. *   
  862. * OUTPUT
  863. *
  864. *   result -- Vector valued turbulence
  865. *   
  866. * RETURNS
  867. *   
  868. * AUTHOR
  869. *
  870. *   POV-Ray Team
  871. *   
  872. * DESCRIPTION   : Computes a Fractal Brownian Motion turbulence value
  873. *                 using repeated calls to a Perlin DNoise function.
  874. *
  875. * CHANGES
  876. *   ??? ???? : Updated with varible Octaves, Lambda, & Omega by [DMF]
  877. *
  878. ******************************************************************************/
  879.  
  880.  
  881. void DTurbulence(VECTOR result, VECTOR  EPoint, TURB *Turb)
  882. {
  883.   DBL Omega, Lambda;
  884.   int i;
  885.   DBL l, o;
  886.   VECTOR value, temp;
  887.   int Octaves=Turb->Octaves;
  888.   
  889.   result[X] = result[Y] = result[Z] = 0.0;
  890.   value[X]  = value[Y]  = value[Z]  = 0.0;
  891.   
  892.   DNoise(result, EPoint);
  893.   
  894.   l = Lambda = Turb->Lambda;
  895.   o = Omega  = Turb->Omega;
  896.  
  897.   for (i = 2; i <= Octaves; i++)
  898.   {
  899.     VScale(temp,EPoint,l);
  900.     
  901.     DNoise(value, temp);
  902.     result[X] += o * value[X];
  903.     result[Y] += o * value[Y];
  904.     result[Z] += o * value[Z];
  905.     if (i < Octaves)
  906.     {
  907.       l *= Lambda;
  908.       o *= Omega;
  909.     }
  910.   }
  911. }
  912.  
  913.  
  914.  
  915. /*****************************************************************************
  916. *
  917. * FUNCTION
  918. *
  919. *   cycloidal
  920. *
  921. * INPUT
  922. *
  923. *   DBL value
  924. *   
  925. * OUTPUT
  926. *   
  927. * RETURNS
  928. *
  929. *   DBL result
  930. *   
  931. * AUTHOR
  932. *
  933. *   POV-Ray Team
  934. *   
  935. * DESCRIPTION
  936. *
  937. * CHANGES
  938. *
  939. ******************************************************************************/
  940.  
  941. DBL cycloidal(DBL value)
  942. {
  943. /*  register int indx;*/
  944.   /* YS feb 1 2001
  945.           Fixed sin_wave and scallop_wave bug
  946.   */
  947.   if (value >= 0.0)
  948.   {
  949.         return sin((DBL) (((value - floor(value)) * 50000.0)) / 50000.0 * TWO_M_PI)  ;
  950.   }
  951.   else
  952.   {
  953.         return 0.0-sin((DBL) (((0.0 - (value + floor(0.0 - value))) * 50000.0)) / 50000.0 * TWO_M_PI);
  954.   }
  955. }
  956.  
  957.  
  958.  
  959. /*****************************************************************************
  960. *
  961. * FUNCTION
  962. *
  963. *   Triangle_Wave
  964. *
  965. * INPUT
  966. *
  967. *   DBL value
  968. *   
  969. * OUTPUT
  970. *   
  971. * RETURNS
  972. *
  973. *   DBL result
  974. *   
  975. * AUTHOR
  976. *
  977. *   POV-Ray Team
  978. *   
  979. * DESCRIPTION
  980. *
  981. * CHANGES
  982. *
  983. ******************************************************************************/
  984.  
  985. DBL Triangle_Wave(DBL value)
  986. {
  987.   register DBL offset;
  988.   
  989.   if (value >= 0.0) 
  990.   {
  991.     offset = value - floor(value);
  992.   }
  993.   else
  994.   {
  995.     offset = value + 1.0 + floor(fabs(value));
  996.   }
  997.   if (offset >= 0.5) 
  998.   {
  999.     return (2.0 * (1.0 - offset));
  1000.   }
  1001.   else
  1002.   {
  1003.     return (2.0 * offset);
  1004.   }
  1005. }
  1006.  
  1007.  
  1008.  
  1009. /*****************************************************************************
  1010. *
  1011. * FUNCTION
  1012. *
  1013. * INPUT
  1014. *
  1015. * OUTPUT
  1016. *
  1017. * RETURNS
  1018. *
  1019. * AUTHOR
  1020. *
  1021. *   POV-Ray Team
  1022. *
  1023. * DESCRIPTION
  1024. *
  1025. * CHANGES
  1026. *
  1027. ******************************************************************************/
  1028.  
  1029. void Transform_Textures(TEXTURE *Textures, TRANSFORM *Trans)
  1030. {
  1031.   TEXTURE *Layer;
  1032.  
  1033.   for (Layer = Textures; Layer != NULL; Layer = (TEXTURE *)Layer->Next)
  1034.   {
  1035.     if (Layer->Type == PLAIN_PATTERN)
  1036.     {
  1037.       Transform_Tpattern((TPATTERN *)Layer->Pigment, Trans);
  1038.       Transform_Tpattern((TPATTERN *)Layer->Tnormal, Trans);
  1039.     }
  1040.     else
  1041.     {
  1042.       Transform_Tpattern((TPATTERN *)Layer, Trans);
  1043.     }
  1044.   }
  1045. }
  1046.  
  1047.  
  1048.  
  1049. /*****************************************************************************
  1050. *
  1051. * FUNCTION
  1052. *
  1053. * INPUT
  1054. *
  1055. * OUTPUT
  1056. *
  1057. * RETURNS
  1058. *
  1059. * AUTHOR
  1060. *
  1061. *   POV-Ray Team
  1062. *   
  1063. * DESCRIPTION
  1064. *
  1065. * CHANGES
  1066. *   6/27/98  MBP  Added initializers for reflection blur
  1067. *   8/27/98  MBP  Added initializers for angle-based reflectivity
  1068. *
  1069. ******************************************************************************/
  1070.  
  1071. FINISH *Create_Finish()
  1072. {
  1073.   FINISH *New;
  1074.   
  1075.   New = (FINISH *)POV_MALLOC(sizeof (FINISH), "finish");
  1076.   
  1077.   Make_RGB(New->Ambient, 0.1, 0.1, 0.1);
  1078.   Make_RGB(New->Reflection_Max, 0.0, 0.0, 0.0);
  1079.   Make_RGB(New->Reflection_Min, 0.0, 0.0, 0.0);
  1080.  
  1081.   New->Reflection_Type = 0;
  1082.  
  1083.   New->Reflection_Falloff = 1;  /* Added by MBP 8/27/98 */
  1084.   New->Reflection_Blur = 0.0;  /* Added by MBP 6/27/98 */
  1085.   New->Reflection_Samples = 1;  /* Added by MBP 6/27/98 */
  1086.  
  1087.   New->Diffuse    = 0.6;
  1088.   New->Brilliance = 1.0;
  1089.   New->Phong      = 0.0;
  1090.   New->Phong_Size = 40.0;
  1091.   New->Specular   = 0.0;
  1092.   New->Roughness  = 1.0 / 0.05;
  1093.  
  1094.   New->Crand = 0.0;
  1095.  
  1096.   New->Metallic = 0.0;
  1097.  
  1098.   New->Irid                = 0.0;
  1099.   New->Irid_Film_Thickness = 0.0;
  1100.   New->Irid_Turb           = 0.0;
  1101.   New->Temp_Caustics = -1.0;
  1102.   New->Temp_IOR     = -1.0;
  1103.   New->Temp_Dispersion  = 1.0;
  1104.   New->Temp_Refract =  1.0;
  1105.   New->Reflect_Exp  =  1.0;
  1106.  
  1107.   /* Added 6/27/98 by MBP for reflection-blur */
  1108.   New->Reflection_Samples = 1;
  1109.   New->Reflection_Blur = 0;
  1110.   New->Reflect_Metallic = 0.0;
  1111.  
  1112.   /* Added Dec 19 1999 by NK */
  1113.   New->Conserve_Energy = FALSE;
  1114.  
  1115. #ifdef BlinnPatch
  1116.   New->Blinn = 0.0;
  1117.   New->Facets = 0.2;
  1118. #endif
  1119.  
  1120.   return(New);
  1121. }
  1122.  
  1123.  
  1124.  
  1125. /*****************************************************************************
  1126. *
  1127. * FUNCTION
  1128. *
  1129. * INPUT
  1130. *   
  1131. * OUTPUT
  1132. *   
  1133. * RETURNS
  1134. *   
  1135. * AUTHOR
  1136. *
  1137. *   POV-Ray Team
  1138. *   
  1139. * DESCRIPTION
  1140. *
  1141. * CHANGES
  1142. *
  1143. ******************************************************************************/
  1144.  
  1145. FINISH *Copy_Finish(FINISH *Old)
  1146. {
  1147.   FINISH *New;
  1148.   
  1149.   if (Old != NULL)
  1150.   {
  1151.     New = Create_Finish();
  1152.     *New = *Old;
  1153.   }
  1154.   else
  1155.     New = NULL;
  1156.   return (New);
  1157. }
  1158.  
  1159.  
  1160.  
  1161. /*****************************************************************************
  1162. *
  1163. * FUNCTION
  1164. *
  1165. * INPUT
  1166. *   
  1167. * OUTPUT
  1168. *   
  1169. * RETURNS
  1170. *   
  1171. * AUTHOR
  1172. *
  1173. *   POV-Ray Team
  1174. *   
  1175. * DESCRIPTION
  1176. *
  1177. * CHANGES
  1178. *
  1179. ******************************************************************************/
  1180.  
  1181. TEXTURE *Create_Texture()
  1182. {
  1183.   TEXTURE *New;
  1184.   
  1185.   New = (TEXTURE *)POV_MALLOC(sizeof (TEXTURE), "texture");
  1186.   
  1187.   Init_TPat_Fields((TPATTERN *)New);
  1188.  
  1189.   New->References = 1;
  1190.  
  1191.   New->Type  = PLAIN_PATTERN;
  1192.   New->Flags = NO_FLAGS;
  1193.  
  1194.   New->Pigment = NULL;
  1195.   New->Tnormal = NULL;
  1196.   New->Finish  = NULL;
  1197.  
  1198.   New->Next          = NULL;
  1199.   New->Next_Material = NULL;
  1200.  
  1201.   return (New);
  1202. }
  1203.  
  1204.  
  1205. /*****************************************************************************
  1206. *
  1207. * FUNCTION
  1208. *
  1209. * INPUT
  1210. *   
  1211. * OUTPUT
  1212. *   
  1213. * RETURNS
  1214. *   
  1215. * AUTHOR
  1216. *
  1217. *   POV-Ray Team
  1218. *   
  1219. * DESCRIPTION
  1220. *
  1221. * CHANGES
  1222. *
  1223. ******************************************************************************/
  1224.  
  1225. TEXTURE *Copy_Texture_Pointer(TEXTURE *Texture)
  1226. {
  1227.   if (Texture != NULL)
  1228.   {
  1229.     Texture->References++;
  1230.   }
  1231.  
  1232.   return(Texture);
  1233. }
  1234.  
  1235.  
  1236.  
  1237.  
  1238. /*****************************************************************************
  1239. *
  1240. * FUNCTION
  1241. *
  1242. * INPUT
  1243. *   
  1244. * OUTPUT
  1245. *   
  1246. * RETURNS
  1247. *   
  1248. * AUTHOR
  1249. *
  1250. *   POV-Ray Team
  1251. *   
  1252. * DESCRIPTION
  1253. *
  1254. * CHANGES
  1255. *
  1256. ******************************************************************************/
  1257.  
  1258. TEXTURE *Copy_Textures(TEXTURE *Textures)
  1259. {
  1260.   TEXTURE *New, *First, *Previous, *Layer;
  1261.   
  1262.   Previous = First = NULL;
  1263.   
  1264.   for (Layer = Textures; Layer != NULL; Layer = (TEXTURE *)Layer->Next)
  1265.   {
  1266.     New = Create_Texture();
  1267.     Copy_TPat_Fields ((TPATTERN *)New, (TPATTERN *)Layer);
  1268.     
  1269.     /*  Mesh copies a texture pointer that already has multiple
  1270.         references.  We just want a clean copy, not a copy
  1271.         that's multply referenced.
  1272.      */
  1273.  
  1274.     New->References = 1;
  1275.  
  1276.     switch (Layer->Type)
  1277.     {
  1278.       case PLAIN_PATTERN:
  1279.         New->Pigment = Copy_Pigment(Layer->Pigment);
  1280.         New->Tnormal = Copy_Tnormal(Layer->Tnormal);
  1281.         New->Finish  = Copy_Finish(Layer->Finish);
  1282.  
  1283.         break;
  1284.       
  1285.       case BITMAP_PATTERN:
  1286.  
  1287.         New->Materials   = Copy_Materials(Layer->Materials);
  1288.         New->Num_Of_Mats = Layer->Num_Of_Mats;
  1289.  
  1290. /*      Not needed. Copied by Copy_TPat_Fields */
  1291. /*      New->Vals.Image  = Copy_Image(Layer->Vals.Image);*/ 
  1292.  
  1293.         break;
  1294.     }
  1295.  
  1296.     if (First == NULL)
  1297.     {
  1298.       First = New;
  1299.     }
  1300.  
  1301.     if (Previous != NULL)
  1302.     {
  1303.       Previous->Next = (TPATTERN *)New;
  1304.     }
  1305.  
  1306.     Previous = New;
  1307.   }
  1308.  
  1309.   return (First);
  1310. }
  1311.  
  1312.  
  1313.  
  1314. /*****************************************************************************
  1315. *
  1316. * FUNCTION
  1317. *
  1318. * INPUT
  1319. *   
  1320. * OUTPUT
  1321. *   
  1322. * RETURNS
  1323. *   
  1324. * AUTHOR
  1325. *
  1326. *   POV-Ray Team
  1327. *   
  1328. * DESCRIPTION
  1329. *
  1330. * CHANGES
  1331. *
  1332. ******************************************************************************/
  1333.  
  1334. static TEXTURE *Copy_Materials(TEXTURE *Old)
  1335. {
  1336.   TEXTURE *New, *First, *Previous, *Material;
  1337.   
  1338.   Previous = First = NULL;
  1339.   
  1340.   for (Material = Old; Material != NULL; Material = Material->Next_Material)
  1341.   {
  1342.     New = Copy_Textures(Material);
  1343.  
  1344.     if (First == NULL)
  1345.     {
  1346.       First = New;
  1347.     }
  1348.  
  1349.     if (Previous != NULL)
  1350.     {
  1351.       Previous->Next_Material = New;
  1352.     }
  1353.  
  1354.     Previous = New;
  1355.   }
  1356.  
  1357.   return (First);
  1358. }
  1359.  
  1360.  
  1361.  
  1362. /*****************************************************************************
  1363. *
  1364. * FUNCTION
  1365. *
  1366. * INPUT
  1367. *   
  1368. * OUTPUT
  1369. *   
  1370. * RETURNS
  1371. *   
  1372. * AUTHOR
  1373. *
  1374. *   POV-Ray Team
  1375. *   
  1376. * DESCRIPTION
  1377. *
  1378. * CHANGES
  1379. *
  1380. ******************************************************************************/
  1381.  
  1382. void Destroy_Textures(TEXTURE *Textures)
  1383. {
  1384.   TEXTURE *Layer = Textures;
  1385.   TEXTURE *Mats;
  1386.   TEXTURE *Temp;
  1387.   
  1388.   if ((Textures == NULL) || (--(Textures->References) > 0))
  1389.   {
  1390.     return;
  1391.   }
  1392.  
  1393.   while (Layer != NULL)
  1394.   {
  1395.     Mats = Layer->Next_Material;
  1396.  
  1397.     while (Mats != NULL)
  1398.     {
  1399.       Temp = Mats->Next_Material;
  1400.       Mats->Next_Material = NULL;
  1401.       Destroy_Textures(Mats);
  1402.       Mats = Temp;
  1403.     }
  1404.  
  1405.     Destroy_TPat_Fields((TPATTERN *)Layer);
  1406.  
  1407.     switch (Layer->Type)
  1408.     {
  1409.       case PLAIN_PATTERN:
  1410.  
  1411.         Destroy_Pigment(Layer->Pigment);
  1412.         Destroy_Tnormal(Layer->Tnormal);
  1413.         Destroy_Finish(Layer->Finish);
  1414.  
  1415.       break;
  1416.  
  1417.  
  1418.       case BITMAP_PATTERN:
  1419.  
  1420.         Destroy_Textures(Layer->Materials);
  1421.         /*taken care of by Destroy_TPat_Fields*/
  1422.         /*Destroy_Image(Layer->Vals.Image);*/
  1423.  
  1424.       break;
  1425.     }
  1426.  
  1427.     Temp = (TEXTURE *)Layer->Next;
  1428.     POV_FREE(Layer);
  1429.     Layer = Temp;
  1430.   }
  1431. }
  1432.  
  1433.  
  1434.  
  1435. /*****************************************************************************
  1436. *
  1437. * FUNCTION
  1438. *
  1439. * INPUT
  1440. *   
  1441. * OUTPUT
  1442. *   
  1443. * RETURNS
  1444. *   
  1445. * AUTHOR
  1446. *
  1447. *   POV-Ray Team
  1448. *   
  1449. * DESCRIPTION
  1450. *
  1451. * CHANGES
  1452. *
  1453. ******************************************************************************/
  1454.  
  1455. void Post_Textures(TEXTURE *Textures)
  1456. {
  1457.   TEXTURE *Layer, *Material;
  1458.   int i;
  1459.   BLEND_MAP *Map;
  1460.   
  1461.   if (Textures == NULL)
  1462.   {
  1463.     return;
  1464.   }
  1465.  
  1466.   for (Layer = Textures; Layer != NULL; Layer = (TEXTURE *)Layer->Next)
  1467.   {
  1468.     if (!((Layer->Flags) & POST_DONE))
  1469.     {
  1470.       switch (Layer->Type)
  1471.       {
  1472.         case PLAIN_PATTERN:
  1473.  
  1474. #ifdef NormalBugFix
  1475.           if(Layer->Tnormal)
  1476.           {
  1477.             Layer->Tnormal->Flags |= 
  1478.               (Layer->Flags & DONT_SCALE_BUMPS_FLAG);
  1479.           }
  1480. #endif
  1481.           Post_Pigment(Layer->Pigment);
  1482.           Post_Tnormal(Layer->Tnormal);
  1483.  
  1484.           break;
  1485.  
  1486.         case BITMAP_PATTERN:
  1487.  
  1488.           for (Material = Layer->Materials; Material != NULL; Material = Material->Next_Material)
  1489.  
  1490.             Post_Textures(Material);
  1491.  
  1492.             break;
  1493.       }
  1494.   
  1495.       if ((Map=Layer->Blend_Map) != NULL)
  1496.       {
  1497.         for (i = 0; i < Map->Number_Of_Entries; i++)
  1498.         {
  1499. #ifdef NormalBugFix
  1500.            Map->Blend_Map_Entries[i].Vals.Texture->Flags |= 
  1501.              (Layer->Flags & DONT_SCALE_BUMPS_FLAG);
  1502. #endif
  1503.            Post_Textures(Map->Blend_Map_Entries[i].Vals.Texture);
  1504.         }
  1505.       }
  1506.       else
  1507.       {
  1508.         if (Layer->Type == AVERAGE_PATTERN)
  1509.         {
  1510.            Error("No texture map in averaged texture.");
  1511.         }
  1512.       }
  1513.     }
  1514.   }
  1515. }
  1516.  
  1517.  
  1518.  
  1519. /*****************************************************************************
  1520. *
  1521. * FUNCTION
  1522. *
  1523. *   Test_Opacity
  1524. *
  1525. * INPUT
  1526. *
  1527. *   Object - Pointer to object
  1528. *
  1529. * OUTPUT
  1530. *
  1531. * RETURNS
  1532. *
  1533. *   int - TRUE, if opaque
  1534. *
  1535. * AUTHOR
  1536. *
  1537. *   Dieter Bayer
  1538. *   
  1539. * DESCRIPTION
  1540. *
  1541. *   Test wether an object is opaque or not, i.e. wether the texture contains
  1542. *   a non-zero filter or alpha channel.
  1543. *
  1544. * CHANGES
  1545. *
  1546. *   Aug 1994 : Creation.
  1547. *
  1548. *   Oct 1994 : Added code to check for opaque image maps. [DB]
  1549. *
  1550. *   Jun 1995 : Added code to check for alpha channel image maps. [DB]
  1551. *
  1552. ******************************************************************************/
  1553.  
  1554. int Test_Opacity(TEXTURE *Texture)
  1555. {
  1556.   int x, y;
  1557.   int Opaque, Help;
  1558.   IMAGE *Image;
  1559.   TEXTURE *Layer, *Material;
  1560.  
  1561.   if (Texture == NULL)
  1562.   {
  1563.     return(FALSE);
  1564.   }
  1565.  
  1566.   /* We assume that the object is not opaque. */
  1567.  
  1568.   Opaque = FALSE;
  1569.  
  1570.   /* Test all layers. If at least one layer is opaque the object is opaque. */
  1571.  
  1572.   for (Layer = Texture; Layer != NULL; Layer = (TEXTURE *)Layer->Next)
  1573.   {
  1574.     switch (Layer->Type)
  1575.     {
  1576.       case PLAIN_PATTERN:
  1577.  
  1578.         /* Test image map for opacity. */
  1579.  
  1580.         if ((Layer->Pigment->Type == BITMAP_PATTERN) &&
  1581.             (Layer->Pigment->Vals.Image != NULL))
  1582.         {
  1583.           /* Layer is not opaque if the image map is used just once. */
  1584.  
  1585.           if (Layer->Pigment->Vals.Image->Once_Flag)
  1586.           {
  1587.             break;
  1588.           }
  1589.  
  1590.           /* Layer is not opaque if there's at least one non-opaque color. */
  1591.  
  1592.           Image = Layer->Pigment->Vals.Image;
  1593.  
  1594.           Help = FALSE;
  1595.  
  1596.           if (Image->Colour_Map != NULL)
  1597.           {
  1598.             /* Test color map. */
  1599.  
  1600.             for (x = 0; x < (int)Image->Colour_Map_Size; x++)
  1601.             {
  1602.               if (fabs(Image->Colour_Map[x].Filter) > EPSILON)
  1603.               {
  1604.                 Help = TRUE;
  1605.  
  1606.                 break;
  1607.               }
  1608.             }
  1609.           }
  1610.           else
  1611.           {
  1612.             /* Test image. */
  1613.  
  1614.             if (Image->data.rgb_lines[0].transm != NULL)
  1615.             {
  1616.               for (y = 0; y < Image->iheight; y++)
  1617.               {
  1618.                 for (x = 0; x < Image->iwidth; x++)
  1619.                 {
  1620.                   if (fabs(Image->data.rgb_lines[y].transm[x]) > EPSILON)
  1621.                   {
  1622.                     Help = TRUE;
  1623.  
  1624.                     break;
  1625.                   }
  1626.                 }
  1627.  
  1628.                 if (Help)
  1629.                 {
  1630.                   break;
  1631.                 }
  1632.               }
  1633.             }
  1634.           }
  1635.  
  1636.           if (Help)
  1637.           {
  1638.             break;
  1639.           }
  1640.         }
  1641.  
  1642.         if (!(Layer->Pigment->Flags & HAS_FILTER))
  1643.         {
  1644.           Opaque = TRUE;
  1645.         }
  1646.  
  1647.         break;
  1648.  
  1649.       case BITMAP_PATTERN:
  1650.  
  1651.         /* Layer is not opaque if the image map is used just once. */
  1652.  
  1653.         if (Layer->Vals.Image != NULL)
  1654.         {
  1655.           if (Layer->Vals.Image->Once_Flag)
  1656.           {
  1657.             break;
  1658.           }
  1659.         }
  1660.  
  1661.         /* Layer is opaque if all materials are opaque. */
  1662.  
  1663.         Help = TRUE;
  1664.  
  1665.         for (Material = Layer->Materials; Material != NULL; Material = Material->Next_Material)
  1666.         {
  1667.           if (!Test_Opacity(Material))
  1668.           {
  1669.             /* Material is not opaque --> layer is not opaque. */
  1670.  
  1671.             Help = FALSE;
  1672.  
  1673.             break;
  1674.           }
  1675.         }
  1676.  
  1677.         if (Help)
  1678.         {
  1679.           Opaque = TRUE;
  1680.         }
  1681.  
  1682.         break;
  1683.     }
  1684.   }
  1685.  
  1686.   return(Opaque);
  1687. }
  1688.  
  1689.  
  1690.  
  1691. /*****************************************************************************
  1692. *
  1693. * FUNCTION
  1694. *
  1695. *   POV_RAND
  1696. *
  1697. * INPUT
  1698. *
  1699. * OUTPUT
  1700. *   
  1701. * RETURNS
  1702. *
  1703. *   int - random value
  1704. *   
  1705. * AUTHOR
  1706. *
  1707. *   POV-Ray Team
  1708. *   
  1709. * DESCRIPTION
  1710. *
  1711. *   Standard pseudo-random function.
  1712. *
  1713. * CHANGES
  1714. *
  1715. *   Feb 1995 : Creation.
  1716. *
  1717. ******************************************************************************/
  1718.  
  1719. int POV_RAND()
  1720. {
  1721.   next_rand = next_rand * 1812433253L + 12345L;
  1722.  
  1723.   return((int)(next_rand >> 16) & RNDMASK);
  1724. }
  1725.  
  1726. int POV_GET_OLD_RAND()
  1727. {
  1728.   return(next_rand);
  1729. }
  1730.  
  1731.  
  1732.  
  1733. /*****************************************************************************
  1734. *
  1735. * FUNCTION
  1736. *
  1737. *   POV_SRAND
  1738. *
  1739. * INPUT
  1740. *
  1741. *   seed - Pseudo-random generator start value
  1742. *   
  1743. * OUTPUT
  1744. *   
  1745. * RETURNS
  1746. *   
  1747. * AUTHOR
  1748. *
  1749. *   POV-Ray Team
  1750. *   
  1751. * DESCRIPTION
  1752. *
  1753. *   Set start value for pseudo-random generator.
  1754. *
  1755. * CHANGES
  1756. *
  1757. *   Feb 1995 : Creation.
  1758. *
  1759. ******************************************************************************/
  1760.  
  1761. void POV_SRAND(int seed)
  1762. {
  1763.   next_rand = (unsigned long int)seed;
  1764. }
  1765.  
  1766.