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