| 1 |
gwlarson |
3.1 |
/* Copyright (c) 1998 Silicon Graphics, Inc. */
|
| 2 |
|
|
|
| 3 |
|
|
#ifndef lint
|
| 4 |
|
|
static char SCCSid[] = "$SunId$ SGI";
|
| 5 |
|
|
#endif
|
| 6 |
|
|
|
| 7 |
|
|
/*
|
| 8 |
|
|
* Octree drawing operations for OpenGL driver.
|
| 9 |
|
|
*/
|
| 10 |
|
|
|
| 11 |
|
|
#include "radogl.h"
|
| 12 |
|
|
|
| 13 |
|
|
#ifndef MAXOCTREE
|
| 14 |
|
|
#define MAXOCTREE 8 /* maximum octrees to load at once */
|
| 15 |
|
|
#endif
|
| 16 |
|
|
|
| 17 |
|
|
static struct otEntry {
|
| 18 |
|
|
char *otfile; /* octree file name */
|
| 19 |
|
|
FVECT cent; /* centroid */
|
| 20 |
|
|
FLOAT rad; /* radius */
|
| 21 |
|
|
int listid; /* display list identifier */
|
| 22 |
|
|
} otCurrent[MAXOCTREE], otNext[MAXOCTREE]; /* current and next list */
|
| 23 |
|
|
|
| 24 |
|
|
#define FORALLOCT(ot,i) for (i=0;i<MAXOCTREE&&ot[i].otfile!=NULL;i++)
|
| 25 |
|
|
|
| 26 |
|
|
|
| 27 |
|
|
otNewOctree(fname) /* add new octree to next list */
|
| 28 |
|
|
char *fname;
|
| 29 |
|
|
{
|
| 30 |
|
|
register int i, j;
|
| 31 |
|
|
/* check if already in next list */
|
| 32 |
|
|
FORALLOCT(otNext, i)
|
| 33 |
|
|
if (!strcmp(fname, otNext[i].otfile))
|
| 34 |
|
|
return;
|
| 35 |
|
|
if (i >= MAXOCTREE) {
|
| 36 |
|
|
error(WARNING, "too many section octrees -- ignoring extra");
|
| 37 |
|
|
return;
|
| 38 |
|
|
}
|
| 39 |
|
|
/* check if copy in current list */
|
| 40 |
|
|
FORALLOCT(otCurrent, j)
|
| 41 |
|
|
if (!strcmp(fname, otCurrent[j].otfile)) {
|
| 42 |
|
|
copystruct(&otNext[i], &otCurrent[i]);
|
| 43 |
|
|
return;
|
| 44 |
|
|
}
|
| 45 |
|
|
/* else load new octree */
|
| 46 |
|
|
otNext[i].otfile = fname;
|
| 47 |
|
|
dolights = 0;
|
| 48 |
|
|
otNext[i].listid = rgl_octlist(fname, otNext[i].cent, &otNext[i].rad);
|
| 49 |
|
|
#ifdef DEBUG
|
| 50 |
|
|
fprintf(stderr, "Loaded octree \"%s\" into listID %d with radius %f\n",
|
| 51 |
|
|
fname, otNext[i].listid, otNext[i].rad);
|
| 52 |
|
|
#endif
|
| 53 |
|
|
}
|
| 54 |
|
|
|
| 55 |
|
|
|
| 56 |
|
|
otEndOctree() /* make next list current */
|
| 57 |
|
|
{
|
| 58 |
|
|
register int i, j;
|
| 59 |
|
|
|
| 60 |
|
|
FORALLOCT(otCurrent, i) {
|
| 61 |
|
|
FORALLOCT(otNext, j)
|
| 62 |
|
|
if (otNext[j].listid == otCurrent[i].listid)
|
| 63 |
|
|
break;
|
| 64 |
|
|
if (j >= MAXOCTREE || otNext[j].otfile == NULL)
|
| 65 |
|
|
glDeleteLists(otCurrent[i].listid, 1); /* not found */
|
| 66 |
|
|
}
|
| 67 |
|
|
bcopy((char *)otNext, (char *)otCurrent, sizeof(otNext));
|
| 68 |
|
|
otNext[0].otfile = NULL;
|
| 69 |
|
|
}
|
| 70 |
|
|
|
| 71 |
|
|
|
| 72 |
|
|
int
|
| 73 |
|
|
otDrawOctrees() /* draw current list of octrees */
|
| 74 |
|
|
{
|
| 75 |
|
|
register int i;
|
| 76 |
|
|
|
| 77 |
|
|
FORALLOCT(otCurrent, i)
|
| 78 |
|
|
glCallList(otCurrent[i].listid);
|
| 79 |
|
|
return(i);
|
| 80 |
|
|
}
|
| 81 |
|
|
|
| 82 |
|
|
|
| 83 |
|
|
otDepthLimit(dl, vorg, vdir) /* compute approximate depth limits for view */
|
| 84 |
|
|
double dl[2];
|
| 85 |
|
|
FVECT vorg, vdir;
|
| 86 |
|
|
{
|
| 87 |
|
|
FVECT v;
|
| 88 |
|
|
double dcent;
|
| 89 |
|
|
register int i;
|
| 90 |
|
|
|
| 91 |
|
|
dl[0] = FHUGE; dl[1] = 0.;
|
| 92 |
|
|
FORALLOCT(otCurrent, i) {
|
| 93 |
|
|
VSUB(v, otCurrent[i].cent, vorg);
|
| 94 |
|
|
dcent = DOT(v, vdir);
|
| 95 |
|
|
if (dl[0] > dcent-otCurrent[i].rad)
|
| 96 |
|
|
dl[0] = dcent-otCurrent[i].rad;
|
| 97 |
|
|
if (dl[1] < dcent+otCurrent[i].rad)
|
| 98 |
|
|
dl[1] = dcent+otCurrent[i].rad;
|
| 99 |
|
|
}
|
| 100 |
|
|
if (dl[0] < 0.)
|
| 101 |
|
|
dl[0] = 0.;
|
| 102 |
|
|
}
|