# 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  

bounding_box.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000, 2001 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 "stdsound.h"
00027 
00028 #include "bounding_box.h"
00029 #include "nel/misc/plane.h"
00030 
00031 using namespace NLMISC;
00032 
00033 namespace NLSOUND {
00034 
00035 
00036 /*
00037  * Constructor
00038  */
00039 CBoundingBox::CBoundingBox() : _Rx(0.0f), _Ry(0.0f), _Rz(0.0f), _Center(CVector::Null)
00040 {
00041 }
00042 
00043 
00044 /*
00045  * Does the box include a point ?
00046  */
00047 bool                    CBoundingBox::include( const CVector& pos ) const
00048 {
00049         if ( pos.x < _Center.x - _Rx ) return false;
00050         if ( pos.x > _Center.x + _Rx ) return false;
00051         if ( pos.y < _Center.y - _Ry ) return false;
00052         if ( pos.y > _Center.y + _Ry ) return false;
00053         if ( pos.z < _Center.z - _Rz ) return false;
00054         if ( pos.z > _Center.z + _Rz ) return false;
00055         return true;
00056 }
00057 
00058 
00059 /*
00060  * Return the environment size
00061  */
00062 float                   CBoundingBox::getDiameter() const
00063 {
00064         // Set it to the average of the three widths (?)
00065         return (_Rx+_Ry+_Rz) / 1.5f;
00066 }
00067 
00068 
00069 /*
00070  * Return the radius at the intersection of the shape and the line between the specified position and the center of the shape
00071  */
00072 float                   CBoundingBox::getRadiusAtIntersect( const NLMISC::CVector& pos ) const
00073 {
00074         return 0.0f;
00075 }
00076 
00077 
00078 /*
00079  *
00080  */
00081 CVector                 CBoundingBox::getIntersectWithLine( const NLMISC::CVector& c, const NLMISC::CVector& p ) const
00082 {
00083         // 1. Build 6 planes made up of the box
00084         CPlane pl[6];
00085         CVector ppos = _Center;
00086         ppos.x = _Center.x + _Rx;
00087         pl[0].make( CVector::I, ppos );
00088         ppos.x = _Center.x - _Rx;
00089         pl[1].make( -CVector::I, ppos );
00090         ppos.x = _Center.x;
00091         ppos.y = _Center.y + _Ry;
00092         pl[2].make( CVector::J, ppos );
00093         ppos.y = _Center.y - _Ry;
00094         pl[3].make( -CVector::J, ppos );
00095         ppos.y = _Center.y;
00096         ppos.z = _Center.z + _Rz;
00097         pl[4].make( CVector::K, ppos );
00098         ppos.z = _Center.z - _Rz;
00099         pl[5].make( -CVector::K, ppos );
00100 
00101         // 2. Maximize the length of the segment to be greater than the size of the box (>=sqrt(3))
00102         CVector v = (p-c).normed();
00103         v *= std::max( std::max( _Rx, _Ry ), _Rz ) * 10.0f;
00104         CVector pfar = c + v;
00105 
00106         // 3. Clip
00107         CVector center = c;
00108         uint i;
00109         for ( i=0; i!=6; ++i )
00110         {
00111                 pl[i].clipSegmentBack( center, pfar );
00112         }
00113 
00114         return pfar;
00115 }
00116 
00117 
00118 /* Return the ratio of a point between this shape and another inner shape.
00119  * The point must be included in this shape (the outer one) and not
00120  * in the inner shape.
00121  * If the point is near this shape, the ratio is near 0.
00122  * If the point is near the inner shape, the ratio is near 1.
00123  */
00124 float                   CBoundingBox::getRatio( const NLMISC::CVector& pos, IBoundingShape *inner ) const
00125 {
00126         /* TEMP: works only with 2 boxes
00127          *
00128          */
00129 
00130         // Let C be the center of the inner shape, P the position of the point
00131 
00132         // 1. Get the intersection A between [CP] and the inner shape
00133         CVector posa = inner->getIntersectWithLine( inner->getCenter(), pos );
00134 
00135         // 2. Get the intersection B between (CP) and the outer shape (this)
00136         CVector posb = getIntersectWithLine( inner->getCenter(), pos );
00137 
00138         // 3. Compute PB / AB
00139         float ab = (posa-posb).norm();
00140         if ( ab != 0 )
00141         {
00142                 float pb = (pos-posb).norm();
00143                 return pb / ab;
00144         }
00145         else
00146         {
00147                 return 1.0f;
00148         }
00149 }
00150 
00151 
00152 /*
00153  * Return the corners (EDIT)
00154  */
00155 void                    CBoundingBox::getCorners( NLMISC::CVector& c1, NLMISC::CVector& c2 )
00156 {
00157         c1.x = _Center.x - _Rx;
00158         c1.y = _Center.y - _Ry;
00159         c1.z = _Center.z - _Rz;
00160         c2.x = _Center.x + _Rx;
00161         c2.y = _Center.y + _Ry;
00162         c2.z = _Center.z + _Rz;
00163 }
00164 
00165 /*
00166  * Set the corners (the corners must be ordered: 1 has smaller x, y, z) (EDIT)
00167  */
00168 void                    CBoundingBox::setCorners( const NLMISC::CVector& c1, const NLMISC::CVector& c2 )
00169 {
00170         _Center.x = (c1.x+c2.x)/2.0f;
00171         _Center.y = (c1.y+c2.y)/2.0f;
00172         _Center.z = (c1.z+c2.z)/2.0f;
00173         _Rx = (c2.x-c1.x)/2.0f;
00174         _Ry = (c2.y-c1.y)/2.0f;
00175         _Rz = (c2.z-c1.z)/2.0f;
00176 }
00177 
00178 
00179 } // NLSOUND