wall.cpp

00001 
00002 /* Copyright (c) 2006-2009, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "wall.h"
00019 
00020 #include "projection.h"
00021 #include "viewport.h"
00022 
00023 #include <eq/base/log.h>
00024 
00025 using namespace eq::base;
00026 using namespace std;
00027 
00028 #define DEG2RAD( angle ) ((angle) * static_cast<float>(M_PI) / 180.f)
00029 
00030 namespace eq
00031 {
00032 Wall::Wall()
00033         : bottomLeft( -.8f, -.5f, -1.f )
00034         , bottomRight( .8f, -.5f, -1.f )
00035         , topLeft(    -.8f,  .5f, -1.f )
00036         , type( TYPE_FIXED )
00037 {
00038 }
00039 
00040 void Wall::resizeHorizontal( const float ratio )
00041 {
00042     if( ratio == 1.f || ratio < 0.f )
00043         return;
00044 
00045     const Vector3f u_2   = (bottomRight - bottomLeft) * .5f;
00046     const Vector3f delta = u_2 * (ratio - 1.f);
00047     bottomLeft  -= delta;
00048     bottomRight += delta;
00049     topLeft     -= delta;
00050 }
00051 
00052 void Wall::resizeVertical( const float ratio )
00053 {
00054     if( ratio == 1.f || ratio < 0.f )
00055         return;
00056 
00057     const Vector3f v_2   = (topLeft - bottomLeft) * .5f;
00058     const Vector3f delta = v_2 * (ratio - 1.f);
00059     bottomLeft  -= delta;
00060     bottomRight -= delta;
00061     topLeft     += delta;
00062 }
00063 
00064 void Wall::resizeLeft( const float ratio )
00065 {
00066     if( ratio == 1.f || ratio < 0.f )
00067         return;
00068 
00069     const Vector3f u   = bottomRight - bottomLeft;
00070     const Vector3f delta = u * (ratio - 1.f);
00071     bottomLeft  -= delta;
00072     topLeft     -= delta;
00073 }
00074 
00075 void Wall::resizeRight( const float ratio )
00076 {
00077     if( ratio == 1.f || ratio < 0.f )
00078         return;
00079 
00080     const Vector3f u   = bottomRight - bottomLeft;
00081     const Vector3f delta = u * (ratio - 1.f);
00082     bottomRight += delta;
00083 }
00084 
00085 void Wall::resizeTop( const float ratio )
00086 {
00087     if( ratio == 1.f || ratio < 0.f )
00088         return;
00089 
00090     const Vector3f v = topLeft - bottomLeft;
00091     const Vector3f delta = v * (ratio - 1.f);
00092     topLeft     += delta;
00093 }
00094 
00095 void Wall::resizeBottom( const float ratio )
00096 {
00097     if( ratio == 1.f || ratio < 0.f )
00098         return;
00099 
00100     const Vector3f v = topLeft - bottomLeft;
00101     const Vector3f delta = v * (ratio - 1.f);
00102     bottomLeft  -= delta;
00103     bottomRight -= delta;
00104 }
00105 
00106 void Wall::apply( const Viewport& viewport)
00107 {
00108     Vector3f u = bottomRight - bottomLeft;
00109     Vector3f v = topLeft - bottomLeft;
00110     
00111     bottomLeft  = bottomLeft + u * viewport.x + v * viewport.y;
00112     bottomRight = bottomLeft + u * viewport.w;
00113     topLeft     = bottomLeft + v * viewport.h;  
00114     
00115 }
00116 
00117 Wall& Wall::operator = ( const Projection& projection )
00118 {
00119     const float width  = fabs( projection.distance * 2.0 * 
00120                                tanf(DEG2RAD( .5f * projection.fov[0] )));
00121     const float height = fabs( projection.distance * 2.0 *
00122                                tanf(DEG2RAD( .5f * projection.fov[1] )));
00123    
00124     bottomLeft[0]  = -width * 0.5f;
00125     bottomLeft[1]  = -height * 0.5f;
00126     bottomLeft[2]  = 0;
00127     bottomRight[0] = width * 0.5f;
00128     bottomRight[1] = -height * 0.5f;
00129     bottomRight[2] = 0;
00130     topLeft[0]     = -width * 0.5f;
00131     topLeft[1]     = height * 0.5f;
00132     topLeft[2]     = 0;
00133 
00134     const float cosP       = cos(DEG2RAD( projection.hpr[1]));
00135     const float sinP       = sin(DEG2RAD( projection.hpr[1]));
00136     const float cosH       = cos(DEG2RAD( projection.hpr[0]));
00137     const float sinH       = sin(DEG2RAD( projection.hpr[0]));
00138     const float cosR       = cos(DEG2RAD( projection.hpr[2]));
00139     const float sinR       = sin(DEG2RAD( projection.hpr[2]));
00140 
00141     Matrix3f  mat ;
00142     const float cosPsinH      =   cosP * sinH;
00143     const float sinPsinH      =   sinP * sinH;
00144 
00145     mat.array[0]  =   cosH * cosR;
00146     mat.array[1]  =  -cosH * sinR;
00147     mat.array[2]  =  -sinH;
00148     mat.array[3]  = -sinPsinH * cosR + cosP * sinR;
00149     mat.array[4]  =  sinPsinH * sinR + cosP * cosR;
00150     mat.array[5]  =  -sinP * cosH;
00151     mat.array[6]  =  cosPsinH * cosR + sinP * sinR;
00152     mat.array[7]  = -cosPsinH * sinR + sinP * cosR;
00153     mat.array[8] =   cosP * cosH;
00154 
00155     bottomLeft  = mat * bottomLeft;
00156     bottomRight = mat * bottomRight;
00157     topLeft     = mat * topLeft;
00158     
00159     Vector3f w( mat.array[6], mat.array[7], mat.array[8] );
00160     
00161     bottomLeft  = bottomLeft  + projection.origin  + w *  projection.distance;
00162     bottomRight = bottomRight + projection.origin  + w *  projection.distance;
00163     topLeft     = topLeft     + projection.origin  + w *  projection.distance;
00164 
00165     return *this;
00166 }    
00167 
00168 bool Wall::operator == ( const Wall& rhs ) const
00169 {
00170     return ( bottomLeft.equals( rhs.bottomLeft, 0.0001f )   &&
00171              bottomRight.equals( rhs.bottomRight, 0.0001f ) &&
00172              topLeft.equals( rhs.topLeft, 0.0001f ));
00173 }
00174 
00175 bool Wall::operator != ( const Wall& rhs ) const
00176 {
00177     return ( !bottomLeft.equals( rhs.bottomLeft, 0.0001f )   ||
00178              !bottomRight.equals( rhs.bottomRight, 0.0001f ) ||
00179              !topLeft.equals( rhs.topLeft, 0.0001f ));
00180 }
00181 
00182 ostream& operator << ( ostream& os, const Wall& wall )
00183 {
00184     os << "wall" << endl;
00185     os << "{" << endl << indent;
00186     os << "bottom_left  " << wall.bottomLeft << endl;
00187     os << "bottom_right " << wall.bottomRight << endl;
00188     os << "top_left     " << wall.topLeft << endl;
00189     os << exdent << "}" << endl;
00190     return os;
00191 }
00192 
00193 }
Generated on Mon Aug 10 18:58:41 2009 for Equalizer 0.9 by  doxygen 1.5.8