home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / SOURCE / render.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-18  |  89.4 KB  |  3,963 lines  |  [TEXT/MPS ]

  1. /****************************************************************************
  2. *                   render.c
  3. *
  4. *  This module implements the main raytracing loop.
  5. *
  6. * 08/07/92 lsk    Changed the normal antialiasing function to use a loop 
  7. *                 where the number of rays per pixel when antialiasing can 
  8. *                 be specified.
  9. *
  10. *  from Persistence of Vision(tm) Ray Tracer
  11. *  Copyright 1996 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. If
  18. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  19. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  20. *  Forum.  The latest version of POV-Ray may be found there as well.
  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. #include <time.h>
  29. #include "frame.h"
  30. #include "vector.h"
  31. #include "povproto.h"
  32. #include "bbox.h"
  33. #include "chi2.h"
  34. #include "colour.h"
  35. #include "lighting.h"
  36. #include "normal.h"
  37. #include "objects.h"
  38. #include "octree.h"
  39. #include "optout.h"
  40. #include "povray.h"
  41. #include "radiosit.h"
  42. #include "ray.h"
  43. #include "render.h"
  44. #include "targa.h"
  45. #include "texture.h"
  46. #include "vbuffer.h"
  47. #include "userio.h"
  48.  
  49.  
  50. /*****************************************************************************
  51. * Local preprocessor defines
  52. ******************************************************************************/
  53.  
  54. #define rand2d(a, b) jitttab[(int)(hashTable[(int)(hashTable[(int)((a)&0xfff)]^(b))&0xfff])&0xff]
  55.  
  56. /* Grid stuff used by focal blur code. */
  57.  
  58. #define grid1size  4
  59. #define hexgrid2size  7
  60. #define hexgrid3size  19
  61. #define hexgrid4size  37
  62.  
  63. /* Grid size (n x n) used while jittering focal blur sub-pixel position. */
  64.  
  65. #define SUB_PIXEL_GRID_SIZE 16
  66.  
  67. /*****************************************************************************
  68. * Local typedefs
  69. ******************************************************************************/
  70.  
  71. typedef struct Pixel_Struct PIXEL;
  72. typedef struct Vec2_Struct VEC2;
  73.  
  74. struct Vec2_Struct
  75. {
  76.   DBL x, y;
  77. };
  78.  
  79. struct Pixel_Struct
  80. {
  81.   int active;
  82.   COLOUR Colour;
  83. };
  84.  
  85.  
  86.  
  87. /*****************************************************************************
  88. * Local variables
  89. ******************************************************************************/
  90.  
  91. int Trace_Level;
  92. int Max_Trace_Level = 5;
  93. int Highest_Trace_Level; /* DMF */
  94.  
  95. /* ADC stuff by DMF. */
  96.  
  97. DBL ADC_Bailout = 1.0/255.0;
  98.  
  99. static COLOUR *Previous_Line, *Current_Line;
  100. static char *Previous_Line_Antialiased_Flags, *Current_Line_Antialiased_Flags;
  101.  
  102. static RAY Camera_Ray;
  103.  
  104. static int SuperSampleCount, RadiosityCount;
  105.  
  106. static DBL maxclr;
  107.  
  108. /* Jitter values are taken from [-0.5*JitterScale, 0.5*JitterScale]. */
  109.  
  110. static DBL JitterScale;
  111.  
  112. /* Jitter ranges unsed during supersampling. */
  113.  
  114. static unsigned short JRanges[] = {1,1,1,1,3,2,5,3,7,4};
  115.  
  116. /* variables used by accumulate_histogram() for statistics on the render */
  117.  
  118. unsigned long           *histogram_grid;
  119. unsigned long           max_histogram_value;
  120. FILE_HANDLE             *Histogram_File_Handle;
  121.  
  122. /*
  123.  * Focal blur stuff.
  124.  */
  125.  
  126. /* Flag telling if focal blur is used. */
  127.  
  128. static int Focal_Blur_Is_Used;
  129.  
  130. /* Direction to focal plane. */
  131.  
  132. static DBL Focal_Distance;
  133.  
  134. /* Array of threshold for confidence test. */
  135.  
  136. static DBL *Sample_Threshold;
  137.  
  138. /* Array giving number of samples to take before next confidence test. */
  139.  
  140. static int *Current_Number_Of_Samples;
  141.  
  142. /* Array of sample locations. */
  143.  
  144. static VEC2 *Sample_Grid;
  145.  
  146. /* Maximum amount of jitter to use. */
  147.  
  148. static DBL Max_Jitter;
  149.  
  150. /* Vectors in the viewing plane. */
  151.  
  152. static VECTOR XPerp, YPerp;
  153.  
  154. /* 2*2 grid */
  155.  
  156. static VEC2 grid1[grid1size] =
  157. {
  158.   {-0.25,  0.25},
  159.   { 0.25,  0.25},
  160.   {-0.25, -0.25},
  161.   { 0.25, -0.25}
  162. };
  163.  
  164. static DBL hexjitter2 = 0.144338;
  165. static int hexgrid2samples[2] = { 7, 0 };
  166. static VEC2 hexgrid2 [hexgrid2size] =
  167. {
  168.   {-0.288675,  0.000000},
  169.   { 0.000000,  0.000000},
  170.   { 0.288675,  0.000000},
  171.   {-0.144338,  0.250000},
  172.   {-0.144338, -0.250000},
  173.   { 0.144338,  0.250000},
  174.   { 0.144338, -0.250000}
  175. };
  176.  
  177. static DBL hexjitter3 = 0.096225;
  178. static int hexgrid3samples[4] = { 7, 6, 6, 0 };
  179. static VEC2 hexgrid3 [hexgrid3size] =
  180. {
  181.   {-0.192450,  0.333333},
  182.   {-0.192450, -0.333333},
  183.   { 0.192450,  0.333333},
  184.   { 0.192450, -0.333333},
  185.   { 0.384900,  0.000000},
  186.   {-0.384900,  0.000000},
  187.   { 0.000000,  0.000000},
  188.  
  189.   { 0.000000,  0.333333},
  190.   { 0.000000, -0.333333},
  191.   {-0.288675,  0.166667},
  192.   {-0.288675, -0.166667},
  193.   { 0.288675,  0.166667},
  194.   { 0.288675, -0.166667},
  195.  
  196.   {-0.096225,  0.166667},
  197.   {-0.096225, -0.166667},
  198.   { 0.096225,  0.166667},
  199.   { 0.096225, -0.166667},
  200.   {-0.192450,  0.000000},
  201.   { 0.192450,  0.000000}
  202. };
  203.  
  204. static DBL hexjitter4 = 0.0721688;
  205. static int hexgrid4samples[9] = { 7, 6, 6, 4, 4, 4, 4, 2, 0 };
  206. static VEC2 hexgrid4 [hexgrid4size] =
  207. {
  208.   { 0.000000,  0.000000},
  209.   {-0.216506,  0.375000},
  210.   { 0.216506, -0.375000},
  211.   {-0.216506, -0.375000},
  212.   { 0.216506,  0.375000},
  213.   {-0.433013,  0.000000},
  214.   { 0.433013,  0.000000},
  215.  
  216.   {-0.144338,  0.250000},
  217.   { 0.144338, -0.250000},
  218.   {-0.144338, -0.250000},
  219.   { 0.144338,  0.250000},
  220.   {-0.288675,  0.000000},
  221.   { 0.288675,  0.000000},
  222.  
  223.   {-0.072169,  0.125000},
  224.   { 0.072169, -0.125000},
  225.   {-0.072169, -0.125000},
  226.   { 0.072169,  0.125000},
  227.   {-0.144338,  0.000000},
  228.   { 0.144338,  0.000000},
  229.  
  230.   {-0.360844,  0.125000},
  231.   {-0.360844, -0.125000},
  232.   { 0.360844,  0.125000},
  233.   { 0.360844, -0.125000},
  234.  
  235.   {-0.288675,  0.250000},
  236.   {-0.288675, -0.250000},
  237.   { 0.288675,  0.250000},
  238.   { 0.288675, -0.250000},
  239.  
  240.   {-0.072169,  0.375000},
  241.   {-0.072169, -0.375000},
  242.   { 0.072169,  0.375000},
  243.   { 0.072169, -0.375000},
  244.  
  245.   {-0.216506,  0.125000},
  246.   {-0.216506, -0.125000},
  247.   { 0.216506,  0.125000},
  248.   { 0.216506, -0.125000},
  249.  
  250.   { 0.000000,  0.250000},
  251.   { 0.000000, -0.250000},
  252. };
  253.  
  254. static float jitttab[256] = {
  255.   -0.500000,0.005890,0.011749,-0.490234,0.023468,-0.470703,-0.480469,0.017609,
  256.   0.046906,-0.447266,-0.441406,0.056671,-0.460938,0.044952,0.035187,-0.466797,
  257.   0.093781,-0.400391,-0.394531,0.103546,-0.382813,0.123077,0.113312,-0.388672,
  258.   -0.421875,0.084015,0.089874,-0.412109,0.070343,-0.423828,-0.433594,0.064484,
  259.   0.187531,-0.306641,-0.300781,0.197296,-0.289063,0.216827,0.207062,-0.294922,
  260.   -0.265625,0.240265,0.246124,-0.255859,0.226593,-0.267578,-0.277344,0.220734,
  261.   -0.343750,0.162140,0.167999,-0.333984,0.179718,-0.314453,-0.324219,0.173859,
  262.   0.140656,-0.353516,-0.347656,0.150421,-0.367188,0.138702,0.128937,-0.373047,
  263.   0.375031,-0.119141,-0.113281,0.384796,-0.101563,0.404327,0.394562,-0.107422,
  264.   -0.078125,0.427765,0.433624,-0.068359,0.414093,-0.080078,-0.089844,0.408234,
  265.   -0.031250,0.474640,0.480499,-0.021484,0.492218,-0.001953,-0.011719,0.486359,
  266.   0.453156,-0.041016,-0.035156,0.462921,-0.054688,0.451202,0.441437,-0.060547,
  267.   -0.187500,0.318390,0.324249,-0.177734,0.335968,-0.158203,-0.167969,0.330109,
  268.   0.359406,-0.134766,-0.128906,0.369171,-0.148438,0.357452,0.347687,-0.154297,
  269.   0.281281,-0.212891,-0.207031,0.291046,-0.195313,0.310577,0.300812,-0.201172,
  270.   -0.234375,0.271515,0.277374,-0.224609,0.257843,-0.236328,-0.246094,0.251984,
  271.   -0.249969,0.255859,0.261719,-0.240204,0.273438,-0.220673,-0.230438,0.267578,
  272.   0.296875,-0.197235,-0.191376,0.306641,-0.210907,0.294922,0.285156,-0.216766,
  273.   0.343750,-0.150360,-0.144501,0.353516,-0.132782,0.373047,0.363281,-0.138641,
  274.   -0.171844,0.333984,0.339844,-0.162079,0.320313,-0.173798,-0.183563,0.314453,
  275.   0.437500,-0.056610,-0.050751,0.447266,-0.039032,0.466797,0.457031,-0.044891,
  276.   -0.015594,0.490234,0.496094,-0.005829,0.476563,-0.017548,-0.027313,0.470703,
  277.   -0.093719,0.412109,0.417969,-0.083954,0.429688,-0.064423,-0.074188,0.423828,
  278.   0.390625,-0.103485,-0.097626,0.400391,-0.117157,0.388672,0.378906,-0.123016,
  279.   0.125000,-0.369110,-0.363251,0.134766,-0.351532,0.154297,0.144531,-0.357391,
  280.   -0.328094,0.177734,0.183594,-0.318329,0.164063,-0.330048,-0.339813,0.158203,
  281.   -0.281219,0.224609,0.230469,-0.271454,0.242188,-0.251923,-0.261688,0.236328,
  282.   0.203125,-0.290985,-0.285126,0.212891,-0.304657,0.201172,0.191406,-0.310516,
  283.   -0.437469,0.068359,0.074219,-0.427704,0.085938,-0.408173,-0.417938,0.080078,
  284.   0.109375,-0.384735,-0.378876,0.119141,-0.398407,0.107422,0.097656,-0.404266,
  285.   0.031250,-0.462860,-0.457001,0.041016,-0.445282,0.060547,0.050781,-0.451141,
  286.   -0.484344,0.021484,0.027344,-0.474579,0.007813,-0.486298,-0.496063,0.001953,
  287. };
  288.  
  289. /* Precomputed ray container values. */
  290.  
  291. static int Primary_Ray_State_Tested;
  292. static int Containing_Index;
  293. static TEXTURE *Containing_Textures[MAX_CONTAINING_OBJECTS];
  294. static OBJECT  *Containing_Objects[MAX_CONTAINING_OBJECTS];
  295. static DBL      Containing_IORs[MAX_CONTAINING_OBJECTS];
  296.  
  297. /* Flag wether to compute camera constant that don't change during one frame. */
  298.  
  299. static int Precompute_Camera_Constants;
  300. static DBL Camera_Aspect_Ratio;
  301.  
  302.  
  303.  
  304.  
  305.  
  306. /*****************************************************************************
  307. * Local functions
  308. ******************************************************************************/
  309.  
  310. static void focal_blur PARAMS((RAY *Ray, COLOUR Colour, DBL x, DBL y));
  311. static void jitter_camera_ray PARAMS((RAY *ray, int ray_number));
  312. static void check_stats PARAMS((int y, int doingMosaic, int pixWidth));
  313. static void do_anti_aliasing PARAMS((int x, int y, COLOUR Colour));
  314. static void output_line PARAMS((int y));
  315. static int  create_ray PARAMS((RAY *ray, DBL x, DBL y, int ray_number));
  316. static void supersample PARAMS((COLOUR result, int x, int y));
  317. static void gamma_correct PARAMS((COLOUR Colour));
  318. static void extract_colors PARAMS((COLOUR Colour, unsigned char *Red, unsigned char *Green, unsigned char *Blue, unsigned char *Alpha, DBL *grey));
  319. static void trace_pixel PARAMS((int x, int y, COLOUR Colour));
  320. static void initialise_histogram PARAMS((void)) ;
  321. static void accumulate_histogram PARAMS((int x, int y, int on));
  322. static void plot_pixel PARAMS((int x, int y, COLOUR Colour));
  323. static void jitter_pixel_position PARAMS((int x, int y, DBL *Jitter_X, DBL *Jitter_Y));
  324. static void trace_sub_pixel PARAMS((int level, PIXEL **Block, int x, int y, int x1, int y1, int x2, int y2, int size, COLOUR Colour, int antialias));
  325. static void trace_ray_with_offset PARAMS((int x, int y, DBL dx, DBL dy, COLOUR Colour));
  326. static void initialize_ray_container_state PARAMS((RAY *Ray, int Compute));
  327. static void initialize_ray_container_state_tree PARAMS((RAY *Ray, BBOX_TREE *Node));
  328.  
  329.  
  330.  
  331. /*****************************************************************************
  332. *
  333. * FUNCTION
  334. *
  335. *   Initialize_Renderer
  336. *
  337. * INPUT
  338. *   
  339. * OUTPUT
  340. *   
  341. * RETURNS
  342. *   
  343. * AUTHOR
  344. *
  345. *   POV-Ray Team
  346. *   
  347. * DESCRIPTION
  348. *
  349. *   Setup renderer. Allocate memory for line storage.
  350. *
  351. * CHANGES
  352. *
  353. *   -
  354. *
  355. ******************************************************************************/
  356.  
  357. void Initialize_Renderer PARAMS((void))
  358. {
  359.   char **Grid;
  360.   int i, xi, yi, Grid_Size;
  361.   int Standard_Sample_Grid_Size;
  362.   size_t size;
  363.   DBL x, y, len;
  364.   DBL T1;
  365.   VEC2 *Standard_Sample_Grid;
  366.  
  367.   maxclr = (DBL)(1 << Color_Bits) - 1.0;
  368.  
  369.   size = (Frame.Screen_Width + 1) * sizeof(COLOUR);
  370.  
  371.   Previous_Line = (COLOUR *)POV_MALLOC(size, "previous line buffer");
  372.   Current_Line  = (COLOUR *)POV_MALLOC(size, "current line buffer");
  373.  
  374.   for (i = 0; i <= Frame.Screen_Width ; i++)
  375.   {
  376.     Make_ColourA(Previous_Line[i], 0.0, 0.0, 0.0, 0.0, 0.0);
  377.     Make_ColourA(Current_Line[i],  0.0, 0.0, 0.0, 0.0, 0.0);
  378.   }
  379.  
  380.   if (opts.Options & ANTIALIAS)
  381.   {
  382.     size = (Frame.Screen_Width + 1) * sizeof(char);
  383.  
  384.     Previous_Line_Antialiased_Flags = (char *)POV_MALLOC(size, "previous line flags");
  385.     Current_Line_Antialiased_Flags  = (char *)POV_MALLOC(size, "current line flags");
  386.  
  387.     for (i = 0; i <= Frame.Screen_Width ; i++)
  388.     {
  389.       Previous_Line_Antialiased_Flags[i] = 0;
  390.       Current_Line_Antialiased_Flags[i]  = 0;
  391.     }
  392.   }
  393.  
  394.   Assign_Vector(Camera_Ray.Initial, Frame.Camera->Location);
  395.  
  396.   if (opts.histogram_on)
  397.   {
  398.     initialise_histogram();
  399.   }
  400.  
  401.   Focal_Blur_Is_Used = (Frame.Camera->Aperture != 0.0) && (Frame.Camera->Blur_Samples > 0);
  402.  
  403.   /* Init focal blur stuff. */
  404.  
  405.   Sample_Grid = NULL;
  406.  
  407.   Sample_Threshold = NULL;
  408.  
  409.   if (Focal_Blur_Is_Used)
  410.   {
  411.     /* Create list of thresholds for confidence test. */
  412.  
  413.     Sample_Threshold = (DBL *)POV_MALLOC(Frame.Camera->Blur_Samples*sizeof(DBL), "sample threshold list");
  414.  
  415.     if (Frame.Camera->Blur_Samples > 1)
  416.     {
  417.       T1 = Frame.Camera->Variance / chdtri((DBL)(Frame.Camera->Blur_Samples-1), Frame.Camera->Confidence);
  418.  
  419.       for (i = 0; i < Frame.Camera->Blur_Samples; i++)
  420.       {
  421.         Sample_Threshold[i] = T1 * chdtri((DBL)(i+1), Frame.Camera->Confidence);
  422.       }
  423.     }
  424.     else
  425.     {
  426.       Sample_Threshold[0] = 0.0;
  427.     }
  428.  
  429.     /* Create list of sample positions. */
  430.  
  431.     Sample_Grid = (VEC2 *)POV_MALLOC(Frame.Camera->Blur_Samples*sizeof(VEC2), "sample grid");
  432.  
  433.     /*
  434.      * Choose sample list and the best standard grid to use.
  435.      */
  436.  
  437.     /* Default is 4x4 standard grid. */
  438.  
  439.     Standard_Sample_Grid = &grid1[0];
  440.  
  441.     Standard_Sample_Grid_Size = 4;
  442.  
  443.     Current_Number_Of_Samples = NULL;
  444.  
  445.     /* Check for 7 samples hexgrid. */
  446.  
  447.     if (Frame.Camera->Blur_Samples >= hexgrid2size)
  448.     {
  449.       Standard_Sample_Grid = &hexgrid2[0];
  450.  
  451.       Standard_Sample_Grid_Size = hexgrid2size;
  452.  
  453.       Current_Number_Of_Samples = &hexgrid2samples[0];
  454.     }
  455.  
  456.     /* Check for 19 samples hexgrid. */
  457.  
  458.     if (Frame.Camera->Blur_Samples >= hexgrid3size)
  459.     {
  460.       Standard_Sample_Grid = &hexgrid3[0];
  461.  
  462.       Standard_Sample_Grid_Size = hexgrid3size;
  463.  
  464.       Current_Number_Of_Samples = &hexgrid3samples[0];
  465.     }
  466.  
  467.     /* Check for 37 samples hexgrid. */
  468.  
  469.     if (Frame.Camera->Blur_Samples >= hexgrid4size)
  470.     {
  471.       Standard_Sample_Grid = &hexgrid4[0];
  472.  
  473.       Standard_Sample_Grid_Size = hexgrid4size;
  474.  
  475.       Current_Number_Of_Samples = &hexgrid4samples[0];
  476.     }
  477.  
  478.     /* Get max. jitter. */
  479.  
  480.     switch (Frame.Camera->Blur_Samples)
  481.     {
  482.       case hexgrid2size :
  483.  
  484.         Max_Jitter = hexjitter2;
  485.  
  486.         break;
  487.  
  488.       case hexgrid3size :
  489.  
  490.         Max_Jitter = hexjitter3;
  491.  
  492.         break;
  493.  
  494.       case hexgrid4size :
  495.  
  496.         Max_Jitter = hexjitter4;
  497.  
  498.         break;
  499.  
  500.       default:
  501.  
  502.         Max_Jitter = 1.0 / (2.0 * sqrt((DBL)Frame.Camera->Blur_Samples));
  503.     }
  504.  
  505.     /* Copy standard grid to sample grid. */
  506.  
  507.     for (i = 0; i < min(Standard_Sample_Grid_Size, Frame.Camera->Blur_Samples); i++)
  508.     {
  509.       Sample_Grid[i] = Standard_Sample_Grid[i];
  510.     }
  511.  
  512.     /* Choose remaining samples from a uniform grid to get "best" coverage. */
  513.  
  514.     if (Frame.Camera->Blur_Samples > Standard_Sample_Grid_Size)
  515.     {
  516.       /* Get sub-pixel grid size (I want it to be odd). */
  517.  
  518.       Grid_Size = (int)sqrt((DBL)Frame.Camera->Blur_Samples) + 1;
  519.  
  520.       if ((Grid_Size & 1) == 0)
  521.       {
  522.         Grid_Size++;
  523.       }
  524.  
  525.       /* Allocate temporary grid. */
  526.  
  527.       Grid = (char **)POV_MALLOC(Grid_Size * sizeof(int *), "temporary sub-pixel grid");
  528.  
  529.       for (i = 0; i < Grid_Size; i++)
  530.       {
  531.         Grid[i] = (char *)POV_CALLOC((unsigned)Grid_Size, sizeof(int), "temporary sub-pixel grid");
  532.       }
  533.  
  534.       /* Mark sub-pixels already covered. */
  535.  
  536.       for (i = 0; i < Standard_Sample_Grid_Size; i++)
  537.       {
  538.         xi = (int)((Sample_Grid[i].x + 0.5) * (DBL)Grid_Size);
  539.         yi = (int)((Sample_Grid[i].y + 0.5) * (DBL)Grid_Size);
  540.  
  541.         Grid[yi][xi] = TRUE;
  542.       }
  543.  
  544.       /* Distribute remaining samples. */
  545.  
  546.       for (i = Standard_Sample_Grid_Size; i < Frame.Camera->Blur_Samples; )
  547.       {
  548.         xi = POV_RAND() % Grid_Size;
  549.         yi = POV_RAND() % Grid_Size;
  550.  
  551.         if (!Grid[yi][xi])
  552.         {
  553.           x = (DBL)(2 * xi + 1) / (DBL)(2 * Grid_Size) - 0.5;
  554.           y = (DBL)(2 * yi + 1) / (DBL)(2 * Grid_Size) - 0.5;
  555.  
  556.           Sample_Grid[i].x = x;
  557.           Sample_Grid[i].y = y;
  558.  
  559.           Grid[yi][xi] = TRUE;
  560.  
  561.           i++;
  562.         }
  563.       }
  564.  
  565.       /* Free temporary grid. */
  566.  
  567.       for (i = 0; i < Grid_Size; i++)
  568.       {
  569.         POV_FREE(Grid[i]);
  570.       }
  571.  
  572.       POV_FREE(Grid);
  573.     }
  574.  
  575.     /*
  576.      * Calculate vectors perpendicular to the current ray
  577.      * We're making a "+" (crosshair) on the film plane.
  578.      */
  579.  
  580.     /* XPerp = vector perpendicular to y/z plane */
  581.  
  582.     VCross(XPerp, Frame.Camera->Up, Frame.Camera->Direction);
  583.  
  584.     VNormalize(XPerp, XPerp);
  585.  
  586.     /* YPerp = vector perpendicular to x/z plane */
  587.  
  588.     VCross(YPerp, Frame.Camera->Direction, XPerp);
  589.  
  590.     VNormalize(YPerp, YPerp);
  591.  
  592.     /* Get adjusted distance to focal plane. */
  593.  
  594.     VLength(len, Frame.Camera->Direction);
  595.  
  596.     Focal_Distance = Frame.Camera->Focal_Distance / len;
  597.   }
  598.  
  599.   /* If a single frame is traced disable field rendering. */
  600. /* Disabled 11/12/95 CEY
  601.   if (opts.FrameSeq.FrameType == FT_SINGLE_FRAME)
  602.   {
  603.     opts.FrameSeq.Field_Render_Flag = FALSE;
  604.   }
  605. */
  606.  
  607.   /* We have to precalculate all camera constants. */
  608.  
  609.   Precompute_Camera_Constants = TRUE;
  610.  
  611.   Primary_Ray_State_Tested = FALSE; 
  612. }
  613.  
  614.  
  615.  
  616. /*****************************************************************************
  617. *
  618. * FUNCTION
  619. *
  620. *   Terminate_Renderer
  621. *
  622. * INPUT
  623. *
  624. * OUTPUT
  625. *
  626. * RETURNS
  627. *
  628. * AUTHOR
  629. *
  630. *   POV-Ray Team
  631. *   
  632. * DESCRIPTION
  633. *
  634. *   -
  635. *
  636. * CHANGES
  637. *
  638. *   -
  639. *
  640. ******************************************************************************/
  641.  
  642. void Terminate_Renderer()
  643. {
  644.   if (Previous_Line != NULL)
  645.   {
  646.     POV_FREE(Previous_Line);
  647.     POV_FREE(Current_Line);
  648.  
  649.     Previous_Line = NULL;
  650.     Current_Line  = NULL;
  651.   }
  652.  
  653.   if (Previous_Line_Antialiased_Flags != NULL)
  654.   {
  655.     POV_FREE(Previous_Line_Antialiased_Flags);
  656.     POV_FREE(Current_Line_Antialiased_Flags);
  657.  
  658.     Previous_Line_Antialiased_Flags = NULL;
  659.     Current_Line_Antialiased_Flags  = NULL;
  660.   }
  661.  
  662.   if (Focal_Blur_Is_Used)
  663.   {
  664.     if (Sample_Threshold != NULL)
  665.     {
  666.       POV_FREE(Sample_Threshold);
  667.  
  668.       Sample_Threshold = NULL;
  669.     }
  670.  
  671.     if (Sample_Grid != NULL)
  672.     {
  673.       POV_FREE(Sample_Grid);
  674.  
  675.       Sample_Grid = NULL;
  676.     }
  677.   }
  678. }
  679.  
  680.  
  681.  
  682. /*****************************************************************************
  683. *
  684. * FUNCTION
  685. *
  686. *   Read_Rendered_Part
  687. *
  688. * INPUT
  689. *   
  690. * OUTPUT
  691. *   
  692. * RETURNS
  693. *   
  694. * AUTHOR
  695. *
  696. *   POV-Ray Team
  697. *   
  698. * DESCRIPTION
  699. *
  700. *   -
  701. *
  702. * CHANGES
  703. *
  704. *   Sep 1994 : Call extract_colors to get pixel's color. [DB]
  705. *
  706. ******************************************************************************/
  707.  
  708. void Read_Rendered_Part(New_Fname)
  709. char *New_Fname;
  710. {
  711.   int rc, x, line_number = 0;
  712.   unsigned char Red, Green, Blue, Alpha;
  713.   DBL grey;
  714.  
  715.   maxclr = (DBL)(1 << Color_Bits) - 1.0;
  716.  
  717.   while ((rc = Read_Line(Output_File_Handle, Previous_Line, &line_number)) == 1)
  718.   {
  719.     if (opts.Options & DISPLAY)
  720.     {
  721.       for (x = 0; x < Frame.Screen_Width ; x++)
  722.       {
  723.         extract_colors(Previous_Line[x], &Red, &Green, &Blue, &Alpha, &grey);
  724.  
  725.         POV_DISPLAY_PLOT(x, line_number, Red, Green, Blue, Alpha);
  726.  
  727.         COOPERATE_1
  728.       }
  729.     }
  730.   }
  731.  
  732.   opts.First_Line = line_number + 1;
  733.  
  734.   Close_File(Output_File_Handle);
  735.  
  736.   if (rc == 0)
  737.   {
  738.     if (Open_File(Output_File_Handle, New_Fname,
  739.         &Frame.Screen_Width, &Frame.Screen_Height, opts.File_Buffer_Size,
  740.         APPEND_MODE) != 1)
  741.     {
  742.       Error("Error opening output file.\n");
  743.     }
  744.  
  745.     return;
  746.   }
  747.  
  748.   Error("Error reading aborted data file.\n");
  749. }
  750.  
  751.  
  752.  
  753. /*****************************************************************************
  754. *
  755. * FUNCTION
  756. *
  757. *   Check_User_Abort
  758. *
  759. * INPUT
  760. *
  761. *   Forced -- if FALSE, then check else force user abort
  762. *   
  763. * OUTPUT
  764. *   
  765. * RETURNS
  766. *   
  767. * AUTHOR
  768. *
  769. *   POV-Ray Team
  770. *   
  771. * DESCRIPTION
  772. *
  773. *   Exit with error if image not completed/user abort.
  774. *
  775. * CHANGES
  776. *
  777. *   -
  778. *
  779. ******************************************************************************/
  780.  
  781. void Check_User_Abort(Forced)
  782. int Forced;
  783. {
  784.   if (Forced)
  785.   {
  786.      Stop_Flag=TRUE;
  787.   }
  788.   else
  789.   {
  790.     if (--opts.Abort_Test_Counter <= 0)
  791.     {
  792.       opts.Abort_Test_Counter = Abort_Test_Every;
  793.  
  794.       TEST_ABORT
  795.     }
  796.   }
  797.  
  798.   if (Stop_Flag)
  799.   {
  800.     Render_Info("\nAborting render...\n");
  801.  
  802.     if ((opts.Options & DISPLAY) && Display_Started)
  803.     {
  804.       POV_DISPLAY_CLOSE
  805.     }
  806.  
  807.     if (opts.Do_Stats)
  808.     {
  809.       PRINT_STATS(stats);
  810.     }
  811.  
  812.     Error("User abort.\n");
  813.   }
  814. }
  815.  
  816.  
  817.  
  818. /*****************************************************************************
  819. *
  820. * FUNCTION
  821. *
  822. *   Start_Tracing_Mosaic_Preview
  823. *
  824. * INPUT
  825. *
  826. *   MosaicPixelSize - # of pixels square to start
  827. *   
  828. * OUTPUT
  829. *   
  830. * RETURNS
  831. *   
  832. * AUTHOR
  833. *
  834. *   Eduard Schwan
  835. *   
  836. * DESCRIPTION
  837. *
  838. *   Trace the entire image, but instead of doing it pixel by pixel,
  839. *   draw every 8th pixel, then every 4th, then every 2nd, then
  840. *   every pixel. This shows the image as a quick chunky preview,
  841. *   and the image gets more detailed as each pass redraws it in
  842. *   increasing detail.  This is a simple subdivision preview method.
  843. *   On the first pass, the entire screen is painted.  On each subsequent
  844. *   pass, smaller squares are painted to fill in more detail.  Any
  845. *   squares that were already calculated on previous passes are NOT
  846. *   redrawn, making this mode just as fast as the non-preview rendering
  847. *   mode (ignoring additional time used by rectangle screen painting.)
  848. *
  849. * CHANGES
  850. *
  851. *   Aug 1994 : Created from Start_Tracing, by Eduard Schwan
  852. *   Dec 1994 : Updated for more regular scanning, by Eduard Schwan
  853. *
  854. ******************************************************************************/
  855.  
  856. void Start_Tracing_Mosaic_Preview(StartPixelSize, EndPixelSize)
  857. int StartPixelSize, EndPixelSize;
  858. {
  859.   unsigned char Red, Green, Blue, Alpha;
  860.   int x, y, x2, y2, PreviewStep, PixelSize, AlreadyPainted, PreviewPass;
  861.   COLOUR Colour;
  862.   DBL grey;
  863.  
  864.   /* PreviewStep tracks how many pixels to skip on each square painted */
  865.  
  866.   PreviewStep = StartPixelSize;
  867.  
  868.   /* do each pass of the image */
  869.   /* increment pass counter and divide PixelSize & PreviewStep by 2 */
  870.  
  871.   for (PreviewPass = 1, PixelSize = StartPixelSize;
  872.         PixelSize >= EndPixelSize;
  873.         PreviewPass++, PixelSize >>= 1, PreviewStep >>= 1)
  874.   {
  875.     /* do each row */
  876.  
  877.     for (y = opts.First_Line; y < opts.Last_Line; y += PreviewStep)
  878.     {
  879.       /* show some status information */
  880.       /* note, this fn should change to show new style for preview */
  881.  
  882.       check_stats(y, 1, PixelSize);
  883.  
  884.       /* do each column/pixel on a row */
  885.  
  886.       for (x = opts.First_Column; x < opts.Last_Column; x += PreviewStep)
  887.       {
  888.         Check_User_Abort(FALSE);
  889.  
  890.         /*
  891.          * Skip any pixels we have done previously.  These would be any pixels
  892.          * that are on a row AND column that is divisible by the previous
  893.          * pass's step-size.  On the first pass, however, do ALL pixels, since
  894.          * there is nothing to skip.
  895.          */
  896.  
  897.         AlreadyPainted = FALSE;
  898.  
  899.         if (PreviewPass > 1)
  900.         {
  901.           if ( ((x-opts.First_Column) % (PreviewStep*2) == 0) &&
  902.                ((y-opts.First_Line) % (PreviewStep*2) == 0) )
  903.           {
  904.             AlreadyPainted = TRUE;
  905.           }
  906.         }
  907.  
  908.         if (!AlreadyPainted)
  909.         {
  910.           /* OK, it is safe to draw this pixel */
  911.  
  912.           trace_pixel(x, y, Colour);
  913.  
  914.           extract_colors(Colour, &Red, &Green, &Blue, &Alpha, &grey);
  915.  
  916.           y2 = min(y + PixelSize - 1, opts.Last_Line);
  917.           x2 = min(x + PixelSize - 1, opts.Last_Column);
  918.  
  919.           POV_DISPLAY_PLOT_RECT(x, x2, y, y2, Red, Green, Blue, Alpha);
  920.         }
  921.       }
  922.  
  923.       if (opts.Options & VERBOSE)
  924.       {
  925.         Status_Info("\r");
  926.       }
  927.     }
  928.   }
  929. }
  930.  
  931.  
  932.  
  933. /*****************************************************************************
  934. *
  935. * FUNCTION
  936. *
  937. *   Start_Tracing_Mosaic_Smooth
  938. *
  939. * INPUT
  940. *
  941. *   MosaicPixelSize - # of pixels square to start
  942. *   
  943. * OUTPUT
  944. *
  945. * RETURNS
  946. *   
  947. * AUTHOR
  948. *
  949. *   Eduard Schwan
  950. *   
  951. * DESCRIPTION
  952. *
  953. *   See comments for Start_Tracing_Mosaic_Preview.
  954. *   Radiosity requires this pass, so it is not optional, and does not
  955. *   require you to set Mosaic_Preview_Start and End.
  956. *   This function does a smooth interpolation of pixel values, so as
  957. *   a result, it re-renders the pixels done on previous passes, so it
  958. *   is about 1/16th slower.  This function will take any tile size, not
  959. *   just powers of two.  The smooth interpolation is conditional, since
  960. *   on some platforms it is quite slow.  When you're doing radiosity,
  961. *   life is slow anyway, so the smooth effect is very nice.
  962. *   Most important difference is that this function does jittering, so
  963. *   that the places at which radiosity tends to be calculated don't lie
  964. *   on a grid and produce unpleasant grid artefacts.
  965. *   This doesn't really have to be a separate function;  the two
  966. *   could be merged.
  967. *
  968. * CHANGES
  969. *
  970. *   Apr 1995 : Created with first radiosity patches
  971. *   Feb 1996 : Made the row buffers dynamically allocated [AED]
  972. *
  973. ******************************************************************************/
  974. void Start_Tracing_Mosaic_Smooth(StartPixelSize, EndPixelSize)
  975. int StartPixelSize, EndPixelSize;
  976. {
  977.   unsigned char Red, Green, Blue, Alpha;
  978.   unsigned char *thisr = NULL, *thisg = NULL, *thisb = NULL, *thisa = NULL;
  979.   unsigned char *upr = NULL, *upg = NULL, *upb = NULL, *upa = NULL;
  980.   int Smooth_Preview = 0;
  981.   int dx, dy, skip,
  982.       tr, tg, tb, ta,
  983.       lastr, lastg, lastb, lasta,
  984.       ulr, urr, llr, lrr,
  985.       ulg, urg, llg, lrg,
  986.       ulb, urb, llb, lrb,
  987.       ula, ura, lla, lra,
  988.       lor, log, lob, loa,
  989.       hir, hig, hib, hia,
  990.       tx, ty, jitter_range, jitter_offset, offset_x, offset_y, first_pass,
  991.       x, y, x2, y2;
  992.   DBL grey, gather_grey;
  993.   COLOUR Colour, avg_gather;
  994.  
  995.   lastr = lastg = lastb = lasta = 0;
  996.  
  997.   opts.Radiosity_Error_Bound *= opts.Radiosity_Low_Error_Factor;
  998.  
  999.   /* Initialize the accumulators which will allow us to set average amb Brightness */
  1000.   Make_Colour(Radiosity_Gather_Total, 0.0, 0.0, 0.0);
  1001.   Radiosity_Gather_Total_Count = 0;
  1002.  
  1003.   /* if radiosity is on, you MUST use preview pass to get reasonable results.
  1004.    * 8x8 is generally a good size to use if the user didn't specify anything.
  1005.    */
  1006.   if ( StartPixelSize == 1 )  StartPixelSize = EndPixelSize = 8;
  1007.  
  1008.   /* Prevent 2x2 or 1x1 passes - this code is very slow at 2x2 or less */
  1009.   if ( StartPixelSize < 4)  StartPixelSize = 4;
  1010.   if ( EndPixelSize   < 4)  EndPixelSize = 4;
  1011.  
  1012.   /* if there is no visible output, might as well just do one pass, it's faster.
  1013.    * The last pass is the one which determines the values which get put into
  1014.    * the radiosity tree, so just do the last (end) pass.
  1015.    */
  1016.   if ( !(opts.Options & DISPLAY))  StartPixelSize = EndPixelSize;
  1017.  
  1018.   /* Finally, end size must always be less than or equal to start size */
  1019.   if ( EndPixelSize > StartPixelSize ) EndPixelSize = StartPixelSize;
  1020.  
  1021.  
  1022.   skip = StartPixelSize;
  1023.   first_pass = TRUE;
  1024.  
  1025.   if (opts.Options & DISPLAY)
  1026.   {
  1027.     upr = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  1028.     upg = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  1029.     upb = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  1030.     upa = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  1031.  
  1032.     thisr = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  1033.     thisg = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  1034.     thisb = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  1035.     thisa = (unsigned char *)POV_MALLOC(opts.Last_Column, "mosaic row buffer");
  1036.   }
  1037.  
  1038.   while ((skip >= 4) && (skip >= EndPixelSize))
  1039.   {
  1040.     /* for each pass */
  1041.  
  1042.     jitter_range  = 3;
  1043.     jitter_offset = skip / 2 - 1;       /* add a very small amount of jitter */
  1044.  
  1045.     if ( skip <= 8 ) Smooth_Preview = 1;
  1046.  
  1047.     for (y = opts.First_Line; y < opts.Last_Line; y += skip)
  1048.     {
  1049.       check_stats(y, 1, skip);
  1050.  
  1051.       for (x = opts.First_Column; x < opts.Last_Column; x += skip)
  1052.       {
  1053.         Check_User_Abort(FALSE);
  1054.  
  1055.         offset_x = jitter_offset + (POV_RAND() % jitter_range);
  1056.         offset_y = jitter_offset + (POV_RAND() % jitter_range);
  1057.  
  1058.         trace_pixel(x + offset_x, y + offset_y, Colour);
  1059.  
  1060.         extract_colors(Colour, &Red, &Green, &Blue, &Alpha, &grey);
  1061.  
  1062.         Assign_Colour(Current_Line[x], Colour);
  1063.  
  1064.         if (opts.Options & DISPLAY)
  1065.         {
  1066.           if ( Smooth_Preview )
  1067.           {
  1068.             /* if smooth colour blending desired */
  1069.  
  1070.             if (y == opts.First_Line)
  1071.             {
  1072.               upr[x] = Red;
  1073.               upg[x] = Green;
  1074.               upb[x] = Blue;
  1075.               upa[x] = Alpha;
  1076.             }
  1077.  
  1078.             ulr = (x>0) ? upr[x-skip] : Red;
  1079.             urr = upr[x];
  1080.  
  1081.             llr = (x>0) ? lastr   : Red;
  1082.             lrr = Red;
  1083.  
  1084.             ulg = (x>0) ? upg[x-skip] : Green;
  1085.             urg = upg[x];
  1086.  
  1087.             llg = (x>0) ? lastg   : Green;
  1088.             lrg = Green;
  1089.  
  1090.             ulb = (x>0) ? upb[x-skip] : Blue;
  1091.             urb = upb[x];
  1092.  
  1093.             llb = (x>0) ? lastb   : Blue;
  1094.             lrb = Blue;
  1095.  
  1096.             ula = (x>0) ? upa[x-skip] : Alpha;
  1097.             ura = upa[x];
  1098.  
  1099.             lla = (x>0) ? lasta   : Alpha;
  1100.             lra = Alpha;
  1101.  
  1102.             for (ty = y, dy = 0; (dy < skip) && (ty < opts.Last_Line); dy++, ty++)
  1103.             {
  1104.               lor = (ulr * (skip-dy) + llr * dy) / skip;
  1105.               hir = (urr * (skip-dy) + lrr * dy) / skip;
  1106.               log = (ulg * (skip-dy) + llg * dy) / skip;
  1107.               hig = (urg * (skip-dy) + lrg * dy) / skip;
  1108.               lob = (ulb * (skip-dy) + llb * dy) / skip;
  1109.               hib = (urb * (skip-dy) + lrb * dy) / skip;
  1110.               loa = (ula * (skip-dy) + lla * dy) / skip;
  1111.               hia = (ura * (skip-dy) + lra * dy) / skip;
  1112.  
  1113.               for (tx = x, dx = 0; (dx < skip) && (tx < opts.Last_Column); dx++, tx++)
  1114.               {
  1115.                 tr = (lor * (skip - dx) + (hir * dx)) / skip;
  1116.                 tg = (log * (skip - dx) + (hig * dx)) / skip;
  1117.                 tb = (lob * (skip - dx) + (hib * dx)) / skip;
  1118.                 ta = (loa * (skip - dx) + (hia * dx)) / skip;
  1119.  
  1120.                 POV_DISPLAY_PLOT (tx, y+dy, tr, tg, tb, ta);
  1121.               }
  1122.             }
  1123.  
  1124.             thisr[x] = Red;
  1125.             thisg[x] = Green;
  1126.             thisb[x] = Blue;
  1127.             thisa[x] = Alpha;
  1128.  
  1129.             lastr = Red;
  1130.             lastg = Green;
  1131.             lastb = Blue;
  1132.             lasta = Alpha;
  1133.           }
  1134.           else
  1135.           {
  1136.             y2 = min(y + skip - 1, opts.Last_Line);
  1137.             x2 = min(x + skip - 1, opts.Last_Column);
  1138.  
  1139.             POV_DISPLAY_PLOT_RECT(x, x2, y, y2, Red, Green, Blue, Alpha);
  1140.           }
  1141.         }
  1142.       } /* end loop for each block horizontally in a row of blocks */
  1143.  
  1144.       /* Swap the previous and current row buffers */
  1145.       if (opts.Options & DISPLAY)
  1146.       {
  1147.         unsigned char * temp;
  1148.  
  1149.         temp = upr;
  1150.         upr = thisr;
  1151.         thisr = temp;
  1152.  
  1153.         temp = upg;
  1154.         upg = thisg;
  1155.         thisg = temp;
  1156.  
  1157.         temp = upb;
  1158.         upb = thisb;
  1159.         thisb = temp;
  1160.  
  1161.         temp = upa;
  1162.         upa = thisa;
  1163.         thisa = temp;
  1164.       }
  1165.  
  1166.       if (opts.Options & VERBOSE)
  1167.       {
  1168.         if (opts.Options & RADIOSITY)
  1169.         {
  1170.           Status_Info("  %ld radiosity samples", ra_gather_count - RadiosityCount);
  1171.         }
  1172.  
  1173.         Status_Info(".    \r");
  1174.       }
  1175.     } /* end loop of rows of blocks */
  1176.  
  1177.     /*
  1178.      * This adjusts the overall brightness value so that the darkening
  1179.      * effect of the radiosity calculation is cancelled out.
  1180.      */
  1181.  
  1182.     if (first_pass)
  1183.     {
  1184.       /* Ensure that the average ambient value returned by compute_ambient() is about
  1185.        * the same as the average ambient value setting in the scene file
  1186.        */
  1187.  
  1188.       if ( Radiosity_Gather_Total_Count )
  1189.       {
  1190.         VInverseScale(avg_gather,  Radiosity_Gather_Total,  (DBL)Radiosity_Gather_Total_Count);
  1191.         gather_grey  = avg_gather[RED]  + avg_gather[GREEN]  + avg_gather[BLUE];
  1192.         if ( gather_grey > 0. )
  1193.         {
  1194.           opts.Radiosity_Brightness = 3. / gather_grey;
  1195.           if ( ot_fd != NULL)
  1196.           { 
  1197.             fprintf(ot_fd, "B%g\n", opts.Radiosity_Brightness);
  1198.           } 
  1199.         }
  1200.       }
  1201.  
  1202.       first_pass = 0;
  1203.     }
  1204.  
  1205.     skip /= 2;
  1206.   } /* end loop of different resolutions */
  1207.  
  1208.   /* Free our row buffers */
  1209.   if (opts.Options & DISPLAY)
  1210.   {
  1211.     POV_FREE(upr);      upr=NULL;  
  1212.     POV_FREE(upg);      upg=NULL;  
  1213.     POV_FREE(upb);      upb=NULL;  
  1214.     POV_FREE(upa);      upa=NULL;  
  1215.                                           
  1216.     POV_FREE(thisr);    thisr=NULL;
  1217.     POV_FREE(thisg);    thisg=NULL;
  1218.     POV_FREE(thisb);    thisb=NULL;
  1219.     POV_FREE(thisa);    thisa=NULL;
  1220.   }
  1221.  
  1222.   opts.Radiosity_Error_Bound /= opts.Radiosity_Low_Error_Factor;
  1223.  
  1224.   if (opts.Options & VERBOSE)
  1225.   {
  1226.     Status_Info("                                                                      \r");
  1227.   }
  1228.   
  1229.   /* Are we in the process of creating a radiosity cache file? */
  1230.   if ( ot_fd != NULL )
  1231.   {
  1232.     fprintf(ot_fd, "P\n");   /* code meaning that preview pass was completed */
  1233.   }
  1234.   opts.Radiosity_Preview_Done = 1;
  1235. }
  1236.  
  1237.  
  1238. /*****************************************************************************
  1239. *
  1240. * FUNCTION
  1241. *
  1242. *   Start_Non_Adaptive_Tracing
  1243. *
  1244. * INPUT
  1245. *   
  1246. * OUTPUT
  1247. *   
  1248. * RETURNS
  1249. *   
  1250. * AUTHOR
  1251. *
  1252. *   POV-Ray Team
  1253. *   
  1254. * DESCRIPTION
  1255. *
  1256. *   Trace pixels by shooting rays at the center of each pixel. If the
  1257. *   colors between a pixel and its left and/or upper neighbor differ
  1258. *   too much all or some of the pixel are supersampled using a fixed
  1259. *   number of rays.
  1260. *
  1261. * CHANGES
  1262. *
  1263. *   Aug 1994 : Modified to call common extract_colors() fn, Eduard Schwan
  1264. *
  1265. *   Sep 1994 : Added code for vista buffer. [DB]
  1266. *
  1267. *   Aug 1995 : Added Field Rendering for NTSC/PAL Animations, Jeff Bowermaster
  1268. *
  1269. *   Aug 1995 : Added code to jitter pixel location. [DB]
  1270. *
  1271. ******************************************************************************/
  1272.  
  1273. void Start_Non_Adaptive_Tracing()
  1274. {
  1275.   int x, y;
  1276.   int antialias_line = TRUE;
  1277.   int skip_lines;
  1278.   int first_line;
  1279.   int skip_odd_lines;
  1280.  
  1281.   /* Set jitterscale. */
  1282.  
  1283.   JitterScale = opts.JitterScale / (DBL)opts.AntialiasDepth;
  1284.  
  1285.   /* Odd/even line tracing depends on the frame number. */
  1286.  
  1287.   skip_odd_lines = !((opts.FrameSeq.FrameNumber % 2) ^ opts.FrameSeq.Odd_Field_Flag);
  1288.  
  1289.   /* Field rendering starts on an odd or even line. */
  1290.  
  1291.   skip_lines = (opts.FrameSeq.Field_Render_Flag) && !(opts.Options & ANTIALIAS);
  1292.  
  1293.   /* Get first line number. */
  1294.  
  1295.   first_line = (opts.Options & ANTIALIAS)?opts.First_Line-1:opts.First_Line;
  1296.  
  1297.   /* Loop over all rows. */
  1298.  
  1299.   for (y = first_line; y < opts.Last_Line; y++)
  1300.   {
  1301.     /* Skip odd or even lines depending on the line number. */
  1302.  
  1303.     if ((skip_lines) && ((y % 2) == skip_odd_lines))
  1304.     {
  1305.       /* Write previous line again. */
  1306.  
  1307.       if ((opts.Options & DISKWRITE) && (y > opts.First_Line))
  1308.       {
  1309.         Write_Line(Output_File_Handle, Previous_Line, y);
  1310.       }
  1311.  
  1312.       continue;
  1313.     }
  1314.  
  1315.     check_stats(y, 0, 1);
  1316.  
  1317.     /* Prune vista tree. */
  1318.  
  1319.     Prune_Vista_Tree(y);
  1320.  
  1321.     /* Precalculate whether to antialias a line. */
  1322.  
  1323.     if (opts.FrameSeq.Field_Render_Flag)
  1324.     {
  1325.       if (y >= opts.First_Line)
  1326.       {
  1327.         antialias_line = ((y % 2) ^ skip_odd_lines);
  1328.       }
  1329.       else
  1330.       {
  1331.         antialias_line = FALSE;
  1332.       }
  1333.     }
  1334.  
  1335.     /* Loop over all columns. */
  1336.  
  1337.     for (x = opts.First_Column; x < opts.Last_Column; x++)
  1338.     {
  1339.       /* Check for user abort. */
  1340.  
  1341.       Check_User_Abort(FALSE);
  1342.  
  1343.       /* Trace current pixel. */
  1344.  
  1345. /*
  1346.       Debug_Info("y = %3d, x = %3d\n", y, x);
  1347. */
  1348.  
  1349.       trace_pixel(x, y, Current_Line[x]);
  1350.  
  1351.       /* Apply anti-aliasing. */
  1352.  
  1353.       if ((opts.Options & ANTIALIAS) && antialias_line)
  1354.       {
  1355.         do_anti_aliasing(x, y, Current_Line[x]);
  1356.       }
  1357.  
  1358.       /* Display pixel. */
  1359.  
  1360.       plot_pixel(x, y, Current_Line[x]);
  1361.     }
  1362.  
  1363.     /* Write current row to disk. */
  1364.  
  1365.     output_line(y);
  1366.   }
  1367.  
  1368.   /* Write last row to disk. */
  1369.  
  1370.   if (opts.Options & DISKWRITE)
  1371.   {
  1372.     if (opts.Last_Line != opts.First_Line)
  1373.     {
  1374.       Write_Line(Output_File_Handle, Previous_Line, opts.Last_Line - 1);
  1375.     }
  1376.   }
  1377. }
  1378.  
  1379.  
  1380.  
  1381. /*****************************************************************************
  1382. *
  1383. * FUNCTION
  1384. *
  1385. *   Start_Adaptive_Tracing
  1386. *
  1387. * INPUT
  1388. *
  1389. * OUTPUT
  1390. *   
  1391. * RETURNS
  1392. *   
  1393. * AUTHOR
  1394. *
  1395. *   Dieter Bayer
  1396. *   
  1397. * DESCRIPTION
  1398. *
  1399. *   Trace pixels by shooting rays at each corner of a pixel and subdividing
  1400. *   if the colors ate the pixel's corenr differ too much. The subdivision
  1401. *   is made recursively by further subdividing those sub-pixels whose colors
  1402. *   differ too much.
  1403. *
  1404. *   Note that is doesn't make any sense to skip line during field tracing
  1405. *   because samples are taken at the corners of the pixels and are shared
  1406. *   among adjacent lines/pixels. Thus leaving every second line doesn't
  1407. *   save anything. The subdivision is only done on the odd/even lines
  1408. *   depending on the lines to be traced.
  1409. *
  1410. * CHANGES
  1411. *
  1412. *   Jul 1995 : Creation
  1413. *
  1414. *   Aug 1995 : Added field rendering support. [DB]
  1415. *
  1416. ******************************************************************************/
  1417.  
  1418. void Start_Adaptive_Tracing()
  1419. {
  1420.   int x, y, xx, xxx, yy, skip_odd_lines;
  1421.   int sub_pixel_size, antialias_line = TRUE;
  1422.   size_t size;
  1423.   COLOUR Colour;
  1424.   PIXEL *First_Row, *Last_Row, **Block, *TempRow, TempPixel;
  1425.  
  1426.   /* If no antialiasing is specified use non-adaptive sampling. */
  1427.  
  1428.   if (!(opts.Options & ANTIALIAS))
  1429.   {
  1430.     Start_Non_Adaptive_Tracing();
  1431.  
  1432.     return;
  1433.   }
  1434.   
  1435.   /* Init color. */
  1436.  
  1437.   Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  1438.  
  1439.   /* Odd/even line tracing depends on the frame number. */
  1440.  
  1441.   skip_odd_lines = !((opts.FrameSeq.FrameNumber % 2) ^ opts.FrameSeq.Odd_Field_Flag);
  1442.  
  1443.   /* Set sub-pixel size to 2**(AntialiasDepth) */
  1444.  
  1445.   sub_pixel_size = 1 << (opts.AntialiasDepth);
  1446.  
  1447.   /* Set jitterscale. */
  1448.  
  1449.   JitterScale = opts.JitterScale / (DBL)(sub_pixel_size+1);
  1450.  
  1451.   /* Allocate row arrays */
  1452.  
  1453.   size = (sub_pixel_size * Frame.Screen_Width + 1) * sizeof(PIXEL);
  1454.  
  1455.   First_Row = (PIXEL *)POV_MALLOC(size, "row buffer");
  1456.   Last_Row  = (PIXEL *)POV_MALLOC(size, "row buffer");
  1457.  
  1458.   /* Allocate block array */
  1459.  
  1460.   Block = (PIXEL **)POV_MALLOC((sub_pixel_size+1) * sizeof(PIXEL *), "block buffer");
  1461.  
  1462.   for (y = 0; y < sub_pixel_size + 1; y++)
  1463.   {
  1464.     Block[y] = (PIXEL *)POV_MALLOC((sub_pixel_size+1) * sizeof(PIXEL), "block buffer");
  1465.   }
  1466.  
  1467.  
  1468.   /**************************************************************************
  1469.    * Init row and block buffer
  1470.    **************************************************************************/
  1471.  
  1472.   for (x = 0; x < sub_pixel_size * Frame.Screen_Width + 1; x++)
  1473.   {
  1474.     First_Row[x].active = FALSE;
  1475.     Last_Row[x].active  = FALSE;
  1476.  
  1477.     Make_ColourA(First_Row[x].Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  1478.     Make_ColourA(Last_Row[x].Colour,  0.0, 0.0, 0.0, 0.0, 0.0);
  1479.   }
  1480.  
  1481.   for (y = 0; y < sub_pixel_size + 1; y++)
  1482.   {
  1483.     for (x = 0; x < sub_pixel_size + 1; x++)
  1484.     {
  1485.       Block[y][x].active = FALSE;
  1486.  
  1487.       Make_ColourA(Block[y][x].Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  1488.     }
  1489.   }
  1490.  
  1491.  
  1492.   /**************************************************************************
  1493.    * Trace all lines, i.e. the image
  1494.    **************************************************************************/
  1495.  
  1496.   for (y = opts.First_Line; y < opts.Last_Line; y++)
  1497.   {
  1498.     check_stats(y, 0, 1);
  1499.  
  1500.     if (opts.Options & USE_VISTA_BUFFER)
  1501.     {
  1502.       Prune_Vista_Tree(y);
  1503.     }
  1504.  
  1505.     /* Set last row inactive */
  1506.  
  1507.     for (xx = 0; xx < sub_pixel_size * Frame.Screen_Width + 1; xx++)
  1508.     {
  1509.       Last_Row[xx].active = FALSE;
  1510.     }
  1511.  
  1512.     /* Set first column inactive */
  1513.  
  1514.     for (yy = 0; yy < sub_pixel_size + 1; yy++)
  1515.     {
  1516.       Block[yy][0].active = FALSE;
  1517.     }
  1518.  
  1519.     /* Precalculate whether to antialias a line. */
  1520.  
  1521.     if (opts.FrameSeq.Field_Render_Flag)
  1522.     {
  1523.       antialias_line = (y % 2) ^ skip_odd_lines;
  1524.     }
  1525.  
  1526.  
  1527.     /************************************************************************
  1528.      * Trace all pixels on the current line
  1529.      ************************************************************************/
  1530.  
  1531.     for (x = opts.First_Column; x < opts.Last_Column; x++)
  1532.     {
  1533.       Check_User_Abort(FALSE);
  1534.  
  1535.       Increase_Counter(stats[Number_Of_Pixels]);
  1536.  
  1537.       /* Initialize current block */
  1538.  
  1539.       for (yy = 1; yy < sub_pixel_size + 1; yy++)
  1540.       {
  1541.         for (xx = 1; xx < sub_pixel_size + 1; xx++)
  1542.         {
  1543.           Block[yy][xx].active = FALSE;
  1544.         }
  1545.       }
  1546.  
  1547.       for (xxx = 0, xx = x * sub_pixel_size; xx < (x+1) * sub_pixel_size + 1; xxx++, xx++)
  1548.       {
  1549.         Block[0][xxx] = First_Row[xx];
  1550.       }
  1551.  
  1552.       /* Do histogram stuff. */
  1553.  
  1554.       if (opts.histogram_on)
  1555.       {
  1556.         accumulate_histogram(x, y, TRUE);
  1557.       }
  1558.  
  1559.       /* Trace pixel centered on (x, y) */
  1560.  
  1561.       trace_sub_pixel(1, Block, x, y, 0, 0, sub_pixel_size, sub_pixel_size, sub_pixel_size, Colour, antialias_line);
  1562.  
  1563.       /* Do histogram stuff. */
  1564.  
  1565.       if (opts.histogram_on)
  1566.       {
  1567.         accumulate_histogram(x, y, FALSE);
  1568.       }
  1569.  
  1570.       /* Store colour in current line */
  1571.  
  1572.       Assign_Colour(Current_Line[x], Colour);
  1573.  
  1574.       /* Display pixel */
  1575.  
  1576.       plot_pixel(x, y, Colour);
  1577.  
  1578.       /* Store current block in rows */
  1579.  
  1580.       for (xxx = 0, xx = x * sub_pixel_size; xx < (x+1) * sub_pixel_size + 1; xxx++, xx++)
  1581.       {
  1582.         First_Row[xx] = Block[0][xxx];
  1583.         Last_Row[xx]  = Block[sub_pixel_size][xxx];
  1584.       }
  1585.  
  1586.       /* Swap first and last block column */
  1587.  
  1588.       for (yy = 0; yy < sub_pixel_size + 1; yy++)
  1589.       {
  1590.         TempPixel                 = Block[yy][0];
  1591.         Block[yy][0]              = Block[yy][sub_pixel_size];
  1592.         Block[yy][sub_pixel_size] = TempPixel;
  1593.       }
  1594.     }
  1595.  
  1596.     output_line(y);
  1597.  
  1598.     /* Swap first and last row */
  1599.  
  1600.     TempRow   = Last_Row;
  1601.     Last_Row  = First_Row;
  1602.     First_Row = TempRow;
  1603.   }
  1604.  
  1605.   /* We've come to the end ... at last! */
  1606.  
  1607.   if (opts.Options & DISKWRITE)
  1608.   {
  1609.     if (opts.Last_Line != opts.First_Line)
  1610.     {
  1611.       Write_Line (Output_File_Handle, Previous_Line, opts.Last_Line - 1);
  1612.     }
  1613.   }
  1614.  
  1615.   /* Free memory. */
  1616.  
  1617.   for (y = 0; y < sub_pixel_size + 1; y++)
  1618.   {
  1619.     POV_FREE(Block[y]);
  1620.   }
  1621.  
  1622.   POV_FREE(Block);
  1623.   POV_FREE(First_Row);
  1624.   POV_FREE(Last_Row);
  1625. }
  1626.  
  1627.  
  1628. /*****************************************************************************
  1629. *
  1630. * FUNCTION
  1631. *
  1632. *   Trace
  1633. *
  1634. * INPUT
  1635. *
  1636. * OUTPUT
  1637. *
  1638. * RETURNS
  1639. *
  1640. *   distance to nearest intersection, or BOUND_HUGE on miss
  1641. *
  1642. * AUTHOR
  1643. *
  1644. *   POV-Ray Team
  1645. *
  1646. * DESCRIPTION
  1647. *
  1648. *   -
  1649. *
  1650. * CHANGES
  1651. *
  1652. *   Nov 1994 : Rearranged calls to Fog, Rainbow and Skyblend.
  1653. *              Added call to Atmosphere for atmospheric effects. [DB]
  1654. *   Jan 1995 : Set intersection depth to Max_Distance for infinite rays. [DB]
  1655. *   Mar 1995 : Added return value for radiosity work [JDM]
  1656. *   Jul 1995 : Added code to support alpha channel. [DB]
  1657. *
  1658. ******************************************************************************/
  1659.  
  1660. DBL Trace(Ray, Colour, Weight)
  1661. RAY *Ray;
  1662. COLOUR Colour;
  1663. DBL Weight;
  1664. {
  1665.   int i, Intersection_Found, all_hollow;
  1666.   OBJECT *Object;
  1667.   INTERSECTION Best_Intersection, New_Intersection;
  1668.  
  1669.   COOPERATE_0
  1670.  
  1671.   Increase_Counter(stats[Number_Of_Rays]);
  1672.  
  1673.   /* Transmittance has to be 1 to make alpha channel output to work. [DB] */
  1674.  
  1675.   Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 1.0);
  1676.  
  1677.   /* Check for max. trace level or ADC bailout. */
  1678.  
  1679.   if ((Trace_Level > Max_Trace_Level) || (Weight < ADC_Bailout))
  1680.   {
  1681.     if (Weight < ADC_Bailout)
  1682.     {
  1683.       Increase_Counter(stats[ADC_Saves]);
  1684.     }
  1685.  
  1686.     return (BOUND_HUGE);
  1687.   }
  1688.  
  1689.   /* Set highest level traced. */
  1690.  
  1691.   if (Trace_Level > Highest_Trace_Level)
  1692.   {
  1693.     Highest_Trace_Level = Trace_Level;
  1694.   }
  1695.  
  1696.   /* What objects does this ray intersect? */
  1697.  
  1698.   Intersection_Found = FALSE;
  1699.  
  1700.   Best_Intersection.Depth = BOUND_HUGE;
  1701.  
  1702.   if (!opts.Use_Slabs)
  1703.   {
  1704.     for (Object = Frame.Objects; Object != NULL; Object = Object -> Sibling)
  1705.     {
  1706.       if (Intersection(&New_Intersection, Object, Ray))
  1707.       {
  1708.         if (New_Intersection.Depth < Best_Intersection.Depth)
  1709.         {
  1710.           Best_Intersection = New_Intersection;
  1711.  
  1712.           Intersection_Found = TRUE;
  1713.         }
  1714.       }
  1715.     }
  1716.   }
  1717.   else
  1718.   {
  1719.     Intersection_Found = Intersect_BBox_Tree(Root_Object, Ray,
  1720.            &Best_Intersection, &Object);
  1721.   }
  1722.  
  1723.   /* Get color for this ray. */
  1724.  
  1725.   if (Intersection_Found)
  1726.   {
  1727.     /* Determine colour of object hit. */
  1728.  
  1729.     Determine_Apparent_Colour(&Best_Intersection, Colour, Ray, Weight);
  1730.   }
  1731.   else
  1732.   {
  1733.       /* Infinite ray, set intersecton distance. */
  1734.  
  1735.       Best_Intersection.Depth = Max_Distance;
  1736.  
  1737.       /* Apply infinite atmospheric effects. */
  1738.  
  1739.       Do_Infinite_Atmosphere(Ray, Colour);
  1740.   }
  1741.  
  1742.   /* Test if all contained objects are hollow. */
  1743.  
  1744.   all_hollow = TRUE;
  1745.  
  1746.   if (Ray->Containing_Index > -1)
  1747.   {
  1748.     for (i = 0; i <= Ray->Containing_Index; i++)
  1749.     {
  1750.       if (!Test_Flag(Ray->Containing_Objects[i], HOLLOW_FLAG))
  1751.       {
  1752.         all_hollow = FALSE;
  1753.  
  1754.         break;
  1755.       }
  1756.     }
  1757.   }
  1758.  
  1759.   /* Apply finite atmospheric effects. */
  1760.  
  1761.   if (all_hollow)
  1762.   {
  1763.     Do_Finite_Atmosphere(Ray, &Best_Intersection, Colour, FALSE);
  1764.   }
  1765.  
  1766.   return (Best_Intersection.Depth);
  1767. }
  1768.  
  1769.  
  1770.  
  1771. /*****************************************************************************
  1772. *
  1773. * FUNCTION
  1774. *
  1775. *   do_anti_aliasing
  1776. *
  1777. * INPUT
  1778. *
  1779. * OUTPUT
  1780. *
  1781. * RETURNS
  1782. *
  1783. * AUTHOR
  1784. *
  1785. *   POV-Ray Team
  1786. *
  1787. * DESCRIPTION
  1788. *
  1789. *   -
  1790. *
  1791. * CHANGES
  1792. *
  1793. *   Aug 1995 : Modified to avoid unnecessary pixel output. [DB]
  1794. *
  1795. *   Aug 1995 : Modified to avoid supersampling of unused lines
  1796. *              when using field tracing. [DB]
  1797. *
  1798. ******************************************************************************/
  1799.  
  1800. static void do_anti_aliasing(x, y, Colour)
  1801. register int x, y;
  1802. COLOUR Colour;
  1803. {
  1804.   char Antialias_Center_Flag = FALSE;
  1805.  
  1806.   Current_Line_Antialiased_Flags[x] = FALSE;
  1807.  
  1808.   /* Test difference to pixel left of current pixel. */
  1809.  
  1810.   if (x != 0)
  1811.   {
  1812.     if (Colour_Distance(Current_Line[x-1],Current_Line[x]) >= Frame.Antialias_Threshold)
  1813.     {
  1814.       Antialias_Center_Flag = TRUE;
  1815.  
  1816.       if (!(Current_Line_Antialiased_Flags[x-1]))
  1817.       {
  1818.         supersample(Current_Line[x-1], x-1, y);
  1819.  
  1820.         Current_Line_Antialiased_Flags[x-1] = TRUE;
  1821.  
  1822.         SuperSampleCount++;
  1823.  
  1824.         plot_pixel(x-1, y, Current_Line[x-1]);
  1825.  
  1826.         COOPERATE_1
  1827.       }
  1828.     }
  1829.   }
  1830.  
  1831.   /* Test difference to pixel above current pixel. */
  1832.  
  1833.   if ((y != opts.First_Line-1) && (!opts.FrameSeq.Field_Render_Flag))
  1834.   {
  1835.     if (Colour_Distance(Previous_Line[x],Current_Line[x]) >= Frame.Antialias_Threshold)
  1836.     {
  1837.       Antialias_Center_Flag = TRUE;
  1838.  
  1839.       if (!(Previous_Line_Antialiased_Flags[x]))
  1840.       {
  1841.         supersample(Previous_Line[x], x, y-1);
  1842.  
  1843.         Previous_Line_Antialiased_Flags[x] = TRUE;
  1844.  
  1845.         SuperSampleCount++;
  1846.  
  1847.         plot_pixel(x, y, Previous_Line[x]);
  1848.  
  1849.         COOPERATE_1
  1850.       }
  1851.     }
  1852.   }
  1853.  
  1854.   /* Supersample current pixel if necessary. */
  1855.  
  1856.   if (Antialias_Center_Flag)
  1857.   {
  1858.     supersample(Current_Line[x], x, y);
  1859.  
  1860.     Current_Line_Antialiased_Flags[x] = TRUE;
  1861.  
  1862.     Assign_Colour(Colour, Current_Line[x]);
  1863.  
  1864.     SuperSampleCount++;
  1865.  
  1866.     COOPERATE_1
  1867.   }
  1868. }
  1869.  
  1870.  
  1871.  
  1872. /*****************************************************************************
  1873. *
  1874. * FUNCTION
  1875. *
  1876. *   supersample
  1877. *
  1878. * INPUT
  1879. *   
  1880. * OUTPUT
  1881. *   
  1882. * RETURNS
  1883. *   
  1884. * AUTHOR
  1885. *
  1886. *   POV-Ray Team
  1887. *   
  1888. * DESCRIPTION
  1889. *
  1890. *   Standard sampling in loop
  1891. *
  1892. * CHANGES
  1893. *
  1894. *   Aug 1995 : Modified to avoid resampling of center sub-pixel. [DB]
  1895. *
  1896. *   Sep 1995 : Weight of a primary ray has to be 1 regardless of its
  1897. *              contribution to a supersampled pixel! [DB]
  1898. *
  1899. ******************************************************************************/
  1900.  
  1901. static void supersample(result, x, y)
  1902. COLOUR result;
  1903. int x, y;
  1904. {
  1905.   int i, j, samples;
  1906.   int JRange, JSteps;
  1907.   DBL JSize, JScale;
  1908.   DBL Jitter_X, Jitter_Y;
  1909.   DBL dx, dy;
  1910.   DBL save_radiosity_error_bound;
  1911.   COLOUR colour;
  1912.  
  1913.   /* Why are we here? */
  1914.  
  1915.   if (opts.AntialiasDepth <= 1)
  1916.   {
  1917.     return;
  1918.   }
  1919.  
  1920.   Increase_Counter(stats[Number_Of_Pixels_Supersampled]);
  1921.  
  1922.   /* Number of samples in pixel (used to scale resulting color). */
  1923.  
  1924.   samples = 1;
  1925.  
  1926.   /* Substantially reduces chances of doing new samples. */
  1927.  
  1928.   save_radiosity_error_bound = opts.Radiosity_Error_Bound;
  1929.  
  1930.   opts.Radiosity_Error_Bound *= 2.0;
  1931.  
  1932.   /* JSize is the size of the jitter scattering area */
  1933.  
  1934.   JSize = 1.0 / opts.AntialiasDepth;
  1935.  
  1936.   /*
  1937.    * JSteps is either 1 or 2 depending on whether the number of samples
  1938.    * is odd or even. This is because the loop need to either run through
  1939.    * or over 0.
  1940.    */
  1941.  
  1942.   JSteps = 2 - (opts.AntialiasDepth % 2);
  1943.  
  1944.   /*
  1945.    * JRange is the range that the loop will run through. I couldn't
  1946.    * come up with a function describing the values, so I used an array
  1947.    * for 2x2 up to 9x9.
  1948.    */
  1949.  
  1950.   JRange = JRanges[opts.AntialiasDepth];
  1951.  
  1952.   /*
  1953.    * JScale is the value with which the current sub-pixel indices
  1954.    * (i,j) have to be scaled to get the real sub-pixel positions.
  1955.    */
  1956.  
  1957.   JScale = JSize / (DBL)JSteps;
  1958.  
  1959.   /* Loop over all sub-pixels. */
  1960.  
  1961.   for (i = -JRange; i <= JRange; i += JSteps)
  1962.   {
  1963.     for (j = -JRange; j <= JRange; j += JSteps)
  1964.     {
  1965.       /* Skip center sub-pixel because we already traced it. */
  1966.  
  1967.       if ((i == 0) && (j == 0))
  1968.       {
  1969.         continue;
  1970.       }
  1971.  
  1972.       /* Increase number of samples. */
  1973.  
  1974.       samples++;
  1975.  
  1976.       /* Jitter grid location. */
  1977.  
  1978.       jitter_pixel_position(x, y, &Jitter_X, &Jitter_Y);
  1979.  
  1980.       /* Trace ray through current sub-pixel. */
  1981.  
  1982.       dx = Jitter_X + i * JScale;
  1983.       dy = Jitter_Y + j * JScale;
  1984.  
  1985.       if (create_ray(&Camera_Ray, (DBL)x+dx, (DBL)y+dy, 0))
  1986.       {
  1987.         Trace_Level = 1;
  1988.  
  1989.         Increase_Counter(stats[Number_Of_Samples]);
  1990.  
  1991.         if (opts.Options & USE_VISTA_BUFFER)
  1992.         {
  1993.           Trace_Primary_Ray(&Camera_Ray, colour, 1.0, x);
  1994.         }
  1995.         else
  1996.         {
  1997.           Trace(&Camera_Ray, colour, 1.0);
  1998.         }
  1999.  
  2000.         Clip_Colour(colour, colour);
  2001.  
  2002.         gamma_correct(colour);
  2003.  
  2004.         Add_Colour(result, result, colour);
  2005.       }
  2006.       else
  2007.       {
  2008.         Make_ColourA(colour, 0.0, 0.0, 0.0, 0.0, 1.0);
  2009.       }
  2010.     }
  2011.   }
  2012.  
  2013.   /* Average pixel's color. */
  2014.  
  2015.   Scale_Colour(result, result, 1.0 / (DBL)samples);
  2016.  
  2017.   opts.Radiosity_Error_Bound = save_radiosity_error_bound;
  2018. }
  2019.  
  2020.  
  2021. /*****************************************************************************
  2022. *
  2023. * FUNCTION
  2024. *
  2025. *   trace_sub_pixel
  2026. *
  2027. * INPUT
  2028. *
  2029. *   level     - current subdivision level
  2030. *   Block     - sub-pixel information of current pixel
  2031. *   x, y      - current pixel
  2032. *   x1, y1    - upper left corner of current sub-pixel
  2033. *   x3, y3    - lower right corner of current sub-pixel
  2034. *   size      - sub-pixel size
  2035. *   antialias - TRUE if antialiasing is allowed
  2036. *
  2037. * OUTPUT
  2038. *
  2039. *   Colour   - (sub-)pixels color
  2040. *
  2041. * RETURNS
  2042. *
  2043. * AUTHOR
  2044. *
  2045. *   Dieter Bayer
  2046. *
  2047. * DESCRIPTION
  2048. *
  2049. *   Trace rays at the corners of the (sub-)pixel. If the colors differ
  2050. *   too much and the max. recursion level isn't reached yet subdivide
  2051. *   pixel into four sub-pixel and trace those.
  2052. *
  2053. * CHANGES
  2054. *
  2055. *   Jul 1995 : Creation.
  2056. *
  2057. ******************************************************************************/
  2058.  
  2059. static void trace_sub_pixel(level, Block, x, y, x1, y1, x3, y3, size, Colour, antialias)
  2060. int level;
  2061. PIXEL **Block;
  2062. int x, y, x1, y1, x3, y3, size;
  2063. COLOUR Colour;
  2064. int antialias;
  2065. {
  2066.   int x2, y2;    /* Coordinates of center sub-pixel of current block.     */
  2067.   DBL dx1, dy1;  /* coord. of upper left corner relative to pixel coord.  */
  2068.   DBL dx3, dy3;  /* coord. of lower right corner relative to pixel coord. */
  2069.   COLOUR C1, C2, C3, C4;
  2070.  
  2071.   /* Get offsets for corner pixels. */
  2072.  
  2073.   dx1 = (DBL)(x1 - size / 2) / (DBL)size;
  2074.   dx3 = (DBL)(x3 - size / 2) / (DBL)size;
  2075.  
  2076.   dy1 = (DBL)(y1 - size / 2) / (DBL)size;
  2077.   dy3 = (DBL)(y3 - size / 2) / (DBL)size;
  2078.  
  2079.   /* Trace upper left corner pixel. */
  2080.  
  2081.   if (!Block[y1][x1].active)
  2082.   {
  2083.     trace_ray_with_offset(x, y, dx1, dy1, C1);
  2084.  
  2085.     Block[y1][x1].active = TRUE;
  2086.  
  2087.     Assign_Colour(Block[y1][x1].Colour, C1);
  2088.   }
  2089.   else
  2090.   {
  2091.     Assign_Colour(C1, Block[y1][x1].Colour);
  2092.   }
  2093.  
  2094.   /* Trace lower left corner pixel. */
  2095.  
  2096.   if (!Block[y3][x1].active)
  2097.   {
  2098.     trace_ray_with_offset(x, y, dx1, dy3, C2);
  2099.  
  2100.     Block[y3][x1].active = TRUE;
  2101.  
  2102.     Assign_Colour(Block[y3][x1].Colour, C2);
  2103.   }
  2104.   else
  2105.   {
  2106.     Assign_Colour(C2, Block[y3][x1].Colour);
  2107.   }
  2108.  
  2109.   /* Trace upper right corner pixel. */
  2110.  
  2111.   if (!Block[y1][x3].active)
  2112.   {
  2113.     trace_ray_with_offset(x, y, dx3, dy1, C3);
  2114.  
  2115.     Block[y1][x3].active = TRUE;
  2116.  
  2117.     Assign_Colour(Block[y1][x3].Colour, C3);
  2118.   }
  2119.     else
  2120.   {
  2121.     Assign_Colour(C3, Block[y1][x3].Colour);
  2122.   }
  2123.  
  2124.   /* Trace lower right corner pixel. */
  2125.  
  2126.   if (!Block[y3][x3].active)
  2127.   {
  2128.     trace_ray_with_offset(x, y, dx3, dy3, C4);
  2129.  
  2130.     Block[y3][x3].active = TRUE;
  2131.  
  2132.     Assign_Colour(Block[y3][x3].Colour, C4);
  2133.   }
  2134.   else
  2135.   {
  2136.     Assign_Colour(C4, Block[y3][x3].Colour);
  2137.   }
  2138.  
  2139.   /* Do we have to check for supersampling? */
  2140.  
  2141.   if (antialias && (level <= opts.AntialiasDepth))
  2142.   {
  2143.     /* Check if upper left sub-block should be supersampled. */
  2144.  
  2145.     if ((Colour_Distance(C1, C2) >= Frame.Antialias_Threshold) ||
  2146.         (Colour_Distance(C2, C4) >= Frame.Antialias_Threshold) ||
  2147.         (Colour_Distance(C3, C4) >= Frame.Antialias_Threshold) ||
  2148.         (Colour_Distance(C1, C3) >= Frame.Antialias_Threshold) ||
  2149.         (Colour_Distance(C1, C4) >= Frame.Antialias_Threshold) ||
  2150.         (Colour_Distance(C2, C3) >= Frame.Antialias_Threshold))
  2151.     {
  2152.       /* Get coordinates of center sub-pixel. */
  2153.  
  2154.       x2 = (x1 + x3) / 2;
  2155.       y2 = (y1 + y3) / 2;
  2156.  
  2157.       /* Trace the four sub-blocks. */
  2158.  
  2159.       trace_sub_pixel(level+1, Block, x, y, x1, y1, x2, y2, size, C1, antialias);
  2160.       trace_sub_pixel(level+1, Block, x, y, x1, y2, x2, y3, size, C2, antialias);
  2161.       trace_sub_pixel(level+1, Block, x, y, x2, y1, x3, y2, size, C3, antialias);
  2162.       trace_sub_pixel(level+1, Block, x, y, x2, y2, x3, y3, size, C4, antialias);
  2163.  
  2164.       if (level == 1)
  2165.       {
  2166.         SuperSampleCount++;
  2167.       }
  2168.     }
  2169.   }
  2170.  
  2171.   /* Average sub-block colors. */
  2172.  
  2173.   Colour[RED]    = 0.25 * (C1[RED]    + C2[RED]    + C3[RED]    + C4[RED]);
  2174.   Colour[GREEN]  = 0.25 * (C1[GREEN]  + C2[GREEN]  + C3[GREEN]  + C4[GREEN]);
  2175.   Colour[BLUE]   = 0.25 * (C1[BLUE]   + C2[BLUE]   + C3[BLUE]   + C4[BLUE]);
  2176.   Colour[TRANSM] = 0.25 * (C1[TRANSM] + C2[TRANSM] + C3[TRANSM] + C4[TRANSM]);
  2177. }
  2178.  
  2179.  
  2180. /*****************************************************************************
  2181. *
  2182. * FUNCTION
  2183. *
  2184. *   trace_ray_with_offset
  2185. *
  2186. * INPUT
  2187. *
  2188. * OUTPUT
  2189. *
  2190. * RETURNS
  2191. *
  2192. * AUTHOR
  2193. *
  2194. *   Dieter Bayer
  2195. *
  2196. * DESCRIPTION
  2197. *
  2198. *   Trace a ray through the pixel at (x,y) with an offset (dx,dy)
  2199. *
  2200. * CHANGES
  2201. *
  2202. *   May 1994 : Creation.
  2203. *
  2204. *   Sep 1995 : Weight of a primary ray has to be 1 regardless of its
  2205. *              contribution to a supersampled pixel! [DB]
  2206. *
  2207. ******************************************************************************/
  2208.  
  2209. static void trace_ray_with_offset(x, y, dx, dy, Colour)
  2210. int x, y;
  2211. DBL dx, dy;
  2212. COLOUR Colour;
  2213. {
  2214.   DBL Jitter_X, Jitter_Y;
  2215.  
  2216.   if (Focal_Blur_Is_Used)
  2217.   {
  2218.     focal_blur(&Camera_Ray, Colour, (DBL)x, (DBL)y);
  2219.   }
  2220.   else
  2221.   {
  2222.     /* Jitter the ray */
  2223.  
  2224.     if (opts.Options & ANTIALIAS)
  2225.     {
  2226.       jitter_pixel_position(x, y, &Jitter_X, &Jitter_Y);
  2227.     }
  2228.     else
  2229.     {
  2230.       Jitter_X = Jitter_Y = 0.0;
  2231.     }
  2232.  
  2233.     if (create_ray (&Camera_Ray, (DBL)x+dx+Jitter_X, (DBL)y+dy+Jitter_Y, 0))
  2234.     {
  2235.       Trace_Level = 1;
  2236.  
  2237.       Increase_Counter(stats[Number_Of_Samples]);
  2238.  
  2239.       if (opts.Options & USE_VISTA_BUFFER)
  2240.       {
  2241.         Trace_Primary_Ray(&Camera_Ray, Colour, 1.0, x);
  2242.       }
  2243.       else
  2244.       {
  2245.         Trace(&Camera_Ray, Colour, 1.0);
  2246.       }
  2247.  
  2248.       Clip_Colour(Colour, Colour);
  2249.  
  2250.       gamma_correct(Colour);
  2251.     }
  2252.     else
  2253.     {
  2254.       Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 1.0);
  2255.     }
  2256.   }
  2257. }
  2258.  
  2259.  
  2260.  
  2261. /*****************************************************************************
  2262. *
  2263. * FUNCTION
  2264. *
  2265. *   focal_blur
  2266. *
  2267. * INPUT
  2268. *   
  2269. * OUTPUT
  2270. *   
  2271. * RETURNS
  2272. *   
  2273. * AUTHOR
  2274. *
  2275. *   POV-Ray Team
  2276. *   
  2277. * DESCRIPTION
  2278. *
  2279. *   Calls create_ray(), which calls jitter_camera_ray() to apply the
  2280. *   correct amount of jitter to the ray.  This routine merely sends out
  2281. *   the correct number of rays and averages them into Colour.
  2282. *
  2283. * CHANGES
  2284. *
  2285. *   Jul 1995 : Added code to use a different sub-pixel location for
  2286. *              each sample. Added code to do a statistic confident
  2287. *              test to make early exists possible. [DB]
  2288. *
  2289. ******************************************************************************/
  2290.  
  2291. static void focal_blur(Ray, Colour, x, y)
  2292. RAY *Ray;
  2293. COLOUR Colour;
  2294. DBL x, y;
  2295. {
  2296.   int nr;     /* Number of current samples. */
  2297.   int level;  /* Index into number of samples list. */
  2298.   int max_s;  /* Number of samples to take before next confidence test. */
  2299.   int dxi, dyi;
  2300.   int i;
  2301.   DBL dx, dy, n;
  2302.   COLOUR C, V1, S1, S2;
  2303.  
  2304.   Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 0.0);
  2305.  
  2306.   Make_ColourA(V1, 0.0, 0.0, 0.0, 0.0, 0.0);
  2307.  
  2308.   Make_ColourA(S1, 0.0, 0.0, 0.0, 0.0, 0.0);
  2309.  
  2310.   Make_ColourA(S2, 0.0, 0.0, 0.0, 0.0, 0.0);
  2311.  
  2312.   nr = 0;
  2313.  
  2314.   level = 0;
  2315.  
  2316.   do
  2317.   {
  2318.     /* Trace number of rays given by the list Current_Number_Of_Samples[]. */
  2319.  
  2320.     max_s = 4;
  2321.  
  2322.     if (Current_Number_Of_Samples != NULL)
  2323.     {
  2324.       if (Current_Number_Of_Samples[level] > 0)
  2325.       {
  2326.         max_s = Current_Number_Of_Samples[level];
  2327.  
  2328.         level++;
  2329.       }
  2330.     }
  2331.  
  2332.     for (i = 0; (i < max_s) && (nr < Frame.Camera->Blur_Samples); i++)
  2333.     {
  2334.       /* Choose sub-pixel location. */
  2335.  
  2336.       dxi = POV_RAND() % SUB_PIXEL_GRID_SIZE;
  2337.       dyi = POV_RAND() % SUB_PIXEL_GRID_SIZE;
  2338.  
  2339.       dx = (DBL)(2 * dxi + 1) / (DBL)(2 * SUB_PIXEL_GRID_SIZE) - 0.5;
  2340.       dy = (DBL)(2 * dyi + 1) / (DBL)(2 * SUB_PIXEL_GRID_SIZE) - 0.5;
  2341.  
  2342.       /* Add jitter to sub-pixel location. */
  2343.  
  2344.       dx += (FRAND() - 0.5) / (DBL)(SUB_PIXEL_GRID_SIZE);
  2345.       dy += (FRAND() - 0.5) / (DBL)(SUB_PIXEL_GRID_SIZE);
  2346.  
  2347.       /* Create and trace ray. */
  2348.  
  2349.       if (create_ray(Ray, x+dx, y+dy, nr))
  2350.       {
  2351.         Trace_Level = 1;
  2352.  
  2353.         Increase_Counter(stats[Number_Of_Samples]);
  2354.  
  2355.         Trace(Ray, C, 1.0);
  2356.  
  2357.         Clip_Colour(C, C);
  2358.  
  2359.         gamma_correct(C);
  2360.  
  2361.         Add_Colour(Colour, Colour, C);
  2362.       }
  2363.       else
  2364.       {
  2365.         Make_ColourA(C, 0.0, 0.0, 0.0, 0.0, 1.0);
  2366.       }
  2367.  
  2368.       /* Add color to color sum. */
  2369.  
  2370.       S1[RED]    += C[RED];
  2371.       S1[GREEN]  += C[GREEN];
  2372.       S1[BLUE]   += C[BLUE];
  2373.       S1[TRANSM] += C[TRANSM];
  2374.  
  2375.       /* Add color to squared color sum. */
  2376.  
  2377.       S2[RED]    += Sqr(C[RED]);
  2378.       S2[GREEN]  += Sqr(C[GREEN]);
  2379.       S2[BLUE]   += Sqr(C[BLUE]);
  2380.       S2[TRANSM] += Sqr(C[TRANSM]);
  2381.  
  2382.       nr++;
  2383.     }
  2384.  
  2385.     /* Get variance of samples. */
  2386.  
  2387.     n = (DBL)nr;
  2388.  
  2389.     V1[RED]    = (S2[RED]    / n - Sqr(S1[RED]    / n)) / n;
  2390.     V1[GREEN]  = (S2[GREEN]  / n - Sqr(S1[GREEN]  / n)) / n;
  2391.     V1[BLUE]   = (S2[BLUE]   / n - Sqr(S1[BLUE]   / n)) / n;
  2392.     V1[TRANSM] = (S2[TRANSM] / n - Sqr(S1[TRANSM] / n)) / n;
  2393.  
  2394.     /* Exit if samples are likely too be good enough. */
  2395.  
  2396.     if ((V1[RED]  < Sample_Threshold[nr-1]) && (V1[GREEN]  < Sample_Threshold[nr-1]) &&
  2397.         (V1[BLUE] < Sample_Threshold[nr-1]) && (V1[TRANSM] < Sample_Threshold[nr-1]))
  2398.     {
  2399.       break;
  2400.     }
  2401.   }
  2402.   while (nr < Frame.Camera->Blur_Samples);
  2403.  
  2404.   Scale_Colour(Colour, Colour, 1.0 / (DBL)nr);
  2405. }
  2406.  
  2407.  
  2408.  
  2409. /*****************************************************************************
  2410. *
  2411. * FUNCTION
  2412. *
  2413. *   jitter_camera_ray
  2414. *
  2415. * INPUT
  2416. *   
  2417. * OUTPUT
  2418. *   
  2419. * RETURNS
  2420. *   
  2421. * AUTHOR
  2422. *
  2423. *   POV-Ray Team
  2424. *   
  2425. * DESCRIPTION
  2426. *
  2427. *   This routine will deflect eye rays only, since it relies on picking
  2428. *   up viewpoint information from the "Frame" variable.
  2429. *
  2430. *   A hexagonal jitter grid is used if number of blur rays is one of
  2431. *   7, 19, or 37, although this should probably be done differently.
  2432. *
  2433. * CHANGES
  2434. *
  2435. *   -
  2436. *
  2437. ******************************************************************************/
  2438.  
  2439. static void jitter_camera_ray(ray, ray_number)
  2440. RAY *ray;
  2441. int ray_number;
  2442. {
  2443.   DBL xjit, yjit, xlen, ylen, r;
  2444.   VECTOR temp_xperp, temp_yperp, deflection;
  2445.  
  2446.   r = Frame.Camera->Aperture * 0.5;
  2447.  
  2448.   xjit = Max_Jitter * ((FRAND() * 2.0) - 1.0);
  2449.   yjit = Max_Jitter * ((FRAND() * 2.0) - 1.0);
  2450.  
  2451.   xlen = r * (Sample_Grid[ray_number].x + xjit);
  2452.   ylen = r * (Sample_Grid[ray_number].y + yjit);
  2453.  
  2454.   /*
  2455.    * Deflect the position of the eye by the size of the aperture, and in
  2456.    * a direction perpendicular to the current direction of view.
  2457.    */
  2458.  
  2459.   VScale(temp_xperp, XPerp, xlen);
  2460.   VScale(temp_yperp, YPerp, ylen);
  2461.  
  2462.   VSub(deflection, temp_xperp, temp_yperp);
  2463.  
  2464.   VAdd(ray->Initial, Frame.Camera->Location, deflection);
  2465.  
  2466.   /*
  2467.    * Deflect the direction of the ray in the opposite direction we deflected
  2468.    * the eye position.  This makes sure that we are looking at the same place
  2469.    * when the distance from the eye is equal to "Focal_Distance".
  2470.    */
  2471.  
  2472.   VScale(ray->Direction, ray->Direction, Focal_Distance);
  2473.   VSub(ray->Direction, ray->Direction, deflection);
  2474.  
  2475.   VNormalize(ray->Direction, ray->Direction);
  2476. }
  2477.  
  2478.  
  2479.  
  2480. /*****************************************************************************
  2481. *
  2482. * FUNCTION
  2483. *
  2484. *   trace_pixel
  2485. *
  2486. * INPUT
  2487. *   
  2488. * OUTPUT
  2489. *   
  2490. * RETURNS
  2491. *   
  2492. * AUTHOR
  2493. *
  2494. *   POV-Ray Team
  2495. *   
  2496. * DESCRIPTION
  2497. *
  2498. *   Trace a primary ray regarding focal blur and vista buffer.
  2499. *   The color of the pixel is clipped and the number of pixels is increased.
  2500. *
  2501. * CHANGES
  2502. *
  2503. *   Sep 1994 : Extracted common code. [DB]
  2504. *   Jan 1995 : Added call to accumulate_histogram() - Chris Cason
  2505. *
  2506. ******************************************************************************/
  2507.  
  2508. static void trace_pixel(x, y, Colour)
  2509. int x, y;
  2510. COLOUR Colour;
  2511. {
  2512.   Increase_Counter(stats[Number_Of_Pixels]);
  2513.  
  2514.   Trace_Level = 1;
  2515.  
  2516.   POV_PRE_PIXEL (x, y, Colour)
  2517.  
  2518.   COOPERATE_0
  2519.  
  2520.   /* Do histogram stuff. */
  2521.   if (opts.histogram_on)
  2522.   {
  2523.     accumulate_histogram(x, y, TRUE);
  2524.   }
  2525.  
  2526.   if (Focal_Blur_Is_Used)
  2527.   {
  2528.     /* Use focal blur tracing. */
  2529.  
  2530.     focal_blur(&Camera_Ray, Colour, (DBL)x, (DBL)y);
  2531.   }
  2532.   else
  2533.   {
  2534.     /* Create and trace ray. */
  2535.  
  2536.     if (create_ray(&Camera_Ray, (DBL)x, (DBL)y, 0))
  2537.     {
  2538.       Increase_Counter(stats[Number_Of_Samples]);
  2539.  
  2540.       if (opts.Options & USE_VISTA_BUFFER)
  2541.       {
  2542.         Trace_Primary_Ray(&Camera_Ray, Colour, 1.0, x);
  2543.       }
  2544.       else
  2545.       {
  2546.         Trace(&Camera_Ray, Colour, 1.0);
  2547.       }
  2548.     }
  2549.     else
  2550.     {
  2551.       Make_ColourA(Colour, 0.0, 0.0, 0.0, 0.0, 1.0);
  2552.     }
  2553.   }
  2554.  
  2555.   Clip_Colour(Colour, Colour);
  2556.  
  2557.   gamma_correct(Colour);
  2558.  
  2559.   /* Do histogram stuff. */
  2560.   if (opts.histogram_on)
  2561.   {
  2562.     accumulate_histogram(x, y, FALSE);
  2563.   }
  2564.  
  2565.   POV_POST_PIXEL (x, y, Colour)
  2566. }
  2567.  
  2568.  
  2569. /*****************************************************************************
  2570. *
  2571. * FUNCTION
  2572. *
  2573. *   create_ray
  2574. *
  2575. * INPUT
  2576. *
  2577. *   ray        - Primary ray for given screen point
  2578. *   x, y       - Coordinates of current pixel
  2579. *   ray_number - number of ray used by jitter_camera_ray()
  2580. *   
  2581. * OUTPUT
  2582. *
  2583. *   ray
  2584. *   
  2585. * RETURNS
  2586. *
  2587. *   int - TRUE, if a ray was created
  2588. *   
  2589. * AUTHOR
  2590. *
  2591. *   Dieter Bayer
  2592. *   Dan Farmer (focal blur, 'ultra wide angle camera')
  2593. *   
  2594. * DESCRIPTION
  2595. *
  2596. *   Create a primary ray depending on the camera model used.
  2597. *
  2598. *   Ideas for the camera models were taken from:
  2599. *
  2600. *     Geoff Wyvill and Craig McNaughton, "Optical Models",
  2601. *     CG International '90, Springer, 1990, p. 83-93
  2602. *
  2603. *     F. Kenton Musgrave, "A panoramic virtual screen for ray tracing",
  2604. *     Graphics Gems III, David Kirk (eds.), p. 288-294
  2605. *
  2606. * CHANGES
  2607. *
  2608. *   May 1994 : Creation.
  2609. *
  2610. *   Aug 1996 : Removed unnecessary width/height parameters. [DB]
  2611. *
  2612. ******************************************************************************/
  2613.  
  2614. static int create_ray(Ray, x, y, ray_number)
  2615. RAY *Ray;
  2616. DBL x, y;
  2617. int ray_number;
  2618. {
  2619.   /* Just some shortcuts. */
  2620.  
  2621. #define FCD Frame.Camera->Direction
  2622. #define FCR Frame.Camera->Right
  2623. #define FCU Frame.Camera->Up
  2624. #define FCL Frame.Camera->Location
  2625.  
  2626.   DBL x0 = 0.0, y0 = 0.0;
  2627.   DBL cx, sx, cy, sy, ty, rad, phi, lx, ly;
  2628.   VECTOR V1;
  2629.  
  2630.   /* Create primary ray according to the camera used. */
  2631.  
  2632.   Assign_Vector(Ray->Initial, FCL);
  2633.  
  2634.   Initialize_Ray_Containers(Ray);
  2635.  
  2636.   switch (Frame.Camera->Type)
  2637.   {
  2638.     /*
  2639.      * Perspective projection (Pinhole camera; POV standard).
  2640.      */
  2641.  
  2642.     case PERSPECTIVE_CAMERA:
  2643.  
  2644.       /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2645.  
  2646.       x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2647.  
  2648.       /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2649.  
  2650.       y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2651.  
  2652.       /* Create primary ray. */
  2653.  
  2654.       VLinComb3(Ray->Direction, 1.0, FCD, x0, FCR, y0, FCU);
  2655.  
  2656.       /* Do focal blurring (by Dan Farmer). */
  2657.  
  2658.       if (Focal_Blur_Is_Used)
  2659.       {
  2660.         jitter_camera_ray(Ray, ray_number);
  2661.  
  2662.         initialize_ray_container_state(Ray, TRUE);
  2663.       }
  2664.       else
  2665.       {
  2666.         initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2667.  
  2668.         Precompute_Camera_Constants = FALSE;
  2669.       }
  2670.  
  2671.     break;
  2672.  
  2673.     /*
  2674.      * Orthographic projection.
  2675.      */
  2676.  
  2677.     case ORTHOGRAPHIC_CAMERA:
  2678.  
  2679.       /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2680.  
  2681.       x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2682.  
  2683.       /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2684.  
  2685.       y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2686.  
  2687.       /* Create primary ray. */
  2688.  
  2689.       Assign_Vector(Ray->Direction, FCD);
  2690.  
  2691.       VLinComb3(Ray->Initial, 1.0, FCL, x0, FCR, y0, FCU);
  2692.  
  2693.       initialize_ray_container_state(Ray, TRUE);
  2694.  
  2695.       break;
  2696.  
  2697.     /*
  2698.      * Fisheye camera.
  2699.      */
  2700.  
  2701.     case FISHEYE_CAMERA:
  2702.  
  2703.       /* Convert the x coordinate to be a DBL from -1.0 to 1.0. */
  2704.  
  2705.       x0 = 2.0 * x / (DBL)Frame.Screen_Width - 1.0;
  2706.  
  2707.       /* Convert the y coordinate to be a DBL from -1.0 to 1.0. */
  2708.  
  2709.       y0 = 2.0 * ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 1.0;
  2710.  
  2711.       /* Get aspect ratio --> we want a circle (do this only once). */
  2712.  
  2713.       if (Precompute_Camera_Constants)
  2714.       {
  2715.         VLength(lx, FCR);
  2716.         VLength(ly, FCU);
  2717.  
  2718.         Camera_Aspect_Ratio = lx / ly;
  2719.  
  2720.         VNormalize(FCR, FCR);
  2721.         VNormalize(FCU, FCU);
  2722.         VNormalize(FCD, FCD);
  2723.       }
  2724.  
  2725.       /* Get polar coordinates. */
  2726.  
  2727.       x0 *= Camera_Aspect_Ratio;
  2728.  
  2729.       rad = sqrt(x0 * x0 + y0 * y0);
  2730.  
  2731.       /* If the pixel lies outside the unit circle no ray is traced. */
  2732.  
  2733.       if (rad > 1.0)
  2734.       {
  2735.         return(FALSE);
  2736.       }
  2737.  
  2738.       if (rad == 0.0)
  2739.       {
  2740.         phi = 0.0;
  2741.       }
  2742.       else
  2743.       {
  2744.         if (x0 < 0.0)
  2745.         {
  2746.           phi = M_PI - asin(y0 / rad);
  2747.         }
  2748.         else
  2749.         {
  2750.           phi = asin(y0 / rad);
  2751.         }
  2752.       }
  2753.  
  2754.       /* Get spherical coordinates. */
  2755.  
  2756.       x0 = phi;
  2757.  
  2758.       /* Set vertical angle to half viewing angle. */
  2759.  
  2760.       y0 = rad * Frame.Camera->Angle * M_PI_360;
  2761.  
  2762.       /* Create primary ray. */
  2763.  
  2764.       cx = cos(x0);  sx = sin(x0);
  2765.       cy = cos(y0);  sy = sin(y0);
  2766.  
  2767.       VLinComb3(Ray->Direction, cx * sy, FCR, sx * sy, FCU, cy, FCD);
  2768.  
  2769.       initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2770.  
  2771.       Precompute_Camera_Constants = FALSE;
  2772.  
  2773.       break;
  2774.  
  2775.     /*
  2776.      * Omnimax camera.
  2777.      */
  2778.  
  2779.     case OMNIMAX_CAMERA:
  2780.  
  2781.       /* Convert the x coordinate to be a DBL from -1.0 to 1.0. */
  2782.  
  2783.       x0 = 2.0 * x / (DBL)Frame.Screen_Width - 1.0;
  2784.  
  2785.       /* Convert the y coordinate to be a DBL from -1.0 to 1.0. */
  2786.  
  2787.       y0 = 2.0 * ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 1.0;
  2788.  
  2789.       /* Get aspect ratio --> we want a circle (do this only once). */
  2790.  
  2791.       if (Precompute_Camera_Constants)
  2792.       {
  2793.         VLength(lx, FCR);
  2794.         VLength(ly, FCU);
  2795.  
  2796.         Camera_Aspect_Ratio = lx / ly;
  2797.  
  2798.         VNormalize(FCR, FCR);
  2799.         VNormalize(FCU, FCU);
  2800.         VNormalize(FCD, FCD);
  2801.       }
  2802.  
  2803.       /* Get polar coordinates. */
  2804.  
  2805.       x0 *= Camera_Aspect_Ratio;
  2806.  
  2807.       rad = sqrt(x0 * x0 + y0 * y0);
  2808.  
  2809.       /* If the pixel lies outside the unit circle no ray is traced. */
  2810.  
  2811.       if (rad > 1.0)
  2812.       {
  2813.         return(FALSE);
  2814.       }
  2815.  
  2816.       if (rad == 0.0)
  2817.       {
  2818.         phi = 0.0;
  2819.       }
  2820.       else
  2821.       {
  2822.         if (x0 < 0.0)
  2823.         {
  2824.           phi = M_PI - asin(y0 / rad);
  2825.         }
  2826.         else
  2827.         {
  2828.           phi = asin(y0 / rad);
  2829.         }
  2830.       }
  2831.  
  2832.       /* Get spherical coordinates. */
  2833.  
  2834.       x0 = phi;
  2835.  
  2836.       y0 = 1.411269 * rad - 0.09439 * rad * rad * rad + 0.25674 * rad * rad * rad * rad * rad;
  2837.  
  2838.       cx = cos(x0);  sx = sin(x0);
  2839.       cy = cos(y0);  sy = sin(y0);
  2840.  
  2841.       /* We can't see below 45 degrees under the projection axis. */
  2842.  
  2843.       if (sx * sy < tan(135.0 * M_PI_180) * cy)
  2844.       {
  2845.         return(FALSE);
  2846.       }
  2847.  
  2848.       /* Create primary ray. */
  2849.  
  2850.       VLinComb3(Ray->Direction, cx * sy, FCR, sx * sy, FCU, cy, FCD);
  2851.  
  2852.       initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2853.  
  2854.       Precompute_Camera_Constants = FALSE;
  2855.  
  2856.       break;
  2857.  
  2858.     /*
  2859.      * Panoramic camera from Graphic Gems III.
  2860.      */
  2861.  
  2862.     case PANORAMIC_CAMERA:
  2863.  
  2864.       /* Convert the x coordinate to be a DBL from 0.0 to 1.0. */
  2865.  
  2866.       x0 = x / (DBL)Frame.Screen_Width;
  2867.  
  2868.       /* Convert the y coordinate to be a DBL from -1.0 to 1.0. */
  2869.  
  2870.       y0 = 2.0 * ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 1.0;
  2871.  
  2872.       /* Get cylindrical coordinates. */
  2873.  
  2874.       x0 = (1.0 - x0) * M_PI;
  2875.  
  2876.       y0 = M_PI_2 * y0;
  2877.  
  2878.       cx = cos(x0);
  2879.       sx = sin(x0);
  2880.  
  2881.       if (fabs(M_PI_2 - fabs(y0)) < EPSILON)
  2882.       {
  2883.         if (y0 > 0.0)
  2884.         {
  2885.           ty = BOUND_HUGE;
  2886.         }
  2887.         else
  2888.         {
  2889.           ty = - BOUND_HUGE;
  2890.         }
  2891.       }
  2892.       else
  2893.       {
  2894.         ty = tan(y0);
  2895.       }
  2896.  
  2897.       /* Create primary ray. */
  2898.  
  2899.       VLinComb3(Ray->Direction, cx, FCR, ty, FCU, sx, FCD);
  2900.  
  2901.       initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2902.  
  2903.       Precompute_Camera_Constants = FALSE;
  2904.  
  2905.       break;
  2906.  
  2907.     /*
  2908.      * Ultra wide angle camera written by Dan Farmer.
  2909.      */
  2910.  
  2911.     case ULTRA_WIDE_ANGLE_CAMERA:
  2912.  
  2913.       /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2914.  
  2915.       x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2916.  
  2917.       /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2918.  
  2919.       y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2920.  
  2921.       /* Create primary ray. */
  2922.  
  2923.       x0 *= Frame.Camera->Angle / 180.0;
  2924.  
  2925.       y0 *= Frame.Camera->Angle / 180.0;
  2926.  
  2927.       cx = cos(x0);  sx = sin(x0);
  2928.       cy = cos(y0);  sy = sin(y0);
  2929.  
  2930.       VLinComb3(Ray->Direction, sx, FCR, sy, FCU, cx * cy, FCD);
  2931.  
  2932.       initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2933.  
  2934.       Precompute_Camera_Constants = FALSE;
  2935.  
  2936.       break;
  2937.  
  2938.     /*
  2939.      * Cylinder camera 1. Axis in "up" direction
  2940.      */
  2941.  
  2942.     case CYL_1_CAMERA:
  2943.  
  2944.       /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2945.  
  2946.       x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2947.  
  2948.       /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2949.  
  2950.       y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2951.  
  2952.       /* Create primary ray. */
  2953.  
  2954.       x0 *= Frame.Camera->Angle * M_PI_180;
  2955.  
  2956.       cx = cos(x0);
  2957.       sx = sin(x0);
  2958.  
  2959.       VLinComb3(Ray->Direction, sx, FCR, y0, FCU, cx, FCD);
  2960.  
  2961.       initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2962.  
  2963.       Precompute_Camera_Constants = FALSE;
  2964.  
  2965.       break;
  2966.  
  2967.     /*
  2968.      * Cylinder camera 2. Axis in "right" direction
  2969.      */
  2970.  
  2971.     case CYL_2_CAMERA:
  2972.  
  2973.       /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  2974.  
  2975.       x0 = x / (DBL)Frame.Screen_Width - 0.5;
  2976.  
  2977.       /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  2978.  
  2979.       y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  2980.  
  2981.       /* Create primary ray. */
  2982.  
  2983.       y0 *= Frame.Camera->Angle * M_PI_180;
  2984.  
  2985.       cy = cos(y0);
  2986.       sy = sin(y0);
  2987.  
  2988.       VLinComb3(Ray->Direction, x0, FCR, sy, FCU, cy, FCD);
  2989.  
  2990.       initialize_ray_container_state(Ray, Precompute_Camera_Constants);
  2991.  
  2992.       Precompute_Camera_Constants = FALSE;
  2993.  
  2994.       break;
  2995.  
  2996.     /*
  2997.      * Cylinder camera 3. Axis in "up" direction, orthogonal in "right"
  2998.      */
  2999.  
  3000.     case CYL_3_CAMERA:
  3001.  
  3002.       /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  3003.  
  3004.       x0 = x / (DBL)Frame.Screen_Width - 0.5;
  3005.  
  3006.       /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  3007.  
  3008.       y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  3009.  
  3010.       /* Create primary ray. */
  3011.  
  3012.       x0 *= Frame.Camera->Angle * M_PI_180;
  3013.  
  3014.       cx = cos(x0);
  3015.       sx = sin(x0);
  3016.  
  3017.       VLinComb2(Ray->Direction, sx, FCR, cx, FCD);
  3018.  
  3019.       VLinComb2(Ray->Initial, 1.0, FCL, y0, FCU);
  3020.  
  3021.       initialize_ray_container_state(Ray, TRUE);
  3022.  
  3023.       break;
  3024.  
  3025.     /*
  3026.      * Cylinder camera 4. Axis in "right" direction, orthogonal in "up"
  3027.      */
  3028.  
  3029.     case CYL_4_CAMERA:
  3030.  
  3031.       /* Convert the x coordinate to be a DBL from -0.5 to 0.5. */
  3032.  
  3033.       x0 = x / (DBL)Frame.Screen_Width - 0.5;
  3034.  
  3035.       /* Convert the y coordinate to be a DBL from -0.5 to 0.5. */
  3036.  
  3037.       y0 = ((DBL)(Frame.Screen_Height - 1) - y) / (DBL)Frame.Screen_Height - 0.5;
  3038.  
  3039.       /* Create primary ray. */
  3040.  
  3041.       y0 *= Frame.Camera->Angle * M_PI_180;
  3042.  
  3043.       cy = cos(y0);
  3044.       sy = sin(y0);
  3045.  
  3046.       VLinComb2(Ray->Direction, sy, FCU, cy, FCD);
  3047.  
  3048.       VLinComb2(Ray->Initial, 1.0, FCL, x0, FCR);
  3049.  
  3050.       initialize_ray_container_state(Ray, TRUE);
  3051.  
  3052.       break;
  3053.  
  3054.     /*
  3055.      * Test camera 1.
  3056.      */
  3057.  
  3058.     case TEST_CAMERA_1:
  3059.  
  3060.       break;
  3061.  
  3062.     /*
  3063.      * Test camera 2.
  3064.      */
  3065.  
  3066.     case TEST_CAMERA_2:
  3067.  
  3068.       break;
  3069.  
  3070.     /*
  3071.      * Test camera 3.
  3072.      */
  3073.  
  3074.     case TEST_CAMERA_3:
  3075.  
  3076.       break;
  3077.  
  3078.     /*
  3079.      * Test camera 4.
  3080.      */
  3081.  
  3082.     case TEST_CAMERA_4:
  3083.  
  3084.       break;
  3085.  
  3086.     default:
  3087.  
  3088.     Error("Unknown camera type in create_ray().\n");
  3089.   }
  3090.  
  3091.   if (Frame.Camera->Tnormal != NULL)
  3092.   {
  3093.     VNormalize(Ray->Direction, Ray->Direction);
  3094.  
  3095.     Make_Vector(V1, x0, y0, 0.0);
  3096.     
  3097.     Perturb_Normal(Ray->Direction, Frame.Camera->Tnormal, V1);
  3098.   }
  3099.   
  3100.   VNormalize(Ray->Direction, Ray->Direction);
  3101.   
  3102.   return(TRUE);
  3103.  
  3104. #undef FCD
  3105. #undef FCR
  3106. #undef FCU
  3107. #undef FCL
  3108. }
  3109.  
  3110.  
  3111.  
  3112. /*****************************************************************************
  3113. *
  3114. * FUNCTION
  3115. *
  3116. *   gamma_correct
  3117. *
  3118. * INPUT
  3119. *
  3120. *   Colour (an array of DBL's)
  3121. *   
  3122. * OUTPUT
  3123. *
  3124. *   The colour array
  3125. *   
  3126. * RETURNS
  3127. *   
  3128. * AUTHOR
  3129. *
  3130. *   POV-Ray Team
  3131. *   
  3132. * DESCRIPTION
  3133. *
  3134. *   Adjust RGB values for overall brightness and gamma curve so that the
  3135. *   image appears a constant brightness regardless of the hardware that
  3136. *   is being used.  This can't be part of extract_colors, since
  3137. *   extract_colors is used multiple times in anti aliasing, and this has
  3138. *   to be called exactly once per pixel output.
  3139. *
  3140. *   If gamma correction is enabled, then file and display pixel values 
  3141. *   will be corrected for the current assumed_gamma, which has default
  3142. *   value 1.00, but can be set by a global_settings {assumed_gamma} in the
  3143. *   source file, and the DisplayGamma value, which can be set in the INI
  3144. *   file via Display_Gamma=n.n or defaults to DEFAULT_DISPLAY_GAMMA
  3145. *   (2.2 unless another value set in the system specific config.h files.)
  3146. *
  3147. *   If gamma correction is turned off (if no global_settings {assumed_gamma}
  3148. *   line occurrs in the scene file) then no gamma correction will be done 
  3149. *   on the pixel values.  If gamma correction is turned off, the 
  3150. *   DisplayGamma value is still relevant for PNG output files, since if 
  3151. *   gamma correction is disabled, it is presumed that the scene is 
  3152. *   "pre-corrected" for the current hardware, and a gAMA chunk with the 
  3153. *   current 1/DisplayGamma value will be output.
  3154. *
  3155. *   When DisplayGamma approximately equals assumed_gamma, it means that we
  3156. *   don't need to do any gamma correction since it is already the correct
  3157. *   brightness.  opts.GammaFactor is calculated once in tokenize.c to
  3158. *   be assumed_gamma/DisplayGamma to avoid re-calculation for each pixel.
  3159. *
  3160. * CHANGES
  3161. *
  3162. *   Apr 1995 :  Created function - Jim McElhiney
  3163. *   Oct 1995 :  Modified to do proper system gamma correction [AED]
  3164. *
  3165. ******************************************************************************/
  3166.  
  3167. static void gamma_correct(Colour)
  3168. COLOUR Colour;
  3169. {
  3170.   if (opts.Options & GAMMA_CORRECT)
  3171.   {
  3172.     Colour[RED]   = pow(Colour[RED],  opts.GammaFactor);
  3173.     Colour[GREEN] = pow(Colour[GREEN],opts.GammaFactor);
  3174.     Colour[BLUE]  = pow(Colour[BLUE], opts.GammaFactor);
  3175.   }
  3176. }
  3177.  
  3178.  
  3179.  
  3180. /*****************************************************************************
  3181. *
  3182. * FUNCTION
  3183. *
  3184. *   extract_colors
  3185. *
  3186. * INPUT
  3187. *
  3188. *   Colour, Red, Green, Blue, Alpha, grey
  3189. *   
  3190. * OUTPUT
  3191. *
  3192. *   Red, Green, Blue, Alpha, grey
  3193. *   
  3194. * RETURNS
  3195. *   
  3196. * AUTHOR
  3197. *
  3198. *   POV-Ray Team
  3199. *   
  3200. * DESCRIPTION
  3201. *
  3202. *   Create appropriate rgba values.
  3203. *
  3204. * CHANGES
  3205. *
  3206. *   Aug 1994 : Extracted common code from Start_Tracing - Eduard Schwan
  3207. *   Jun 1995 : Alpha channel support -CEY
  3208. *
  3209. ******************************************************************************/
  3210.  
  3211. static void extract_colors(Colour, Red, Green, Blue, Alpha, grey)
  3212. COLOUR Colour;
  3213. unsigned char *Red, *Green, *Blue, *Alpha;
  3214. DBL *grey;
  3215. {
  3216.   if (opts.PaletteOption == GREY)
  3217.   {
  3218.     *grey = Colour[RED] * 0.287 + Colour[GREEN] * 0.589 + Colour[BLUE] * 0.114;
  3219.  
  3220.     *Red = *Green = *Blue = (unsigned char)((*grey) * maxclr);
  3221.   }
  3222.   else
  3223.   {
  3224.     *Red   = (unsigned char)(Colour[RED]    * maxclr);
  3225.     *Green = (unsigned char)(Colour[GREEN]  * maxclr);
  3226.     *Blue  = (unsigned char)(Colour[BLUE]   * maxclr);
  3227.     *Alpha = (unsigned char)(Colour[TRANSM] * maxclr);
  3228.   }
  3229. }
  3230.  
  3231.  
  3232.  
  3233. /*****************************************************************************
  3234. *
  3235. * FUNCTION
  3236. *
  3237. *   plot_pixel
  3238. *
  3239. * INPUT
  3240. *
  3241. *   x, y   - pixel location
  3242. *   Colour - pixel color
  3243. *   
  3244. * OUTPUT
  3245. *   
  3246. * RETURNS
  3247. *   
  3248. * AUTHOR
  3249. *
  3250. *   Dieter Bayer
  3251. *
  3252. * DESCRIPTION
  3253. *
  3254. *   Display a pixel on the screen.
  3255. *
  3256. * CHANGES
  3257. *
  3258. *   Aug 1995 : Creation. Extracted from common code.
  3259. *
  3260. ******************************************************************************/
  3261.  
  3262. static void plot_pixel(x, y, Colour)
  3263. int x, y;
  3264. COLOUR Colour;
  3265. {
  3266.   unsigned char Red, Green, Blue, Alpha;
  3267.   DBL grey;
  3268.  
  3269.   if ((opts.Options & DISPLAY) && (y != opts.First_Line - 1))
  3270.   {
  3271.     extract_colors(Colour, &Red, &Green, &Blue, &Alpha, &grey);
  3272.  
  3273.     POV_DISPLAY_PLOT(x, y, Red, Green, Blue, Alpha);
  3274.   }
  3275. }
  3276.  
  3277.  
  3278.  
  3279. /*****************************************************************************
  3280. *
  3281. * FUNCTION
  3282. *
  3283. *   jitter_pixel_position
  3284. *
  3285. * INPUT
  3286. *
  3287. *   x, y     - pixel location
  3288. *   
  3289. * OUTPUT
  3290. *
  3291. *   Jitter_X - pseudo-random offset to x-coordinate
  3292. *   Jitter_Y - pseudo-random offset to y-coordinate
  3293. *   
  3294. * RETURNS
  3295. *   
  3296. * AUTHOR
  3297. *
  3298. *   Dieter Bayer
  3299. *   
  3300. * DESCRIPTION
  3301. *
  3302. *   Apply jitter to a pixel location.
  3303. *
  3304. * CHANGES
  3305. *
  3306. *   Aug 1995 : Creation. Extracted from common code.
  3307. *
  3308. ******************************************************************************/
  3309.  
  3310. static void jitter_pixel_position(x, y, Jitter_X, Jitter_Y)
  3311. int x, y;
  3312. DBL *Jitter_X, *Jitter_Y;
  3313. {
  3314.   static int Jitt_Offset = 10;
  3315.  
  3316.   if (opts.Options & JITTER)
  3317.   {
  3318.     *Jitter_X = rand2d(x + Jitt_Offset, y);
  3319.  
  3320.     Jitt_Offset++;
  3321.  
  3322.     *Jitter_Y = rand2d(x + Jitt_Offset, y);
  3323.  
  3324.     Jitt_Offset++;
  3325.  
  3326.     *Jitter_X *= JitterScale;
  3327.     *Jitter_Y *= JitterScale;
  3328.   }
  3329.   else
  3330.   {
  3331.     *Jitter_X = *Jitter_Y = 0.0;
  3332.   }
  3333. }
  3334.  
  3335. /*****************************************************************************
  3336. *
  3337. * FUNCTION
  3338. *
  3339. *   output_line
  3340. *
  3341. * INPUT
  3342. *
  3343. *   y              - current line number
  3344. *   
  3345. * OUTPUT
  3346. *   
  3347. * RETURNS
  3348. *   
  3349. * AUTHOR
  3350. *
  3351. *   POV-Ray Team
  3352. *   
  3353. * DESCRIPTION
  3354. *
  3355. *   -
  3356. *
  3357. * CHANGES
  3358. *
  3359. *   -
  3360. *
  3361. ******************************************************************************/
  3362.  
  3363. static void output_line(y)
  3364. int y;
  3365. {
  3366.   COLOUR *Temp_Colour_Ptr;
  3367.   char *Temp_Char_Ptr;
  3368.  
  3369.   if (opts.Options & DISKWRITE)
  3370.   {
  3371.     if (y > opts.First_Line)
  3372.     {
  3373.       Write_Line(Output_File_Handle, Previous_Line, y - 1);
  3374.     }
  3375.   }
  3376.  
  3377.   if (opts.Options & VERBOSE)
  3378.   {
  3379.     if (opts.Options & ANTIALIAS)
  3380.     {
  3381.       if (opts.Options & RADIOSITY)
  3382.       {
  3383.         Status_Info(" supersampled %d, %ld radiosity.",
  3384.                     SuperSampleCount, ra_gather_count - RadiosityCount);
  3385.       }
  3386.       else
  3387.       {
  3388.         Status_Info(" supersampled %d times.", SuperSampleCount);
  3389.       }
  3390.     }
  3391.     else
  3392.     {
  3393.       if (opts.Options & RADIOSITY)
  3394.       {
  3395.         Status_Info("  %ld radiosity samples.", ra_gather_count - RadiosityCount);
  3396.       }
  3397.     }
  3398.  
  3399.     Status_Info("       \r");
  3400.   }
  3401.  
  3402.   Temp_Colour_Ptr = Previous_Line;
  3403.   Previous_Line   = Current_Line;
  3404.   Current_Line    = Temp_Colour_Ptr;
  3405.  
  3406.   Temp_Char_Ptr                   = Previous_Line_Antialiased_Flags;
  3407.   Previous_Line_Antialiased_Flags = Current_Line_Antialiased_Flags;
  3408.   Current_Line_Antialiased_Flags  = Temp_Char_Ptr;
  3409. }
  3410.  
  3411. /*****************************************************************************
  3412. *
  3413. * FUNCTION
  3414. *
  3415. *   initialise_histogram
  3416. *
  3417. * INPUT
  3418. *
  3419. * OUTPUT
  3420. *
  3421. * RETURNS
  3422. *
  3423. * AUTHOR
  3424. *
  3425. *   Chris Cason
  3426. *
  3427. * DESCRIPTION
  3428. *
  3429. * Initialise histogram collation if available, otherwise force histogram off.
  3430. *
  3431. * CHANGES
  3432. *
  3433. ******************************************************************************/
  3434.  
  3435. static void initialise_histogram ()
  3436. {
  3437. #if PRECISION_TIMER_AVAILABLE
  3438.   if (opts.histogram_on)
  3439.   {
  3440.     PRECISION_TIMER_INIT
  3441.     histogram_grid = POV_CALLOC (opts.histogram_x * opts.histogram_y,
  3442.                                  sizeof(unsigned long), "histogram grid");
  3443.   }
  3444. #else
  3445.   opts.histogram_on = FALSE ;
  3446. #endif
  3447. }
  3448.  
  3449. /*****************************************************************************
  3450. *
  3451. * FUNCTION
  3452. *
  3453. *   destroy_histogram
  3454. *
  3455. * INPUT
  3456. *
  3457. * OUTPUT
  3458. *
  3459. * RETURNS
  3460. *
  3461. * AUTHOR
  3462. *
  3463. *   Andreas Dilger
  3464. *
  3465. * DESCRIPTION
  3466. *
  3467. * CHANGES
  3468. *
  3469. ******************************************************************************/
  3470.  
  3471. void destroy_histogram ()
  3472. {
  3473. #if PRECISION_TIMER_AVAILABLE
  3474.   if (Histogram_File_Handle != NULL)
  3475.   {
  3476.     Close_File(Histogram_File_Handle);
  3477.     POV_FREE(Histogram_File_Handle);
  3478.     Histogram_File_Handle = NULL;
  3479.   }
  3480.  
  3481.   if (histogram_grid != NULL)
  3482.   {
  3483.     POV_FREE (histogram_grid) ;
  3484.     histogram_grid = NULL;
  3485.   }
  3486. #endif
  3487. }
  3488.  
  3489. /*****************************************************************************
  3490. *
  3491. * FUNCTION
  3492. *
  3493. *   accumulate_histogram
  3494. *
  3495. * INPUT
  3496. *
  3497. *   int x, y - pixel position on screen, on - starting pixel
  3498. *   
  3499. * OUTPUT
  3500. *   
  3501. * RETURNS
  3502. *   
  3503. * AUTHOR
  3504. *
  3505. *   Chris Cason
  3506. *   
  3507. * DESCRIPTION
  3508. *
  3509. * Accumulate statistics on the histogram grid given on the command line.
  3510. * The total amount of time that the program spends in tracing pixels in the
  3511. * particular grid section that the pixel lies in is eventually written to an
  3512. * output file.
  3513. *
  3514. * CHANGES
  3515. *
  3516. * Oct 1995:  Modified to return if PRECISION_TIMER_AVAILABLE == 0 [CJC]
  3517. *
  3518. ******************************************************************************/
  3519.  
  3520. static void accumulate_histogram(x, y, on)
  3521. int x, y, on;
  3522. {
  3523. #if PRECISION_TIMER_AVAILABLE
  3524.   int loc_x, loc_y;
  3525.   unsigned long  *p;
  3526.  
  3527.   if (y < 0)
  3528.   {
  3529.     return;
  3530.   }
  3531.  
  3532.   if (!on)
  3533.   {
  3534.     PRECISION_TIMER_STOP
  3535.  
  3536.     /* determine which grid section the pixel lies in */
  3537.  
  3538.     loc_x = x * opts.histogram_x / Frame.Screen_Width;
  3539.     loc_y = y * opts.histogram_y / Frame.Screen_Height;
  3540.  
  3541.     p = histogram_grid + (long) loc_y * opts.histogram_x + loc_x;
  3542.  
  3543.     *p += PRECISION_TIMER_COUNT;
  3544.  
  3545.     if (*p > max_histogram_value)
  3546.     {
  3547.       max_histogram_value = *p;
  3548.     }
  3549.   }
  3550.   else
  3551.   {
  3552.     PRECISION_TIMER_START
  3553.   }
  3554. #endif
  3555. }
  3556.  
  3557. /*****************************************************************************
  3558. *
  3559. * FUNCTION
  3560. *
  3561. *   write_histogram
  3562. *
  3563. * INPUT
  3564. *
  3565. *   filename - file to output the data to.
  3566. *   
  3567. * OUTPUT
  3568. *   
  3569. * RETURNS
  3570. *   
  3571. * AUTHOR
  3572. *
  3573. *   Chris Cason
  3574. *   
  3575. * DESCRIPTION
  3576. *
  3577. * Processes and then writes the accumulated histogram statistics to a CSV
  3578. * (comma separated value) file. Programs such as Microsoft Excel can read CSV.
  3579. * Also accomodates image file output, such as Targa, for height field usage.
  3580. *
  3581. * CHANGES
  3582. *
  3583. * Sep 1995:  Added support for grayscale PNG histogram output [AED]
  3584. * Oct 1995:  Fixed TGA, PPM output for 0 - 1 range and use HF_GRAY_16 [AED]
  3585. * Oct 1995:  Modified to return if PRECISION_TIMER_AVAILABLE == 0 [CJC]
  3586. *
  3587. ******************************************************************************/
  3588.  
  3589. void write_histogram(filename)
  3590. char *filename;
  3591. {
  3592. #if PRECISION_TIMER_AVAILABLE
  3593.   int x, y, x_step, y_step;
  3594.   unsigned long OptionsSave;
  3595.   int OutputQualitySave;
  3596.   unsigned long *p;
  3597.   FILE *f;
  3598.   COLOUR *line, *l;
  3599.  
  3600.   Status_Info ("\nWriting histogram file '%s'", filename);
  3601.  
  3602.   switch (opts.histogram_type)
  3603.   {
  3604.     case CSV :
  3605.  
  3606.       if ((f = fopen (filename, WRITE_FILE_STRING)) == NULL)
  3607.       {
  3608.         Warning (0.0, "Cannot open file %s for histogram output.", filename);
  3609.  
  3610.         return;
  3611.       }
  3612.  
  3613.       for (y = 0, p = histogram_grid; y < opts.histogram_y ; y++)
  3614.       {
  3615.         for (x = 0; x < opts.histogram_x ; x++)
  3616.         {
  3617.              fprintf (f, "%s%010lu", x ? ", " : "", *p++);
  3618.         }
  3619.  
  3620.         fprintf (f, "\n");
  3621.       }
  3622.  
  3623.       fclose (f);
  3624.  
  3625.       break;
  3626.  
  3627.     case PPM :
  3628.     case SYS :
  3629.     case TARGA :
  3630.     case PNG:
  3631.  
  3632.       OptionsSave = opts.Options;
  3633.       OutputQualitySave = opts.OutputQuality;
  3634.  
  3635.       opts.Options = HF_GRAY_16;
  3636.       opts.OutputQuality = 12;
  3637.  
  3638.       Histogram_File_Handle->file_type = HIST_FTYPE;
  3639.  
  3640.       if (Open_File (Histogram_File_Handle, filename,
  3641.           &Frame.Screen_Width, &Frame.Screen_Height, 0, WRITE_MODE) != 1)
  3642.       {
  3643.         Warning (0.0, "Cannot open file %s for histogram output.", filename);
  3644.         return;
  3645.       }
  3646.  
  3647.       line = (COLOUR *)POV_CALLOC(Frame.Screen_Width, sizeof(COLOUR), "histogram buffer");
  3648.  
  3649.       y_step = Frame.Screen_Height / opts.histogram_y;
  3650.       x_step = Frame.Screen_Width / opts.histogram_x;
  3651.  
  3652.       for (y = 0; y < Frame.Screen_Height ; y++)
  3653.       {
  3654.         p = histogram_grid + (long) (y / y_step) * opts.histogram_x;
  3655.  
  3656.         for (x = 0, l = line; x < Frame.Screen_Width ; x++, l++)
  3657.         {
  3658.           (*l) [RED] =
  3659.           (*l) [GREEN] =
  3660.           (*l) [BLUE] = (COLC)*(p + x / x_step) / max_histogram_value;
  3661.         }
  3662.         Write_Line (Histogram_File_Handle, line, y);
  3663.       }
  3664.  
  3665.       POV_FREE (line);
  3666.  
  3667.       Close_File (Histogram_File_Handle);
  3668.  
  3669.       POV_FREE (Histogram_File_Handle);
  3670.  
  3671.       Histogram_File_Handle=NULL;
  3672.  
  3673.       opts.Options = OptionsSave;
  3674.       opts.OutputQuality = OutputQualitySave;
  3675.  
  3676.       break;
  3677.  
  3678.     case NONE:  /* Just to quiet warnings */
  3679.     default:
  3680.       break;
  3681.   }
  3682. #endif
  3683. }
  3684.  
  3685. /*****************************************************************************
  3686. *
  3687. * FUNCTION
  3688. *
  3689. *   check_stats
  3690. *
  3691. * INPUT
  3692. *   y = current row
  3693. *   doingMosaic = 1 if doing mosaic preview (show pixWidth)
  3694. *   pixWidth = size of pixel
  3695. * OUTPUT
  3696. *
  3697. * RETURNS
  3698. *
  3699. * AUTHOR
  3700. *
  3701. *   POV-Ray Team
  3702. *
  3703. * DESCRIPTION
  3704. *
  3705. *   -
  3706. *
  3707. * CHANGES
  3708. *
  3709. *   6/17/95 esp Added display of mosaic pixWidth
  3710. *
  3711. ******************************************************************************/
  3712.  
  3713. static void check_stats(y, doingMosaic, pixWidth)
  3714. register int y;
  3715. register int doingMosaic;
  3716. register int pixWidth;
  3717. {
  3718.   DBL time_dif;
  3719.   unsigned long hrs, mins;
  3720.   DBL secs;
  3721.  
  3722.   /* New verbose options CdW */
  3723.  
  3724.   if (opts.Options & VERBOSE)
  3725.   {
  3726.     STOP_TIME
  3727.  
  3728.     time_dif = TIME_ELAPSED
  3729.  
  3730.     if (time_dif > 0.0)
  3731.     {
  3732.       SPLIT_TIME(time_dif, &hrs, &mins, &secs);
  3733.  
  3734.       Status_Info("%3ld:%02ld:%02ld ", hrs, mins, (long)secs);
  3735.     }
  3736.     else
  3737.     {
  3738.       Status_Info("  -:--:-- ");
  3739.     }
  3740.  
  3741.     Status_Info("Rendering line %4d of %4d", y-opts.First_Line+1, opts.Last_Line-opts.First_Line);
  3742.  
  3743.     if (doingMosaic)
  3744.     {
  3745.       Status_Info(" at %dx%d  \b\b", pixWidth, pixWidth);
  3746.     }
  3747.  
  3748.     if (opts.Options & ANTIALIAS)
  3749.     {
  3750.       SuperSampleCount = 0;
  3751.     }
  3752.     else
  3753.     {
  3754.       Status_Info(". ");
  3755.     }
  3756.  
  3757.     RadiosityCount = ra_gather_count;
  3758.   }
  3759. }
  3760.  
  3761.  
  3762. /*****************************************************************************
  3763. *
  3764. * FUNCTION
  3765. *
  3766. *   initialize_ray_container_state
  3767. *
  3768. * INPUT
  3769. *
  3770. * OUTPUT
  3771. *
  3772. * RETURNS
  3773. *
  3774. * AUTHOR
  3775. *
  3776. *   Dieter Bayer
  3777. *
  3778. * DESCRIPTION
  3779. *
  3780. *   Initialize the containing lists of a primary ray by testing wether
  3781. *   the ray's starting point is inside any object. All objects that the
  3782. *   ray's origin is currently inside will be added to the containing
  3783. *   lists.
  3784. *
  3785. *   This is neccessary to make halos work if the camera is inside the
  3786. *   halo. It is also neccessary to make refraction work correctly if
  3787. *   the camera is inside this object.
  3788. *
  3789. * CHANGES
  3790. *
  3791. *   Mar 1996 : Creation.
  3792. *
  3793. ******************************************************************************/
  3794.  
  3795. static void initialize_ray_container_state(Ray, Compute)
  3796. RAY *Ray;
  3797. int Compute;
  3798. {
  3799.   int i, solid;
  3800.   OBJECT *Object;
  3801.  
  3802.   if (Compute)
  3803.   {
  3804.     Containing_Index = -1;
  3805.  
  3806.     if (!opts.Use_Slabs)
  3807.     {
  3808.       for (Object = Frame.Objects; Object != NULL; Object = Object -> Sibling)
  3809.       {
  3810.         if (Inside(Ray->Initial, Object))
  3811.         {
  3812.           if ((++Containing_Index)>=MAX_CONTAINING_OBJECTS)
  3813.           {
  3814.              Error("Too many nested objects\n");
  3815.           }
  3816.           Containing_Objects[Containing_Index] = Object;
  3817.           Containing_Textures[Containing_Index]  = Object->Texture;
  3818.  
  3819.           if ((Object->Texture != NULL) &&
  3820.               (Object->Texture->Type == PLAIN_PATTERN) &&
  3821.               (Object->Texture->Finish != NULL))
  3822.           {
  3823.             Containing_IORs[Containing_Index] = Object->Texture->Finish->Index_Of_Refraction;
  3824.           }
  3825.           else
  3826.           {
  3827.             Containing_IORs[Containing_Index] = Frame.Atmosphere_IOR;
  3828.           }
  3829.         }
  3830.       }
  3831.     }
  3832.     else
  3833.     {
  3834.       initialize_ray_container_state_tree(Ray, Root_Object);
  3835.     }
  3836.   }
  3837.  
  3838.   for (i = 0; i <= Containing_Index; i++)
  3839.   {
  3840.     Ray->Containing_Textures[i] = Containing_Textures[i];
  3841.     Ray->Containing_Objects[i]  = Containing_Objects[i];
  3842.     Ray->Containing_IORs[i]     = Containing_IORs[i];
  3843.   }
  3844.  
  3845.   Ray->Containing_Index = Containing_Index;
  3846.  
  3847.   /* Test if we are in a hollow object (do this only once). */
  3848.  
  3849.   if (!Primary_Ray_State_Tested)
  3850.   {
  3851.     solid = FALSE;
  3852.  
  3853.     for (i = 0; i <= Containing_Index; i++)
  3854.     {
  3855.       if (!Test_Flag(Containing_Objects[i], HOLLOW_FLAG))
  3856.       {
  3857.         solid = TRUE;
  3858.  
  3859.         break;
  3860.       }
  3861.     }
  3862.  
  3863.     if (solid)
  3864.     {
  3865.       Warning(0.0, "Camera is inside a non-hollow object.\nAtmosphere, fog, and halo may not work as expected.\n");
  3866.     }
  3867.  
  3868.     Primary_Ray_State_Tested = TRUE;
  3869.   }
  3870. }
  3871.  
  3872.  
  3873.  
  3874. /*****************************************************************************
  3875. *
  3876. * FUNCTION
  3877. *
  3878. *   initialize_ray_container_state_tree
  3879. *
  3880. * INPUT
  3881. *
  3882. * OUTPUT
  3883. *
  3884. * RETURNS
  3885. *
  3886. * AUTHOR
  3887. *
  3888. *   Dieter Bayer
  3889. *
  3890. * DESCRIPTION
  3891. *
  3892. *   Step down the bounding box hierarchy and test for all node wether
  3893. *   the ray's origin is inside or not. If it's inside a node descend
  3894. *   further. If a leaf is reached and the ray's origin is inside the
  3895. *   leaf object insert the objects data into the ray's containing lists.
  3896. *
  3897. * CHANGES
  3898. *
  3899. *   Mar 1996 : Creation.
  3900. *
  3901. ******************************************************************************/
  3902.  
  3903. static void initialize_ray_container_state_tree(Ray, Node)
  3904. RAY *Ray;
  3905. BBOX_TREE *Node;
  3906. {
  3907.   int i;
  3908.   OBJECT *Object;
  3909.  
  3910.   /* Check current node. */
  3911.  
  3912.   if ((Ray->Initial[X] < (DBL)Node->BBox.Lower_Left[X]) ||
  3913.       (Ray->Initial[Y] < (DBL)Node->BBox.Lower_Left[Y]) ||
  3914.       (Ray->Initial[Z] < (DBL)Node->BBox.Lower_Left[Z]) ||
  3915.       (Ray->Initial[X] > (DBL)Node->BBox.Lower_Left[X] + (DBL)Node->BBox.Lengths[X]) ||
  3916.       (Ray->Initial[Y] > (DBL)Node->BBox.Lower_Left[Y] + (DBL)Node->BBox.Lengths[Y]) ||
  3917.       (Ray->Initial[Z] > (DBL)Node->BBox.Lower_Left[Z] + (DBL)Node->BBox.Lengths[Z]))
  3918.   {
  3919.     return;
  3920.   }
  3921.  
  3922.   if (Node->Entries)
  3923.   {
  3924.     /* This is a node containing leaves to be checked. */
  3925.  
  3926.     for (i = 0; i < Node->Entries; i++)
  3927.     {
  3928.       initialize_ray_container_state_tree(Ray, Node->Node[i]);
  3929.     }
  3930.   }
  3931.   else
  3932.   {
  3933.     /* This is a leaf so test contained object. */
  3934.  
  3935.     Object = (OBJECT *)Node->Node;
  3936.  
  3937.     if (Inside(Ray->Initial, Object))
  3938.     {
  3939.       if (Object->Texture != NULL)
  3940.       {
  3941.         if ((++Containing_Index)>=MAX_CONTAINING_OBJECTS)
  3942.         {
  3943.            Error("Too many nested objects\n");
  3944.         }
  3945.         Containing_Objects[Containing_Index] = Object;
  3946.         Containing_Textures[Containing_Index]  = Object->Texture;
  3947.  
  3948.         if ((Object->Texture != NULL) &&
  3949.             (Object->Texture->Type == PLAIN_PATTERN) &&
  3950.             (Object->Texture->Finish != NULL))
  3951.         {
  3952.           Containing_IORs[Containing_Index] = Object->Texture->Finish->Index_Of_Refraction;
  3953.         }
  3954.         else
  3955.         {
  3956.           Containing_IORs[Containing_Index] = Frame.Atmosphere_IOR;
  3957.         }
  3958.       }
  3959.     }
  3960.   }
  3961. }
  3962.  
  3963.