ken@turtleva.UUCP (Ken Turkowski) (12/16/83)
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!