home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / coregraf / g31.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-01-06  |  12.7 KB  |  331 lines

  1. /*    g3 - three dimensional graphics interface
  2.  
  3.     history...
  4.         4 Jul 85    Renamed to set_linestyle(), set_linewidth, etc. per
  5.     revised CORE standard.  Corrected clipping parameters for small viewports.
  6.         21 Apr 85    Removed declarations of draw_line and erase_line, since
  7.     they weren't used.
  8.         18 Apr 85    Initializing linestyle and linewidth.
  9.         9 Mar 85    hid (*erase_line)() references behind #ifdef's. changed
  10.     init() references to init_graphics(), removed inquire_current_color().
  11.  
  12.     bugs...
  13. */
  14.  
  15. #include "math.h"
  16.  
  17. /*        variables defined in file of hardware-dependent
  18.         routines, such as gz.c                                    */
  19.  
  20. extern int pixels_wide,pixels_high;    /* device size in pixels */
  21. extern double best_width,best_height;    /* device height/width (proportional
  22.                 to actual dimensions in inches, but one of these *must* be 1,
  23.                 and the other must be in the range 0 to 1) */
  24. extern clear_graphics();        /* clears screen */
  25. extern init_graphics();
  26. extern finish_graphics();
  27.  
  28.  
  29. /*        variables        */
  30.  
  31. int debugging=0;
  32.  
  33. int
  34. clipping=0,                /* nonzero if clipping is enabled    */
  35. front_clipping=0,        /* nonzero if front clipping is enabled */
  36. back_clipping=0,        /* nonzero if back clipping is enabled */
  37. graphics_level=1,        /* level of CORE graphics requested */
  38. need_depth,                /* nonzero if depth must be calculated (perspective
  39.                         projection or depth clipping */
  40. num_segments=0,            /* number of segments that still exist */
  41. persp_proj=0,            /* nonzero if perspective projection requested */
  42. segment_open=0,            /* nonzero if a segment is open    */
  43. wmin1,wmax1,            /* minimum & maximum x values in device coordinates */
  44. wmin2,wmax2;            /* minimum & maximum y values in device coordinates */
  45.  
  46. double
  47. aspect_ratio,            /* height/width ratio of display */
  48. left_handed=1.,            /* 1 for LH world coordinate system, -1 for RH */
  49. vdist=0.,                /* distance from viewpoint along view plane normal to
  50.                             viewplane    */
  51. c_bottom[4],c_top[4],    /* clip vectors...if x is visible, then            */
  52. c_left[4],c_right[4],    /* x[0]*c[0] + x[1]*c[1] + x[2]*c[2] > c[3]        */
  53. c_near[4],c_far[4],        /* for c equal to each of these six arrays        */
  54. cur_x, cur_y, cur_z,            /* current position (world coordinates) */
  55. uu, vv, nn,                        /* current position (viewport coordinates) */
  56. norm1=0., norm2=0., norm3=1.,    /* view plane normal */
  57. p1=0., p2=0., p3=1.,            /* direction for parallel projection, or
  58.                                     center of projection */
  59. up1=0., up2=1., up3=0.,            /* view up vector */
  60. vrp1=0., vrp2=0., vrp3=0.,        /* view reference point */
  61.  
  62. umin=0., umax=1.,                /* window in world coordinates */
  63. vmin=0., vmax=1.,
  64. wmin=0., wmax=1.,
  65. vp_xmin=0., vp_xmax=1.,            /* requested viewport in NDC */
  66. vp_ymin=0., vp_ymax=1.,
  67. vp_zmin=0., vp_zmax=1.,
  68. ndc_width=1., ndc_height=1., ndc_depth=1.,    /* requested limits on NDC values */
  69.  
  70. rot11, rot12, rot13, rot14,     /* rotation & projection matrix */
  71. rot21, rot22, rot23, rot24,
  72. rot31, rot32, rot33, rot34;  /* (3rd row is for perspective projections) */
  73.  
  74. /*        CORE graphics routines        */
  75.  
  76. /*    clip_window - enable clipping if i is nonzero */
  77. clip_window(i) int i; {clipping=i; reset_line();}
  78.  
  79. /*    close_temporary_segment - close the current segment */
  80. close_temporary_segment()
  81. {    segment_open=0;
  82. }
  83.  
  84. /*    coordinate_system_type - set to RH coordinates if i is nonzero */
  85. coordinate_system_type(i) int i; {left_handed=(i?-1.:1.);
  86. }
  87.  
  88. /*    create_temporary_segment - create a new segment */
  89. create_temporary_segment()
  90. {    static double
  91.     skew13, skew23,    skew33,
  92.     size, p_lnth,
  93.     vp11, vp22, vp13, vp23, vp14, vp24, vp33,
  94.     n1, n2, n3,    n4,            /* view plane unit normal */
  95.     u1, u2, u3, u4,            /* horizontal unit vector in rotated system */
  96.     v1, v2, v3, v4,            /* vertical unit vector in rotated system */
  97.     width_used,height_used,
  98.     xscale,yscale;
  99.  
  100.     if(debugging)
  101.         {printf("persp_proj = %d, p = (%f,%f,%f)\n",persp_proj,p1,p2,p3);
  102.         }
  103.     set_linestyle(0);    /* SOLID line */
  104.     set_linewidth(1);
  105.     segment_open=1;
  106.     num_segments++;
  107.     size=sqrt(norm1*norm1 + norm2*norm2 + norm3*norm3);
  108.     if(size==0.)                            /* ensure finite vpn */
  109.         {puts("view plane normal has no length\n");
  110.         n1=0.; n2=0.; n3=1.;
  111.         }
  112.     else {n1=norm1/size; n2=norm2/size; n3=norm3/size;}
  113.     if((up1==0.)&&(up2==0.)&&(up3==0.))        /* ensure finite up vector  */
  114.         {puts("up vector has no length\n");
  115.         up1=0.; up2=1.; up3=0.;
  116.         }
  117.     if(debugging) printf("up = (%10f,%10f,%10f) \n",up1,up2,up3);
  118.     u1=up2*n3 - up3*n2;        /* find horizontal unit vector u in */
  119.     u2=up3*n1 - up1*n3;        /* rotated system = up CROSS n */
  120.     u3=up1*n2 - up2*n1;
  121.     size=sqrt(u1*u1 + u2*u2 + u3*u3);
  122.     if(size==0.)
  123.         {puts("view plane normal and up vector are in same direction\n");
  124.         u1=1.; u2=0.; u3=0.; v1=0.; v2=1.; v3=0.;
  125.         }
  126.     else
  127.         {u1=u1/size; u2=u2/size; u3=u3/size;
  128.         v1=n2*u3 - n3*u2;    /* find vertical unit vector v in */
  129.         v2=n3*u1 - n1*u3;    /* rotated system = n CROSS u */
  130.         v3=n1*u2 - n2*u1;
  131.         size=sqrt(v1*v1 + v2*v2 + v3*v3);        /* u & n finite & normal, */
  132.         v1=v1/size; v2=v2/size; v3=v3/size;     /* so size is nonzero */
  133.         }
  134.     p_lnth=sqrt(p1*p1 + p2*p2 + p3*p3);
  135.     if(p_lnth==0.)                    /* ensure p vector has finite length */
  136.         {puts("parallel/perspective vector has no length\n");
  137.         p1=0.; p2=0.; p3=1.; p_lnth=1.;
  138.         }
  139. /*            For parallel projection, the transformation is...
  140.  
  141.     (rot11 rot12 rot13 rot14)  (x)
  142.     (rot21 rot22 rot23 rot24)  (y) =
  143.                                (z)
  144.                                (1)
  145.                                     (u1  u2  u3  0)  (1       -vrp1)  (x)
  146.                    (1  0 skew13 0)  (v1  v2  v3  0)  (   1    -vrp2)  (y)
  147.   (vp11  0  vp13)  (0  1 skew23 0)  (n1  n2  n3  0)  (      1 -vrp3)  (z)
  148.   ( 0  vp22 vp23)  (0  0   0    1)  (0   0   0   1)  (          1  )  (1)
  149. ...where the rightmost matrix shifts the input point to account for the view
  150. reference point location, the next rotates it to the u, v, n coordinates, the
  151. "skew" matrix accounts for oblique projection, and the "vp" matrix transforms
  152. to the viewport in device coordinates.
  153.  
  154. For perspective projections, the transformation is:
  155.  
  156. (r)   (a/c)     (a)     (rot11 rot12 rot13 rot14)  (x)
  157. (s) = (b/c),    (b)  =  (rot21 rot22 rot23 rot24)  (y) =
  158.                 (c)     (rot31 rot32 rot33 rot34)  (z)
  159.                                                    (1)
  160.                                                        ( 1      -vrp1)  (x)
  161. (vp11  0  vp13)  ( 1     skew13 )  ( u1  u2  u3  u4 )  (   1    -vrp2)  (y)
  162. ( 0  vp22 vp23)  (    1  skew23 )  ( v1  v2  v3  v4 )  (      1 -vrp3)  (z)
  163. ( 0    0    1 )  (       skew33 )  ( n1  n2  n3  n4 )  (          1  )  (1)
  164.  
  165. c is the depth coordinate, scaled so that 0 is the same depth as the center of
  166. perspective, and 1 is the depth of the viewplane.
  167. */
  168.     u4=-(u1*p1 + u2*p2 + u3*p3);
  169.     v4=-(v1*p1 + v2*p2 + v3*p3);
  170.     skew13=u4;
  171.     skew23=v4;
  172.     aspect_ratio=best_height/best_width;
  173.     if((0.>=ndc_width)|(0.>=ndc_height))
  174.         {puts("invalid ndc coordinate limits");
  175.         ndc_width=ndc_height=1.;
  176.         }
  177.     if((0.>vp_xmin)|(vp_xmin>vp_xmax)|(vp_xmax>ndc_width)|
  178.     (0.>vp_ymin)|(vp_ymin>vp_ymax)|(vp_ymax>ndc_height))
  179.         {puts("invalid viewport");
  180.         vp_xmin=0.; vp_xmax=ndc_width;
  181.         vp_ymin=0.; vp_ymax=ndc_height;
  182.         }
  183.     if(ndc_height/ndc_width>aspect_ratio)  /* user isn't using all the width */
  184.         {height_used=(double)pixels_high-1;
  185.         width_used=(double)(pixels_wide-1)
  186.             *aspect_ratio*ndc_width/ndc_height;
  187.         }
  188.     else                                /* user isn't using all the height */
  189.         {height_used=(double)(pixels_high-1)
  190.             /aspect_ratio/(ndc_width/ndc_height);
  191.         width_used=(double)pixels_wide-1;
  192.         }
  193.     xscale=width_used/ndc_width;
  194.     yscale=height_used/ndc_height;
  195.     wmin1=(int)(xscale*vp_xmin);
  196.     wmax1=(int)(xscale*vp_xmax);
  197.     wmin2=(int)(yscale*(ndc_height-vp_ymax));
  198.     wmax2=(int)(yscale*(ndc_height-vp_ymin));
  199.     vp11= xscale*(vp_xmax-vp_xmin)/(umax-umin); 
  200.     vp22=-yscale*(vp_ymax-vp_ymin)/(vmax-vmin);
  201.     vp14=vp13= xscale*(umax*vp_xmin-umin*vp_xmax)/(umax-umin);
  202.     vp24=vp23=-yscale*(vmax*vp_ymin-vmin*vp_ymax)/(vmax-vmin) + height_used;
  203.     if(debugging)
  204.         {printf("vp = %10f              %10f \n",vp11,vp13);
  205.         printf( "                 %10f  %10f \n",vp22,vp23);
  206.         printf( "                                   1    \n");
  207.         }
  208.     if(persp_proj)                         /* perspective projection */
  209.         {n4=-(n1*p1 + n2*p2 + n3*p3);
  210.         if(fabs(n4)<.001*p_lnth)
  211.             {puts("can\'t project view reference point onto view plane \n");
  212.             n4=1.;
  213.             }
  214.         skew13=-skew13/n4;
  215.         skew23=-skew23/n4;
  216.         if(fabs(n4+vdist)<1.e-10)
  217.             {puts("center of projection is in view plane \n");
  218.             vdist=0.;
  219.             }
  220.         vp33=skew33=1./(n4+vdist);
  221.         vp13=vp11*skew13 + vp13*skew33;
  222.         vp23=vp22*skew23 + vp23*skew33;
  223.                         /* vp is now the product of the 1st 2 matrices */
  224.         rot11= vp11*u1 + vp13*n1;
  225.         rot12= vp11*u2 + vp13*n2;
  226.         rot13=(vp11*u3 + vp13*n3) *left_handed;
  227.         rot14= vp11*u4 + vp13*n4;
  228.         rot21= vp22*v1 + vp23*n1;
  229.         rot22= vp22*v2 + vp23*n2;
  230.         rot23=(vp22*v3 + vp23*n3) *left_handed;
  231.         rot24= vp22*v4 + vp23*n4;
  232.         rot31= vp33*n1;
  233.         rot32= vp33*n2;
  234.         rot33= vp33*n3            *left_handed;
  235.         rot34= vp33*n4;
  236.         rot14= rot14 - (rot11*vrp1 + rot12*vrp2 + rot13*vrp3);
  237.         rot24= rot24 - (rot21*vrp1 + rot22*vrp2 + rot23*vrp3);
  238.         rot34= rot34 - (rot31*vrp1 + rot32*vrp2 + rot33*vrp3);
  239.         c_bottom[0]=0.;                /* (umin,vmin,1) CROSS (umax,vmin,1) */
  240.         c_bottom[1]=umin-umax;
  241.         c_bottom[2]=vmin*(umin-umax);
  242.         c_bottom[3]=0.;
  243.         c_top[0]=0.;                /* (umax,vmax,1) CROSS (umin,vmax,1) */
  244.         c_top[1]=umin-umax;
  245.         c_top[2]=vmax*(umax-umin);
  246.         c_top[3]=0.;
  247.         c_left[0]=vmax-vmin;        /* (umin,vmax,1) CROSS (umin,vmin,1) */
  248.         c_left[1]=0.;
  249.         c_left[2]=umin*(vmin-vmax);
  250.         c_left[3]=0.;
  251.         c_right[0]=vmin-vmax;        /* (umax,vmin,1) CROSS (umax,vmax,1) */
  252.         c_right[1]=0.;
  253.         c_right[2]=umax*(vmax-vmin);
  254.         c_right[3]=0.;
  255.         }
  256.     else                                 /* parallel projection */
  257.         {
  258.     /*
  259.         vp13=vp11*skew13;
  260.         vp23=vp22*skew23;
  261.         rot11= vp11*u1 + vp13*n1;
  262.         rot21= vp22*v1 + vp23*n1;
  263.         rot12= vp11*u2 + vp13*n2;
  264.         rot22= vp22*v2 + vp23*n2;
  265.         rot13=(vp11*u3 + vp13*n3) *left_handed;
  266.         rot23=(vp22*v3 + vp23*n3) *left_handed;
  267.         rot14=-(rot11*vrp1 + rot12*vrp2 + rot13*vrp3) + vp14;
  268.         rot24=-(rot21*vrp1 + rot22*vrp2 + rot23*vrp3) + vp24;
  269.     */
  270.         rot11=(u1 + skew13*n1)*vp11;
  271.         rot21=(v1 + skew23*n1)*vp22;
  272.         rot12=(u2 + skew13*n2)*vp11;
  273.         rot22=(v2 + skew23*n2)*vp22;
  274.         rot13=(u3 + skew13*n3)*vp11 *left_handed;
  275.         rot23=(v3 + skew23*n3)*vp22 *left_handed;
  276.         rot14=-(rot11*vrp1 + rot12*vrp2 + rot13*vrp3) + vp13;
  277.         rot24=-(rot21*vrp1 + rot22*vrp2 + rot23*vrp3) + vp23;
  278.         }
  279.     c_near[0]=c_near[1]=0.; c_near[2]=1.; c_near[3]=wmin;
  280.     c_far[0]=c_far[1]=0.; c_far[2]=-1.; c_far[3]=-wmax;
  281.     if(debugging)
  282.         {printf("skew = 1       %10f \n",skew13);
  283.         printf("          1    %10f \n",skew23);
  284.         printf("               %10f \n",skew33);
  285.         printf("u,v,n=  %10f  %10f  %10f  %10f \n",u1,u2,u3,u4);
  286.         printf("        %10f  %10f  %10f  %10f \n",v1,v2,v3,v4);
  287.         printf("        %10f  %10f  %10f  %10f \n",n1,n2,n3,n4);
  288.         printf("vrp = 1          %10f \n",-vrp1);
  289.         printf("          1      %10f \n",-vrp2);
  290.         printf("              1  %10f \n",-vrp3);
  291.         printf("                  1  \n");
  292.         printf("rot= %10f  %10f  %10f  %10f \n",rot11,rot12,rot13,rot14);
  293.         printf("     %10f  %10f  %10f  %10f \n",rot21,rot22,rot23,rot24);
  294.         printf("     %10f  %10f  %10f  %10f \n",rot31,rot32,rot33,rot34);
  295.         printf("width_used= %5.1f  height_used= %5.1f \n",
  296.             width_used, height_used);
  297.         printf("xscale= %5f  yscale= %5f \n",xscale, yscale);
  298.         getchar();
  299.         show_clipping();
  300.         }
  301.     move_abs_3(0.,0.,0.);
  302. }
  303.  
  304. show_clipping()
  305. {    printf("umin = %f       vmin = %f        wmin = %f \n",umin,vmin,wmin);
  306.     printf("umax = %f       vmax = %f        wmax = %f \n",umax,vmax,wmax);
  307.     printf("vp_xmin = %f    vp_ymin = %f     vp_zmin = %f \n",vp_xmin,vp_ymin,vp_zmin);
  308.     printf("vp_xmax = %f    vp_ymax = %f     vp_zmax = %f \n",vp_xmax,vp_ymax,vp_zmax);
  309.     printf("ndc_width = %f  ndc_height = %f  ndc_depth = %f \n",ndc_width,ndc_height,ndc_depth);
  310.     printf("wmin1 = %d   wmin2 = %d \n",wmin1,wmin2);
  311.     printf("wmax1 = %d   wmax2 = %d \n",wmax1,wmax2);
  312.     printf("c_left   = (%10f,%10f,%10f,%10f) \n",c_left[0],c_left[1],c_left[2],c_left[3]);
  313.     printf("c_right  = (%10f,%10f,%10f,%10f) \n",c_right[0],c_right[1],c_right[2],c_right[3]);
  314.     printf("c_bottom = (%10f,%10f,%10f,%10f) \n",c_bottom[0],c_bottom[1],c_bottom[2],c_bottom[3]);
  315.     printf("c_top    = (%10f,%10f,%10f,%10f) \n",c_top[0],c_top[1],c_top[2],c_top[3]);
  316.     printf("c_near   = (%10f,%10f,%10f,%10f) \n",c_near[0],c_near[1],c_near[2],c_near[3]);
  317.     printf("c_far    = (%10f,%10f,%10f,%10f) \n",c_far[0],c_far[1],c_far[2],c_far[3]);
  318.     getchar();
  319. }
  320.  
  321. /*    initialize_core - initialize everything */
  322. initialize_core(out,in,dimension)
  323. int out,    /* 0=basic  1=buffered  2=dynamic a  3=dynamic b  4=dynamic c */
  324. in,            /* 0=none  1=synchronous  2=complete */
  325. dimension;    /* 2=2D  3=3D */
  326. {    if(out>1 || in>1)
  327.         {puts("WARNING: no retained segments or input primitives supported\n");
  328.         getchar();
  329.         }
  330. }
  331.