/* patchlist.c */ #include "patchlist.h" #include "patchlist_geom.h" #include "bounds.h" #include "patch.h" #include "hitlist.h" /* computes a bounding box for the given list of PATCHes. The bounding box is * filled in in 'boundingbox' and a pointer to it returned. */ float *PatchListBounds(PATCHLIST *pl, float *boundingbox) { BOUNDINGBOX b; BoundsInit(boundingbox); ForAllPatches(patch, pl) { PatchBounds(patch, b); BoundsEnlarge(boundingbox, b); } EndForAll; return boundingbox; } /* Tests whether the RAY intersect the PATCHes in the list. See geom.h * (GeomDiscretisationIntersect()) for more explanation. */ HITREC *PatchListIntersect(PATCHLIST *pl, RAY *ray, float mindist, float *maxdist, int hitflags, HITREC *hitstore) { HITREC *hit = (HITREC *)NULL; ForAllPatches(P, pl) { HITREC *h = PatchIntersect(P, ray, mindist, maxdist, hitflags, hitstore); if (h) { if (hitflags & HIT_ANY) return h; else hit = h; } } EndForAll; return hit; } HITLIST *PatchListAllIntersections(HITLIST *hits, PATCHLIST *patches, RAY *ray, float mindist, float maxdist, int hitflags) { HITREC hitstore; ForAllPatches(P, patches) { float tmax = maxdist; /* do not modify maxdist */ HITREC *hit = PatchIntersect(P, ray, mindist, &tmax, hitflags, &hitstore); if (hit) { hits = HitListAdd(hits, DuplicateHit(hit)); } } EndForAll; return hits; } /* The following routines are needed to make patchlists look like GEOMs. This * is required for shaft culling (see shaftculling.[ch] and clustering (see * cluster.[ch]. In both cases, the PATCHes pointed to should not be * destroyed, only the PATCHLIST should. */ static void PatchlistDestroy(PATCHLIST *patchlist) { PatchListDestroy(patchlist); } static void PatchPrintId(FILE *out, PATCH *patch) { fprintf(out, "%d ", patch->id); } static void PatchlistPrint(FILE *out, PATCHLIST *patchlist) { fprintf(out, "patchlist:\n"); PatchListIterate1B(patchlist, PatchPrintId, out); fprintf(out, "\nend of patchlist.\n"); } static PATCHLIST *PatchlistPatchlist(PATCHLIST *patchlist) { return patchlist; } static PATCHLIST *PatchlistDuplicate(PATCHLIST *patchlist) { return PatchListDuplicate(patchlist); } GEOM_METHODS patchlistMethods = { (float *(*)(void *, float *))PatchListBounds, (void (*)(void *))PatchlistDestroy, (void (*)(FILE *, void *))PatchlistPrint, (GEOMLIST *(*)(void *))NULL, (PATCHLIST *(*)(void *))PatchlistPatchlist, (HITREC *(*)(void *, RAY *, float, float *, int, HITREC *))PatchListIntersect, (HITLIST *(*)(HITLIST *, void *, RAY *, float, float, int))PatchListAllIntersections, (void *(*)(void *))PatchlistDuplicate };