Graphics source in C: hsalgs/bbox_task.c
Ken Turkowski
ken at turtleva.UUCP
Fri Dec 16 12:25:10 AEST 1983
echo x - hsalgs/bbox_task.c
cat >hsalgs/bbox_task.c <<'!Funky!Stuff!'
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bbox_task.c - displays bounding boxes on various devices
based on priority information from obj_sort and program names
and file names gathered by scn_assmblr
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
#include "scn_assmblr.h"
#define X 0
#define Y 1
#define Z 2
extern short ramp_lnth; /* globals from obj_sort */
extern double view_angle;
static FILE *bstream,*popen();
static double sqrt(),cos(),sin(),cot_x,cot_y;
static float light_postn[3];
static short bbits;
static short pol[6][4] = { 0, 1, 2, 3,
4, 5, 6, 7,
7, 6, 1, 0,
3, 2, 5, 4,
1, 6, 5, 2,
7, 0, 3, 4, };
/* ++++++++++++++++++++++++++ BBOX_TASK ++++++++++++++++++++++++++++++++++ */
bbox_task(obj_array,p_list,dvc,num_bits,divisions,frmnum) /* render bounding
boxes in priority order */
object_def *obj_array; struct { short obj,insep; } p_list[]; char *dvc;
short num_bits,divisions,frmnum;
{ short i,cnt;
bbits = num_bits;
cot_x = cos(DtoR * view_angle/2.) / sin(DtoR * view_angle/2.);
cot_y = cot_x / .75;
if (!bbits) /* line-drawing device */
if (strcmp(dvc,"meg") == 0) bstream = popen("megdrawl","w");
else if (strcmp(dvc,"vt" ) == 0) bstream = popen("vtdrawl" ,"w");
else if (strcmp(dvc,"crt") == 0) bstream = popen("crtdrawl","w");
else if (strcmp(dvc,"h19") == 0) bstream = popen("h19drawl","w");
else fprintf(stderr,"bbox_task: %s not a line-drawing device\n");
else /* raster device */
{ double mag_light;
bstream = popen("tiler","w");
if (strcmp(dvc,"fb") == 0)
fprintf(bstream,"device\t\t%s %d\n",dvc,frmnum);
else
fprintf(bstream,"device\t\t%s %d %d %d\n",dvc,bbits,divisions,frmnum);
if (strcmp(dvc,"fb") == 0)
cot_y *= 640./512.; /* adjust for pixel distortion on 512x484 */
else if (strcmp(dvc,"aed") == 0)
cot_y = cot_x * 512./483.;
light_postn[0] = light_postn[1] = light_postn[2] = 0.;
transform(light_postn,obj_array[LIT].comp_mtx,light_postn);
mag_light = sqrt(sqr(light_postn[0]) + sqr(light_postn[1]) +
sqr(light_postn[2]));
light_postn[0] /= mag_light; /* normalize light source vector */
light_postn[1] /= mag_light;
light_postn[2] /= mag_light;
}
/* ----------------------- traverse priority list --------------------- */
cnt = 0;
while (p_list[cnt].obj != 0) cnt++; /* count displayed objects */
if (bbits) for (i=cnt-1; i>=0; i--) bbox_output(&obj_array[p_list[i].obj]);
else for (i=0; i<cnt; i++) bbox_output(&obj_array[p_list[i].obj]);
pclose(bstream); /* stop display program */
}
/* +++++++++++++++++++++++++++++++ BBOX_OUTPUT ++++++++++++++++++++++++++++ */
bbox_output(object) /* expand bounding box to polygons and output */
object_def *object;
{ float bbx[8][3],clr_vec[3]; short kp,kv;
printf(" bbox for %s\n",object->name);
/* convert bounding box to polygons */
bbx[0][0] = bbx[1][0] = bbx[6][0] = bbx[7][0] = object->box[0];/*x*/
bbx[2][0] = bbx[3][0] = bbx[4][0] = bbx[5][0] = object->box[1];
bbx[0][1] = bbx[1][1] = bbx[2][1] = bbx[3][1] = object->box[2];/*y*/
bbx[4][1] = bbx[5][1] = bbx[6][1] = bbx[7][1] = object->box[3];
bbx[0][2] = bbx[3][2] = bbx[4][2] = bbx[7][2] = object->box[4];/*z*/
bbx[1][2] = bbx[2][2] = bbx[5][2] = bbx[6][2] = object->box[5];
for (kv=0; kv<8; kv++) /* transform */
transform(bbx[kv],object->comp_mtx,bbx[kv]);
/* get polygons in order */
for (kp=0; kp<6; kp++) /* for each of 6 sides on box */
{ double poly[24],poly2[24]; float vec[3]; short i,npts;
npts = 4;
for (i=0; i<npts; i++) /* copy polygon */
{ poly[3*i+X] = bbx[pol[kp][i]][0];
poly[3*i+Y] = bbx[pol[kp][i]][1];
poly[3*i+Z] = bbx[pol[kp][i]][2];
}
/* get normal vector */
{ struct { float x,y,z; } pt1,pt2;
pt1.x = poly[3+X] - poly[0+X];
pt1.y = poly[3+Y] - poly[0+Y];
pt1.z = poly[3+Z] - poly[0+Z];
pt2.x = poly[6+X] - poly[3+X];
pt2.y = poly[6+Y] - poly[3+Y];
pt2.z = poly[6+Z] - poly[3+Z];
vec[0] = pt1.y*pt2.z - pt1.z*pt2.y;
vec[1] = pt1.z*pt2.x - pt1.x*pt2.z;
vec[2] = pt1.x*pt2.y - pt1.y*pt2.x;
}
if ((poly[0+X]*vec[0] + poly[0+Y]*vec[1] + poly[0+Z]*vec[2])
> 0) continue; /* skip out if backfacing */
if (bbits) /* color calculation */
{ double dot_prod,mag_vec;
mag_vec = sqrt(sqr(vec[0]) + sqr(vec[1]) + sqr(vec[2]));
if (mag_vec > 0.0) dot_prod = (vec[0]*light_postn[0] +
vec[1]*light_postn[1] +
vec[2]*light_postn[2]) / mag_vec;
else dot_prod = 0.;
if (dot_prod < 0.) dot_prod = 0.;
dot_prod = .3 + .7*dot_prod; /* add 30% ambient light */
if ((bbits == 8) || (bbits == 10)) /* pseudocolor */
clr_vec[0] = object->clr_num*ramp_lnth + 1
+ (short)(dot_prod*ramp_lnth);
else /* full color */
{ clr_vec[0] = dot_prod * object->clr[0];
clr_vec[1] = dot_prod * object->clr[1];
clr_vec[2] = dot_prod * object->clr[2];
}
}
/* predistort and clip */
for (i=0; i<3*npts; i+=3)
{ poly[i+X] *= cot_x; poly[i+Y] *= cot_y; }
polclp(0,&npts,poly,poly2,3);
if (npts < 3) break; /* skip if out */
/* do perspective divide */
for (i=0; i<3*npts; i+=3)
{ poly[i+X] /= poly[i+Z]; poly[i+Y] /= poly[i+Z]; }
/* send out polygons by vertex coordinates and colors */
if (bbits) fprintf(bstream,"polygon %d\n",npts); /* header for tiler */
else fprintf(bstream,"m %g %g 1.\n", /* moveto 1st vtx for lines */
poly[3*(npts-1)+X],poly[3*(npts-1)+Y]);
/* pseudocolor */
if ((bbits == 8) || (bbits == 10)) for (kv=0; kv<3*npts; kv+=3)
fprintf(bstream,"%g %g %g\n",poly[kv+X],poly[kv+Y],clr_vec[0]);
else if (bbits == 32) for (kv=0; kv<3*npts; kv+=3) /* full color */
fprintf(bstream,"%g %g %g %g %g\n",poly[kv+X],
poly[kv+Y],clr_vec[0],clr_vec[1],clr_vec[2]);
else if (!bbits) for (kv=0; kv<3*npts; kv+=3) /* line drawing */
fprintf(bstream,"d %g %g 1.\n",poly[kv+X],poly[kv+Y]);
}
}
/* +++++++++++++++++++++++++++++ POLCLP +++++++++++++++++++++++++++++++++++++ */
polclp(pass,npts,pts,pt2,npars) /* polygon clipper (eyespace) */
short *npts,pass,npars; double pts[],pt2[];
{ short i,lk,m; float dist,last_dist;
if ((pass == 4) || (*npts < 3)) return; /* completion conditions */
last_dist = 0.0; m = 0; lk = 0;
for (i=0; i<=*npts; i++)
{ short k,l;
k = (i == *npts) ? 0 : i*npars;
switch (pass)
{ case 0: { dist = pts[k+Z]+pts[k+X]; break; } /* left side */
case 1: { dist = pts[k+Z]-pts[k+X]; break; } /* right side */
case 2: { dist = pts[k+Z]+pts[k+Y]; break; } /* bottom */
case 3: { dist = pts[k+Z]-pts[k+Y]; break; } /* top */
}
if (i == 0) { last_dist = dist; lk = k; continue; } /* 1st pnt? */
if (last_dist * dist < 0.0) /* put out point if clip plane crossed */
{ float t,t1;
t = dist / (dist - last_dist); t1 = 1.0 - t;
for (l=0; l<npars; l++) pt2[m+l] = pts[k+l] * t1 + pts[lk+l] * t;
m += npars;
}
if (dist >= 0.0) /* copy point if inside */
{ for (l=0; l<npars; l++) pt2[m+l] = pts[k+l];
m += npars;
}
lk = k; last_dist = dist;
} /* recurse for next plane */
*npts = m/npars; polclp(++pass,npts,pt2,pts,npars);
}
!Funky!Stuff!
More information about the Comp.sources.unix
mailing list