frustumData.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 "frustumData.h"
00019 
00020 #include <eq/client/projection.h>
00021 #include <eq/client/wall.h>
00022 
00023 #define DEG2RAD( angle ) ( (angle) * static_cast<float>(M_PI) / 180.f )
00024 
00025 namespace eq
00026 {
00027 namespace server
00028 {
00029 
00030 FrustumData::FrustumData()
00031         : _width(0.f)
00032         , _height(0.f)
00033         , _type( Wall::TYPE_FIXED )
00034 {
00035 }
00036 
00037 void FrustumData::applyWall( const eq::Wall& wall )
00038 {
00039     Vector3f u = wall.bottomRight - wall.bottomLeft;
00040     Vector3f v = wall.topLeft - wall.bottomLeft;
00041     Vector3f w( u[1]*v[2] - u[2]*v[1],
00042                       u[2]*v[0] - u[0]*v[2],
00043                       u[0]*v[1] - u[1]*v[0] );
00044 
00045     _type   = wall.type;
00046     _width  = u.normalize();
00047     _height = v.normalize();
00048     w.normalize();
00049 
00050     _xfm.array[0]  = u[0];
00051     _xfm.array[1]  = v[0];
00052     _xfm.array[2]  = w[0];
00053     _xfm.array[3]  = 0.;
00054              
00055     _xfm.array[4]  = u[1];
00056     _xfm.array[5]  = v[1];
00057     _xfm.array[6]  = w[1];
00058     _xfm.array[7]  = 0.;
00059              
00060     _xfm.array[8]  = u[2];
00061     _xfm.array[9]  = v[2];
00062     _xfm.array[10] = w[2];
00063     _xfm.array[11] = 0.;
00064 
00065     const Vector3f center((wall.bottomRight[0] + wall.topLeft[0]) * 0.5f,
00066                                 (wall.bottomRight[1] + wall.topLeft[1]) * 0.5f,
00067                                 (wall.bottomRight[2] + wall.topLeft[2]) * 0.5f);
00068 
00069     _xfm.array[12] = -(u[0]*center[0] + u[1]*center[1] + u[2]*center[2]);
00070     _xfm.array[13] = -(v[0]*center[0] + v[1]*center[1] + v[2]*center[2]);
00071     _xfm.array[14] = -(w[0]*center[0] + w[1]*center[1] + w[2]*center[2]);
00072     _xfm.array[15] = 1.;
00073 }
00074 
00075 void FrustumData::applyProjection( const eq::Projection& projection )
00076 {
00077     const float cosH = cosf( DEG2RAD( projection.hpr[0] ));
00078     const float sinH = sinf( DEG2RAD( projection.hpr[0] ));
00079     const float cosP = cosf( DEG2RAD( projection.hpr[1] ));
00080     const float sinP = sinf( DEG2RAD( projection.hpr[1] ));
00081     const float cosR = cosf( DEG2RAD( projection.hpr[2] ));
00082     const float sinR = sinf( DEG2RAD( projection.hpr[2] ));
00083 
00084     // HPR Matrix = -roll[z-axis] * -pitch[x-axis] * -head[y-axis]
00085     const float rot[9] =
00086         {
00087             sinR*sinP*sinH + cosR*cosH,  cosR*sinP*sinH - sinR*cosH,  cosP*sinH,
00088             cosP*sinR,                   cosP*cosR,                  -sinP,
00089             sinR*sinP*cosH - cosR*sinH,  cosR*sinP*cosH + sinR*sinH,  cosP*cosH 
00090         };
00091 
00092     // translation = HPR x -origin
00093     const Vector3f& origin   = projection.origin;
00094     const float           distance = projection.distance;
00095     const Vector3f  trans(
00096                -( rot[0]*origin[0] + rot[3]*origin[1] + rot[6]*origin[2] ),
00097                -( rot[1]*origin[0] + rot[4]*origin[1] + rot[7]*origin[2] ),
00098                -( rot[2]*origin[0] + rot[5]*origin[1] + rot[8]*origin[2] ));
00099 
00100     _xfm.array[0]  = rot[0];
00101     _xfm.array[1]  = rot[1];
00102     _xfm.array[2]  = rot[2];
00103     _xfm.array[3]  = 0.;
00104 
00105     _xfm.array[4]  = rot[3];
00106     _xfm.array[5]  = rot[4];
00107     _xfm.array[6]  = rot[5];
00108     _xfm.array[7]  = 0.;
00109             
00110     _xfm.array[8]  = rot[6];                
00111     _xfm.array[9]  = rot[7];
00112     _xfm.array[10] = rot[8];
00113     _xfm.array[11] = 0.;
00114 
00115     _xfm.array[12] = trans[0];
00116     _xfm.array[13] = trans[1];
00117     _xfm.array[14] = trans[2] + distance;
00118     _xfm.array[15] = 1.;
00119 
00120     _width  = distance * 2.f * tanf(DEG2RAD( .5f * projection.fov[0] ));
00121     _height = distance * 2.f * tanf(DEG2RAD( .5f * projection.fov[1] ));
00122     _type   = Wall::TYPE_FIXED;
00123 }
00124  
00125 std::ostream& operator << ( std::ostream& os, const FrustumData& frustumData )
00126 {
00127     os << "size: " << frustumData.getWidth() << "x" << frustumData.getHeight()
00128        << " xfm: " << frustumData.getTransform() << std::endl;
00129     return os;
00130 }
00131 
00132 }
00133 }
Generated on Mon Aug 10 18:58:33 2009 for Equalizer 0.9 by  doxygen 1.5.8