00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00025 #include "glc_boundingbox.h"
00026 #include "maths/glc_matrix4x4.h"
00027
00028 quint32 GLC_BoundingBox::m_ChunkId= 0xA707;
00029
00031
00033
00034 GLC_BoundingBox::GLC_BoundingBox()
00035 : m_Lower(0, 0, 0)
00036 , m_Upper(0, 0, 0)
00037 , m_IsEmpty(true)
00038 {
00039
00040 }
00041
00042 GLC_BoundingBox::GLC_BoundingBox(const GLC_BoundingBox& boundingBox)
00043 : m_Lower(boundingBox.m_Lower)
00044 , m_Upper(boundingBox.m_Upper)
00045 , m_IsEmpty(boundingBox.m_IsEmpty)
00046 {
00047 }
00048
00049 GLC_BoundingBox::GLC_BoundingBox(const GLC_Point3d& lower, const GLC_Point3d& upper)
00050 : m_Lower(lower)
00051 , m_Upper(upper)
00052 , m_IsEmpty(false)
00053 {
00054
00055 }
00056
00058
00060
00061 quint32 GLC_BoundingBox::chunckID()
00062 {
00063 return m_ChunkId;
00064 }
00065
00066 bool GLC_BoundingBox::intersect(const GLC_Point3d& point) const
00067 {
00068 if (!m_IsEmpty)
00069 {
00070 bool result= (point.x() < m_Upper.x()) && (point.y() < m_Upper.y())
00071 && (point.z() < m_Upper.z()) && (point.x() > m_Lower.x())
00072 && (point.y() > m_Lower.y()) && (point.z() > m_Lower.z());
00073
00074 return result;
00075 }
00076 else
00077 {
00078 return false;
00079 }
00080 }
00081
00082 bool GLC_BoundingBox::intersectBoundingSphere(const GLC_Point3d& point) const
00083 {
00084 const double distance= (center() - point).length();
00085 return distance < boundingSphereRadius();
00086 }
00087
00088 bool GLC_BoundingBox::intersectBoundingSphere(const GLC_BoundingBox& boundingSphere) const
00089 {
00090 const double distance= (center() - boundingSphere.center()).length();
00091 return distance < (boundingSphereRadius() + boundingSphere.boundingSphereRadius());
00092 }
00093
00095
00097
00098 GLC_BoundingBox& GLC_BoundingBox::combine(const GLC_Point3d& point)
00099 {
00100 if (m_IsEmpty)
00101 {
00102 m_Lower= point;
00103 m_Upper= point;
00104 m_IsEmpty= false;
00105 }
00106 else
00107 {
00108 double lowerX= qMin(point.x(), m_Lower.x());
00109 double lowerY= qMin(point.y(), m_Lower.y());
00110 double lowerZ= qMin(point.z(), m_Lower.z());
00111 m_Lower.setVect(lowerX, lowerY, lowerZ);
00112
00113 double upperX= qMax(point.x(), m_Upper.x());
00114 double upperY= qMax(point.y(), m_Upper.y());
00115 double upperZ= qMax(point.z(), m_Upper.z());
00116 m_Upper.setVect(upperX, upperY, upperZ);
00117 }
00118 return *this;
00119 }
00120
00121 GLC_BoundingBox& GLC_BoundingBox::combine(const GLC_Point3df& pointf)
00122 {
00123 GLC_Point3d point(pointf);
00124 if (m_IsEmpty)
00125 {
00126 m_Lower= point;
00127 m_Upper= point;
00128 m_IsEmpty= false;
00129 }
00130 else
00131 {
00132 double lowerX= qMin(point.x(), m_Lower.x());
00133 double lowerY= qMin(point.y(), m_Lower.y());
00134 double lowerZ= qMin(point.z(), m_Lower.z());
00135 m_Lower.setVect(lowerX, lowerY, lowerZ);
00136
00137 double upperX= qMax(point.x(), m_Upper.x());
00138 double upperY= qMax(point.y(), m_Upper.y());
00139 double upperZ= qMax(point.z(), m_Upper.z());
00140 m_Upper.setVect(upperX, upperY, upperZ);
00141 }
00142 return *this;
00143 }
00144
00145 GLC_BoundingBox& GLC_BoundingBox::combine(const GLC_BoundingBox& box)
00146 {
00147 if (m_IsEmpty && !box.m_IsEmpty)
00148 {
00149 m_Lower= box.m_Lower;
00150 m_Upper= box.m_Upper;
00151 m_IsEmpty= box.m_IsEmpty;
00152 }
00153 else if (! box.m_IsEmpty)
00154 {
00155 double lowerX= qMin(box.m_Lower.x(), m_Lower.x());
00156 double lowerY= qMin(box.m_Lower.y(), m_Lower.y());
00157 double lowerZ= qMin(box.m_Lower.z(), m_Lower.z());
00158 m_Lower.setVect(lowerX, lowerY, lowerZ);
00159
00160 double upperX= qMax(box.m_Upper.x(), m_Upper.x());
00161 double upperY= qMax(box.m_Upper.y(), m_Upper.y());
00162 double upperZ= qMax(box.m_Upper.z(), m_Upper.z());
00163 m_Upper.setVect(upperX, upperY, upperZ);
00164 }
00165
00166 return *this;
00167 }
00168
00169 GLC_BoundingBox& GLC_BoundingBox::transform(const GLC_Matrix4x4& matrix)
00170 {
00171 if (!m_IsEmpty)
00172 {
00173
00174 GLC_Point3d corner1(m_Lower);
00175 GLC_Point3d corner7(m_Upper);
00176 GLC_Point3d corner2(corner7.x(), corner1.y(), corner1.z());
00177 GLC_Point3d corner3(corner7.x(), corner7.y(), corner1.z());
00178 GLC_Point3d corner4(corner1.x(), corner7.y(), corner1.z());
00179 GLC_Point3d corner5(corner1.x(), corner1.y(), corner7.z());
00180 GLC_Point3d corner6(corner7.x(), corner1.y(), corner7.z());
00181 GLC_Point3d corner8(corner1.x(), corner7.y(), corner7.z());
00182
00183 corner1 = (matrix * corner1);
00184 corner2 = (matrix * corner2);
00185 corner3 = (matrix * corner3);
00186 corner4 = (matrix * corner4);
00187 corner5 = (matrix * corner5);
00188 corner6 = (matrix * corner6);
00189 corner7 = (matrix * corner7);
00190 corner8 = (matrix * corner8);
00191
00192
00193 GLC_BoundingBox boundingBox;
00194 boundingBox.combine(corner1);
00195 boundingBox.combine(corner2);
00196 boundingBox.combine(corner3);
00197 boundingBox.combine(corner4);
00198 boundingBox.combine(corner5);
00199 boundingBox.combine(corner6);
00200 boundingBox.combine(corner7);
00201 boundingBox.combine(corner8);
00202
00203 m_Lower= boundingBox.m_Lower;
00204 m_Upper= boundingBox.m_Upper;
00205 }
00206
00207 return *this;
00208 }
00209
00210 QDataStream &operator<<(QDataStream &stream, const GLC_BoundingBox &bBox)
00211 {
00212 quint32 chunckId= GLC_BoundingBox::m_ChunkId;
00213 stream << chunckId;
00214
00215 stream << bBox.m_IsEmpty;
00216 stream << bBox.m_Lower;
00217 stream << bBox.m_Upper;
00218
00219 return stream;
00220 }
00221
00222 QDataStream &operator>>(QDataStream &stream, GLC_BoundingBox &bBox)
00223 {
00224 quint32 chunckId;
00225 stream >> chunckId;
00226 Q_ASSERT(chunckId == GLC_BoundingBox::m_ChunkId);
00227
00228 stream >> bBox.m_IsEmpty;
00229 stream >> bBox.m_Lower;
00230 stream >> bBox.m_Upper;
00231
00232 return stream;
00233 }
00234