1 //------------------------------------------------------------------------------
2 // File : minmaxbox.cpp
3 //------------------------------------------------------------------------------
4 // GLVU : Copyright 1997 - 2002
5 // The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its
8 // documentation for any purpose is hereby granted without fee, provided that
9 // the above copyright notice appear in all copies and that both that copyright
10 // notice and this permission notice appear in supporting documentation.
11 // Binaries may be compiled with this software without any royalties or
14 // The University of North Carolina at Chapel Hill makes no representations
15 // about the suitability of this software for any purpose. It is provided
16 // "as is" without express or implied warranty.
18 //=========================================================================
19 // minmaxbox.cpp : min-max box routines
20 //=========================================================================
22 //-----------------------------------------------------------------------------
23 // Calculates the eight corner vertices of the MinMaxBox.
24 // V must be prealloced.
27 // 1---0 | VERTS : 0=RTN,1=LTN,2=LBN,3=RBN,4=RTF,5=LTF,6=LBF,7=RBF
28 // | | 7 (L,R, B,T, N,F) = (Left,Right, Bottom,Top, Near,Far)
31 //-----------------------------------------------------------------------------
32 void GetMinMaxBoxVerts(const float Min[3], const float Max[3], float V[8][3])
34 #define SET(v,x,y,z) v[0]=x; v[1]=y; v[2]=z;
35 SET(V[0],Max[0],Max[1],Max[2]); SET(V[4],Max[0],Max[1],Min[2]);
36 SET(V[1],Min[0],Max[1],Max[2]); SET(V[5],Min[0],Max[1],Min[2]);
37 SET(V[2],Min[0],Min[1],Max[2]); SET(V[6],Min[0],Min[1],Min[2]);
38 SET(V[3],Max[0],Min[1],Max[2]); SET(V[7],Max[0],Min[1],Min[2]);
41 //--------------------------------------------------------------------------
42 // Ray-MinMaxBox intersection test. Returns 0 or 1, calcs In-Out "HitTimes"
43 // IsectPts can be calculated as:
44 // InIsectPt = Start + Dir * InT (if InT>0)
45 // OutIsectPt = Start + Dir * OutT (if OutT>0)
46 //--------------------------------------------------------------------------
47 int RayMinMaxBoxIsect(const float Start[3], const float Dir[3],
48 const float Min[3], const float Max[3],
49 float *InT, float *OutT)
51 *InT=-99999, *OutT=99999; // INIT INTERVAL T-VAL ENDPTS TO -/+ "INFINITY"
52 float NewInT, NewOutT; // STORAGE FOR NEW T VALUES
54 // X-SLAB (PARALLEL PLANES PERPENDICULAR TO X-AXIS) INTERSECTION (Xaxis is Normal)
55 if (Dir[0] == 0) // CHECK IF RAY IS PARALLEL TO THE SLAB PLANES
56 { if ((Start[0] < Min[0]) || (Start[0] > Max[0])) return(0); }
59 NewInT = (Min[0]-Start[0])/Dir[0]; // CALC Tval ENTERING MIN PLANE
60 NewOutT = (Max[0]-Start[0])/Dir[0]; // CALC Tval ENTERING MAX PLANE
61 if (NewOutT>NewInT) { if (NewInT>*InT) *InT=NewInT; if (NewOutT<*OutT) *OutT=NewOutT; }
62 else { if (NewOutT>*InT) *InT=NewOutT; if (NewInT<*OutT) *OutT=NewInT; }
63 if (*InT>*OutT) return(0);
66 // Y-SLAB (PARALLEL PLANES PERPENDICULAR TO Y-AXIS) INTERSECTION (Yaxis is Normal)
67 if (Dir[1] == 0) // CHECK IF RAY IS PARALLEL TO THE SLAB PLANES
68 { if ((Start[1] < Min[1]) || (Start[1] > Max[1])) return(0); }
71 NewInT = (Min[1]-Start[1])/Dir[1]; // CALC Tval ENTERING MIN PLANE
72 NewOutT = (Max[1] - Start[1])/Dir[1]; // CALC Tval ENTERING MAX PLANE
73 if (NewOutT>NewInT) { if (NewInT>*InT) *InT=NewInT; if (NewOutT<*OutT) *OutT=NewOutT; }
74 else { if (NewOutT>*InT) *InT=NewOutT; if (NewInT<*OutT) *OutT=NewInT; }
75 if (*InT>*OutT) return(0);
78 // Z-SLAB (PARALLEL PLANES PERPENDICULAR TO Z-AXIS) INTERSECTION (Zaxis is Normal)
79 if (Dir[2] == 0) // CHECK IF RAY IS PARALLEL TO THE SLAB PLANES
80 { if ((Start[2] < Min[2]) || (Start[2] > Max[2])) return(0); }
83 NewInT = (Min[2]-Start[2])/Dir[2]; // CALC Tval ENTERING MIN PLANE
84 NewOutT = (Max[2]-Start[2])/Dir[2]; // CALC Tval ENTERING MAX PLANE
85 if (NewOutT>NewInT) { if (NewInT>*InT) *InT=NewInT; if (NewOutT<*OutT) *OutT=NewOutT; }
86 else { if (NewOutT>*InT) *InT=NewOutT; if (NewInT<*OutT) *OutT=NewInT; }
87 if (*InT>*OutT) return(0);
90 // CHECK IF INTERSECTIONS ARE "AT OR BEYOND" THE START OF THE RAY
91 if (*InT>=0 || *OutT>=0) return(1);
95 //--------------------------------------------------------------------------
96 // returns whether or not an edge intersects a MinMaxBox. The hit times
97 // are returned just as in the ray isect test.
98 //--------------------------------------------------------------------------
99 int EdgeMinMaxBoxIsect(const float A[3], const float B[3],
100 const float Min[3], const float Max[3],
101 float *InT, float *OutT)
103 float Dir[3] = {B[0]-A[0],B[1]-A[1],B[2]-A[2]};
104 if ( RayMinMaxBoxIsect(A,Dir,Min,Max,InT,OutT) )
105 if (*InT>=0 && *InT<=1) return(1);
106 else if (*OutT>=0 && *OutT<=1) return(1);