home *** CD-ROM | disk | FTP | other *** search
- /*
- Input Format
- ------------
- view parameters
- number of colour channels
- number of surfaces
- for each surface :
- grid_info :
- horizontal_divisions
- vertical_divisions
- emitter_flag (0 - NonEmitter,
- 1 - Diffuse Emitter)
- if emitter for each channel
- source_strength
- reflection_type (0 - Diffuse 1 - Specular)
- for each color_channel
- reflectance values
- geom_type (0 - quadrilateral, 1 - Sphere, 2 - Bubble, 3 - Cylinder
- 4 - Tube, 5 - Cone, 6 - Cup, 7 - Ring, 8 - Polygon > 8 others)
- geometry :
- for quadrilateral
- P00
- P10
- P11
- P01 (Vertices Counter Clockwise)
- for sphere and bubble
- centre
- radius
- for cylinder and tube
- base point1
- base point2
- radius
- for cone and cup
- apex point
- apex radius
- base point
- base radius
- for ring
- center
- normal
- inner radius
- outer radius
- for polygon
- number of vertices
- vertices
- .
- .
- for others
- nill
- Optionally
- ----------
- Subdivisions of Bounding Volume :
- across_x, across_y, across_z.
- */
- #include <stdio.h>
- #include <math.h>
- #include <malloc.h>
-
- #include "GraphicsGems.h"
- #include "data_structure.h"
- #include "objects.h"
- #include "render.h"
- extern int verbose_flag;
-
- #include "raddecl.h"
-
- #define MAXPATHS 3
- /*
- NOTE
- ----
- The vector n must be a unit vector.
- */
- /*
- compute_rotation_matrix(n,m)
- Vector3 *n;
- Matrix4 *m;
- {
- if ((n->x==0)&&(n->y==0)){
- m->element[0][0]=m->element[1][1]=m->element[2][2]=1;
- m->element[0][1]=m->element[0][2]=m->element[1][0]=m->element[1][2]=
- m->element[2][0]=m->element[2][1]=0.0;
- }
- else {
- double factor=1.0/sqrt(n->x*n->x+n->y*n->y);
- double cos_theta=n->z;
- double sin_theta=sqrt(1.0-cos_theta*cos_theta);
- double cos_phi=n->x*factor;
- double sin_phi=n->y*factor;
- m->element[0][0]=cos_theta*cos_phi;
- m->element[0][1]=cos_theta*sin_phi;
- m->element[0][2]=sin_theta;
- m->element[1][0]= -sin_phi;
- m->element[1][1]=cos_phi;m->element[1][2]=0;
- m->element[2][0]=cos_phi*sin_theta;
- m->element[2][1]=sin_phi*sin_theta;
- m->element[2][2]=cos_theta;
- }
- 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.;
- m->element[3][3]=1.;
-
- }
- */
- static void circular_path_view_computation(nf,h_type,normal,EP,U,V,N)
- /*
- Returns normalized U,V,N vectors of the viewing coordinate system.
- IMPORTANT
- ---------
- Assumes that vector 'normal' has been NORMALIZED.
- */
- int nf;
- int h_type;
- Vector3 *normal;
- Point3 EP[];
- Vector3 U[],V[],N[];
- {
- int i;
- Point3 centre;
- double radius;
- int start_angle,end_angle;
- double angle,delta_angle;
- Vector3 transform_vector();
- Matrix4 m;
-
- for(i=0;i<nf;i++) V[i] = *normal;
- /* Input */
- scanf("%lf%lf%lf",&(centre.x),&(centre.y),&(centre.z));
- scanf("%lf",&radius);
- scanf("%d%d",&start_angle,&end_angle);
- if (start_angle<0) start_angle += 180;
- if (end_angle<0) end_angle += 180;
- if ((start_angle<0)||(end_angle<0)) error("Angle ranges are +-180.");
-
- delta_angle=DTOR*((double)(end_angle-start_angle)/(double)nf);
- angle = DTOR*(double)start_angle;
- align_Z_to_axis(normal,&m);
- for(i=0;i<nf;i++){
- /* Compute the point on the circle with centre at origin and on XY plane */
- EP[i].x=radius*cos(angle); EP[i].y=radius*sin(angle); EP[i].z=0;
- /* Rotate the point to lie on the actual plane of the circle. */
- EP[i]=transform_vector(&(EP[i]),&m);
- /* View plane Normal vector is the radius vector i.e. centre - eye_point. */
- N[i].x = -EP[i].x; N[i].y = -EP[i].y; N[i].z = -EP[i].z;
- V3Normalize(&(N[i]));
- if (h_type) V3Cross(&(N[i]),&(V[i]),&(U[i]));
- else V3Cross(&(V[i]),&(N[i]),&(U[i]));
- /* Translate the eye vector. */
- V3Add(&(EP[i]),¢re,&(EP[i]));
-
- angle+=delta_angle;
- }
- }
-
- static void linear_path_view_computation(nf,h_type,normal,EP,U,V,N)
- int nf;
- int h_type;
- Vector3 *normal;
- Point3 EP[];
- Vector3 U[],V[],N[];
- {
- int i;
- Point3 start,end,dir1,dir2;
-
- /* input */
- scanf("%lf%lf%lf",&(start.x),&(start.y),&(start.z));
- scanf("%lf%lf%lf",&(end.x),&(end.y),&(end.z));
- if ((start.x==end.x)&&(start.y==end.y)&&(start.z==end.z))
- error("Zero path specification.");
- /* compute */
- if (h_type) V3Sub(&end,&start,&dir1);
- else V3Sub(&start,&end,&dir1);
- V3Normalize(&dir1);
- V3Cross(normal,&dir1,&dir2);
- for(i=0;i<nf;i++){ V[i] = *normal; U[i]=dir1; N[i]=dir2; }
- V3Sub(&end,&start,&dir1);
- dir1.x/=nf; dir1.y/=nf; dir1.z/=nf;
- for(i=0;i<nf;i++){
- EP[i]=start; V3Add(&start,&dir1,&start);
- }
- }
-
- static void null_path_view_computation(nf,h_type,normal,EP,U,V,N)
- int nf;
- int h_type;
- Vector3 *normal;
- Point3 EP[];
- Vector3 U[],V[],N[];
- {
- error("This path Not implemented.");
- }
-
- static void (*path_specific_view_computation[MAXPATHS])()={
- linear_path_view_computation,
- circular_path_view_computation,
- null_path_view_computation
- };
-
- static void set_other_view_parameters(U,V,N,h,v,delta_h,delta_v,
- vd,delta_U,delta_V)
- Vector3 *U,*V,*N;
- double h,v,delta_h,delta_v;
- Vector3 *vd,*delta_U,*delta_V;
- {
- if (output_format==Rle){
- vd->x=N->x-U->x*(h-delta_h/2)-V->x*(v-delta_v/2);
- vd->y=N->y-U->y*(h-delta_h/2)-V->y*(v-delta_v/2);
- vd->z=N->z-U->z*(h-delta_h/2)-V->z*(v-delta_v/2);
-
- delta_U->x=U->x*delta_h; delta_V->x=V->x*delta_v;
- delta_U->y=U->y*delta_h; delta_V->y=V->y*delta_v;
- delta_U->z=U->z*delta_h; delta_V->z=V->z*delta_v;
- }
- else{
- vd->x=N->x-U->x*(h-delta_h/2)+V->x*(v-delta_v/2);
- vd->y=N->y-U->y*(h-delta_h/2)+V->y*(v-delta_v/2);
- vd->z=N->z-U->z*(h-delta_h/2)+V->z*(v-delta_v/2);
-
- delta_U->x=U->x*delta_h; delta_V->x= -V->x*delta_v;
- delta_U->y=U->y*delta_h; delta_V->y= -V->y*delta_v;
- delta_U->z=U->z*delta_h; delta_V->z= -V->z*delta_v;
- }
- }
- #define LINEAR 0
- #define CIRCULAR 1
-
- static void read_view_parameters()
- /*
- a) Simple Viewing Mode
- ------------------
- viewtype : v - for perspective
-
- Image Resolution : <xreso, yreso>
- View Point : <x,y,z>
- view Plane Normal : <dx,dy,dy>
- view up vector : <dx,dy,dz>
- horiz fiel of view : <angle>
- vert field of view : <angle>
-
- b) SPL Viewing Model :
- -------------------
- viewtype : s - for special
-
- A synthetic camera moves along a SPECIFIED PATH.
- The path for convenience is on a plane. So specified
- PLANE NORMAL fixes the camera up position.
- The horizontal axis of the camera is ALONG or AGAINST
- the tangent to the path.
- Camera view plane is at a fixed distance away from the eye position.( 1 unit).
- The view plane extent is specified by the FIELD OF VIEW angle(FOV).
- To allow for the change in field of view while moving along the
- path the start FOV and the end FOV is specified. A linear
- interpolated FOV is provided for the required frame.
-
- Implementation Limitations:
- ---------------------------
- 1) Path is planar path.
- 2) Only paths supported are line and circular arc.
-
- Input Format
- ------------
- number of frames
- if (number of frames > 0)
- rows and cols in the frame
- field of view range : start FOV, end FOV
- path plane normal
- camera horizontal axis : Along the path(1) or Against the path (0)
- camera vertical offset from path : start_offset, end_offset
- type of path : linear(0) or circular_arc(1)
- path specific input :
- if circular arc :
- origin of circle, radius of circle
- start angle and end angle of the arc
- Angle 0 - Indicates viewing
- along the X-axis of the Camera.
- if linear :
- start point, end point
-
- Output
- ------
- For each frame :
- ray (start, direction) of the vector passing through
- bottomleft pixel --- for .rle
- top_left pixel --- for other formats.
- horizontal increment for each col.
- vertical increment for each row.
-
- */
- {
- int i;
- int path_type,h_axis_type;
- double start_fov,end_fov,delta_fov;
- double start_offset,end_offset,delta_offset;
- Vector3 path_normal;
- Point3 EP[MAXFRAMES];
- Vector3 U[MAXFRAMES],V[MAXFRAMES],N[MAXFRAMES];
- int ch;
- while(ch=getchar()){
- if (ch == EOF) error("Empty Data File.");
- if (ch == ' ' || ch == '\n'|| ch == '\t') continue;
- break;
- }
- if (ch == VT_SPL){
- scanf("%d",&(view.nframes));
- if (view.nframes==0) return;
- if (view.nframes>MAXFRAMES){
- if (verbose_flag)fprintf(stderr,"Frames specified is greater thatn Max supported %d.\n",
- MAXFRAMES);
- view.nframes=MAXFRAMES;
- }
- scanf("%d%d",&(view.cols),&(view.rows));
- scanf("%lf%lf",&start_fov,&end_fov);
- scanf("%lf%lf%lf",&(path_normal.x),&(path_normal.y),&(path_normal.z));
- V3Normalize(&path_normal);
- scanf("%d",&h_axis_type);
- scanf("%lf%lf",&start_offset,&end_offset);
- scanf("%d",&path_type); if (path_type > 2) path_type = 2;
- path_specific_view_computation[path_type](view.nframes,h_axis_type,&path_normal,EP,U,V,N);
- delta_fov=end_fov-start_fov;
- delta_offset=end_offset-start_offset;
- for(i=0;i<view.nframes;i++){
- double h,v,delta_h,delta_v;
-
- h=v=tan((start_fov*DTOR)/2.0); /* DTOR : Degree to Radian, from Graphics Gems */
- delta_h=2*h/view.cols; delta_v=2*v/view.rows;
-
- view.eye_point[i].x=EP[i].x;
- view.eye_point[i].y=EP[i].y+start_offset;
- view.eye_point[i].z=EP[i].z;
- set_other_view_parameters(&(U[i]),&(V[i]),&(N[i]),
- h,v,delta_h,delta_v,
- &(view.view_direction[i]),
- &(view.delta_u[i]),&(view.delta_v[i]));
- start_offset+=delta_offset;
- start_fov+=delta_fov;
- }
- }
- else{ /* Simple View Specification. */
- double h,v,delta_h,delta_v,start_fov;
- Vector3 UV;
- view.nframes=1;
- scanf("%d%d",&(view.cols),&(view.rows));
- scanf("%lf%lf%lf",&(view.eye_point[0].x),
- &(view.eye_point[0].y),
- &(view.eye_point[0].z));
- scanf("%lf%lf%lf",&(N[0].x),&(N[0].y),&(N[0].z));
- V3Normalize(&(N[0]));
- scanf("%lf%lf%lf",&(UV.x),&(UV.y),&(UV.z));
- V3Normalize(&UV);
- V3Cross(&(N[0]),&UV,&(U[0]));
- V3Normalize(&(U[0]));
- V3Cross(&(U[0]),&(N[0]),&(V[0]));
- scanf("%lf",&start_fov);
- h=tan((start_fov*DTOR)/2.0); /* DTOR : Degree to Radian, from Graphics Gems */
- scanf("%lf",&start_fov);
- v=tan((start_fov*DTOR)/2.0);
- delta_h=2*h/view.cols; delta_v=2*v/view.rows;
- set_other_view_parameters(&(U[0]),&(V[0]),&(N[0]),
- h,v,delta_h,delta_v,
- &(view.view_direction[0]),
- &(view.delta_u[0]),&(view.delta_v[0]));
- }
- }
- int input()
- {
- int i,j,k;
- int emitter_flag,gtype;
- int grid_count=0;
-
- read_view_parameters();
- scanf("%d",&color_channels);
- if (color_channels > MAXCHANNELS)
- error("Cannot Accept more Channels Now.");
- scanf("%d",&number_objects);
- if ((object=(Obj *)malloc(sizeof(Obj)*number_objects))==NULL)
- error("Cannot Allocate Object Array");
- for(i=0; i<number_objects; i++){
- object[i].start_grid_index=grid_count; /* For Radiosity Work */
- scanf("%d%d",&(object[i].grid_h_reso),&(object[i].grid_v_reso));
- grid_count += object[i].grid_v_reso*object[i].grid_h_reso;
- if ( (object[i].grid= (Surface_Grid_structure *)calloc(
- object[i].grid_v_reso*object[i].grid_h_reso,
- sizeof(Surface_Grid_structure))) == NULL
- ) error("Cannot Allocate Grid.");
- scanf("%d",&emitter_flag);
- if (emitter_flag){
- if (light_sources >= MAXSOURCES)
- error("Cannot accept somany light sources.");
- source[light_sources].oindex=i;
- source[light_sources].emission_type=emitter_flag-1;
- for(k=0;k<color_channels;k++){
- scanf("%lf",&(source[light_sources].strength[k]));
- }
- if(emitter_flag>=2){
- if (verbose_flag)fprintf(stderr,
- "WARNING : Rendering of directional sources are incorrect.\n");
- scanf("%lf%lf%lf",
- &(source[light_sources].dir.x),
- &(source[light_sources].dir.y),
- &(source[light_sources].dir.z));
- V3Normalize(&(source[light_sources].dir));
- scanf("%lf",
- &(source[light_sources].spread));
- align_Z_to_axis(
- &(source[light_sources].dir),
- &(source[light_sources].xform));
- }
- light_sources++;
- }
- scanf("%d",>ype);
- if(gtype >= MAX_REFLECTION_TYPE)gtype = MAX_REFLECTION_TYPE-1;
- object[i].surface_reflection_type=gtype;
- for (k=0;k<color_channels;k++)
- scanf("%lf",&(object[i].reflectance[k]));
- scanf("%d",>ype);
- if (gtype >= MAX_GEOMETRY_TYPE) gtype = MAX_GEOMETRY_TYPE-1;
- object[i].surface_geometry_type=gtype;
- object[i].object_specific_structure=
- ofunc[gtype].read_geometry_specific_input();
- }
- if (scanf("%d%d%d",&(volume_grid.x_subdivision),
- &(volume_grid.y_subdivision),&(volume_grid.z_subdivision)) < 3)
- volume_grid.x_subdivision=
- volume_grid.y_subdivision=
- volume_grid.z_subdivision=1;
- if (!(volume_grid.x_subdivision
- &&volume_grid.y_subdivision
- &&volume_grid.z_subdivision))
- error("Zero Subdivision specified for Volume Grid Structure.\n");
- if ((volume_grid.voxels = (Voxel *)calloc(
- volume_grid.x_subdivision*
- volume_grid.y_subdivision*
- volume_grid.z_subdivision,
- sizeof(Voxel))) ==NULL)
- error("Cannot Create Spacially Subdivision Structure.");
-
- return(grid_count);
- }
-