LCOV - code coverage report
Current view: top level - eq/fabric - projection.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 59 73 80.8 %
Date: 2016-07-30 05:04:55 Functions: 6 9 66.7 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2007-2016, 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       12112 : Projection::Projection()
      34             :         : origin( 0.f, 0.f, 0.f ),
      35             :           distance( 1.f ),
      36             :           fov( 77.3196f, 53.1301f ),
      37       12112 :           hpr( 0.f, 0.f, 0.f )
      38       12112 : {}
      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        1260 : Projection& Projection::operator = ( const Wall& wall )
      61             : {
      62        1260 :     Vector3f u = wall.bottomRight - wall.bottomLeft;
      63        1260 :     Vector3f v = wall.topLeft - wall.bottomLeft;
      64        1260 :     const float width  = u.normalize();
      65        1260 :     const float height = v.normalize();
      66             : 
      67        1260 :     const Vector3f w = vmml::cross( u, v );
      68        1260 :     const Vector3f center( (wall.bottomRight[0] + wall.topLeft[0]) * 0.5f,
      69        1260 :                            (wall.bottomRight[1] + wall.topLeft[1]) * 0.5f,
      70        3780 :                            (wall.bottomRight[2] + wall.topLeft[2]) * 0.5f );
      71             : 
      72        1260 :     if ( distance <= std::numeric_limits< float >::epsilon( ))
      73           0 :         distance = center.length();
      74             : 
      75        1260 :     Matrix3f  mat;
      76        1260 :     mat.array[0] = u[0];
      77        1260 :     mat.array[1] = u[1];
      78        1260 :     mat.array[2] = u[2];
      79             : 
      80        1260 :     mat.array[3] = v[0];
      81        1260 :     mat.array[4] = v[1];
      82        1260 :     mat.array[5] = v[2];
      83             : 
      84        1260 :     mat.array[6] = w[0];
      85        1260 :     mat.array[7] = w[1];
      86        1260 :     mat.array[8] = w[2];
      87             : 
      88        1260 :     fov[0] = RAD2DEG( atanf(0.5f * width / distance  )) * 2.0f;
      89        1260 :     fov[1] = RAD2DEG( atanf(0.5f * height / distance )) * 2.0f;
      90             : 
      91        1260 :     hpr[0] = -asinf( mat.array[2] );
      92        1260 :     const float cosH = cosf(hpr[0]);
      93        1260 :     hpr[0] =  RAD2DEG(hpr[0]);
      94             : 
      95        1260 :     if( fabs( cosH ) > std::numeric_limits< float >::epsilon( ))
      96             :     {
      97        1226 :         float tr_x      =  mat.array[8] / cosH;
      98        1226 :         float tr_y      = -mat.array[5] / cosH;
      99        1226 :         hpr[1]  = RAD2DEG( atan2f( tr_y, tr_x ));
     100             : 
     101        1226 :         tr_x      =  mat.array[0] / cosH;
     102        1226 :         tr_y      = -mat.array[1] / cosH;
     103        1226 :         hpr[2]  = RAD2DEG( atan2f( tr_y, tr_x ));
     104             :     }
     105             :     else
     106             :     {
     107          34 :         hpr[1]  = 0.f;
     108             : 
     109          34 :         const float tr_x = mat.array[4];
     110          34 :         const float tr_y = mat.array[3];
     111             : 
     112          34 :         hpr[2]  = RAD2DEG( atan2f( tr_y, tr_x ));
     113             :     }
     114             : 
     115        1260 :     origin = center - w * distance;
     116        1260 :     return *this;
     117             : }
     118             : 
     119          30 : bool Projection::operator == ( const Projection& rhs ) const
     120             : {
     121          36 :     return(  origin.equals( rhs.origin, 0.0001f )   &&
     122          12 :            (fabsf( distance - rhs.distance ) < 0.0001f ) &&
     123          42 :            fov.equals( rhs.fov, 0.0001f ) &&
     124          36 :            hpr.equals( rhs.hpr, 0.0001f ));
     125             : }
     126             : 
     127           0 : bool Projection::operator != ( const Projection& rhs ) const
     128             : {
     129           0 :     return ( !origin.equals( rhs.origin, 0.0001f )  ||
     130           0 :             (fabsf(distance - rhs.distance) >= 0.0001f ) ||
     131           0 :             !fov.equals( rhs.fov, 0.0001f ) ||
     132           0 :             !hpr.equals( rhs.hpr, 0.0001f ));
     133             : }
     134             : 
     135             : 
     136           6 : std::ostream& operator << ( std::ostream& os, const Projection& projection )
     137             : {
     138           6 :     const std::ios::fmtflags flags = os.flags();
     139           6 :     os.setf( std::ios::fixed, std::ios::floatfield );
     140             : 
     141           6 :     os << "projection" << std::endl
     142           6 :        << "{" << std::endl << lunchbox::indent
     143          12 :        << "origin   " << projection.origin << std::endl
     144          12 :        << "distance " << projection.distance << std::endl
     145          12 :        << "fov      " << projection.fov << std::endl
     146          12 :        << "hpr      " << projection.hpr << std::endl
     147           6 :        << lunchbox::exdent << "}";
     148             : 
     149           6 :     os.setf( flags );
     150           6 :     return os;
     151             : }
     152             : 
     153             : }
     154          84 : }

Generated by: LCOV version 1.11