00001 #include "bbox.h" 00002 00007 #include <iostream> 00008 using namespace std; 00009 00010 #include <math/matrix4.h> 00011 #include <glt/viewport.h> 00012 00013 BoundingBox::BoundingBox() 00014 : _defined(false) 00015 { 00016 } 00017 00018 BoundingBox::BoundingBox(const Vector &min,const Vector &max) 00019 : _defined(true), _min(min), _max(max) 00020 { 00021 } 00022 00023 bool &BoundingBox::defined() { return _defined; } 00024 const bool BoundingBox::defined() const { return _defined; } 00025 00026 Vector &BoundingBox::min() { return _min; } 00027 const Vector &BoundingBox::min() const { return _min; } 00028 Vector &BoundingBox::max() { return _max; } 00029 const Vector &BoundingBox::max() const { return _max; } 00030 00031 Vector 00032 BoundingBox::center() const 00033 { 00034 return (_min+_max)*0.5; 00035 } 00036 00037 real BoundingBox::width() const { return _max[0] - _min[0]; } 00038 real BoundingBox::height() const { return _max[1] - _min[1]; } 00039 real BoundingBox::depth() const { return _max[2] - _min[2]; } 00040 00041 void 00042 BoundingBox::points(std::vector<Vector> &p) const 00043 { 00044 p.clear(); 00045 p.reserve(8); 00046 p.push_back(Vector(_min.x(), _min.y(), _min.z())); 00047 p.push_back(Vector(_min.x(), _min.y(), _max.z())); 00048 p.push_back(Vector(_min.x(), _max.y(), _min.z())); 00049 p.push_back(Vector(_min.x(), _max.y(), _max.z())); 00050 p.push_back(Vector(_max.x(), _min.y(), _min.z())); 00051 p.push_back(Vector(_max.x(), _min.y(), _max.z())); 00052 p.push_back(Vector(_max.x(), _max.y(), _min.z())); 00053 p.push_back(Vector(_max.x(), _max.y(), _max.z())); 00054 } 00055 00056 void 00057 BoundingBox::reset() 00058 { 00059 _defined = false; 00060 } 00061 00062 BoundingBox & 00063 BoundingBox::operator+=(const Vector &p) 00064 { 00065 if (!_defined) 00066 { 00067 _min = _max = p; 00068 _defined = true; 00069 } 00070 else 00071 { 00072 _min.vmin(p); 00073 _max.vmax(p); 00074 } 00075 00076 return *this; 00077 } 00078 00079 BoundingBox & 00080 BoundingBox::operator+=(const vector<Vector> &p) 00081 { 00082 if (!p.size()) 00083 return *this; 00084 00085 uint32 i = 0; 00086 00087 if (!_defined) 00088 { 00089 _min = _max = p.front(); 00090 _defined = true; 00091 i = 1; 00092 } 00093 00094 for (; i<p.size(); i++) 00095 { 00096 _min.vmin(p[i]); 00097 _max.vmax(p[i]); 00098 } 00099 00100 return *this; 00101 } 00102 00103 BoundingBox & 00104 BoundingBox::operator+=(const BoundingBox &box) 00105 { 00106 if (!_defined && box._defined) 00107 { 00108 _min = box._min; 00109 _max = box._max; 00110 _defined = true; 00111 return *this; 00112 } 00113 00114 if (_defined && box._defined) 00115 { 00116 _min.vmin(box._min); 00117 _max.vmax(box._max); 00118 } 00119 00120 return *this; 00121 } 00122 00123 BoundingBox & 00124 BoundingBox::operator*=(const BoundingBox &box) 00125 { 00126 if (_defined && box._defined) 00127 { 00128 _min.vmax(box._min); 00129 _max.vmin(box._max); 00130 00131 if 00132 ( 00133 _min.x()>_max.x() || 00134 _min.y()>_max.y() || 00135 _min.z()>_max.z() 00136 ) 00137 _defined = false; 00138 } 00139 else 00140 _defined = false; 00141 00142 return *this; 00143 } 00144 00145 bool 00146 BoundingBox::operator==(const BoundingBox &box) const 00147 { 00148 if (!_defined && !box._defined) 00149 return true; 00150 00151 if (_defined && box._defined) 00152 return _min==box._min && _max==box._max; 00153 else 00154 return false; 00155 } 00156 00157 bool 00158 BoundingBox::inside(const Vector &pos) const 00159 { 00160 if (pos.x()<_min.x() || pos.x()>_max.x()) return false; 00161 if (pos.y()<_min.y() || pos.y()>_max.y()) return false; 00162 if (pos.z()<_min.z() || pos.z()>_max.z()) return false; 00163 00164 return true; 00165 } 00166 00167 bool 00168 BoundingBox::intersects(const BoundingBox &box) const 00169 { 00170 if (!_defined || !box._defined) 00171 return false; 00172 00173 if (_min.x() > box._max.x()) return false; 00174 if (_min.y() > box._max.y()) return false; 00175 if (_min.z() > box._max.z()) return false; 00176 00177 if (_max.x() < box._min.x()) return false; 00178 if (_max.y() < box._min.y()) return false; 00179 if (_max.z() < box._min.z()) return false; 00180 00181 return true; 00182 } 00183 00184 bool 00185 BoundingBox::project(const Matrix &model,const Matrix &proj,const GltViewport &view) 00186 { 00187 bool ok = true; 00188 00189 vector<Vector> pnt; 00190 points(pnt); 00191 00192 reset(); 00193 for (int j=0; j<pnt.size(); j++) 00194 { 00195 ok &= pnt[j].project(model,proj,view); 00196 operator+=(pnt[j]); 00197 } 00198 00199 return ok; 00200 } 00201 00202 ostream & 00203 operator<<(ostream &os, const BoundingBox &b) 00204 { 00205 os << b.min() << " - " << b.max(); 00206 return os; 00207 } 00208 00209 BoundingBox sum(const BoundingBox &a,const BoundingBox &b) 00210 { 00211 BoundingBox tmp(a); 00212 tmp += b; 00213 return tmp; 00214 } 00215 00216 BoundingBox intersection(const BoundingBox &a,const BoundingBox &b) 00217 { 00218 BoundingBox tmp(a); 00219 tmp *= b; 00220 return tmp; 00221 } 00222