00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef SGBox_H
00019 #define SGBox_H
00020
00021 template<typename T>
00022 class SGBox {
00023 public:
00024 SGBox() :
00025 _min(SGLimits<T>::max(), SGLimits<T>::max(), SGLimits<T>::max()),
00026 _max(-SGLimits<T>::max(), -SGLimits<T>::max(), -SGLimits<T>::max())
00027 { }
00028 SGBox(const SGVec3<T>& pt) :
00029 _min(pt),
00030 _max(pt)
00031 { }
00032 SGBox(const SGVec3<T>& min, const SGVec3<T>& max) :
00033 _min(min),
00034 _max(max)
00035 { }
00036 template<typename S>
00037 explicit SGBox(const SGBox<S>& box) :
00038 _min(box.getMin()),
00039 _max(box.getMax())
00040 { }
00041
00042 void setMin(const SGVec3<T>& min)
00043 { _min = min; }
00044 const SGVec3<T>& getMin() const
00045 { return _min; }
00046
00047 void setMax(const SGVec3<T>& max)
00048 { _max = max; }
00049 const SGVec3<T>& getMax() const
00050 { return _max; }
00051
00052 SGVec3<T> getCorner(unsigned i) const
00053 { return SGVec3<T>((i&1) ? _min[0] : _max[0],
00054 (i&2) ? _min[1] : _max[1],
00055 (i&4) ? _min[2] : _max[2]); }
00056
00057 template<typename S>
00058 SGVec3<T> getNearestCorner(const SGVec3<S>& pt) const
00059 {
00060 SGVec3<T> center = getCenter();
00061 return SGVec3<T>((pt[0] <= center[0]) ? _min[0] : _max[0],
00062 (pt[1] <= center[1]) ? _min[1] : _max[1],
00063 (pt[2] <= center[2]) ? _min[2] : _max[2]);
00064 }
00065 template<typename S>
00066 SGVec3<T> getFarestCorner(const SGVec3<S>& pt) const
00067 {
00068 SGVec3<T> center = getCenter();
00069 return SGVec3<T>((pt[0] > center[0]) ? _min[0] : _max[0],
00070 (pt[1] > center[1]) ? _min[1] : _max[1],
00071 (pt[2] > center[2]) ? _min[2] : _max[2]);
00072 }
00073
00074
00075
00076 SGVec3<T> getCenter() const
00077 { return T(0.5)*(_min + _max); }
00078
00079
00080 SGVec3<T> getSize() const
00081 { return _max - _min; }
00082 SGVec3<T> getHalfSize() const
00083 { return T(0.5)*getSize(); }
00084
00085 T getVolume() const
00086 {
00087 if (empty())
00088 return 0;
00089 return (_max[0] - _min[0])*(_max[1] - _min[1])*(_max[2] - _min[2]);
00090 }
00091
00092 const bool empty() const
00093 { return !valid(); }
00094
00095 bool valid() const
00096 {
00097 if (_max[0] < _min[0])
00098 return false;
00099 if (_max[1] < _min[1])
00100 return false;
00101 if (_max[2] < _min[2])
00102 return false;
00103 return true;
00104 }
00105
00106 void clear()
00107 {
00108 _min[0] = SGLimits<T>::max();
00109 _min[1] = SGLimits<T>::max();
00110 _min[2] = SGLimits<T>::max();
00111 _max[0] = -SGLimits<T>::max();
00112 _max[1] = -SGLimits<T>::max();
00113 _max[2] = -SGLimits<T>::max();
00114 }
00115
00116 void expandBy(const SGVec3<T>& v)
00117 { _min = min(_min, v); _max = max(_max, v); }
00118
00119 void expandBy(const SGBox<T>& b)
00120 { _min = min(_min, b._min); _max = max(_max, b._max); }
00121
00122
00123 unsigned getBroadestAxis() const
00124 {
00125 SGVec3<T> size = getSize();
00126 if (size[1] <= size[0] && size[2] <= size[0])
00127 return 0;
00128 else if (size[2] <= size[1])
00129 return 1;
00130 else
00131 return 2;
00132 }
00133
00134
00135 unsigned getSmallestAxis() const
00136 {
00137 SGVec3<T> size = getSize();
00138 if (size[1] >= size[0] && size[2] >= size[0])
00139 return 0;
00140 else if (size[2] >= size[1])
00141 return 1;
00142 else
00143 return 2;
00144 }
00145
00146 private:
00147 SGVec3<T> _min;
00148 SGVec3<T> _max;
00149 };
00150
00152 template<typename char_type, typename traits_type, typename T>
00153 inline
00154 std::basic_ostream<char_type, traits_type>&
00155 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGBox<T>& box)
00156 { return s << "min = " << box.getMin() << ", max = " << box.getMax(); }
00157
00158 #endif