home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_09_12 / 9n12038a < prev    next >
Text File  |  1991-10-14  |  9KB  |  227 lines

  1. #include "solid.h"
  2.  
  3. void define_solid(int this_obj_type)
  4. /*  Constructs solid descriptor */
  5. {
  6.     struct obj_defn *this_defn_ptr;
  7.     struct facet *facet_ptr;
  8.     struct vertex *vertex_ptr;
  9.     int sweep_index; /* varies from 0 to "sweeps" - 1;
  10.         0 and "sweeps" - 1 are polar sweeps */
  11.     int facet_index; /* index of facets for each sweep;
  12.         varies from 0 to facet_max */
  13.     int sweep_count; /* number of sweeps to make */
  14.     int facet_max; /* number of facets per sweep */
  15.     int vertex_ref_index; /* index of current vertex */
  16.     int vertex_s; /* index of 1st vertex for sweep */
  17.     float vert_angle; /* angle first side of facet
  18.         forms with positive x axis in x-y plane */
  19.     float vert_angle_init; /* initial vert_angle */
  20.     float vert_delta; /* angle formed by sides of
  21.         current facet in x-y plane */
  22.     float horiz_angle; /* angle 1st side of facet forms
  23.         with positive x axis in x-z plane */
  24.     float vert_scale; /* scaling factor in xy plane */
  25.     float horiz_scale; /* scaling factor in xz plane */
  26.     int num_vertices, num_facets, num_vertex_refs;
  27.     int region; /* -1 = north polar, 1 = south polar,
  28.         0 elsewhere */
  29.     float sqrt2;
  30.  
  31.     sqrt2 = sqrt(2.0);
  32.     switch(this_obj_type) {
  33.         case CUBE_OBJ: {
  34.             sweep_count = 3;
  35.             facet_max = 4;
  36.             vert_angle_init = PI / 4.0;
  37.             vert_delta = PI / 2.0;
  38.             vert_scale = 1.0 / sqrt2;
  39.             horiz_scale = 2.0 / sqrt2;
  40.             num_vertices = 8;
  41.             num_facets = 6;
  42.             num_vertex_refs = 24;
  43.             break;
  44.         }
  45.         case SPHERE_OBJ: {
  46.             sweep_count = sweeps;
  47.             facet_max = facets;
  48.             vert_angle_init = PI / (float)sweeps;
  49.             vert_delta = PI / (float)sweeps;
  50.             vert_scale = 0.5;
  51.             horiz_scale = 1.0;
  52.             num_vertices = (sweep_count - 1) *
  53.                 facet_max + 2;
  54.             num_facets = sweep_count * facet_max;
  55.             num_vertex_refs = (4 * sweep_count - 2) *
  56.                 facet_max;
  57.             break;
  58.         }
  59.         case CYLIND_OBJ: {
  60.             sweep_count = 3;
  61.             facet_max = facets;
  62.             vert_angle_init = PI / 4.0;
  63.             vert_delta = PI / 2.0;
  64.             vert_scale = 1.0 / sqrt2;
  65.             horiz_scale = 2.0 / sqrt2;
  66.             num_vertices = 2 * facet_max;
  67.             num_facets = 2 + facet_max;
  68.             num_vertex_refs = 6 * facet_max;
  69.             break;
  70.         }
  71.         case CONE_OBJ: {
  72.             sweep_count = 2;
  73.             facet_max = facets;
  74.             vert_angle_init = 3.0 * PI / 4.0;
  75.             vert_scale = 1.0 / sqrt2;
  76.             horiz_scale = 2.0 / sqrt2;
  77.             num_vertices = facet_max + 1;
  78.             num_facets = facet_max + 1;
  79.             num_vertex_refs = 4 * facet_max;
  80.             break;
  81.         }
  82.         default:
  83.             quit(ERR_OBJTYPE, __FILE__, __LINE__);
  84.     }
  85.     if ((vertex_ptr = (struct vertex *)malloc(
  86.         num_vertices * sizeof(struct vertex))) == NULL)
  87.         /* allocate storage for vertices */
  88.         quit(ERR_MEMORY, __FILE__, __LINE__);
  89.  
  90.     if ((facet_ptr = (struct facet *)malloc(num_facets
  91.         * sizeof(struct facet) + num_vertex_refs *
  92.         sizeof(INDEX))) == NULL) /* allocate storage
  93.         for facet descriptors */
  94.         quit(ERR_MEMORY, __FILE__, __LINE__);
  95.  
  96.     /* construct definition descriptor */
  97.     if ((this_defn_ptr = (struct obj_defn *)malloc(
  98.         sizeof(struct obj_defn))) == NULL)
  99.         quit(ERR_MEMORY, __FILE__, __LINE__);
  100.     this_defn_ptr->vertex_count = num_vertices;
  101.     this_defn_ptr->vertex_first = vertex_ptr;
  102.     this_defn_ptr->facet_count = num_facets;
  103.     this_defn_ptr->facet_first = facet_ptr;
  104.  
  105.     /* fill in vertex coords and facet descriptors */
  106.     vertex_s = 0;
  107.     vert_angle = vert_angle_init;
  108.     /* main loop; each execution performs one sweep */
  109.     for (sweep_index = 0; sweep_index < sweep_count;
  110.         ++sweep_index) {
  111.         region = (sweep_index == 0) ? -1 :
  112.             ((sweep_index == sweep_count - 1) ? 1 : 0);
  113.         /* construct vertices */
  114.         if ((region != 0 && this_obj_type ==
  115.             SPHERE_OBJ) || (region == -1 &&
  116.             this_obj_type == CONE_OBJ)) { /* construct
  117.             polar vertex */
  118.             vertex_ptr->coord[0] = vertex_ptr->coord[2]
  119.                 = 0.0;
  120.             vertex_ptr->coord[1] = 0.5 * ((sweep_index
  121.                 == 0) ? 1 : -1);
  122.             ++vertex_ptr; /* point to next vertex */
  123.             ++vertex_s;
  124.         }
  125.         if (region != 1) { /* construct normal vertices
  126.             counterclockwise along bottom edge of sweep
  127.             as viewed from top of object */
  128.             horiz_angle = 2.0 * PI - PI /
  129.                 (float)facet_max;
  130.             for (facet_index = 0; facet_index <
  131.                 facet_max; ++facet_index) {
  132.                 vertex_ptr->coord[0] = vert_scale *
  133.                     sin(vert_angle) * horiz_scale *
  134.                     cos(horiz_angle); /* x-coord */
  135.                 vertex_ptr->coord[1] = vert_scale *
  136.                     cos(vert_angle); /* y-coord */
  137.                 vertex_ptr->coord[2] = vert_scale *
  138.                     sin(vert_angle) * horiz_scale *
  139.                     sin(horiz_angle); /* z-coord */
  140.                 ++vertex_ptr; /* point to next */
  141.                 horiz_angle -= 2.0 * PI / (float)
  142.                     facet_max;
  143.             }
  144.         }
  145.         /* construct facet descriptors for sweep */
  146.         switch (region) {
  147.             case -1:
  148.             case 1: { /* polar region: construct
  149.                 triangular facets of sphere or cone or
  150.                 top facet of cube or cylinder */
  151.                 if (this_obj_type == SPHERE_OBJ ||
  152.                     (this_obj_type == CONE_OBJ &&
  153.                     region == -1)) { /* polar
  154.                     triangular facets of sphere or
  155.                     cone */
  156.                     for (facet_index = 0; facet_index <
  157.                         facet_max; ++facet_index,
  158.                         facet_ptr = ADV_FACET_PTR(3)) {
  159.                         facet_ptr->vertex_count = 3;
  160.                         facet_ptr->vertex_index[0] =
  161.                             (region == -1) ? 0 :
  162.                             (num_vertices - 1);
  163.                             /* polar vertex */
  164.                         facet_ptr->vertex_index[1] =
  165.                             (region == -1) ?
  166.                             ((facet_index == 0) ?
  167.                             facet_max : facet_index) :
  168.                             (num_vertices - facet_max -
  169.                             1 + facet_index);
  170.                         facet_ptr->vertex_index[2] =
  171.                             (region == -1) ? (1 +
  172.                             facet_index) :
  173.                             ((num_vertices - facet_max
  174.                             - 2) + ((facet_index == 0)
  175.                             ? facet_max :
  176.                             facet_index));
  177.                     }
  178.                 }
  179.                 if (this_obj_type == CUBE_OBJ ||
  180.                     this_obj_type == CYLIND_OBJ ||
  181.                     (region == 1 && this_obj_type ==
  182.                     CONE_OBJ)) { /* top or bottom facet
  183.                     of cube or cylinder or bottom facet
  184.                     of cone */
  185.                     facet_ptr->vertex_count =
  186.                         facet_max;
  187.                     for (facet_index = 0; facet_index
  188.                         < facet_max; ++facet_index)
  189.                         facet_ptr->vertex_index
  190.                         [facet_index] = (region == -1)
  191.                         ? facet_index : (num_vertices -
  192.                         facet_index - 1);
  193.                     facet_ptr = ADV_FACET_PTR
  194.                         (facet_max);
  195.                 }
  196.                 break;
  197.             }
  198.             case 0: { /* construct rectangular facets
  199.                 between lines of latitude */
  200.                 for (facet_index = 0; facet_index <
  201.                     facet_max; ++facet_index, facet_ptr
  202.                     = ADV_FACET_PTR(4)) {
  203.                     facet_ptr->vertex_count = 4;
  204.                     facet_ptr->vertex_index[0] =
  205.                         vertex_s - facet_max +
  206.                         facet_index; facet_ptr->
  207.                         vertex_index[1] = vertex_s -
  208.                         facet_max - 1 + ((facet_index
  209.                         == 0) ? facet_max :
  210.                         facet_index);
  211.                     facet_ptr->vertex_index[2] =
  212.                         (facet_index == 0) ? (vertex_s
  213.                         + facet_max - 1) : (vertex_s -
  214.                         1 + facet_index);
  215.                     facet_ptr->vertex_index[3] =
  216.                         vertex_s + facet_index;
  217.                 }
  218.             }
  219.         }
  220.         vert_angle += vert_delta;
  221.         vertex_s += facet_max;
  222.     }
  223.     defn_ptr[this_obj_type] = this_defn_ptr; /* save
  224.         pointer to definition */
  225.     return;
  226. }
  227.