Listing 1 (soldfs.c)

#include "solid.h"

void define_solid(int this_obj_type)
/*  Constructs solid descriptor */
{
   struct obj_defn *this_defn_ptr;
   struct facet *facet_ptr;
   struct vertex *vertex_ptr;
   int sweep_index; /* varies from 0 to "sweeps" - 1;
      0 and "sweeps" - 1 are polar sweeps */
   int facet_index; /* index of facets for each sweep;
      varies from 0 to facet_max */
   int sweep_count; /* number of sweeps to make */
   int facet_max; /* number of facets per sweep */
   int vertex_ref_index; /* index of current vertex */
   int vertex_s; /* index of 1st vertex for sweep */
   float vert_angle; /* angle first side of facet
      forms with positive x axis in x-y plane */
   float vert_angle_init; /* initial vert_angle */
   float vert_delta; /* angle formed by sides of
      current facet in x-y plane */
   float horiz_angle; /* angle 1st side of facet forms
      with positive x axis in x-z plane */
   float vert_scale; /* scaling factor in xy plane */
   float horiz_scale; /* scaling factor in xz plane */
   int num_vertices, num_facets, num_vertex_refs;
   int region; /* -1 = north polar, 1 = south polar,
      0 elsewhere */
   float sqrt2;

   sqrt2 = sqrt(2.0);
   switch(this_obj_type) {
      case CUBE_OBJ: {
         sweep_count = 3;
         facet_max = 4;
         vert_angle_init = PI / 4.0;
         vert_delta = PI / 2.0;
         vert_scale = 1.0 / sqrt2;
         horiz_scale = 2.0 / sqrt2;
         num_vertices = 8;
         num_facets = 6;
         num_vertex_refs = 24;
         break;
      }
      case SPHERE_OBJ: {
         sweep_count = sweeps;
         facet_max = facets;
         vert_angle_init = PI / (float)sweeps;
         vert_delta = PI / (float)sweeps;
         vert_scale = 0.5;
         horiz_scale = 1.0;
         num_vertices = (sweep_count - 1) *
            facet_max + 2;
         num_facets = sweep_count * facet_max;
         num_vertex_refs = (4 * sweep_count - 2) *
            facet_max;
         break;
      }
      case CYLIND_OBJ: {
         sweep_count = 3;
         facet_max = facets;
         vert_angle_init = PI / 4.0;
         vert_delta = PI / 2.0;
         vert_scale = 1.0 / sqrt2;
         horiz_scale = 2.0 / sqrt2;
         num_vertices = 2 * facet_max;
         num_facets = 2 + facet_max;
         num_vertex_refs = 6 * facet_max;
         break;
      }
      case CONE_OBJ: {
         sweep_count = 2;
         facet_max = facets;
         vert_angle_init = 3.0 * PI / 4.0;
         vert_scale = 1.0 / sqrt2;
         horiz_scale = 2.0 / sqrt2;
         num_vertices = facet_max + 1;
         num_facets = facet_max + 1;
         num_vertex_refs = 4 * facet_max;
         break;
      }
      default:
         quit(ERR_OBJTYPE, _FILE_, _LINE_);
   }
   if ((vertex_ptr = (struct vertex *)malloc(
      num_vertices * sizeof(struct vertex))) == NULL)
      /* allocate storage for vertices */
      quit(ERR_MEMORY, _FILE_, _LINE_);

   if ((facet_ptr = (struct facet *)malloc(num_facets
      * sizeof(struct facet) + num_vertex_refs *
      sizeof(INDEX))) == NULL) /* allocate storage
      for facet descriptors */
      quit(ERR_MEMORY, _FILE_, _LINE_ );

   /* construct definition descriptor */
   if ((this_defn_ptr = (struct obj_defn *)malloc(
      sizeof(struct obj_defn))) == NULL)
      quit(ERR_MEMORY, _FILE_, _LINE_);
   this_defn_ptr->vertex_count = num_vertices;
   this_defn_ptr->vertex_first = vertex_ptr;
   this_defn_ptr->facet_count = num_facets;
   this_defn_ptr->facet_first = facet_ptr;

   /* fill in vertex coords and facet descriptors */
   vertex_s = 0;
   vert_angle = vert_angle_init;
   /* main loop; each execution performs one sweep */
   for (sweep_index = 0; sweep_index < sweep_count;
      ++sweep_index) {
      region = (sweep_index == 0) ? -1 :
         ((sweep_index == sweep_count - 1) ? 1 : 0);
      /* construct vertices */
      if ((region != 0 && this_obj_type ==
         SPHERE_OBJ) || (region == -1 &&
         this_obj_type == CONE_OBJ)) { /* construct
         polar vertex */
         vertex_ptr->coord[0] = vertex_ptr->coord[2]
            = 0.0;
         vertex_ptr->coord[1] = 0.5 * ((sweep_index
            == 0) ? 1 : -1);
         ++vertex_ptr; /* point to next vertex */
         ++vertex_s;
      }
      if (region != 1) { /* construct normal vertices
         counterclockwise along bottom edge of sweep
         as viewed from top of object */
         horiz_angle = 2.0 * PI - PI /
            (float)facet_max;
         for (facet_index = 0; facet_index <
            facet_max; ++facet_index) {
            vertex_ptr->coord[0] = vert_scale *
                sin(vert_angle) * horiz_scale *
                cos(horiz_angle); /* x-coord */
            vertex_ptr->coord[1] = vert_scale *
                cos(vert_angle); /* y-coord */
            vertex_ptr->coord[2] = vert_scale *
                sin(vert_angle) * horiz_scale *
                sin(horiz_angle); /* z-coord */
            ++vertex_ptr; /* point to next */
            horiz_angle -= 2.0 * PI / (float)
                facet_max;
         }
      }
      /* construct facet descriptors for sweep */
      switch (region) {
         case -1:
         case 1: { /* polar region: construct
            triangular facets of sphere or cone or
            top facet of cube or cylinder */
            if (this_obj_type == SPHERE_OBJ ||
                (this_obj_type == CONE_OBJ &&
         region == -1)) { /* polar
         triangular facets of sphere or
         cone */
         for (facet_index = 0; facet_index <
            facet_max; ++facet_index,
            facet_ptr = ADV_FACET_PTR(3)) {
            facet_ptr->vertex_count = 3;
            facet_ptr->vertex_index[0] =
                (region == -1) ? 0 :
                (num_vertices - 1);
                /* polar vertex */
            facet_ptr->vertex_index[1] =
                (region == -1) ?
                ((facet_index == 0) ?
                facet_max : facet_index) :
                (num_vertices - facet_max -
                1 + facet_index);
            facet_ptr->vertex_index[2] =
                (region == -1) ? (1 +
                facet_index) :
                ((num_vertices - facet_max
                - 2) + ((facet index == 0)
                ? facet_max :
                facet_index));
         }
      {
      if (this_obj_type == CUBE_OBJ ||
         this_obj_type == CYLIND_OBJ ||
         (region == 1 && this_obj_type ==
         CONE_OBJ)) { /* top or bottom facet
         of cube or cylinder or bottom facet
         of cone */
         facet_ptr->vertex_count =
            facet_max;
         for (facet_index = 0; facet_index
            < facet_max; ++facet_index)
            facet_ptr->vertex_index
            [facet_index] = (region == -1)
            ? facet_index : (num_vertices -
            facet_index - 1);
         facet_ptr = ADV_FACET_PTR
            (facet_max);
            }
            break;
         }
         case 0: { /* construct rectangular facets
            between lines of latitude */
            for (facet_index = 0; facet_index <
                facet_max; ++facet_index, facet_ptr
                = ADV_FACET_PTR(4)) {
                facet_ptr->vertex_count = 4;
                facet_ptr->vertex_index[0] =
                  vertex_s - facet_max +
                  facet_index; facet_ptr->
                  vertex_index[1] = vertex_s -
                  facet_max - 1 + ((facet_index
                  == 0) ? facet_max :
                  facet_index);-
                facet_ptr->vertex_index[2] =
                  (facet_index == 0) ? (vertex_s
                  + facet_max - 1) : (vertex_s -
                  1 + facet_index);
                facet_ptr->vertex_index[3] =
                  vertex_s + facet_index;
            }
         }
      }
      vert_angle += vert_delta;
      vertex_s += facet_max;
   }
   defn_ptr[this_obj_type] = this_defn_ptr; /* save
      pointer to definition */
   return;
}
/* End of File */