home *** CD-ROM | disk | FTP | other *** search
- /*
- Author: S.N.pattanaik
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <math.h>
-
- #include "GraphicsGems.h"
- #include "data_structure.h"
- #include "render.h"
- #include "vox.h"
-
- #include "raddecl.h"
-
- #define Hemicube_Reso 50
-
- #ifdef __BORLANDC__
- extern unsigned int _stklen=50*1024;
- #endif
-
- int matherr(struct exception *erre) {
-
- char errorstr[][10]={"DOMAIN","SING","OVERFLOW","UNDERFLOW","TLOSS","PLOSS"};
-
- printf("MATH ERROR: Function \n",erre->name);
- printf("Type %s \n",errorstr[erre->type-1]);
- printf("Press a key to continue\n");
- getche();
-
- return(0);
- }
-
-
- #include <signal.h>
-
- typedef void (*fptr)();
-
- void Catcher(int *reglist) {
- printf("Caught error!\n"); /* make return AX = 3 */
- }
-
-
- /* Begin Global Variables */
- int color_channels=0;
- int number_objects=0;
- int number_volumes=0;
- int light_sources=0;
- Obj *object;
- Source source[MAXSOURCES];
- Volume_grid volume_grid;
- ViewParameter view;
- double brightness_mult_factor=1.;
- int total_surface_grid_points;
- long total_rays=1;
- int intensity_out_flag=For_Grids_Only;
- int verbose_output_flag=0;
- int hemicube_resolution=Hemicube_Reso;
- int verbose_flag=0;
- int output_format;
- /* End Global Variables */
-
- static int progressive_distribution_flag = 0;
-
- int error(s)
- char *s;
- {
- fprintf(stderr,"ERROR : %s\n",s);
- exit(0);
- }
- int show_usage()
- {
- fprintf(stderr,"USAGE : rad [options] image_file < scene data\n");
- fprintf(stderr,"Options :\n");
- fprintf(stderr,"\t-v : for verbose output to STDERR.\n\t\tDefault : Silent.\n");
- fprintf(stderr,"\t-s shading type (Flat/Gouraud).\n\t\tDefault : %s.\n",
- (view.shading_type==FLAT)?"Flat":
- (view.shading_type==GOURAUD)?"Gouraud":
- "Gouraud+TrilinearInterpolation");
- fprintf(stderr,"\t-i intensity file (precomputed intensity input).\n\t\tDefault : compute.\n");
- fprintf(stderr,"\t-O intensity file (for intensity output for main surfaces).\n");
- fprintf(stderr,"\t-o intensity file (for intensity output for grid) points.\n");
- fprintf(stderr,"\t-b <Brightness Multiplication Factor>.\n\t\tDefault : %g.\n",
- brightness_mult_factor);
- fprintf(stderr,"\t-p <no. of passes>. Carry out analytical(Radiosity) solution\n\t\tby Progressive Distribution.\n");
- fprintf(stderr,"\t-P <RayTracing/Scan>. Carry out hemicube projection by ray tracing or scan conversion.\n");
- fprintf(stderr,"\t-H <Hemicube Resolution>.\n\t\tDefault Resolution : %d.\n",hemicube_resolution);
- #if defined(__BORLANDC__) || defined(__WATCOMC__)
- fprintf(stderr,"\t-f RLE/RADIANCE/RAW/TEXT.\n\t\tDefault Output Format : %s.\n",
- (output_format==Rle)?"RLE":
- (output_format==Radiance)?"RADIANCE":
- (output_format==Raw)?"RAW":"TEXT"
- );
- #else
- fprintf(stderr,"\t-f RLE/RADIANCE/SUNRASTER/RAW/TEXT.\n\t\tDefault Output Format : %s.\n",
- (output_format==Rle)?"RLE":
- (output_format==Radiance)?"RADIANCE":
- (output_format==Sunraster)?"SUNRASTER":
- (output_format==Raw)?"RAW":"TEXT"
- );
- #endif
- /*
- 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");
- */
- fprintf(stderr,"HARDCODED OPTIONS : Maybe changed by editing data_structure.h.\n");
- fprintf(stderr,"\tMAXCHANNELS : %d.\n",MAXCHANNELS);
- fprintf(stderr,"\tMAXSOURCES : %d.\n",MAXSOURCES);
- exit(0);
- }
- void init_view()
- {
- view.shading_type=GOURAUD;
- #if defined (RADIANCE)
- output_format = Radiance;
- #else
- #if defined (RLE)
- output_format = Rle;
- #else
- #if defined (SUNRASTER) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
- output_format = Sunraster;
- #else
- #if defined (RAW)
- output_format = Raw;
- #else
- output_format = Text;
- #endif
- #endif
- #endif
- #endif
- }
- static int progressive_passes= -1;
- int main(argc,argv)
- int argc;
- char **argv;
- {
- int input();
- long render();
- long solve_analytically();
- int parse_parameters();
- int precomputed_intensity;
- FILE *in_intfile=NULL,*out_intfile=NULL;
- char *imagefl;
-
-
- #ifdef __BORLANDC__
- signal(SIGFPE, (fptr)Catcher); /* cast Catcher to appropriate type */
- #endif
-
- // signal(SIGFPE, SIG_IGN); /* cast Catcher to appropriate type */
-
- init_view();
- precomputed_intensity=
- parse_parameters(argc,argv,
- &imagefl,&in_intfile,&out_intfile);
- total_surface_grid_points=input();
- if (verbose_flag)fprintf(stderr,"Input Complete.\n");
- preprocess();
- if (verbose_flag)fprintf(stderr,"Preprocessing Complete.\n");
- if (precomputed_intensity) read_in_intensity(in_intfile);
- else {
- long progressive_radiosity();
- long fullmatrix_radiosity();
- total_rays+=(progressive_distribution_flag)
- ?progressive_radiosity(progressive_passes,
- 0,out_intfile)
- :fullmatrix_radiosity(0,out_intfile);
- }
- if (out_intfile!=NULL) fclose(out_intfile);
- total_rays+=render(imagefl);
- }
-
- int parse_parameters(argc,argv,imagefl,in_intfile,out_intfile)
- int argc;
- char **argv;
- char **imagefl;
- FILE **in_intfile,**out_intfile;
- {
- #define invalid_filename(s) (!isalnum(s[0]))
-
- int index=1;
- int precomputed_intensity=0;
- extern int ProjectionByRaytracing;
-
- if (argc < 2) show_usage();
- while((index < argc) && (argv[index][0] == '-')){
- switch(argv[index][1]){
- case 'p' : progressive_distribution_flag = 1;
- index++; if (index >= argc) show_usage();
- sscanf(argv[index],"%d",&progressive_passes);
- break;
- case 'H' : index++; if (index >= argc) show_usage();
- sscanf(argv[index],"%d",
- &hemicube_resolution);
- break;
- case 's' : /* Shading Type : Flat/Gouraud.
- Default is Flat. */
- index++; if (index >= argc) show_usage();
- if (strcmp(argv[index],"Gouraud")==0)
- view.shading_type=GOURAUD;
- else if(strcmp(argv[index],"GouraudPlus")==0)
- view.shading_type=GOURAUD_PLUS;
- else if (strcmp(argv[index],"Flat")==0)
- view.shading_type=FLAT;
- else show_usage();
- break;
- case 'f' : /* Output Format */
- index++; if (index >= argc) show_usage();
- if (strcmp(argv[index],"RLE")==0)
- output_format=Rle;
- else if(strcmp(argv[index],"RADIANCE")==0)
- output_format=Radiance;
- #if !defined(__BORLANDC__) && !defined(__WATCOMC__)
- else if (strcmp(argv[index],"SUNRASTER")==0)
- output_format=Sunraster;
- #endif
- else if (strcmp(argv[index],"RAW")==0)
- output_format=Raw;
- else if (strcmp(argv[index],"TEXT")==0)
- output_format=Text;
- else show_usage();
- break;
- case 'P' : /* Selecting projection method */
- index++; if (index >= argc) show_usage();
- if (strcmp(argv[index],"RayTracing")==0)
- ProjectionByRaytracing=1;
- else if (strcmp(argv[index],"Scan")==0)
- ProjectionByRaytracing=0;
- else show_usage();
- break;
- case 'i' : /* Pre computed intensity */
- index++; if (index >= argc) show_usage();
- if (invalid_filename(argv[index]))
- error("Invalid intensity filename.");
- *in_intfile=fopen(argv[index],"r");
- if (*in_intfile == NULL)
- error("Precomputed Intensity File Does Not Exist.");
- else{
- precomputed_intensity=1;
- }
- break;
- case 'O' : intensity_out_flag=For_Main_Surfaces_Only;
- case 'o' :
- if (argv[index][2]=='v') verbose_output_flag = 1;
- index++; if (index >= argc) show_usage();
- if (invalid_filename(argv[index]))
- error("Invalid Intensity file name.");
- #if defined(__MSDOS__) || defined(__WATCOMC__)
- if ((*out_intfile=fopen(argv[index],"wb"))==NULL)
- error("Cannot write to intensity file.");
- #else
- if ((*out_intfile=fopen-(argv[index],"w"))==NULL)
- error("Cannot write to intensity file.");
- #endif
- break;
- case 'b' : /* Brightness multiplication factor. */
- index++; if (index >= argc) show_usage();
- sscanf(argv[index],"%lf",&brightness_mult_factor);
- break;
- case 'v' : verbose_flag = 1; break;
- default : fprintf(stderr,"Option %s not supported.\n",
- argv[index]);
- break;
- }
- index++;
- }
- if (argc > index) {
- if (invalid_filename(argv[index]))
- error("Invalid Image filename.");
- *imagefl=argv[index];
- }
- if (verbose_flag){
- fprintf(stderr,"%s.\n",
- (view.shading_type==GOURAUD)
- ?"Gouraud Shading"
- :(view.shading_type==FLAT)?"Flat Shading"
- :"Gouraud+TrilinearInterpolation");
- fprintf(stderr,"Image Format : %s.\n",
- (output_format==Rle)?"RLE":
- (output_format==Radiance)?"RADIANCE":
- #if !defined(__BORLANDC__) && !defined(__WATCOMC__)
- (output_format==Sunraster)?"SUNRASTER":
- #endif
- (output_format==Raw)?"RAW":"TEXT"
- );
- if (precomputed_intensity)
- fprintf(stderr,"Uses Precomputed Intensity.\n");
- }
- return(precomputed_intensity);
- }
-
- Vector3 transform_vector(v,m)
- Vector3 *v;
- Matrix4 *m;
- {
- Vector3 result;
- result.x= v->x * m->element[0][0]
- + v->y * m->element[1][0]
- + v->z * m->element[2][0];
- result.y= v->x * m->element[0][1]
- + v->y * m->element[1][1]
- + v->z * m->element[2][1];
- result.z= v->x * m->element[0][2]
- + v->y * m->element[1][2]
- + v->z * m->element[2][2];
- return(result);
- }
-
- void align_axis_to_Z(v,m)
- Vector3 *v;
- Matrix4 *m;
- {
- m->element[0][3]= m->element[1][3]= m->element[2][3]=
- m->element[3][0]=m->element[3][1]=m->element[3][2]=0.0;
- m->element[3][3]=1.0;
- if (fabs(v->y) < EPSILON && fabs(v->z) < EPSILON){
- m->element[0][0]=m->element[0][1]=
- m->element[1][0]=m->element[1][2]=
- m->element[2][1]=m->element[2][2]=0.;
- m->element[1][1] = 1.;
- m->element[0][2] = v->x;
- m->element[2][0] = -v->x;
- }
- else{
- double len = sqrt(v->y*v->y+v->z*v->z);
- m->element[0][0] = len; m->element[0][1] = 0.; m->element[0][2] = v->x;
- m->element[1][0] = -v->x*v->y/len; m->element[1][1] = v->z/len; m->element[1][2] = v->y;
- m->element[2][0] = -v->x*v->z/len; m->element[2][1] = -v->y/len; m->element[2][2] = v->z;
- }
- }
-
- #define exchange(a,b) {temp=b; b = a; a = temp;}
- void align_Z_to_axis(v,m)
- Vector3 *v;
- Matrix4 *m;
- {
- double temp;
- align_axis_to_Z(v,m);
- /* Transpose */
- exchange(m->element[1][0],m->element[0][1])
- exchange(m->element[2][0],m->element[0][2])
- exchange(m->element[2][1],m->element[1][2])
- }
- #undef exchange
-
- void mirror_reflection(N,dir,o)
- /*
- IMPORTANT
- ---------
- Modifies the vector dir.
- */
- Vector3 *N; /* Input */
- Vector3 *dir; /* Input and Output */
- Obj *o; /* Input */
- {
- double N_dot_V_mul_2=2.0*V3Dot (N,dir);
-
- dir->x -= N_dot_V_mul_2 * N->x;
- dir->y -= N_dot_V_mul_2 * N->y;
- dir->z -= N_dot_V_mul_2 * N->z;
- }
-
- static int check_overlap(min1,max1,min2,max2)
- double min1,max1,min2,max2;
- {
- if (min1 > min2){
- if (min1 > max2) return(0);
- }
- else if (min2 > max1) return(0);
- return(1);
- }
-
- int bounds_overlap(b1,b2)
- /*
- 3D Bounds overlap iff
- X extents overlap and
- Y extents overlap and
- Z extents overlap.
- */
- Box3 *b1,*b2;
- {
- int check_overlap();
- /* Check X extent */
- if (check_overlap(b1->min.x,b1->max.x,b2->min.x,b2->max.x))
- /* Check Y extent */
- if (check_overlap(b1->min.y,b1->max.y,b2->min.y,b2->max.y))
- /* Check Z extent */
- if (check_overlap(b1->min.z,b1->max.z,b2->min.z,b2->max.z))
- return(1);
- return(0);
- }
-
- Point3 get_bilinear(q,u,v)
- Quadrilateral *q;
- double u,v;
- {
- Point3 p;
- p.x = q->P00.x*(1.0-u)*(1.0-v)
- + q->P10.x*u*(1.0-v)
- + q->P01.x*(1.0-u)*v
- + q->P11.x*u*v;
- p.y = q->P00.y*(1.0-u)*(1.0-v)
- + q->P10.y*u*(1.0-v)
- + q->P01.y*(1.0-u)*v
- + q->P11.y*u*v;
- p.z = q->P00.z*(1.0-u)*(1.0-v)
- + q->P10.z*u*(1.0-v)
- + q->P01.z*(1.0-u)*v
- + q->P11.z*u*v;
- return(p);
- }
-
-