]> git.mxchange.org Git - simgear.git/blob - simgear/math/SGBox.hxx
Compile even if OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION is not set.
[simgear.git] / simgear / math / SGBox.hxx
1 // Copyright (C) 2006  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 //
17
18 #ifndef SGBox_H
19 #define SGBox_H
20
21 template<typename T>
22 class SGBox {
23 public:
24   SGBox() :
25     _min(SGLimits<T>::max(), SGLimits<T>::max(), SGLimits<T>::max()),
26     _max(-SGLimits<T>::max(), -SGLimits<T>::max(), -SGLimits<T>::max())
27   { }
28   SGBox(const SGVec3<T>& pt) :
29     _min(pt),
30     _max(pt)
31   { }
32   SGBox(const SGVec3<T>& min, const SGVec3<T>& max) :
33     _min(min),
34     _max(max)
35   { }
36   template<typename S>
37   explicit SGBox(const SGBox<S>& box) :
38     _min(box.getMin()),
39     _max(box.getMax())
40   { }
41
42   void setMin(const SGVec3<T>& min)
43   { _min = min; }
44   const SGVec3<T>& getMin() const
45   { return _min; }
46
47   void setMax(const SGVec3<T>& max)
48   { _max = max; }
49   const SGVec3<T>& getMax() const
50   { return _max; }
51
52   SGVec3<T> getCorner(unsigned i) const
53   { return SGVec3<T>((i&1) ? _min[0] : _max[0],
54                      (i&2) ? _min[1] : _max[1],
55                      (i&4) ? _min[2] : _max[2]); }
56
57   template<typename S>
58   SGVec3<T> getNearestCorner(const SGVec3<S>& pt) const
59   {
60     SGVec3<T> center = getCenter();
61     return SGVec3<T>((pt[0] <= center[0]) ? _min[0] : _max[0],
62                      (pt[1] <= center[1]) ? _min[1] : _max[1],
63                      (pt[2] <= center[2]) ? _min[2] : _max[2]);
64   }
65   template<typename S>
66   SGVec3<T> getFarestCorner(const SGVec3<S>& pt) const
67   {
68     SGVec3<T> center = getCenter();
69     return SGVec3<T>((pt[0] > center[0]) ? _min[0] : _max[0],
70                      (pt[1] > center[1]) ? _min[1] : _max[1],
71                      (pt[2] > center[2]) ? _min[2] : _max[2]);
72   }
73
74
75   // Only works for floating point types
76   SGVec3<T> getCenter() const
77   { return T(0.5)*(_min + _max); }
78
79   // Only valid for nonempty boxes
80   SGVec3<T> getSize() const
81   { return _max - _min; }
82   SGVec3<T> getHalfSize() const
83   { return T(0.5)*getSize(); }
84
85   T getVolume() const
86   {
87     if (empty())
88       return 0;
89     return (_max[0] - _min[0])*(_max[1] - _min[1])*(_max[2] - _min[2]);
90   }
91
92   const bool empty() const
93   { return !valid(); }
94
95   bool valid() const
96   {
97     if (_max[0] < _min[0])
98       return false;
99     if (_max[1] < _min[1])
100       return false;
101     if (_max[2] < _min[2])
102       return false;
103     return true;
104   }
105
106   void clear()
107   {
108     _min[0] = SGLimits<T>::max();
109     _min[1] = SGLimits<T>::max();
110     _min[2] = SGLimits<T>::max();
111     _max[0] = -SGLimits<T>::max();
112     _max[1] = -SGLimits<T>::max();
113     _max[2] = -SGLimits<T>::max();
114   }
115
116   void expandBy(const SGVec3<T>& v)
117   { _min = min(_min, v); _max = max(_max, v); }
118
119   void expandBy(const SGBox<T>& b)
120   { _min = min(_min, b._min); _max = max(_max, b._max); }
121
122   // Note that this only works if the box is nonmepty
123   unsigned getBroadestAxis() const
124   {
125     SGVec3<T> size = getSize();
126     if (size[1] <= size[0] && size[2] <= size[0])
127       return 0;
128     else if (size[2] <= size[1])
129       return 1;
130     else
131       return 2;
132   }
133
134   // Note that this only works if the box is nonmepty
135   unsigned getSmallestAxis() const
136   {
137     SGVec3<T> size = getSize();
138     if (size[1] >= size[0] && size[2] >= size[0])
139       return 0;
140     else if (size[2] >= size[1])
141       return 1;
142     else
143       return 2;
144   }
145
146 private:
147   SGVec3<T> _min;
148   SGVec3<T> _max;
149 };
150
151 /// Output to an ostream
152 template<typename char_type, typename traits_type, typename T>
153 inline
154 std::basic_ostream<char_type, traits_type>&
155 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGBox<T>& box)
156 { return s << "min = " << box.getMin() << ", max = " << box.getMax(); }
157
158 #endif