home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / rad386 / radiosit / src / input.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-24  |  12.8 KB  |  442 lines

  1. /*
  2. Input Format
  3. ------------
  4. view parameters
  5. number of colour channels
  6. number of surfaces
  7. for each surface :
  8.     grid_info :
  9.         horizontal_divisions
  10.         vertical_divisions
  11.     emitter_flag (0 - NonEmitter, 
  12.               1 - Diffuse Emitter)
  13.     if emitter for each channel 
  14.         source_strength
  15.     reflection_type (0 - Diffuse 1 - Specular)
  16.     for each color_channel 
  17.         reflectance values
  18.     geom_type (0 - quadrilateral, 1 - Sphere, 2 - Bubble, 3 - Cylinder
  19.            4 - Tube, 5 - Cone, 6 - Cup, 7 - Ring, 8 - Polygon > 8 others)
  20.     geometry : 
  21.         for quadrilateral
  22.             P00 
  23.             P10 
  24.             P11 
  25.             P01 (Vertices Counter Clockwise) 
  26.         for sphere and bubble
  27.             centre
  28.             radius
  29.         for cylinder and tube
  30.             base point1
  31.             base point2
  32.             radius
  33.         for cone and cup
  34.             apex point
  35.             apex radius
  36.             base point
  37.             base radius
  38.         for ring
  39.             center
  40.             normal
  41.             inner radius
  42.             outer radius
  43.         for polygon
  44.             number of vertices
  45.             vertices
  46.             .
  47.             .
  48.         for others
  49.             nill
  50. Optionally
  51. ----------
  52. Subdivisions of Bounding Volume :
  53.     across_x, across_y, across_z.
  54. */
  55. #include <stdio.h>
  56. #include <math.h>
  57. #include <malloc.h>
  58.  
  59. #include "GraphicsGems.h"
  60. #include "data_structure.h"
  61. #include "objects.h"
  62. #include "render.h"
  63. extern int verbose_flag;
  64.  
  65. #include "raddecl.h"
  66.  
  67. #define MAXPATHS 3
  68. /*
  69.     NOTE
  70.     ----
  71.     The vector n must be a unit vector.
  72. */
  73. /*
  74. compute_rotation_matrix(n,m)
  75. Vector3 *n;
  76. Matrix4 *m;
  77. {
  78.     if ((n->x==0)&&(n->y==0)){
  79.         m->element[0][0]=m->element[1][1]=m->element[2][2]=1;
  80.         m->element[0][1]=m->element[0][2]=m->element[1][0]=m->element[1][2]=
  81.             m->element[2][0]=m->element[2][1]=0.0;
  82.     }
  83.     else {
  84.         double factor=1.0/sqrt(n->x*n->x+n->y*n->y);
  85.         double cos_theta=n->z;
  86.         double sin_theta=sqrt(1.0-cos_theta*cos_theta);
  87.         double cos_phi=n->x*factor;
  88.         double sin_phi=n->y*factor;
  89.         m->element[0][0]=cos_theta*cos_phi;
  90.         m->element[0][1]=cos_theta*sin_phi;
  91.         m->element[0][2]=sin_theta;
  92.         m->element[1][0]= -sin_phi;
  93.             m->element[1][1]=cos_phi;m->element[1][2]=0;
  94.         m->element[2][0]=cos_phi*sin_theta;
  95.         m->element[2][1]=sin_phi*sin_theta;
  96.         m->element[2][2]=cos_theta;
  97.     }
  98.         m->element[0][3]=
  99.                 m->element[1][3]=
  100.                 m->element[2][3]=
  101.                 m->element[3][0]=
  102.                 m->element[3][1]=
  103.                 m->element[3][2]=0.;
  104.         m->element[3][3]=1.;
  105.  
  106. }
  107. */
  108. static void circular_path_view_computation(nf,h_type,normal,EP,U,V,N)
  109. /*
  110.     Returns normalized U,V,N vectors of the viewing coordinate system.
  111.     IMPORTANT
  112.     ---------
  113.     Assumes that vector 'normal' has been NORMALIZED.
  114. */
  115. int nf;
  116. int h_type;
  117. Vector3 *normal;
  118. Point3 EP[];
  119. Vector3 U[],V[],N[];
  120. {
  121.     int i;
  122.     Point3 centre;
  123.     double radius;
  124.     int start_angle,end_angle;
  125.     double angle,delta_angle;
  126.     Vector3 transform_vector();
  127.     Matrix4 m;
  128.  
  129.     for(i=0;i<nf;i++) V[i] = *normal;
  130.     /* Input */
  131.     scanf("%lf%lf%lf",&(centre.x),&(centre.y),&(centre.z));
  132.     scanf("%lf",&radius);
  133.     scanf("%d%d",&start_angle,&end_angle);
  134.     if (start_angle<0) start_angle += 180;
  135.     if (end_angle<0) end_angle += 180;
  136.     if ((start_angle<0)||(end_angle<0)) error("Angle ranges are +-180.");
  137.     
  138.     delta_angle=DTOR*((double)(end_angle-start_angle)/(double)nf);
  139.     angle = DTOR*(double)start_angle;
  140.     align_Z_to_axis(normal,&m);
  141.     for(i=0;i<nf;i++){
  142.         /* Compute the point on the circle with centre at origin and on XY plane */
  143.         EP[i].x=radius*cos(angle); EP[i].y=radius*sin(angle); EP[i].z=0;
  144.         /* Rotate the point to lie on the actual plane of the circle. */
  145.         EP[i]=transform_vector(&(EP[i]),&m);
  146.         /* View plane Normal vector is the radius vector i.e. centre - eye_point. */
  147.         N[i].x = -EP[i].x; N[i].y = -EP[i].y; N[i].z = -EP[i].z;
  148.         V3Normalize(&(N[i]));
  149.         if (h_type) V3Cross(&(N[i]),&(V[i]),&(U[i]));
  150.         else V3Cross(&(V[i]),&(N[i]),&(U[i]));
  151.         /* Translate the eye vector. */
  152.         V3Add(&(EP[i]),¢re,&(EP[i]));
  153.  
  154.         angle+=delta_angle;
  155.     }
  156. }
  157.  
  158. static void linear_path_view_computation(nf,h_type,normal,EP,U,V,N)
  159. int nf;
  160. int h_type;
  161. Vector3 *normal;
  162. Point3 EP[];
  163. Vector3 U[],V[],N[];
  164. {
  165.     int i;
  166.     Point3 start,end,dir1,dir2;
  167.  
  168.     /* input */
  169.     scanf("%lf%lf%lf",&(start.x),&(start.y),&(start.z));
  170.     scanf("%lf%lf%lf",&(end.x),&(end.y),&(end.z));
  171.     if ((start.x==end.x)&&(start.y==end.y)&&(start.z==end.z))
  172.         error("Zero path specification.");
  173.     /* compute */
  174.     if (h_type) V3Sub(&end,&start,&dir1);
  175.     else V3Sub(&start,&end,&dir1);
  176.     V3Normalize(&dir1);
  177.     V3Cross(normal,&dir1,&dir2);
  178.     for(i=0;i<nf;i++){ V[i] = *normal; U[i]=dir1; N[i]=dir2; }
  179.     V3Sub(&end,&start,&dir1);
  180.     dir1.x/=nf; dir1.y/=nf; dir1.z/=nf;
  181.     for(i=0;i<nf;i++){
  182.         EP[i]=start; V3Add(&start,&dir1,&start);
  183.     }
  184. }
  185.  
  186. static void null_path_view_computation(nf,h_type,normal,EP,U,V,N)
  187. int nf;
  188. int h_type;
  189. Vector3 *normal;
  190. Point3 EP[];
  191. Vector3 U[],V[],N[];
  192. {
  193.     error("This path Not implemented.");
  194. }
  195.  
  196. static void (*path_specific_view_computation[MAXPATHS])()={
  197.     linear_path_view_computation,
  198.     circular_path_view_computation,
  199.     null_path_view_computation
  200. };
  201.  
  202. static void set_other_view_parameters(U,V,N,h,v,delta_h,delta_v,
  203.                     vd,delta_U,delta_V)
  204. Vector3 *U,*V,*N;
  205. double h,v,delta_h,delta_v;
  206. Vector3 *vd,*delta_U,*delta_V;
  207. {
  208.     if (output_format==Rle){
  209.         vd->x=N->x-U->x*(h-delta_h/2)-V->x*(v-delta_v/2);
  210.         vd->y=N->y-U->y*(h-delta_h/2)-V->y*(v-delta_v/2);
  211.         vd->z=N->z-U->z*(h-delta_h/2)-V->z*(v-delta_v/2);
  212.  
  213.         delta_U->x=U->x*delta_h; delta_V->x=V->x*delta_v;
  214.         delta_U->y=U->y*delta_h; delta_V->y=V->y*delta_v;
  215.         delta_U->z=U->z*delta_h; delta_V->z=V->z*delta_v;
  216.     }
  217.     else{
  218.         vd->x=N->x-U->x*(h-delta_h/2)+V->x*(v-delta_v/2);
  219.         vd->y=N->y-U->y*(h-delta_h/2)+V->y*(v-delta_v/2);
  220.         vd->z=N->z-U->z*(h-delta_h/2)+V->z*(v-delta_v/2);
  221.     
  222.         delta_U->x=U->x*delta_h; delta_V->x= -V->x*delta_v;
  223.         delta_U->y=U->y*delta_h; delta_V->y= -V->y*delta_v;
  224.         delta_U->z=U->z*delta_h; delta_V->z= -V->z*delta_v;
  225.     }
  226. }
  227. #define LINEAR 0
  228. #define CIRCULAR 1
  229.  
  230. static void read_view_parameters()
  231. /*
  232.     a) Simple Viewing Mode
  233.        ------------------
  234.     viewtype : v - for perspective
  235.  
  236.     Image Resolution : <xreso, yreso>
  237.     View Point : <x,y,z>
  238.     view Plane Normal : <dx,dy,dy>
  239.     view up vector : <dx,dy,dz>
  240.     horiz fiel of view : <angle>
  241.     vert field of view : <angle>
  242.  
  243.     b) SPL Viewing Model :
  244.        -------------------
  245.     viewtype : s - for special
  246.  
  247.     A synthetic camera moves along a SPECIFIED PATH.
  248.     The path for convenience is on a plane. So specified 
  249.     PLANE NORMAL fixes the camera up position.
  250.     The horizontal axis of the camera is ALONG or AGAINST
  251.     the tangent to the path.
  252.     Camera view plane is at a fixed distance away from the eye position.( 1 unit).
  253.     The view plane extent is specified by the FIELD OF VIEW angle(FOV).
  254.     To allow for the change in field of view while moving along the
  255.     path the start FOV and the end FOV is specified. A linear
  256.     interpolated FOV is provided for the required frame.
  257.  
  258.     Implementation Limitations:
  259.     ---------------------------
  260.     1) Path is planar path.
  261.     2) Only paths supported are line and circular arc.
  262.  
  263.     Input Format
  264.     ------------
  265.     number of frames
  266.     if (number of frames > 0)
  267.         rows and cols in the frame 
  268.         field of view range : start FOV, end FOV
  269.         path plane normal
  270.         camera horizontal axis : Along the path(1) or Against the path (0)
  271.         camera vertical offset from path : start_offset, end_offset
  272.         type of path : linear(0) or circular_arc(1)
  273.         path specific input :
  274.             if circular arc :
  275.                 origin of circle, radius of circle
  276.                 start angle and end angle of the arc
  277.                 Angle 0 - Indicates viewing
  278.                     along the X-axis of the Camera.
  279.             if linear :
  280.                 start point, end point
  281.  
  282.     Output
  283.     ------
  284.     For each frame :
  285.         ray (start, direction) of the vector passing through
  286.             bottomleft pixel --- for .rle
  287.                 top_left pixel   --- for other formats.
  288.         horizontal increment for each col.
  289.         vertical increment for each row.
  290.         
  291. */
  292. {
  293.     int i;
  294.     int path_type,h_axis_type;
  295.     double start_fov,end_fov,delta_fov;
  296.     double start_offset,end_offset,delta_offset;
  297.     Vector3 path_normal;
  298.     Point3 EP[MAXFRAMES];
  299.     Vector3 U[MAXFRAMES],V[MAXFRAMES],N[MAXFRAMES];
  300.     int ch;
  301.     while(ch=getchar()){
  302.         if (ch == EOF) error("Empty Data File.");
  303.         if (ch == ' ' || ch == '\n'|| ch == '\t') continue;
  304.         break;
  305.     }
  306.     if (ch == VT_SPL){
  307.     scanf("%d",&(view.nframes));
  308.     if (view.nframes==0) return;
  309.     if (view.nframes>MAXFRAMES){
  310.         if (verbose_flag)fprintf(stderr,"Frames specified is greater thatn Max supported %d.\n",
  311.             MAXFRAMES);
  312.         view.nframes=MAXFRAMES;
  313.     }
  314.     scanf("%d%d",&(view.cols),&(view.rows));
  315.     scanf("%lf%lf",&start_fov,&end_fov);
  316.     scanf("%lf%lf%lf",&(path_normal.x),&(path_normal.y),&(path_normal.z));
  317.     V3Normalize(&path_normal);
  318.     scanf("%d",&h_axis_type);
  319.     scanf("%lf%lf",&start_offset,&end_offset);
  320.     scanf("%d",&path_type); if (path_type > 2) path_type = 2;
  321.     path_specific_view_computation[path_type](view.nframes,h_axis_type,&path_normal,EP,U,V,N);
  322.     delta_fov=end_fov-start_fov;
  323.     delta_offset=end_offset-start_offset;
  324.     for(i=0;i<view.nframes;i++){
  325.         double h,v,delta_h,delta_v;
  326.  
  327.         h=v=tan((start_fov*DTOR)/2.0); /* DTOR : Degree to Radian, from Graphics Gems */
  328.         delta_h=2*h/view.cols; delta_v=2*v/view.rows;
  329.  
  330.         view.eye_point[i].x=EP[i].x;
  331.         view.eye_point[i].y=EP[i].y+start_offset;
  332.         view.eye_point[i].z=EP[i].z;
  333.         set_other_view_parameters(&(U[i]),&(V[i]),&(N[i]),
  334.                 h,v,delta_h,delta_v,
  335.                 &(view.view_direction[i]),
  336.                 &(view.delta_u[i]),&(view.delta_v[i]));
  337.         start_offset+=delta_offset;
  338.         start_fov+=delta_fov;
  339.     }
  340.     }
  341.     else{ /* Simple View Specification. */
  342.         double h,v,delta_h,delta_v,start_fov;
  343.         Vector3 UV;
  344.         view.nframes=1;
  345.         scanf("%d%d",&(view.cols),&(view.rows));
  346.         scanf("%lf%lf%lf",&(view.eye_point[0].x),
  347.                   &(view.eye_point[0].y),
  348.                   &(view.eye_point[0].z));
  349.         scanf("%lf%lf%lf",&(N[0].x),&(N[0].y),&(N[0].z));
  350.                V3Normalize(&(N[0]));
  351.         scanf("%lf%lf%lf",&(UV.x),&(UV.y),&(UV.z));
  352.         V3Normalize(&UV);
  353.         V3Cross(&(N[0]),&UV,&(U[0]));
  354.         V3Normalize(&(U[0]));
  355.         V3Cross(&(U[0]),&(N[0]),&(V[0]));
  356.         scanf("%lf",&start_fov);
  357.         h=tan((start_fov*DTOR)/2.0); /* DTOR : Degree to Radian, from Graphics Gems */
  358.         scanf("%lf",&start_fov);
  359.         v=tan((start_fov*DTOR)/2.0);
  360.         delta_h=2*h/view.cols; delta_v=2*v/view.rows;
  361.         set_other_view_parameters(&(U[0]),&(V[0]),&(N[0]),
  362.                 h,v,delta_h,delta_v,
  363.                 &(view.view_direction[0]),
  364.                 &(view.delta_u[0]),&(view.delta_v[0]));
  365.     }
  366. }
  367. int input()
  368. {
  369.     int i,j,k;
  370.     int emitter_flag,gtype;
  371.     int grid_count=0;
  372.  
  373.     read_view_parameters();
  374.     scanf("%d",&color_channels);
  375.     if (color_channels > MAXCHANNELS) 
  376.         error("Cannot Accept more Channels Now.");
  377.     scanf("%d",&number_objects);
  378.     if ((object=(Obj *)malloc(sizeof(Obj)*number_objects))==NULL)
  379.         error("Cannot Allocate Object Array");
  380.     for(i=0; i<number_objects; i++){
  381.         object[i].start_grid_index=grid_count; /* For Radiosity Work */
  382.         scanf("%d%d",&(object[i].grid_h_reso),&(object[i].grid_v_reso));
  383.         grid_count += object[i].grid_v_reso*object[i].grid_h_reso;
  384.         if ( (object[i].grid= (Surface_Grid_structure *)calloc(
  385.             object[i].grid_v_reso*object[i].grid_h_reso,
  386.             sizeof(Surface_Grid_structure))) == NULL
  387.         ) error("Cannot Allocate Grid.");
  388.         scanf("%d",&emitter_flag);
  389.         if (emitter_flag){
  390.             if (light_sources >= MAXSOURCES)
  391.                 error("Cannot accept somany light sources.");
  392.             source[light_sources].oindex=i;
  393.             source[light_sources].emission_type=emitter_flag-1;
  394.             for(k=0;k<color_channels;k++){
  395.                 scanf("%lf",&(source[light_sources].strength[k]));
  396.             }
  397.             if(emitter_flag>=2){
  398.                 if (verbose_flag)fprintf(stderr,
  399.                     "WARNING : Rendering of directional sources are incorrect.\n");
  400.                 scanf("%lf%lf%lf",
  401.                     &(source[light_sources].dir.x),
  402.                     &(source[light_sources].dir.y),
  403.                     &(source[light_sources].dir.z));
  404.                 V3Normalize(&(source[light_sources].dir));
  405.                 scanf("%lf",
  406.                     &(source[light_sources].spread));
  407.                 align_Z_to_axis(
  408.                     &(source[light_sources].dir),
  409.                     &(source[light_sources].xform));
  410.             }
  411.             light_sources++;
  412.         }
  413.         scanf("%d",>ype);
  414.         if(gtype >= MAX_REFLECTION_TYPE)gtype = MAX_REFLECTION_TYPE-1;
  415.         object[i].surface_reflection_type=gtype;
  416.         for (k=0;k<color_channels;k++)
  417.             scanf("%lf",&(object[i].reflectance[k]));
  418.         scanf("%d",>ype);
  419.         if (gtype >= MAX_GEOMETRY_TYPE) gtype = MAX_GEOMETRY_TYPE-1;
  420.         object[i].surface_geometry_type=gtype;
  421.         object[i].object_specific_structure=
  422.             ofunc[gtype].read_geometry_specific_input();
  423.     }
  424.     if (scanf("%d%d%d",&(volume_grid.x_subdivision),
  425.         &(volume_grid.y_subdivision),&(volume_grid.z_subdivision)) < 3)
  426.         volume_grid.x_subdivision=
  427.             volume_grid.y_subdivision=
  428.                 volume_grid.z_subdivision=1;
  429.     if (!(volume_grid.x_subdivision
  430.         &&volume_grid.y_subdivision
  431.             &&volume_grid.z_subdivision))
  432.         error("Zero Subdivision specified for Volume Grid Structure.\n");
  433.     if ((volume_grid.voxels = (Voxel *)calloc(
  434.                     volume_grid.x_subdivision*
  435.                     volume_grid.y_subdivision*
  436.                     volume_grid.z_subdivision,
  437.                     sizeof(Voxel))) ==NULL)
  438.         error("Cannot Create Spacially Subdivision Structure.");
  439.     
  440.     return(grid_count);
  441. }
  442.