Back to index

radiance  4R0+20100331
o_instance.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char RCSid[] = "$Id: o_instance.c,v 2.6 2004/03/30 16:13:00 schorsch Exp $";
00003 #endif
00004 /*
00005  *  o_instance.c - routines for creating octrees for other octrees
00006  */
00007 
00008 #include  "standard.h"
00009 
00010 #include  "object.h"
00011 
00012 #include  "octree.h"
00013 
00014 #include  "instance.h"
00015 
00016 #include  "mesh.h"
00017 
00018 #include  "plocate.h"
00019 
00020 /*
00021  *     To determine if two cubes intersect:
00022  *
00023  *     1) Check to see if any vertices of first cube are inside the
00024  *        second (intersection).
00025  *
00026  *     2) Check to see if all vertices of first are to one side of
00027  *        second (no intersection).
00028  *
00029  *     3) Perform 1 and 2 with roles reversed.
00030  *
00031  *     4) Check to see if any portion of any edge of second is inside
00032  *        first (intersection).
00033  *
00034  *     5) If test 4 fails, we have no intersection.
00035  *
00036  *     Note that if we were testing two boxes, we would need
00037  *  to check that neither had any edges inside the other to be sure.
00038  *     Since an octree is a volume rather than a surface, we will
00039  *  return a value of 2 if the cube is entirely within the octree.
00040  */
00041 
00042 
00043 static int o_cube(CUBE  *cu1, FULLXF  *fxf, CUBE  *cu);
00044 
00045 
00046 static int
00047 o_cube(                     /* determine if cubes intersect */
00048        CUBE  *cu1,
00049        FULLXF  *fxf,
00050        CUBE  *cu
00051 )
00052 {
00053        static int  vstart[4] = {0, 3, 5, 6};
00054        FVECT  cumin, cumax;
00055        FVECT  vert[8];
00056        FVECT  v1, v2;
00057        int  vloc, vout;
00058        register int  i, j;
00059                                    /* check if cube vertex in octree */
00060        for (j = 0; j < 3; j++)
00061               cumax[j] = (cumin[j] = cu1->cuorg[j]) + cu1->cusize;
00062        vloc = ABOVE | BELOW;
00063        vout = 0;
00064        for (i = 0; i < 8; i++) {
00065               for (j = 0; j < 3; j++) {
00066                      v1[j] = cu->cuorg[j];
00067                      if (i & 1<<j)
00068                             v1[j] += cu->cusize;
00069               }
00070               multp3(v2, v1, fxf->b.xfm);
00071               if ( (j = plocate(v2, cumin, cumax)) )
00072                      vout++;
00073               vloc &= j;
00074        }
00075        if (vout == 0)                     /* all inside */
00076               return(O_IN);
00077        if (vout < 8)               /* some inside */
00078               return(O_HIT);
00079        if (vloc)                   /* all to one side */
00080               return(O_MISS);
00081                                    /* octree vertices in cube? */
00082        for (j = 0; j < 3; j++)
00083               cumax[j] = (cumin[j] = cu->cuorg[j]) + cu->cusize;
00084        vloc = ABOVE | BELOW;
00085        for (i = 0; i < 8; i++) {
00086               for (j = 0; j < 3; j++) {
00087                      v1[j] = cu1->cuorg[j];
00088                      if (i & 1<<j)
00089                             v1[j] += cu1->cusize;
00090               }
00091               multp3(vert[i], v1, fxf->f.xfm);
00092               if ( (j = plocate(vert[i], cumin, cumax)) )
00093                      vloc &= j;
00094               else
00095                      return(O_HIT);       /* vertex inside */
00096        }
00097        if (vloc)                   /* all to one side */
00098               return(O_MISS);
00099                                    /* check edges */
00100        for (i = 0; i < 4; i++)
00101               for (j = 0; j < 3; j++) {
00102                                           /* clip modifies vertices! */
00103                      VCOPY(v1, vert[vstart[i]]);
00104                      VCOPY(v2, vert[vstart[i] ^ 1<<j]);
00105                      if (clip(v1, v2, cumin, cumax))
00106                             return(O_HIT);              /* edge inside */
00107               }
00108 
00109        return(O_MISS);                    /* no intersection */
00110 }
00111 
00112 
00113 int
00114 o_instance(                 /* determine if instance intersects */
00115        OBJREC  *o,
00116        CUBE  *cu
00117 )
00118 {
00119        INSTANCE  *ins;
00120                                    /* get octree bounds */
00121        ins = getinstance(o, IO_BOUNDS);
00122                                    /* call o_cube to do the work */
00123        return(o_cube(&ins->obj->scube, &ins->x, cu));
00124 }
00125 
00126 
00127 int
00128 o_mesh(                            /* determine if mesh intersects */
00129        OBJREC  *o,
00130        CUBE  *cu
00131 )
00132 {
00133        MESHINST      *mip;
00134                                    /* get mesh bounds */
00135        mip = getmeshinst(o, IO_BOUNDS);
00136                                    /* call o_cube to do the work */
00137        return(o_cube(&mip->msh->mcube, &mip->x, cu));
00138 }