LCOV - code coverage report
Current view: top level - eq/fabric - projection.cpp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 60 74 81.1 %
Date: 2014-06-18 Functions: 6 9 66.7 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2007-2011, Stefan Eilemann <eile@equalizergraphics.com> 
       3             :  *
       4             :  * This library is free software; you can redistribute it and/or modify it under
       5             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       6             :  * by the Free Software Foundation.
       7             :  *  
       8             :  * This library is distributed in the hope that it will be useful, but WITHOUT
       9             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      10             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      11             :  * details.
      12             :  * 
      13             :  * You should have received a copy of the GNU Lesser General Public License
      14             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      15             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      16             :  */
      17             : 
      18             : #include "projection.h"
      19             : #include "wall.h"
      20             : 
      21             : #include <lunchbox/log.h>
      22             : 
      23             : #ifndef M_PI
      24             : #  define M_PI 3.14159265358979323846264338327
      25             : #endif
      26             : #define DEG2RAD( angle ) ((angle) * static_cast<float>(M_PI) / 180.f)
      27             : #define RAD2DEG( angle ) ((angle) * 180.f / static_cast<float>(M_PI))
      28             : 
      29             : namespace eq
      30             : {
      31             : namespace fabric
      32             : {
      33        7247 : Projection::Projection()
      34             :         : origin( 0.f, 0.f, 0.f ),
      35             :           distance( 1.f ),
      36             :           fov( 77.3196f, 53.1301f ),
      37        7247 :           hpr( 0.f, 0.f, 0.f )
      38        7247 : {}
      39             : 
      40           0 : void Projection::resizeHorizontal( const float ratio )
      41             : {
      42           0 :     if( ratio == 1.f || ratio < 0.f )
      43           0 :         return;
      44             : 
      45             :     //const float newWidth_2 = ratio * distance * tanf(DEG2RAD( .5f * fov[1] ));
      46             :     //fov[1] = 2.f * atanf( newWidth_2 / distance );
      47             :     // -> distance can be removed:
      48           0 :     fov[0] = RAD2DEG( 2.f * atanf( ratio * tanf( DEG2RAD( .5f * fov[0] ))));
      49             : }
      50             : 
      51           0 : void Projection::resizeVertical( const float ratio )
      52             : {
      53           0 :     if( ratio == 1.f || ratio < 0.f )
      54           0 :         return;
      55             : 
      56             :     // see resizeHorizontal
      57           0 :     fov[1] = RAD2DEG( 2.f * atanf( ratio * tanf( DEG2RAD( .5f * fov[1] ))));
      58             : }
      59             : 
      60         755 : Projection& Projection::operator = ( const Wall& wall )
      61             : {
      62         755 :     Vector3f u = wall.bottomRight - wall.bottomLeft;
      63         755 :     Vector3f v = wall.topLeft - wall.bottomLeft;
      64         755 :     const float width  = u.normalize();
      65         755 :     const float height = v.normalize();
      66             : 
      67         755 :     Vector3f w;
      68         755 :     w.cross( u, v );
      69             : 
      70         755 :     const Vector3f center( (wall.bottomRight[0] + wall.topLeft[0]) * 0.5f,
      71         755 :                            (wall.bottomRight[1] + wall.topLeft[1]) * 0.5f,
      72        2265 :                            (wall.bottomRight[2] + wall.topLeft[2]) * 0.5f );
      73             :     
      74         755 :     if ( distance <= std::numeric_limits< float >::epsilon( ))
      75           0 :         distance = center.length(); 
      76             : 
      77         755 :     Matrix3f  mat;
      78         755 :     mat.array[0] = u[0];
      79         755 :     mat.array[1] = u[1];
      80         755 :     mat.array[2] = u[2];
      81             :              
      82         755 :     mat.array[3] = v[0];
      83         755 :     mat.array[4] = v[1];
      84         755 :     mat.array[5] = v[2];
      85             :              
      86         755 :     mat.array[6] = w[0];
      87         755 :     mat.array[7] = w[1];
      88         755 :     mat.array[8] = w[2];
      89             : 
      90         755 :     fov[0] = RAD2DEG( atanf(0.5f * width / distance  )) * 2.0f;
      91         755 :     fov[1] = RAD2DEG( atanf(0.5f * height / distance )) * 2.0f;
      92             : 
      93         755 :     hpr[0] = -asinf( mat.array[2] );
      94         755 :     const float cosH = cosf(hpr[0]);
      95         755 :     hpr[0] =  RAD2DEG(hpr[0]);
      96             : 
      97         755 :     if( fabs( cosH ) > std::numeric_limits< float >::epsilon( ))      
      98             :     {
      99         738 :         float tr_x      =  mat.array[8] / cosH;     
     100         738 :         float tr_y      = -mat.array[5] / cosH;
     101         738 :         hpr[1]  = RAD2DEG( atan2f( tr_y, tr_x ));
     102             : 
     103         738 :         tr_x      =  mat.array[0] / cosH;          
     104         738 :         tr_y      = -mat.array[1] / cosH;
     105         738 :         hpr[2]  = RAD2DEG( atan2f( tr_y, tr_x ));
     106             :     }
     107             :     else                                  
     108             :     {
     109          17 :         hpr[1]  = 0.f;         
     110             : 
     111          17 :         const float tr_x = mat.array[4];  
     112          17 :         const float tr_y = mat.array[3];
     113             : 
     114          17 :         hpr[2]  = RAD2DEG( atan2f( tr_y, tr_x ));
     115             :     }
     116             :     
     117         755 :     origin = center - w * distance;
     118         755 :     return *this;
     119             : }
     120             : 
     121          15 : bool Projection::operator == ( const Projection& rhs ) const
     122             : {
     123          18 :     return(  origin.equals( rhs.origin, 0.0001f )   &&
     124           6 :            (fabsf( distance - rhs.distance ) < 0.0001f ) &&
     125          21 :            fov.equals( rhs.fov, 0.0001f ) &&
     126          18 :            hpr.equals( rhs.hpr, 0.0001f ));
     127             : }
     128             : 
     129           0 : bool Projection::operator != ( const Projection& rhs ) const
     130             : {
     131           0 :     return ( !origin.equals( rhs.origin, 0.0001f )  ||
     132           0 :             (fabsf(distance - rhs.distance) >= 0.0001f ) ||
     133           0 :             !fov.equals( rhs.fov, 0.0001f ) ||
     134           0 :             !hpr.equals( rhs.hpr, 0.0001f ));
     135             : }
     136             : 
     137             : 
     138           3 : std::ostream& operator << ( std::ostream& os, const Projection& projection )
     139             : {
     140           3 :     const std::ios::fmtflags flags = os.flags();
     141           3 :     os.setf( std::ios::fixed, std::ios::floatfield );
     142             : 
     143           3 :     os << "projection" << std::endl
     144           3 :        << "{" << std::endl << lunchbox::indent
     145           6 :        << "origin   " << projection.origin << std::endl
     146           6 :        << "distance " << projection.distance << std::endl
     147           6 :        << "fov      " << projection.fov << std::endl
     148           6 :        << "hpr      " << projection.hpr << std::endl
     149           3 :        << lunchbox::exdent << "}";
     150             : 
     151           3 :     os.setf( flags );
     152           3 :     return os;
     153             : }
     154             : 
     155             : }
     156          45 : }

Generated by: LCOV version 1.10