extern void ambnotify( /* record new modifier */ OBJECT obj ) { static int hitlimit = 0; OBJREC *o; char **amblp; if (obj == OVOID) { /* starting over */ ambset[0] = 0; hitlimit = 0; return; } o = objptr(obj); if (hitlimit || !ismodifier(o->otype)) return; for (amblp = amblist; *amblp != NULL; amblp++) if (!strcmp(o->oname, *amblp)) { if (ambset[0] >= MAXASET) { error(WARNING, "too many modifiers in ambient list"); hitlimit++; return; /* should this be fatal? */ } insertelem(ambset, obj); return; } }
static void add2full( /* add object to full node */ register CUBE *cu, OBJECT obj ) { OCTREE ot; OBJECT oset[MAXSET+1]; CUBE cukid; register int i, j; objset(oset, cu->cutree); cukid.cusize = cu->cusize * 0.5; if (oset[0] < objlim || cukid.cusize < (oset[0] < MAXSET ? mincusize : mincusize/256.0)) { /* add to set */ if (oset[0] >= MAXSET) { sprintf(errmsg, "set overflow in addobject (%s)", objptr(obj)->oname); error(INTERNAL, errmsg); } insertelem(oset, obj); cu->cutree = fullnode(oset); return; } /* subdivide cube */ if ((ot = octalloc()) == EMPTY) error(SYSTEM, "out of octree space"); /* assign subcubes */ for (i = 0; i < 8; i++) { cukid.cutree = EMPTY; for (j = 0; j < 3; j++) { cukid.cuorg[j] = cu->cuorg[j]; if ((1<<j) & i) cukid.cuorg[j] += cukid.cusize; } for (j = 1; j <= oset[0]; j++) addface(&cukid, oset[j]); addface(&cukid, obj); /* returned node */ octkid(ot, i) = cukid.cutree; } cu->cutree = ot; }
static OCTREE cvmeshoct( /* convert triangles in subtree */ OCTREE ot ) { int i; if (isempty(ot)) return(EMPTY); if (isfull(ot)) { OBJECT oset1[MAXSET+1]; OBJECT oset2[MAXSET+1]; objset(oset1, ot); oset2[0] = 0; for (i = oset1[0]; i > 0; i--) insertelem(oset2, cvmeshtri(oset1[i])); return(fullnode(oset2)); } for (i = 8; i--; ) octkid(ot, i) = cvmeshoct(octkid(ot, i)); return(ot); }
static void add2full( /* add object to full node */ register CUBE *cu, OBJECT obj, int inc ) { OCTREE ot; OBJECT oset[MAXSET+1]; CUBE cukid; unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8]; register int i, j; objset(oset, cu->cutree); cukid.cusize = cu->cusize * 0.5; if (inc==O_IN || oset[0] < objlim || cukid.cusize < (oset[0] < MAXSET ? mincusize : mincusize/256.0)) { /* add to set */ if (oset[0] >= MAXSET) { sprintf(errmsg, "set overflow in addobject (%s)", objptr(obj)->oname); error(INTERNAL, errmsg); } insertelem(oset, obj); cu->cutree = fullnode(oset); return; } /* subdivide cube */ if ((ot = octalloc()) == EMPTY) error(SYSTEM, "out of octree space"); /* mark volumes */ j = (oset[0]+7)>>3; while (j--) volflg[j] = inflg[j] = 0; for (j = 1; j <= oset[0]; j++) if (isvolume(objptr(oset[j])->otype)) { setbit(volflg,j-1); if ((*ofun[objptr(oset[j])->otype].funp) (objptr(oset[j]), cu) == O_IN) setbit(inflg,j-1); } /* assign subcubes */ for (i = 0; i < 8; i++) { cukid.cutree = EMPTY; for (j = 0; j < 3; j++) { cukid.cuorg[j] = cu->cuorg[j]; if ((1<<j) & i) cukid.cuorg[j] += cukid.cusize; } /* surfaces first */ for (j = 1; j <= oset[0]; j++) if (!tstbit(volflg,j-1)) addobject(&cukid, oset[j]); /* then this object */ addobject(&cukid, obj); /* then partial volumes */ for (j = 1; j <= oset[0]; j++) if (tstbit(volflg,j-1) && !tstbit(inflg,j-1)) addobject(&cukid, oset[j]); /* full volumes last */ for (j = 1; j <= oset[0]; j++) if (tstbit(inflg,j-1)) addobject(&cukid, oset[j]); /* returned node */ octkid(ot, i) = cukid.cutree; } cu->cutree = ot; }