00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdmisc.h"
00027
00028 #include "nel/misc/aabbox.h"
00029 #include "nel/misc/polygon.h"
00030 #include "nel/misc/bsphere.h"
00031 #include "nel/misc/matrix.h"
00032
00033
00034
00035 namespace NLMISC {
00036
00037
00038
00039 bool CAABBox::clipFront(const CPlane &p) const
00040 {
00041 CVector hswap;
00042
00043
00044 if(p*(Center + HalfSize) > 0) return true;
00045 if(p*(Center - HalfSize) > 0) return true;
00046 hswap.set(-HalfSize.x, HalfSize.y, HalfSize.z);
00047 if(p*(Center + hswap) > 0) return true;
00048 if(p*(Center - hswap) > 0) return true;
00049 hswap.set(HalfSize.x, -HalfSize.y, HalfSize.z);
00050 if(p*(Center + hswap) > 0) return true;
00051 if(p*(Center - hswap) > 0) return true;
00052 hswap.set(HalfSize.x, HalfSize.y, -HalfSize.z);
00053 if(p*(Center + hswap) > 0) return true;
00054 if(p*(Center - hswap) > 0) return true;
00055
00056 return false;
00057 }
00058
00059 bool CAABBox::clipBack(const CPlane &p) const
00060 {
00061 CVector hswap;
00062
00063
00064 if(p*(Center + HalfSize) < 0) return true;
00065 if(p*(Center - HalfSize) < 0) return true;
00066 hswap.set(-HalfSize.x, HalfSize.y, HalfSize.z);
00067 if(p*(Center + hswap) < 0) return true;
00068 if(p*(Center - hswap) < 0) return true;
00069 hswap.set(HalfSize.x, -HalfSize.y, HalfSize.z);
00070 if(p*(Center + hswap) < 0) return true;
00071 if(p*(Center - hswap) < 0) return true;
00072 hswap.set(HalfSize.x, HalfSize.y, -HalfSize.z);
00073 if(p*(Center + hswap) < 0) return true;
00074 if(p*(Center - hswap) < 0) return true;
00075
00076 return false;
00077 }
00078
00079
00080
00081 bool CAABBox::include(const CVector &a) const
00082 {
00083 if(Center.x+HalfSize.x<a.x) return false;
00084 if(Center.x-HalfSize.x>a.x) return false;
00085 if(Center.y+HalfSize.y<a.y) return false;
00086 if(Center.y-HalfSize.y>a.y) return false;
00087 if(Center.z+HalfSize.z<a.z) return false;
00088 if(Center.z-HalfSize.z>a.z) return false;
00089 return true;
00090 }
00091
00092
00093
00094 bool CAABBox::include(const CAABBox &box) const
00095 {
00096 if(Center.x+HalfSize.x < box.Center.x+box.HalfSize.x) return false;
00097 if(Center.x-HalfSize.x > box.Center.x-box.HalfSize.x) return false;
00098 if(Center.y+HalfSize.y < box.Center.y+box.HalfSize.y) return false;
00099 if(Center.y-HalfSize.y > box.Center.y-box.HalfSize.y) return false;
00100 if(Center.z+HalfSize.z < box.Center.z+box.HalfSize.z) return false;
00101 if(Center.z-HalfSize.z > box.Center.z-box.HalfSize.z) return false;
00102 return true;
00103 }
00104
00105
00106
00107 bool CAABBox::intersect(const CAABBox &box) const
00108 {
00109 CVector mina = getMin(), maxa = getMax(),
00110 minb = box.getMin(), maxb = box.getMax();
00111
00112 return ! ( mina.x > maxb.x ||
00113 mina.y > maxb.y ||
00114 mina.z > maxb.z ||
00115 minb.x > maxa.x ||
00116 minb.y > maxa.y ||
00117 minb.z > maxa.z);
00118 }
00119
00120
00121 bool CAABBox::intersect(const CVector &a, const CVector &b, const CVector &c) const
00122 {
00123
00124 if(include(a) || include(b) || include(c))
00125 return true;
00126
00127 CPlane planes[6];
00128 makePyramid(planes);
00129 CPolygon poly(a,b,c);
00130 poly.clip(planes, 6);
00131 if(poly.getNumVertices()==0)
00132 return false;
00133 return true;
00134 }
00135
00136
00137 bool CAABBox::intersect(const CBSphere &s) const
00138 {
00139 if (Center.x + HalfSize.x < s.Center.x - s.Radius) return false;
00140 if (Center.y + HalfSize.y < s.Center.y - s.Radius) return false;
00141 if (Center.z + HalfSize.z < s.Center.z - s.Radius) return false;
00142
00143 if (Center.x - HalfSize.x > s.Center.x + s.Radius) return false;
00144 if (Center.y - HalfSize.y > s.Center.y + s.Radius) return false;
00145 if (Center.z - HalfSize.z > s.Center.z + s.Radius) return false;
00146
00147 return true;
00148 }
00149
00150
00151
00152
00153 void CAABBox::makePyramid(CPlane planes[6]) const
00154 {
00155 planes[0].make(CVector(-1,0,0), Center-HalfSize);
00156 planes[1].make(CVector(+1,0,0), Center+HalfSize);
00157 planes[2].make(CVector(0,-1,0), Center-HalfSize);
00158 planes[3].make(CVector(0,+1,0), Center+HalfSize);
00159 planes[4].make(CVector(0,0,-1), Center-HalfSize);
00160 planes[5].make(CVector(0,0,+1), Center+HalfSize);
00161 }
00162
00163
00164
00165 void CAABBox::serial(NLMISC::IStream &f)
00166 {
00167 (void)f.serialVersion(0);
00168 f.serial(Center);
00169 f.serial(HalfSize);
00170 }
00171
00172
00173
00174 void CAABBox::extend(const CVector &v)
00175 {
00176 CVector bmin= getMin(), bmax= getMax();
00177
00178 bmin.minof(bmin, v);
00179 bmax.maxof(bmax, v);
00180 setMinMax(bmin, bmax);
00181 }
00182
00183
00184
00190 CAABBox CAABBox::computeAABBoxUnion(const CAABBox &b1, const CAABBox &b2)
00191 {
00192 CAABBox result;
00193 CVector min, max;
00194 CVector min1 = b1.getMin()
00195 ,max1 = b1.getMax()
00196 ,min2 = b2.getMin()
00197 ,max2 = b2.getMax();
00198 max.maxof(max1, max2);
00199 min.minof(min1, min2);
00200 result.setMinMax(min, max);
00201 return result;
00202 }
00203
00204
00205
00206 void CAABBox::computeIntersection(const CAABBox &b1, const CAABBox &b2)
00207 {
00208 CVector min1 = b1.getMin(), max1 = b1.getMax(),
00209 min2 = b2.getMin(), max2 = b2.getMax();
00210 CVector minr, maxr;
00211
00212
00213 maxr.minof(max1, max2);
00214 minr.maxof(min1, min2);
00215
00216 setMinMax(minr, maxr);
00217 }
00218
00219
00220
00221 CAABBox CAABBox::transformAABBox(const CMatrix &mat, const CAABBox &box)
00222 {
00223
00224 CAABBox result;
00225
00226 const CVector &m = mat * box.getCenter();
00227 const CVector &h = mat.mulVector(box.getHalfSize());
00228 CVector tmp, min, max;
00229 min = max = m;
00230 tmp = m + CVector(h.x, h.y, -h.z); min.minof(min, tmp); max.maxof(max, tmp);
00231 tmp = m + CVector(h.x, -h.y, h.z); min.minof(min, tmp); max.maxof(max, tmp);
00232 tmp = m + CVector(h.x, -h.y, -h.z); min.minof(min, tmp); max.maxof(max, tmp);
00233 tmp = m + CVector(-h.x, h.y, h.z); min.minof(min, tmp); max.maxof(max, tmp);
00234 tmp = m + CVector(-h.x, h.y, -h.z); min.minof(min, tmp); max.maxof(max, tmp);
00235 tmp = m + CVector(-h.x, -h.y, h.z); min.minof(min, tmp); max.maxof(max, tmp);
00236 tmp = m + CVector(-h.x, -h.y, -h.z); min.minof(min, tmp); max.maxof(max, tmp);
00237
00238 result.setMinMax(min, max);
00239
00240 return result;
00241 }
00242
00243
00244
00245
00246 bool CAABBoxExt::clipFront(const CPlane &p) const
00247 {
00248
00249
00250
00251 float d= p*Center;
00252 if(d<-RadiusMax)
00253 return false;
00254
00255 if(d>-RadiusMin)
00256 return true;
00257
00258
00259 return CAABBox::clipFront(p);
00260 }
00261
00262
00263
00264 bool CAABBoxExt::clipBack(const CPlane &p) const
00265 {
00266
00267
00268
00269 float d= p*Center;
00270 if(d>RadiusMax)
00271 return false;
00272
00273 if(d<RadiusMin)
00274 return true;
00275
00276
00277 return CAABBox::clipBack(p);
00278 }
00279
00280
00281
00282 void CAABBoxExt::serial(NLMISC::IStream &f)
00283 {
00284 CAABBox::serial(f);
00285 if(f.isReading())
00286 updateRadius();
00287 }
00288
00289
00290 }