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 >
Wrap
Text File
|
1991-10-14
|
9KB
|
227 lines
#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;
}