src/Box.h

Go to the documentation of this file.
00001 #ifndef BOX_H
00002 #define BOX_H
00003 
00004 
00005 #include "Vec3f.h"
00006 #include "Ray.h"
00007 #include "Axis.h"
00008 #include "SplitPlane.h"
00009 
00010 
00016 class Box
00017 {
00018 public:
00021     Box()
00022     {
00023         clear();
00024     }
00025 
00031     Box(const Vec3f & minVertex, const Vec3f & maxVertex)
00032         : mMin(minVertex),
00033             mMax(maxVertex)
00034     {
00035     }
00036 
00041     void extend(const Vec3f & a)
00042     {
00043         mMin = min(a - Vec3f(EPSILON), mMin);
00044         mMax = max(a + Vec3f(EPSILON), mMax);
00045     }
00046 
00051     void extend(const Box & box)
00052     {
00053         extend(box.mMin - Vec3f(EPSILON));
00054         extend(box.mMax + Vec3f(EPSILON));
00055     }
00056 
00059     void clear()
00060     {
00061         mMin = Vec3f(INFINITY, INFINITY, INFINITY);
00062         mMax = Vec3f(-INFINITY, -INFINITY, -INFINITY);
00063     }
00064 
00070     std::pair<float, float> intersect(const Ray & ray) const
00071     {
00072         float d0 = -INFINITY;
00073         float d1 = INFINITY;
00074 
00075         if (fabs(ray.dir().x()) > EPSILON)
00076         {
00077             d0 = (mMin.x() - ray.org().x()) / ray.dir().x();
00078             d1 = (mMax.x() - ray.org().x()) / ray.dir().x();
00079             if (d1 < d0)
00080                 std::swap(d0, d1);
00081         }
00082 
00083         if (fabs(ray.dir().y()) > EPSILON)
00084         {
00085             float t0, t1;
00086             t0 = (mMin.y() - ray.org().y()) / ray.dir().y();
00087             t1 = (mMax.y() - ray.org().y()) / ray.dir().y();
00088             if (t1 < t0)
00089                 std::swap(t0, t1);
00090             d0 = std::max(d0, t0);
00091             d1 = std::min(d1, t1);
00092         }
00093 
00094         if (fabs(ray.dir().z()) > EPSILON)
00095         {
00096             float t0, t1;
00097             t0 = (mMin.z() - ray.org().z()) / ray.dir().z();
00098             t1 = (mMax.z() - ray.org().z()) / ray.dir().z();
00099             if (t1 < t0)
00100                 std::swap(t0, t1);
00101             d0 = std::max(d0, t0);
00102             d1 = std::min(d1, t1);
00103         }
00104 
00105         if (d1 < d0 || d0 <= -INFINITY)
00106             return std::make_pair(INFINITY, -INFINITY);
00107         else
00108             return std::make_pair(d0 - EPSILON, d1 + EPSILON);
00109     }
00110 
00113     inline const Vec3f & minVertex() const
00114     {
00115         return mMin;
00116     }
00117 
00120     inline const Vec3f & maxVertex() const
00121     {
00122         return mMax;
00123     }
00124 
00131     float area(const SplitPlane & plane) const    // FIXME not accurate
00132     {
00133         assert(plane.direction() != NO_AXIS);
00134 //        assert(mMin[plane.direction()] <= plane.position() && plane.position() <= mMax[plane.direction()]);
00135 
00136         Vec3f diff = mMax - mMin;
00137         return (plane.position() - mMin[plane.direction()]) / diff[plane.direction()];
00138     }
00139 
00145     std::pair<Box, Box> split(const SplitPlane & plane) const
00146     {
00147         assert(plane.direction() != NO_AXIS);
00148 //        LOG("[" << mMin << " , " << mMax << "]  " << plane.position() << " " << plane.direction());
00149 //        assert(mMin[plane.direction()] <= plane.position() && plane.position() <= mMax[plane.direction()]);
00150 
00151         switch (plane.direction())
00152         {
00153             case X_AXIS:    return std::make_pair(Box(mMin, Vec3f(plane.position() - EPSILON, mMax.y(), mMax.z())),
00154                                                     Box(Vec3f(plane.position() + EPSILON, mMin.y(), mMin.z()), mMax));
00155             case Y_AXIS:    return std::make_pair(Box(mMin, Vec3f(mMax.x(), plane.position() - EPSILON, mMax.z())),
00156                                                     Box(Vec3f(mMin.x(), plane.position() + EPSILON, mMin.z()), mMax));
00157             case Z_AXIS:    return std::make_pair(Box(mMin, Vec3f(mMax.x(), mMax.y(), plane.position() - EPSILON)),
00158                                                     Box(Vec3f(mMin.x(), mMin.y(), plane.position() + EPSILON), mMax));
00159             default:        return std::make_pair(Box(), Box());
00160         }
00161     }
00162 
00167     Box clip(const Box & other) const
00168     {
00169         return Box(max(mMin, other.mMin), min(mMax, other.mMax));
00170     }
00171 
00172 private:
00174     Vec3f mMin;
00175 
00177     Vec3f mMax;
00178 };
00179 
00180 #endif
00181 

Generated on Fri Feb 1 00:01:42 2008 for Grayfall by  doxygen 1.5.1