# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

aabbox.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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         // The bbox is front of the plane if only one of his vertex is in front.
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         // The bbox is back of the plane if only one of his vertex is in back.
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         // Trivial test.
00124         if(include(a) || include(b) || include(c))
00125                 return true;
00126         // Else, must test if the polygon intersect the pyamid.
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         // don't test if intersect or not.
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         // TODO : optimize this a bit if possible...
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         // Assume normalized planes.
00249 
00250         // if( SpherMax OUT )   return false.
00251         float   d= p*Center;
00252         if(d<-RadiusMax)
00253                 return false;
00254         // if( SphereMin IN )   return true;
00255         if(d>-RadiusMin)
00256                 return true;
00257 
00258         // else, standard clip box.
00259         return CAABBox::clipFront(p);
00260 }
00261 
00262 
00263 // ***************************************************************************
00264 bool    CAABBoxExt::clipBack(const CPlane &p) const
00265 {
00266         // Assume normalized planes.
00267 
00268         // if( SpherMax OUT )   return false.
00269         float   d= p*Center;
00270         if(d>RadiusMax)
00271                 return false;
00272         // if( SphereMin IN )   return true;
00273         if(d<RadiusMin)
00274                 return true;
00275 
00276         // else, standard clip box.
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 } // NLMISC