Clipp3D.cpp
上传用户:lhwx1029
上传日期:2013-03-07
资源大小:1173k
文件大小:11k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /** 3DGPL *************************************************
  2.  * ()                                                     *
  3.  * 3-D volume and Z clipping.                             *
  4.  *                                                        *
  5.  * Defines:                                               *
  6.  *  C_volume_clipping        Out of view-volume elements; *
  7.  *                                                        *
  8.  *  C_line_z_clipping        Clipping a line;             *
  9.  *  C_polygon_z_clipping     View plane cliping;          *
  10.  *  C_line_xyz_clipping      Arbitrry clipping of a line; *
  11.  *  C_polygon_xyz_clipping   Arbitrry plane cliping.      *
  12.  *                                                        *
  13.  * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca)      *
  14. **********************************************************/
  15. #include "RayTracing.h"           /* HW_copy_int stuff */
  16. #include "Trans.h"                 /* T_plane etc. */
  17. #include "Clipper.h"             /* clipping constants */
  18. #include <limits.h>                         /* INT_MAX & INT_MIN */
  19. int C_3D_clipping;                          /* type of performed clipping */
  20. /**********************************************************
  21.  * Accept/reject volume clipping.                         *
  22.  *                                                        *
  23.  * RETURNS:  0 when extend is for sure outside the        *
  24.  * --------    view volume, just discard it;              *
  25.  *          -1 when further clipping is required;         *
  26.  *           1 when element has a fair chance to be       *
  27.  *             inside the view volume, and should be      *
  28.  *             clipped by 2-D clipping when rasterizing.  *
  29.  *                                                        *
  30.  *               | z                                      *
  31.  *              |    /      Clipping volume is a pyramid *
  32.  *              |   /       with 90 degree angle,        *
  33.  *              |  /        so the real view volume      *
  34.  *        -x>z  | /  x>z    better be inside it.         * 
  35.  *              |/                                       *
  36.  *       --------+--------- x                             *
  37.  *       z<C_Z_CLIPPING_MIN                               *
  38.  *                                                        *
  39. **********************************************************/
  40. int C_volume_clipping(int *min,int *max)
  41. {
  42.  if((max[2]<min[0])||(max[2]<min[1])||(max[2]<-max[0])||
  43.    (max[2]<-max[1])||(max[2]<=C_Z_CLIPPING_MIN))
  44.  {
  45.   return(0);                                /* outside */
  46.  }
  47.  else
  48.  {
  49.   if(min[2]<C_Z_CLIPPING_MIN) return(-1);   /* partly behind clipping plane */
  50.   else return(1);
  51.  }
  52. }
  53. /**********************************************************
  54.  * Line clipping using binary search technique.           *
  55.  *                                                        *
  56.  * RETURNS: 0 element was outside the view volume;        *
  57.  * -------- 1 element was clipped to the view volume.     *
  58.  *                                                        *
  59.  * SETS: C_3D_clipping to 1 if first vertex was clipped;  *
  60.  * ----- 0 otherwise.                                     *
  61. **********************************************************/
  62. int C_line_z_clipping(int **vertex1,int **vertex2,int dimension)
  63. {
  64.  register int i;
  65.  register int whereto;
  66.  register int *l,*r,*m,*t;                  /* left right midle and tmp */
  67.  static int c_store0[C_MAX_DIMENSIONS];     /* static stores for clipped vxes */
  68.  static int c_store1[C_MAX_DIMENSIONS];
  69.  static int c_store2[C_MAX_DIMENSIONS];
  70.  int **vmn,**vmx;                           /* so that *vmn[3] < *vmx[3] */
  71.  int swap;                                  /* were coordinates swaped? */
  72.  C_3D_clipping=0;                           /* default no clipping yet */
  73.  if((*vertex1)[2]<(*vertex2)[2])            /* only Z counts 0=X,1=Y,2=Z,... */
  74.  { swap=0; vmn=vertex1; vmx=vertex2; }      /* so that *vmn[2] < *vmx[2] */
  75.  else
  76.  { swap=1; vmn=vertex2; vmx=vertex1; }
  77.  if((*vmx)[2]<=C_Z_CLIPPING_MIN) return(0); /* compleately outside */
  78.  else
  79.  {
  80.   if((*vmn)[2]<=C_Z_CLIPPING_MIN)           /* clipping */
  81.   {
  82.    HW_copy_int(*vmn,m=c_store0,dimension);  /* copying old vertices */
  83.    HW_copy_int(*vmx,r=c_store1,dimension);
  84.    l=c_store2;
  85.    whereto=1;
  86.    while(m[2]!=C_Z_CLIPPING_MIN)
  87.    {
  88.     if(whereto==1) { t=l; l=m; m=t; }
  89.     else           { t=r; r=m; m=t; }
  90.     for(i=0;i<dimension;i++) m[i]=(l[i]+r[i])>>1;
  91.     whereto=m[2]<C_Z_CLIPPING_MIN;
  92.    }
  93.    *vmn=m;                                  /* that is why m[] is static */
  94.    C_3D_clipping=swap^1;
  95.   }
  96.   return(1);                                /* partialy or not clipped */
  97.  }
  98. }
  99. /***********************************************************
  100.  * Creating a z-clipped polygon.                           *
  101.  *                                                         *
  102.  * RETURNS: number of elements in the clipped polygon.     *
  103.  * -------- (0 when compleately behind view plane)         *
  104.  *                                                         *
  105.  *         |            1-2-3-4-5-6-1  -> 2-2'-5'-6-1-2    *
  106.  *         |5'                                             *
  107.  *      5*-*-----*6     If first vertex in the line is     *
  108.  *      /  |           clipped, both vertices are copyed, *
  109.  *    4*   |       *1   If no clipping or second one is    *
  110.  *        |      /     clipped then only second one is    *
  111.  *      3*-*-----*2     copyed. If both vertices are       *
  112.  *         |2'          clipped, neither one is copyed.    *
  113.  *                                                         *
  114. ***********************************************************/
  115. int C_polygon_z_clipping(int *from,register int *to,
  116.                          int dimension,int length
  117.                         )
  118. {
  119.  register int i;
  120.  int *v1,*v2,new_lng=0;
  121.  int *first_vrtx=to;                        /* begining of the source */
  122.  for(i=0;i<length;i++)                      /* for all edges */
  123.  {
  124.   v1=(int*)from; from+=dimension; v2=(int*)from;
  125.   if(C_line_z_clipping(&v1,&v2,dimension))  /* clipping */
  126.   {
  127.    if(C_3D_clipping)                        /* depends which one was clipped */
  128.    {
  129.     HW_copy_int(v1,to,dimension); to+=dimension;
  130.     HW_copy_int(v2,to,dimension); to+=dimension;
  131.     new_lng+=2;                             /* first point clipped */
  132.    }
  133.    else
  134.    {
  135.     HW_copy_int(v2,to,dimension); to+=dimension;
  136.     new_lng++;                              /* second point clipped */
  137.    }
  138.   }
  139.  }
  140.  HW_copy_int(first_vrtx,to,dimension);      /* looping the polygon vertices */
  141.  return(new_lng);
  142. }
  143. /**********************************************************
  144.  * Line clipping using binary search technique.           *
  145.  *                                                        *
  146.  * RETURNS: 0 when line is compleately outside;           *
  147.  * -------- 1 otherwise.                                  *
  148.  *                                                        *
  149.  * SETS:  C_3D_clipping to 1 when first or both points    *
  150.  * -----  were changed; 0 otherwise.                      *
  151. **********************************************************/
  152. int C_line_xyz_clipping(int **vertex1,int **vertex2,
  153.                         int *by1,int *by2,int *by3,
  154.                         int dimension
  155.                        )
  156. {
  157.  int v1,v2,plane[4],tmp[3];                 /* plane equation */
  158.  register int i;
  159.  register int whereto;
  160.  register int *l,*r,*m,*t;                  /* left right midle and tmp */
  161.  static int c_store0[C_MAX_DIMENSIONS];     /* static stores for clipped vxes */
  162.  static int c_store1[C_MAX_DIMENSIONS];
  163.  static int c_store2[C_MAX_DIMENSIONS];
  164.  int **vmn,**vmx;                           /* so that *vmn[3] < *vmx[3] */
  165.  int swap,itmp;                             /* were coordinates swaped? */
  166.  C_3D_clipping=0;                           /* default no clipping yet */
  167.  T_plane(by1,by2,by3,plane);
  168.  v1=T_vertex_on_plane(*vertex1,plane);
  169.  v2=T_vertex_on_plane(*vertex2,plane);
  170.  if(v1<v2)
  171.  { swap=0; vmn=vertex1; vmx=vertex2; }
  172.  else
  173.  { swap=1; vmn=vertex2; vmx=vertex1; itmp=v1; v1=v2; v2=itmp; }
  174.  if(v2<=0) return(0);                       /* compleately outside */
  175.  else
  176.  {
  177.   if(v1<=0)                                 /* clipping */
  178.   {
  179.    HW_copy_int(*vmn,l=c_store2,dimension);  /* copying old vertices */
  180.    HW_copy_int(*vmn,m=c_store0,dimension);  
  181.    HW_copy_int(*vmx,r=c_store1,dimension);
  182.    whereto=1;
  183.    while((T_vertex_on_plane(m,plane)!=0)&&  /* while not on the plane and */
  184.          (T_norm(T_vector(l,r,tmp,3))>C_TOLERANCE)
  185.         )                                   /* not close enough */
  186.    {
  187.     if(whereto==1) { t=l; l=m; m=t; }
  188.     else           { t=r; r=m; m=t; }
  189.     for(i=0;i<dimension;i++) m[i]=(l[i]+r[i])>>1;
  190.     whereto=T_vertex_on_plane(m,plane)<0;
  191.    }
  192.    *vmn=m;                                  /* that is why m[] is static */
  193.    C_3D_clipping=swap^1;
  194.   }
  195.   return(1);                                /* partialy or not clipped */
  196.  }
  197. }
  198. /**********************************************************
  199.  * Creating a polygon clipped by any plane.               *
  200.  *                                                        *
  201.  * RETURNS: number of vertices in the clipped polygon.    *
  202.  * -------- (0 when compleately clipped)                  *
  203.  *                                                        *
  204.  *                       1-2-3-4-5-6-1  -> 2'-3'-5'-6'    *
  205.  *         5'                                            *
  206.  *      5*-*------*6     If first vertex in the line is   *
  207.  *      /              being clipped both vertices are  *
  208.  *    4*            *1  copyed If no clipping or second  *
  209.  *            3'  /    one is clipped then only second  *
  210.  *      3*-----*--*2     one is copyed. If both vertices  *
  211.  *                      are clipped, neither is copyed.  *
  212.  *                                                        *
  213. **********************************************************/
  214. int C_polygon_xyz_clipping(int *from,register int *to,
  215.                            int *by1,int *by2,int *by3,
  216.                            int dimension,int length
  217.                           )
  218. {
  219.  register int i;
  220.  int *v1,*v2,new_lng=0;
  221.  int *first_vrtx=to;                        /* begining of the source */
  222.  for(i=0;i<length;i++)                      /* for all edges */
  223.  {
  224.   v1=(int*)from; from+=dimension; v2=(int*)from;
  225.   if(C_line_xyz_clipping(&v1,&v2,by1,by2,by3,dimension))
  226.   {                                         /* clipping */
  227.    if(C_3D_clipping)                        /* depends which one was clipped */
  228.    {
  229.     HW_copy_int(v1,to,dimension); to+=dimension;
  230.     HW_copy_int(v2,to,dimension); to+=dimension;
  231.     new_lng+=2;                             /* first point clipped */
  232.    }
  233.    else
  234.    {
  235.     HW_copy_int(v2,to,dimension); to+=dimension;
  236.     new_lng++;                              /* second point clipped */
  237.    }
  238.   }
  239.  }
  240.  HW_copy_int(first_vrtx,to,dimension);      /* looping the polygon vertices */
  241.  return(new_lng);
  242. }
  243. /**********************************************************/