Back to index

radiance  4R0+20100331
bbox.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char RCSid[] = "$Id: bbox.c,v 2.6 2005/06/14 17:10:06 greg Exp $";
00003 #endif
00004 /*
00005  *  bbox.c - routines for bounding box computation.
00006  */
00007 
00008 #include  "copyright.h"
00009 
00010 #include  "standard.h"
00011 #include  "object.h"
00012 #include  "octree.h"
00013 #include  "otypes.h"
00014 #include  "face.h"
00015 #include  "cone.h"
00016 #include  "instance.h"
00017 #include  "mesh.h"
00018 #include  "oconv.h"
00019 
00020 
00021 static void point2bbox(FVECT  p, FVECT  bbmin, FVECT  bbmax);
00022 static void circle2bbox(FVECT  cent, FVECT  norm, double  rad, FVECT  bbmin, FVECT  bbmax);
00023 
00024 
00025 void
00026 add2bbox(            /* expand bounding box to fit object */
00027        register OBJREC  *o,
00028        FVECT  bbmin,
00029        FVECT  bbmax
00030 )
00031 {
00032        CONE  *co;
00033        FACE  *fo;
00034        INSTANCE  *io;
00035        MESHINST  *mi;
00036        FVECT  v;
00037        register int  i, j;
00038 
00039        switch (o->otype) {
00040        case OBJ_SPHERE:
00041        case OBJ_BUBBLE:
00042               if (o->oargs.nfargs != 4)
00043                      objerror(o, USER, "bad arguments");
00044               for (i = 0; i < 3; i++) {
00045                      VCOPY(v, o->oargs.farg);
00046                      v[i] -= o->oargs.farg[3];
00047                      point2bbox(v, bbmin, bbmax);
00048                      v[i] += 2.0 * o->oargs.farg[3];
00049                      point2bbox(v, bbmin, bbmax);
00050               }
00051               break;
00052        case OBJ_FACE:
00053               fo = getface(o);
00054               j = fo->nv;
00055               while (j--)
00056                      point2bbox(VERTEX(fo,j), bbmin, bbmax);
00057               break;
00058        case OBJ_CONE:
00059        case OBJ_CUP:
00060        case OBJ_CYLINDER:
00061        case OBJ_TUBE:
00062        case OBJ_RING:
00063               co = getcone(o, 0);
00064               if (o->otype != OBJ_RING)
00065                      circle2bbox(CO_P0(co), co->ad, CO_R0(co), bbmin, bbmax);
00066               circle2bbox(CO_P1(co), co->ad, CO_R1(co), bbmin, bbmax);
00067               break;
00068        case OBJ_INSTANCE:
00069               io = getinstance(o, IO_BOUNDS);
00070               for (j = 0; j < 8; j++) {
00071                      for (i = 0; i < 3; i++) {
00072                             v[i] = io->obj->scube.cuorg[i];
00073                             if (j & 1<<i)
00074                                    v[i] += io->obj->scube.cusize;
00075                      }
00076                      multp3(v, v, io->x.f.xfm);
00077                      point2bbox(v, bbmin, bbmax);
00078               }
00079               break;
00080        case OBJ_MESH:
00081               mi = getmeshinst(o, IO_BOUNDS);
00082               for (j = 0; j < 8; j++) {
00083                      for (i = 0; i < 3; i++) {
00084                             v[i] = mi->msh->mcube.cuorg[i];
00085                             if (j & 1<<i)
00086                                    v[i] += mi->msh->mcube.cusize;
00087                      }
00088                      multp3(v, v, mi->x.f.xfm);
00089                      point2bbox(v, bbmin, bbmax);
00090               }
00091               break;
00092        }
00093 }
00094 
00095 
00096 static void
00097 point2bbox(          /* expand bounding box to fit point */
00098        register FVECT  p,
00099        register FVECT  bbmin,
00100        register FVECT  bbmax
00101 )
00102 {
00103        register int  i;
00104 
00105        for (i = 0; i < 3; i++) {
00106               if (p[i] < bbmin[i])
00107                      bbmin[i] = p[i];
00108               if (p[i] > bbmax[i])
00109                      bbmax[i] = p[i];
00110        }
00111 }
00112 
00113 
00114 static void
00115 circle2bbox(  /* expand bbox to fit circle */
00116        FVECT  cent,
00117        FVECT  norm,
00118        double  rad,
00119        FVECT  bbmin,
00120        FVECT  bbmax
00121 )
00122 {
00123        double d, r;
00124        register int  i;
00125 
00126        for (i = 0; i < 3; i++) {
00127               r = sqrt(1. - norm[i]*norm[i]);
00128               d = cent[i] + r*rad;
00129               if (d > bbmax[i])
00130                      bbmax[i] = d;
00131               d = cent[i] - r*rad;
00132               if (d < bbmin[i])
00133                      bbmin[i] = d;
00134        }
00135 }