home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / radiance / simplerd.lha / simplerad / FinalFTP / Light / display.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-21  |  14.2 KB  |  475 lines

  1. /**********************************************************************/
  2. /* display.c                                                          */
  3. /*                                                                    */
  4. /* Routines for displaying the current scene.                         */
  5. /*                                                                    */
  6. /* Copyright (C) 1992, Bernard Kwok                                   */
  7. /* All rights reserved.                                               */
  8. /* Revision 1.0                                                       */
  9. /* May, 1992                                                          */
  10. /**********************************************************************/
  11. #include <stdio.h>
  12. #include "geo.h"
  13. #include "struct.h"
  14. #include "rad.h"
  15. #include "io.h"
  16. #include "display.h"
  17.  
  18. extern OptionType Option;
  19. extern RadParams ReadLog;
  20. extern Colour Pr_Add_Ambient();
  21. extern int test_vtxshade;
  22.  
  23. extern Scene RadScene;
  24. extern void Create_Initial_ReceiverList();
  25.  
  26. #ifndef DAMN_SMALL
  27. #define DAMN_SMALL 1e-10
  28. #endif
  29.  
  30. /**********************************************************************/
  31. /* Convert Spectra into RGB triples                                   */
  32. /**********************************************************************/
  33. ColourChar SpectraToRGB(spectra)
  34.      Spectra *spectra;
  35. {
  36.   ColourChar c;
  37.   Spectra r;
  38.   double max=1.0;
  39.   int k;
  40.  
  41.   /* Scale the intensity */  
  42.   for(k=MAX_SPECTRA_SAMPLES;k--;) {
  43.     if(spectra->samples[k] > max)
  44.       max = spectra->samples[k];
  45.   }
  46.   r = *spectra;
  47.   if (max > 1.0) {
  48.     for (k=MAX_SPECTRA_SAMPLES; k--;)
  49.       r.samples[k] /= max;
  50.   }
  51.  
  52.   /* Convert to a 32-bit colour, assume first 3 samples of spectra are
  53.      r,g,b. else do colour conversion here */
  54.   c.a = 0;
  55.   c.r = (char) (r.samples[0] * RGB_SCALE + RGB_ROUND);
  56.   c.g = (char) (r.samples[1] * RGB_SCALE + RGB_ROUND);
  57.   c.b = (char) (r.samples[2] * RGB_SCALE + RGB_ROUND);
  58.      
  59.   return c;
  60. }
  61.  
  62. /**********************************************************************/
  63. /* Scale Spectra is the values overflow */
  64. /**********************************************************************/
  65. Spectra SpectraScale(spectra)
  66.      Spectra spectra;
  67. {
  68.   Spectra r;
  69.   double max=1.0;
  70.   int k;
  71.  
  72.   /* Scale the intensity */  
  73.   for(k=MAX_SPECTRA_SAMPLES;k--;) {
  74.     if(spectra.samples[k] > max)
  75.       max = spectra.samples[k];
  76.   }
  77.   r = spectra;
  78.   if (max > 1.0) 
  79.     for (k=0; k<MAX_SPECTRA_SAMPLES; k++) 
  80.       r.samples[k] /= max;
  81.  
  82.   return r;
  83. }
  84.  
  85. /**********************************************************************/
  86. /* Find maximum spectra value for each spectrum                       */
  87. /**********************************************************************/
  88. void MaxSpectra(spectra, maxS)
  89.      Spectra spectra;
  90.      double maxS[3];
  91. {
  92.   int k;
  93.  
  94.   /* Scale the intensity */  
  95.   for(k=0;k<MAX_SPECTRA_SAMPLES;k++) 
  96.     if(spectra.samples[k] > maxS[k])
  97.       maxS[k] = spectra.samples[k];
  98. }
  99.  
  100. /**********************************************************************/
  101. /* Colour scaling */
  102. /**********************************************************************/
  103. void ColourScale(c)
  104.      Colour c;
  105. {
  106.   double max=1.0;
  107.  
  108.   /* Scale the colour */  
  109.   if(c.r > max) max = c.r;
  110.   if(c.g > max) max = c.g;
  111.   if(c.b > max) max = c.b;
  112.  
  113.   if (max > 1.0) {
  114.     c.r /= max;
  115.     c.g /= max;
  116.     c.b /= max;
  117.   }
  118. }
  119.  
  120. /**********************************************************************/
  121. /* Test if two polygons have the same surface properties              */
  122. /* Only test for same simple reflectance, and emittance currently     */
  123. /**********************************************************************/
  124. int Poly_SameProperties(p1, p2)
  125.      Polygon *p1, *p2;
  126. {
  127.   int i;
  128.   Spectra p_p1, p_p2;
  129.   Spectra E_p1, E_p2;
  130.   int p_same, E_same;
  131.   
  132.   p_p1 = poly_reflect(p1);
  133.   p_p2 = poly_reflect(p2);
  134.   E_p1 = poly_emit(p1);
  135.   E_p2 = poly_emit(p2);
  136.  
  137.   i=0; p_same = 1; E_same = 1;
  138.   while(p_same && E_same && (i<MAX_SPECTRA_SAMPLES)) {
  139.     p_same = (p_p1.samples[i] == p_p2.samples[i]);
  140.     E_same = (E_p1.samples[i] == E_p2.samples[i]);
  141.     i++;
  142.   }
  143.   return (p_same && E_same);
  144. }
  145.  
  146. /**********************************************************************/
  147. /* Test if 2 polygons are on the same plane (different from coplanar) */
  148. /* Check same normal vector and d value                               */
  149. /**********************************************************************/
  150. int Poly_SamePlane(p1, p2) 
  151.      Polygon *p1, *p2;
  152. {
  153.   return (vsame(&p1->normal[0], &p2->normal[0], VTX_TOLERANCE) && 
  154.       equal(p1->d, p2->d));
  155. }
  156.  
  157. /**********************************************************************/
  158. /* Interpolate vertex radiosities from adjacent patch radiosities */
  159. /**********************************************************************/
  160. void Interpolate_FromPatches(ep, c)
  161.      Polygon *ep;
  162.      Colour c[MAX_PATCH_VTX]; /* Colour of four vertices */
  163. {
  164.   int i,j;
  165.   int num_samples;
  166.   PolyList *adjpolys;
  167.   int num_adjpolys;
  168.   int tmpc[MAX_PATCH_CHILDREN];
  169.   int same_norm, same_obj, angle_ok;
  170.   Vector current_vtx_pos, current_vtx_nrm;
  171.   Colour tmpcol;
  172.   Spectra polyp;
  173.  
  174.   polyp = poly_reflect(ep);
  175.   for (i=0;i<ep->numVert;i++) {
  176.     c[i].a = 0;
  177.     
  178.     /* Find adjacent polygons to this vertex */      
  179.     adjpolys = ep->vert[i]->polylist;          
  180.     num_adjpolys = ep->vert[i]->polyhead.num_polys;
  181.     current_vtx_pos = ep->vert[i]->pos;
  182.     current_vtx_nrm = ep->normal[0];
  183.     
  184.     /* Take average radiosity of adjacent polygons as vertex radiosity */
  185.     /* Use (vertex rad * intensity scale) as RGB colour */
  186.     num_samples = 0;
  187.     c[i].r = 0.0;
  188.     c[i].g = 0.0; 
  189.     c[i].b = 0.0;
  190.     for(j=0;j<num_adjpolys;j++, adjpolys=adjpolys->next) {
  191.       
  192.       /* Polygon has no children */
  193.       if (IsLeaf(adjpolys->patch, tmpc)) {
  194.     
  195.     /* Check same normal and same object */
  196.     same_norm = vsame(&adjpolys->patch->normal[0], ¤t_vtx_nrm, 
  197.               VTX_TOLERANCE);
  198.     same_obj = (poly_object(adjpolys->patch) == poly_object(ep));
  199.  
  200.     /* Don't interpolate around corners ! */
  201.     angle_ok = (dot(&adjpolys->patch->normal[0], ¤t_vtx_nrm)
  202.             >= DAMN_SMALL);
  203.  
  204.     /* Must have same properties and be on the same object */
  205.     if (Poly_SameProperties(adjpolys->patch, ep) && angle_ok &&
  206.         ((same_norm && !same_obj) || same_obj)) {
  207.       c[i].r = c[i].r + adjpolys->patch->B.samples[0];
  208.       c[i].g = c[i].g + adjpolys->patch->B.samples[1];
  209.       c[i].b = c[i].b + adjpolys->patch->B.samples[2];
  210.       num_samples++;
  211.     }
  212.       }
  213.     }
  214.     if (num_samples == 0) {
  215.  (void) fprintf(stderr,"Oh Oh. This vertex does not belong to a polygon ! \n");
  216.       exit(1);
  217.     }
  218.     c[i].r = c[i].r / (double) num_samples;
  219.     c[i].g = c[i].g / (double) num_samples;
  220.     c[i].b = c[i].b / (double) num_samples;
  221.  
  222.     if (Option.ambient) {
  223.       c[i] = Pr_Add_Ambient(c[i], polyp);
  224.       ColourScale(c[i]);
  225.     }
  226.   }
  227. }
  228.  
  229. /**********************************************************************/
  230. /* Vertex radiosities = radiosity at vertex. No interpolation         */
  231. /**********************************************************************/
  232. void Interpolate_FromVertices2(ep, c)
  233.      Polygon *ep;
  234.      Colour c[MAX_PATCH_VTX]; /* Colour of four vertices */
  235. {
  236.   int i;
  237.   Colour tmpcol;
  238.   Spectra polyp;
  239.   
  240.   polyp = poly_reflect(ep);
  241.   for (i=0;i<ep->numVert;i++) {
  242.     c[i].r = ep->vtx_B[i].samples[0];
  243.     c[i].g = ep->vtx_B[i].samples[1];
  244.     c[i].b = ep->vtx_B[i].samples[2];
  245.     if (Option.ambient) {
  246.       c[i] = Pr_Add_Ambient(c[i], polyp);
  247.       ColourScale(c[i]);
  248.     }
  249.   }
  250. }
  251.  
  252. /**********************************************************************/
  253. /* Vertex radiosities = average of all vertex B values */
  254. /**********************************************************************/
  255. void Interpolate_FromVertices(ep, c)
  256.      Polygon *ep;
  257.      Colour c[MAX_PATCH_VTX]; /* Colour of four vertices */
  258. {
  259.   int i,j,k;
  260.   double num_samples;
  261.   PolyList *adjpolys;
  262.   int num_adjpolys;
  263.   Vector current_vtx_pos;
  264.   Vector current_vtx_nrm;
  265.   int tmpc[MAX_PATCH_CHILDREN];
  266.   Colour tmpcol;
  267.   int same_norm, same_obj, angle_ok;
  268.   Spectra polyp;
  269.  
  270.   for (i=0;i<ep->numVert;i++) {
  271.  
  272.     /* Find adjacent polygons to this vertex */      
  273.     adjpolys = ep->vert[i]->polylist;
  274.     num_adjpolys = ep->vert[i]->polyhead.num_polys;
  275.     current_vtx_pos = ep->vert[i]->pos;
  276.     current_vtx_nrm = ep->normal[0];
  277.     
  278.     /* Take average radiosity of all vertex radiosities for a given
  279.        vertex position as vertex radiosity. */
  280.     num_samples = 1.0;
  281.     c[i].r = ep->vtx_B[i].samples[0];
  282.     c[i].g = ep->vtx_B[i].samples[1];
  283.     c[i].b = ep->vtx_B[i].samples[2];
  284.     
  285.     for(j=0;j<num_adjpolys;j++, adjpolys=adjpolys->next) {
  286.     
  287.       /* Must not have any sub-elements, and can't be current poly */
  288.       if (adjpolys->patch != ep) {
  289.     if (IsLeaf(adjpolys->patch, tmpc)) {
  290.  
  291.       /* Check for same normal and same object */
  292.       same_norm = vsame(&adjpolys->patch->normal[0], ¤t_vtx_nrm, 
  293.                 VTX_TOLERANCE);
  294.       same_obj = (poly_object(adjpolys->patch) == poly_object(ep));
  295.  
  296.       /* Don't interpolate around corners ! */
  297.       angle_ok = (dot(&adjpolys->patch->normal[0], ¤t_vtx_nrm)
  298.               >= DAMN_SMALL);
  299.  
  300.       /* Must have the same properties */
  301.       if (Poly_SameProperties(adjpolys->patch, ep) && angle_ok &&
  302.           ((same_norm && !same_obj) || same_obj)) {
  303.         
  304.         /* Must have the same vertex position */
  305.         for (k=0;k<adjpolys->patch->numVert;k++) {
  306.           if (vsame(&adjpolys->patch->vert[k]->pos, ¤t_vtx_pos, 
  307.             VTX_TOLERANCE)) {
  308.         c[i].r = c[i].r + adjpolys->patch->vtx_B[k].samples[0];
  309.         c[i].g = c[i].g + adjpolys->patch->vtx_B[k].samples[1];
  310.         c[i].b = c[i].b + adjpolys->patch->vtx_B[k].samples[2];
  311.         num_samples = num_samples + 1.0;
  312.           } /* Same vtx */
  313.         }
  314.       } /* Same prop */
  315.     } /* Not first */
  316.       } /* Is leaf */
  317.     }
  318.     tmpcol.r = c[i].r / num_samples;
  319.     tmpcol.g = c[i].g / num_samples;
  320.     tmpcol.b = c[i].b / num_samples;
  321.     
  322.     /* Return interpolated vertex radiosities with or w/o ambient term */
  323.     if (Option.ambient) {
  324.       polyp = poly_reflect(ep);
  325.       c[i] = Pr_Add_Ambient(tmpcol, polyp);
  326.       ColourScale(c[i]);
  327.     } else {
  328.       c[i].r = tmpcol.r; c[i].g = tmpcol.g; c[i].b = tmpcol.b;
  329.     }
  330.   }
  331. }
  332.  
  333. /**********************************************************************/
  334. /* Prepare receiver list of scaling all values first (not used)       */
  335. /**********************************************************************/
  336. void Prep_List()
  337. {
  338.   long i,k;
  339.   Elist *el;
  340.   Elist *tmp;
  341.   Polygon *epr;
  342.   Colour c[MAX_PATCH_VTX]; /* Colour of four vertices */
  343.   Spectra tmpS;
  344.   double maxS[3];
  345.   
  346.   /* Find elements to draw, and find max intensity */
  347.   tmp = ReadLog.elements;
  348.   el = ReadLog.elements;
  349.   maxS[0] = 1.; maxS[1] = 1.; maxS[2] = 1.;
  350.   for (k=0;k<ReadLog.num_elements;k++) {
  351.     epr = el->element;
  352.     for (i=0;i<epr->numVert;i++) { 
  353.       /* tmpS = SpectraScale(epr->vtx_B[i]); */
  354.       MaxSpectra(epr->vtx_B[i], maxS); 
  355.     }
  356.     el = el->next;
  357.   }
  358.   ReadLog.elements = tmp;
  359.  
  360.   el = ReadLog.elements;
  361.   for (k=0;k<ReadLog.num_elements;k++) {
  362.     epr = el->element;
  363.     for (i=0;i<epr->numVert;i++) { /* Scale all vertex spectras */
  364.       epr->vtx_dB[i].samples[0] = epr->vtx_B[i].samples[0] /* / maxS[0] */;
  365.       epr->vtx_dB[i].samples[1] = epr->vtx_B[i].samples[1] /* / maxS[1] */;
  366.       epr->vtx_dB[i].samples[2] = epr->vtx_B[i].samples[2] /* / maxS[2] */;
  367.     }
  368.     el = el->next;
  369.   }
  370.   ReadLog.elements = tmp;
  371. }
  372.  
  373. /**********************************************************************/
  374. /* Display current PR results */
  375. /**********************************************************************/
  376. void DisplayResults(view)
  377.      Camera view;
  378. {
  379.   long i,k;
  380.   Elist *elptr;
  381.   Polygon *ep;
  382.   Colour c[MAX_PATCH_VTX]; /* Colour of four vertices */
  383.   Spectra tmpS;
  384.  
  385.   /* Prep_List(); */
  386.   /* Create_Initial_ReceiverList(&RadScene); */
  387.  
  388.   if (Option.debug) 
  389.     (void) printf("\n\t> Drawing %d elements\n", ReadLog.num_elements);
  390.   
  391.   if (Option.show_pr_steps) Begin_DrawDispl(view, 0);
  392.  
  393.   /* Draw all elements in RGB scale */
  394.   elptr = ReadLog.elements;
  395.   for (k=0;k<ReadLog.num_elements;k++) {
  396.     ep = elptr->element;
  397.  
  398.     /* Interpolate colour of vertex from colour of adjacent polygons 
  399.        or from adjacent vertices */
  400.     if (Option.rad_interp_type == INTERP_VTX_FROM_PATCH)
  401.       Interpolate_FromPatches(ep, c);
  402.     else if (Option.rad_interp_type == INTERP_VTX_FROM_VTX) {
  403.       if (test_vtxshade) 
  404.     Interpolate_FromVertices2(ep, c);
  405.       else
  406.     Interpolate_FromVertices(ep, c);
  407.     } else
  408.       (void) fprintf(stderr,"Invalid radiosity interpolation type %d\n",
  409.           Option.rad_interp_type);
  410.  
  411.     if (Option.show_pr_steps) 
  412.       Draw_ElementRGB(ep, c);
  413.     elptr = elptr->next;
  414.   }
  415.  
  416.   if (Option.show_pr_steps) End_DrawDispl();
  417. }
  418.  
  419. /**********************************************************************/
  420. /* Get radiosity (B) for polygon vertices                             */
  421. /**********************************************************************/
  422. void  Poly_VertexB(ep, c)
  423.      Polygon *ep;
  424.      Colour c[MAX_PATCH_VTX]; /* Colour of four vertices */
  425. {
  426.   /* Quantasize color */ 
  427.   /* c = SpectraToRGB(&s); */
  428.  
  429.   /* Interpolate colour of vertex from colour of adjacent polygons 
  430.      or from adjacent vertices */
  431.   if (Option.rad_interp_type == INTERP_VTX_FROM_PATCH)
  432.     Interpolate_FromPatches(ep, c);
  433.   else if (Option.rad_interp_type == INTERP_VTX_FROM_VTX) {
  434.     if (test_vtxshade) 
  435.       Interpolate_FromVertices2(ep, c);
  436.     else
  437.       Interpolate_FromVertices(ep, c);
  438.   }
  439.   else
  440.     (void) fprintf(stderr,"Invalid radiosity interpolation type %d\n",
  441.         Option.rad_interp_type);
  442. }
  443.  
  444. /**********************************************************************/
  445. /* Draw an element in single colour                                   */
  446. /**********************************************************************/
  447. void Draw_Element(ep, colour)
  448.      Polygon *ep;
  449.      unsigned long colour;
  450. {
  451.   Vector pts[MAX_PATCH_VTX];
  452.   int nPts = ep->numVert;
  453.   int j;
  454.  
  455.   for (j=0;j<nPts;j++) 
  456.     pts[j] = ep->vert[j]->pos;
  457.   Draw_Polygon(nPts, pts, &(ep->normal[0]), colour);
  458. }
  459.  
  460. /**********************************************************************/
  461. /* Draw an element shaded from vertx colours                          */
  462. /**********************************************************************/
  463. void Draw_ElementRGB(ep, colour)
  464.      Polygon *ep;
  465.      Colour colour[4];
  466. {
  467.   Vector pts[MAX_PATCH_VTX];
  468.   int nPts = ep->numVert;
  469.   int j;
  470.  
  471.   for (j=0;j<nPts;j++) 
  472.     pts[j] = ep->vert[j]->pos;  
  473.   Draw_PolygonRGB(nPts, pts, &(ep->normal[0]), colour);
  474. }
  475.