home *** CD-ROM | disk | FTP | other *** search
/ 3D Color Clip Art / 3D_Color_Clip_Art.bin / 3d-progs / rad386 / main.c < prev    next >
C/C++ Source or Header  |  1996-11-15  |  12KB  |  413 lines

  1. /*
  2.         Author: S.N.pattanaik
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include <math.h>
  9.  
  10. #include "GraphicsGems.h"
  11. #include "data_structure.h"
  12. #include "render.h"
  13. #include "vox.h"
  14.  
  15. #include "raddecl.h"
  16.  
  17. #define Hemicube_Reso 50
  18.  
  19. #ifdef __BORLANDC__
  20. extern unsigned int _stklen=50*1024;
  21. #endif
  22.  
  23. int matherr(struct exception *erre) {
  24.  
  25.     char errorstr[][10]={"DOMAIN","SING","OVERFLOW","UNDERFLOW","TLOSS","PLOSS"};
  26.  
  27.     printf("MATH ERROR: Function \n",erre->name);
  28.     printf("Type %s \n",errorstr[erre->type-1]);
  29.     printf("Press a key to continue\n");
  30.     getche();
  31.  
  32.     return(0);
  33.     }
  34.  
  35.  
  36. #include <signal.h>
  37.  
  38. typedef void (*fptr)();
  39.  
  40. void Catcher(int *reglist) {
  41.    printf("Caught error!\n"); /* make return AX = 3 */
  42. }
  43.  
  44.  
  45. /* Begin Global Variables */
  46.     int color_channels=0;
  47.     int number_objects=0;
  48.     int number_volumes=0;
  49.     int light_sources=0;
  50.     Obj *object;
  51.     Source source[MAXSOURCES];
  52.     Volume_grid volume_grid;
  53.     ViewParameter view;
  54.     double brightness_mult_factor=1.;
  55.     int total_surface_grid_points;
  56.     long total_rays=1;
  57.     int intensity_out_flag=For_Grids_Only;
  58.     int verbose_output_flag=0;
  59.     int hemicube_resolution=Hemicube_Reso;
  60.     int verbose_flag=0;
  61.     int output_format;
  62. /* End Global Variables */
  63.  
  64. static int progressive_distribution_flag = 0;
  65.  
  66. int error(s)
  67. char *s;
  68. {
  69.     fprintf(stderr,"ERROR : %s\n",s);
  70.     exit(0);
  71. }
  72. int show_usage()
  73. {
  74.     fprintf(stderr,"USAGE : rad [options] image_file < scene data\n");
  75.     fprintf(stderr,"Options :\n");
  76.     fprintf(stderr,"\t-v : for verbose output to STDERR.\n\t\tDefault : Silent.\n");
  77.     fprintf(stderr,"\t-s shading type (Flat/Gouraud).\n\t\tDefault : %s.\n",
  78.         (view.shading_type==FLAT)?"Flat":
  79.             (view.shading_type==GOURAUD)?"Gouraud":
  80.             "Gouraud+TrilinearInterpolation");
  81.     fprintf(stderr,"\t-i intensity file (precomputed intensity input).\n\t\tDefault : compute.\n");
  82.     fprintf(stderr,"\t-O intensity file (for intensity output for main surfaces).\n");
  83.     fprintf(stderr,"\t-o intensity file (for intensity output for grid) points.\n");
  84.     fprintf(stderr,"\t-b <Brightness Multiplication Factor>.\n\t\tDefault : %g.\n",
  85.         brightness_mult_factor);
  86.     fprintf(stderr,"\t-p <no. of passes>. Carry out analytical(Radiosity) solution\n\t\tby Progressive Distribution.\n");
  87.     fprintf(stderr,"\t-P <RayTracing/Scan>. Carry out hemicube projection by ray tracing or scan conversion.\n");
  88.     fprintf(stderr,"\t-H <Hemicube Resolution>.\n\t\tDefault Resolution : %d.\n",hemicube_resolution);
  89. #if defined(__BORLANDC__) || defined(__WATCOMC__)
  90.     fprintf(stderr,"\t-f RLE/RADIANCE/RAW/TEXT.\n\t\tDefault Output Format : %s.\n",
  91.         (output_format==Rle)?"RLE":
  92.         (output_format==Radiance)?"RADIANCE":
  93.         (output_format==Raw)?"RAW":"TEXT"
  94.     );
  95. #else
  96.     fprintf(stderr,"\t-f RLE/RADIANCE/SUNRASTER/RAW/TEXT.\n\t\tDefault Output Format : %s.\n",
  97.         (output_format==Rle)?"RLE":
  98.         (output_format==Radiance)?"RADIANCE":
  99.         (output_format==Sunraster)?"SUNRASTER":
  100.         (output_format==Raw)?"RAW":"TEXT"
  101.     );
  102. #endif
  103. /*
  104.     fprintf(stderr,"NOTE : If number of frames>1\n\tthen the image files are named with the frame number appended\n\tto the specified file name.\n");
  105. */
  106.     fprintf(stderr,"HARDCODED OPTIONS : Maybe changed by editing data_structure.h.\n");
  107.     fprintf(stderr,"\tMAXCHANNELS : %d.\n",MAXCHANNELS);
  108.     fprintf(stderr,"\tMAXSOURCES : %d.\n",MAXSOURCES);
  109.     exit(0);
  110. }
  111. void init_view()
  112. {
  113.         view.shading_type=GOURAUD;
  114. #if defined (RADIANCE)
  115.     output_format = Radiance;
  116. #else
  117. #if defined (RLE)
  118.     output_format = Rle;
  119. #else
  120. #if defined (SUNRASTER) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
  121.     output_format = Sunraster;
  122. #else
  123. #if defined (RAW)
  124.     output_format = Raw;
  125. #else
  126.     output_format = Text;
  127. #endif
  128. #endif
  129. #endif
  130. #endif
  131. }
  132. static int progressive_passes= -1;
  133. int main(argc,argv)
  134. int argc;
  135. char **argv;
  136. {
  137.     int input();
  138.     long render();
  139.     long solve_analytically();
  140.     int parse_parameters();
  141.     int precomputed_intensity;
  142.     FILE *in_intfile=NULL,*out_intfile=NULL;
  143.     char *imagefl;
  144.  
  145.  
  146. #ifdef __BORLANDC__
  147.    signal(SIGFPE, (fptr)Catcher);  /* cast Catcher to appropriate type */
  148. #endif
  149.  
  150. //   signal(SIGFPE, SIG_IGN);  /* cast Catcher to appropriate type */
  151.  
  152.     init_view();
  153.     precomputed_intensity=
  154.         parse_parameters(argc,argv,
  155.             &imagefl,&in_intfile,&out_intfile);
  156.     total_surface_grid_points=input();
  157.     if (verbose_flag)fprintf(stderr,"Input Complete.\n");
  158.     preprocess();
  159.     if (verbose_flag)fprintf(stderr,"Preprocessing Complete.\n");
  160.     if (precomputed_intensity) read_in_intensity(in_intfile);
  161.     else {
  162.         long progressive_radiosity();
  163.         long fullmatrix_radiosity();
  164.         total_rays+=(progressive_distribution_flag)
  165.             ?progressive_radiosity(progressive_passes,
  166.                 0,out_intfile)
  167.             :fullmatrix_radiosity(0,out_intfile);
  168.     }
  169.     if (out_intfile!=NULL) fclose(out_intfile);
  170.     total_rays+=render(imagefl);
  171. }
  172.  
  173. int parse_parameters(argc,argv,imagefl,in_intfile,out_intfile)
  174. int argc;
  175. char **argv;
  176. char **imagefl;
  177. FILE **in_intfile,**out_intfile;
  178. {
  179. #define invalid_filename(s) (!isalnum(s[0]))
  180.  
  181.     int index=1;
  182.     int precomputed_intensity=0;
  183.     extern int ProjectionByRaytracing;
  184.  
  185.     if (argc < 2) show_usage();
  186.     while((index < argc) && (argv[index][0] == '-')){
  187.         switch(argv[index][1]){
  188.         case 'p' : progressive_distribution_flag = 1;
  189.                index++; if (index >= argc) show_usage();
  190.                sscanf(argv[index],"%d",&progressive_passes);
  191.                break;
  192.         case 'H' : index++; if (index >= argc) show_usage();
  193.                sscanf(argv[index],"%d",
  194.                 &hemicube_resolution);
  195.                break;
  196.         case 's' : /* Shading Type : Flat/Gouraud.
  197.                   Default is Flat. */
  198.                index++;  if (index >= argc) show_usage();
  199.                if (strcmp(argv[index],"Gouraud")==0)
  200.                 view.shading_type=GOURAUD;
  201.                else if(strcmp(argv[index],"GouraudPlus")==0)
  202.                 view.shading_type=GOURAUD_PLUS;
  203.                else if (strcmp(argv[index],"Flat")==0)
  204.                 view.shading_type=FLAT;
  205.                else show_usage();
  206.                break;
  207.         case 'f' : /* Output Format */
  208.                index++;  if (index >= argc) show_usage();
  209.                if (strcmp(argv[index],"RLE")==0)
  210.                 output_format=Rle;
  211.                else if(strcmp(argv[index],"RADIANCE")==0)
  212.                 output_format=Radiance;
  213. #if !defined(__BORLANDC__) && !defined(__WATCOMC__)
  214.                else if (strcmp(argv[index],"SUNRASTER")==0)
  215.                 output_format=Sunraster;
  216. #endif
  217.                else if (strcmp(argv[index],"RAW")==0)
  218.                 output_format=Raw;
  219.                else if (strcmp(argv[index],"TEXT")==0)
  220.                 output_format=Text;
  221.                else show_usage();
  222.                break;
  223.         case 'P' : /* Selecting projection method */
  224.                index++;  if (index >= argc) show_usage();
  225.                if (strcmp(argv[index],"RayTracing")==0)
  226.                 ProjectionByRaytracing=1;
  227.                else if (strcmp(argv[index],"Scan")==0)
  228.                 ProjectionByRaytracing=0;
  229.                else show_usage();
  230.                break;
  231.         case 'i' : /* Pre computed intensity */
  232.                index++; if (index >= argc) show_usage();
  233.                if (invalid_filename(argv[index]))
  234.                 error("Invalid intensity filename.");
  235.                *in_intfile=fopen(argv[index],"r");
  236.                if (*in_intfile == NULL) 
  237.                 error("Precomputed Intensity File Does Not Exist.");
  238.                else{
  239.                 precomputed_intensity=1;
  240.                }
  241.                break;
  242.         case 'O' : intensity_out_flag=For_Main_Surfaces_Only;
  243.         case 'o' :
  244.                if (argv[index][2]=='v') verbose_output_flag = 1;
  245.                index++; if (index >= argc) show_usage();
  246.                if (invalid_filename(argv[index]))
  247.                 error("Invalid Intensity file name.");
  248. #if defined(__MSDOS__) || defined(__WATCOMC__)
  249.                if ((*out_intfile=fopen(argv[index],"wb"))==NULL)
  250.                 error("Cannot write to intensity file.");
  251. #else
  252.                if ((*out_intfile=fopen-(argv[index],"w"))==NULL)
  253.                 error("Cannot write to intensity file.");
  254. #endif
  255.                break;
  256.         case 'b' : /* Brightness multiplication factor. */
  257.                index++; if (index >= argc) show_usage();
  258.                sscanf(argv[index],"%lf",&brightness_mult_factor);
  259.                break;
  260.         case 'v' : verbose_flag = 1; break;
  261.         default  : fprintf(stderr,"Option %s not supported.\n",
  262.                     argv[index]);
  263.                break;
  264.         }
  265.         index++;
  266.     }
  267.         if (argc > index) {
  268.                 if (invalid_filename(argv[index]))
  269.                                 error("Invalid Image filename.");
  270.                 *imagefl=argv[index];
  271.     }
  272.     if (verbose_flag){
  273.     fprintf(stderr,"%s.\n",
  274.         (view.shading_type==GOURAUD)
  275.         ?"Gouraud Shading"
  276.         :(view.shading_type==FLAT)?"Flat Shading"
  277.             :"Gouraud+TrilinearInterpolation");
  278.     fprintf(stderr,"Image Format : %s.\n",
  279.         (output_format==Rle)?"RLE":
  280.         (output_format==Radiance)?"RADIANCE":
  281. #if !defined(__BORLANDC__) && !defined(__WATCOMC__)
  282.         (output_format==Sunraster)?"SUNRASTER":
  283. #endif
  284.         (output_format==Raw)?"RAW":"TEXT"
  285.     );
  286.     if (precomputed_intensity)
  287.         fprintf(stderr,"Uses Precomputed Intensity.\n");
  288.     }
  289.     return(precomputed_intensity);
  290. }
  291.  
  292. Vector3 transform_vector(v,m)
  293. Vector3 *v;
  294. Matrix4 *m;
  295. {
  296.     Vector3 result;
  297.     result.x= v->x * m->element[0][0]
  298.         + v->y * m->element[1][0]
  299.         + v->z * m->element[2][0];
  300.     result.y= v->x * m->element[0][1]
  301.         + v->y * m->element[1][1]
  302.         + v->z * m->element[2][1];
  303.     result.z= v->x * m->element[0][2]
  304.         + v->y * m->element[1][2]
  305.         + v->z * m->element[2][2];
  306.     return(result);
  307. }
  308.  
  309. void align_axis_to_Z(v,m)
  310. Vector3 *v;
  311. Matrix4 *m;
  312. {
  313.     m->element[0][3]= m->element[1][3]= m->element[2][3]=
  314.         m->element[3][0]=m->element[3][1]=m->element[3][2]=0.0;
  315.     m->element[3][3]=1.0;
  316.     if (fabs(v->y) < EPSILON && fabs(v->z) < EPSILON){
  317.         m->element[0][0]=m->element[0][1]=
  318.             m->element[1][0]=m->element[1][2]=
  319.             m->element[2][1]=m->element[2][2]=0.;
  320.         m->element[1][1] = 1.;
  321.         m->element[0][2] = v->x;
  322.         m->element[2][0] = -v->x;
  323.     }
  324.     else{
  325.         double len = sqrt(v->y*v->y+v->z*v->z);
  326.         m->element[0][0] = len; m->element[0][1] = 0.; m->element[0][2] = v->x;
  327.         m->element[1][0] = -v->x*v->y/len; m->element[1][1] = v->z/len; m->element[1][2] = v->y;
  328.         m->element[2][0] = -v->x*v->z/len; m->element[2][1] = -v->y/len; m->element[2][2] = v->z;
  329.     }
  330. }
  331.  
  332. #define exchange(a,b) {temp=b; b = a; a = temp;}
  333. void align_Z_to_axis(v,m)
  334. Vector3 *v;
  335. Matrix4 *m;
  336. {
  337.     double temp;
  338.     align_axis_to_Z(v,m);
  339.     /* Transpose */
  340.     exchange(m->element[1][0],m->element[0][1])
  341.     exchange(m->element[2][0],m->element[0][2])
  342.     exchange(m->element[2][1],m->element[1][2])
  343. }
  344. #undef exchange
  345.  
  346. void mirror_reflection(N,dir,o)
  347. /*
  348.     IMPORTANT
  349.     ---------
  350.     Modifies the vector dir.
  351. */
  352. Vector3 *N;        /* Input */
  353. Vector3 *dir;        /* Input and Output */
  354. Obj *o;            /* Input */
  355. {
  356.     double     N_dot_V_mul_2=2.0*V3Dot (N,dir);
  357.  
  358.     dir->x -= N_dot_V_mul_2 * N->x;
  359.     dir->y -= N_dot_V_mul_2 * N->y;
  360.     dir->z -= N_dot_V_mul_2 * N->z;
  361. }
  362.  
  363. static int check_overlap(min1,max1,min2,max2)
  364. double min1,max1,min2,max2;
  365. {
  366.         if (min1 > min2){
  367.                 if (min1 > max2) return(0);
  368.         }
  369.         else if (min2 > max1) return(0);
  370.         return(1);
  371. }
  372.  
  373. int bounds_overlap(b1,b2)
  374. /*
  375.         3D Bounds overlap iff
  376.                 X extents overlap and
  377.                 Y extents overlap and
  378.                 Z extents overlap.
  379. */
  380. Box3 *b1,*b2;
  381. {
  382.         int check_overlap();
  383.         /* Check X extent */
  384.         if (check_overlap(b1->min.x,b1->max.x,b2->min.x,b2->max.x))
  385.                 /* Check Y extent */
  386.                 if (check_overlap(b1->min.y,b1->max.y,b2->min.y,b2->max.y))
  387.                         /* Check Z extent */
  388.                         if (check_overlap(b1->min.z,b1->max.z,b2->min.z,b2->max.z))
  389.                                 return(1);
  390.         return(0);
  391. }
  392.  
  393. Point3 get_bilinear(q,u,v)
  394. Quadrilateral *q;
  395. double u,v;
  396. {
  397.         Point3 p;
  398.         p.x = q->P00.x*(1.0-u)*(1.0-v)
  399.               + q->P10.x*u*(1.0-v)
  400.               + q->P01.x*(1.0-u)*v
  401.               + q->P11.x*u*v;
  402.         p.y = q->P00.y*(1.0-u)*(1.0-v)
  403.               + q->P10.y*u*(1.0-v)
  404.               + q->P01.y*(1.0-u)*v
  405.               + q->P11.y*u*v;
  406.         p.z = q->P00.z*(1.0-u)*(1.0-v)
  407.               + q->P10.z*u*(1.0-v)
  408.               + q->P01.z*(1.0-u)*v
  409.               + q->P11.z*u*v;
  410.         return(p);
  411. }
  412.  
  413.