home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / 3DGPL.ZIP / 3DGPL / CODE / CLIPPER / CLIPP-3D.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-22  |  7.8 KB  |  191 lines

  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.  *                                                        *
  11.  *  (6/1995) By Sergei Savchenko. (savs@cs.mcgill.ca).    *
  12.  *  Copyright (c) 1995 Sergei Savchenko.                  *
  13.  *  THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
  14.  *  WITHOUT AUTHORISATION                                 *
  15. \**********************************************************/
  16.  
  17. #include <limits.h>                         /* INT_MAX & INT_MIN */
  18.  
  19. #include "../hardware/hardware.h"           /* HW_copy_int stuff */
  20. #include "../clipper/clipper.h"             /* clipping constants */
  21.  
  22. int C_3D_clipping;                          /* type of performed clipping */
  23.  
  24. /**********************************************************\
  25.  *  Hole element volume clipping,                         *
  26.  *                                                        *
  27.  *  RETURNS:  0 when array of passed vertices is for sure *
  28.  *  --------    outside the view volume;                  *
  29.  *           -1 when further clipping is required;        *
  30.  *            1 when element has a fair chanse to be      *
  31.  *              inside the view volume, and should be     *
  32.  *              clipped by 2-D clipping when rendering    *
  33.  *              onto the screen.                          *
  34.  *                                                        *
  35.  *               | z                                      *
  36.  *          \    |    /        View volume is a piramid   *
  37.  *           \   |   /         with 90 degree angle.      *
  38.  *            \  |  /                                     *
  39.  *        -x>z \ | /  x>z                                 *
  40.  *              \|/                                       *
  41.  *       --------+--------- x                             *
  42.  *       z<C_Z_CLIPPING_MIN                               *
  43.  *                                                        *
  44.  *  ADDITIONAL FUNCTIONS: 1) extraction of tuples &       *
  45.  *  ---------------------    FORMAT change                *
  46.  *  source:       n,a1,...,aN      where N=dimension-3    *
  47.  *  destanation:  x,y,z,a1,...,aN  (x,y,z extracted from  *
  48.  *  int *vertex array starting from index n)              *
  49. \**********************************************************/
  50.  
  51. int C_volume_clipping(register int *from,register int *to,
  52.                       int *vertex,int dimension,int length
  53.                      )
  54. {
  55.  register int i;
  56.  int xmin,ymin,zmin,xmax,ymax,zmax;
  57.  
  58.  dimension-=3;                              /* but X,Y,Z */
  59.  
  60.  ymin=xmin=zmin=INT_MAX;
  61.  ymax=xmax=zmax=INT_MIN;                    /* initializing searching */
  62.  
  63.  for(i=0;i<length;i++)
  64.  {
  65.   HW_copy_int(&vertex[*from++],to,3);       /* copying actual tuples */
  66.  
  67.   if(*to>xmax) xmax=*to;                    /* determining polygon extend */
  68.   if(*to<xmin) xmin=*to;
  69.   to++;
  70.   if(*to>ymax) ymax=*to;
  71.   if(*to<ymin) ymin=*to;
  72.   to++;
  73.   if(*to>zmax) zmax=*to;
  74.   if(*to<zmin) zmin=*to;                    /* by searching max/min */
  75.   to++;
  76.  
  77.   HW_copy_int(from,to,dimension);           /* rest (for shading etc)*/
  78.   to+=dimension;
  79.   from+=dimension;
  80.  }
  81.  
  82.  if((zmax<xmin)||(zmax<ymin)||(zmax<-xmax)||
  83.    (zmax<-ymax)||(zmax<=C_Z_CLIPPING_MIN))
  84.   return(0);                                /* outside */
  85.  else
  86.   if(zmin<C_Z_CLIPPING_MIN) return(-1);     /* partly behind clipping plane */
  87.   else return(1);
  88. }
  89.  
  90. /**********************************************************\
  91.  *  Line clipping using binary search technique.          *
  92.  *                                                        *
  93.  *  RETURNS: 0 element is outside the view volume;        *
  94.  *  -------  1 element is clipped to the view volume.     *
  95.  *                                                        *
  96.  *  SETS: C_3D_clipping to 1 if first vertex was clipped; *
  97.  *  -----               0 otherwise.                      *
  98. \**********************************************************/
  99.  
  100. int C_line_z_clipping(int **vertex1,int **vertex2,int dimension)
  101. {
  102.  register int i;
  103.  register int whereto;
  104.  register int *l,*r,*m,*t;                  /* left right and midle and tmp */
  105.  static int c_store0[C_MAX_DIMENSIONS];     /* static stores for clipped vxes */
  106.  static int c_store1[C_MAX_DIMENSIONS];
  107.  static int c_store2[C_MAX_DIMENSIONS];
  108.  int **vmn,**vmx;                           /* so that *vmn[3] < *vmx[3] */
  109.  int swap;                                  /* were coordinates swaped? */
  110.  
  111.  C_3D_clipping=0;                           /* default no clipping yet */
  112.  
  113.  if((*vertex1)[2]<(*vertex2)[2])            /* only Z counts 0=X,1=Y,2=Z,... */
  114.  { swap=0; vmn=vertex1; vmx=vertex2; }      /* so that *vmn[2] < *vmx[2] */
  115.  else
  116.  { swap=1; vmn=vertex2; vmx=vertex1; }
  117.  
  118.  if((*vmx)[2]<C_Z_CLIPPING_MIN) return(0);
  119.  else
  120.  {
  121.   if((*vmn)[2]<=C_Z_CLIPPING_MIN)           /* clipping */
  122.   {
  123.    HW_copy_int(*vmn,l=c_store0,dimension);  /* copying old vertices */
  124.    HW_copy_int(*vmx,m=c_store1,dimension);
  125.    r=c_store2;
  126.  
  127.    whereto=0;
  128.    while(m[2]!=C_Z_CLIPPING_MIN)
  129.    {
  130.     if(whereto==1) { t=l; l=m; m=t; }
  131.     else           { t=r; r=m; m=t; }
  132.     for(i=0;i<dimension;i++) m[i]=(l[i]+r[i])>>1;
  133.     whereto=m[2]<C_Z_CLIPPING_MIN;
  134.    }
  135.    *vmn=m;                                  /* that is why m[] is static */
  136.    C_3D_clipping=swap^1;
  137.   }
  138.   return(1);                                /* partialy or not clipped */
  139.  }
  140. }
  141.  
  142. /***********************************************************\
  143.  *  Creating a z-clipped polygon.                          *
  144.  *                                                         *
  145.  *  RETURNS: number of elements in the clipped polygon.    *
  146.  *  -------  (0 when compleately behind view plane)        *
  147.  *                                                         *
  148.  *          |            1-2-3-4-5-6-1  -> 2-2'-5'-6-1-2   *
  149.  *          |5'                                            *
  150.  *       5*-*-----*6     If first dot in the line is being *
  151.  *       /  |      \     clipped both points are copyed,   *
  152.  *     4*   |       *1   If no clipping or second point is *
  153.  *       \  |      /     clipped then only second point is *
  154.  *       3*-*-----*2     copyed. If both points are        *
  155.  *          |2'          clipped well, neither is copyed.  *
  156. \***********************************************************/
  157.  
  158. int C_polygon_z_clipping(register int *from,register int *to,
  159.                          int dimension,int length
  160.                         )
  161. {
  162.  register int i;
  163.  int *v1,*v2,new_lng=0;
  164.  int *first_vrtx=to;                        /* begining of the source */
  165.  
  166.  for(i=0;i<length;i++)                      /* for all edges */
  167.  {
  168.   v1=from; from+=dimension; v2=from;        /* taking two vertices */
  169.  
  170.   if(C_line_z_clipping(&v1,&v2,dimension))  /* clipping */
  171.   {
  172.    if(C_3D_clipping)                        /* depends which one was clipped */
  173.    {
  174.     HW_copy_int(v1,to,dimension); to+=dimension;
  175.     HW_copy_int(v2,to,dimension); to+=dimension;
  176.     new_lng+=2;                             /* first point clipped */
  177.    }
  178.    else
  179.    {
  180.     HW_copy_int(v2,to,dimension); to+=dimension;
  181.     new_lng++;                              /* second point clipped */
  182.    }
  183.   }
  184.  }
  185.  HW_copy_int(first_vrtx,to,dimension);      /* looping the polygon vertices */
  186.  
  187.  return(new_lng);
  188. }
  189.  
  190. /**********************************************************/
  191.