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