LCOV - code coverage report
Current view: top level - eq/fabric - wall.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 105 154 68.2 %
Date: 2016-07-30 05:04:55 Functions: 14 20 70.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2006-2016, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #include "wall.h"
      20             : #include "projection.h"
      21             : #include "pixelViewport.h"
      22             : 
      23             : #include <lunchbox/log.h>
      24             : 
      25             : #ifndef M_PI
      26             : #  define M_PI 3.14159265358979323846264338327
      27             : #endif
      28             : #define DEG2RAD( angle ) ((angle) * static_cast<float>(M_PI) / 180.f)
      29             : 
      30             : namespace eq
      31             : {
      32             : namespace fabric
      33             : {
      34             : 
      35       13498 : Wall::Wall()
      36             :     : bottomLeft( -.8f, -.5f, -1.f )
      37             :     , bottomRight( .8f, -.5f, -1.f )
      38             :     , topLeft(    -.8f,  .5f, -1.f )
      39       13498 :     , type( TYPE_FIXED )
      40             : {
      41       13498 : }
      42             : 
      43          12 : Wall::Wall( const Vector3f& bl, const Vector3f& br, const Vector3f& tl )
      44             :     : bottomLeft( bl )
      45             :     , bottomRight( br )
      46             :     , topLeft( tl )
      47          12 :     , type( TYPE_FIXED )
      48             : {
      49          12 : }
      50             : 
      51           4 : void Wall::resizeHorizontal( const float ratio )
      52             : {
      53           4 :     if( ratio == 1.f || ratio < 0.f )
      54           4 :         return;
      55             : 
      56           4 :     const Vector3f u_2   = (bottomRight - bottomLeft) * .5f;
      57           4 :     const Vector3f delta = u_2 * (ratio - 1.f);
      58           4 :     bottomLeft  -= delta;
      59           4 :     bottomRight += delta;
      60           4 :     topLeft     -= delta;
      61             : }
      62             : 
      63           2 : void Wall::resizeVertical( const float ratio )
      64             : {
      65           2 :     if( ratio == 1.f || ratio < 0.f )
      66           2 :         return;
      67             : 
      68           2 :     const Vector3f v_2   = (topLeft - bottomLeft) * .5f;
      69           2 :     const Vector3f delta = v_2 * (ratio - 1.f);
      70           2 :     bottomLeft  -= delta;
      71           2 :     bottomRight -= delta;
      72           2 :     topLeft     += delta;
      73             : }
      74             : 
      75           0 : void Wall::resizeLeft( const float ratio )
      76             : {
      77           0 :     if( ratio == 1.f || ratio < 0.f )
      78           0 :         return;
      79             : 
      80           0 :     const Vector3f u   = bottomRight - bottomLeft;
      81           0 :     const Vector3f delta = u * (ratio - 1.f);
      82           0 :     bottomLeft  -= delta;
      83           0 :     topLeft     -= delta;
      84             : }
      85             : 
      86           0 : void Wall::resizeRight( const float ratio )
      87             : {
      88           0 :     if( ratio == 1.f || ratio < 0.f )
      89           0 :         return;
      90             : 
      91           0 :     const Vector3f u   = bottomRight - bottomLeft;
      92           0 :     const Vector3f delta = u * (ratio - 1.f);
      93           0 :     bottomRight += delta;
      94             : }
      95             : 
      96           0 : void Wall::resizeTop( const float ratio )
      97             : {
      98           0 :     if( ratio == 1.f || ratio < 0.f )
      99           0 :         return;
     100             : 
     101           0 :     const Vector3f v = topLeft - bottomLeft;
     102           0 :     const Vector3f delta = v * (ratio - 1.f);
     103           0 :     topLeft     += delta;
     104             : }
     105             : 
     106           0 : void Wall::resizeBottom( const float ratio )
     107             : {
     108           0 :     if( ratio == 1.f || ratio < 0.f )
     109           0 :         return;
     110             : 
     111           0 :     const Vector3f v = topLeft - bottomLeft;
     112           0 :     const Vector3f delta = v * (ratio - 1.f);
     113           0 :     bottomLeft  -= delta;
     114           0 :     bottomRight -= delta;
     115             : }
     116             : 
     117           0 : void Wall::resizeHorizontalToAR( const float aspectRatio )
     118             : {
     119           0 :     const Vector3f u_2   = (bottomRight - bottomLeft) * .5f;
     120           0 :     const Vector3f v_2   = (topLeft - bottomLeft) * .5f;
     121             : 
     122           0 :     const float currentAR = u_2.length() / v_2.length();
     123           0 :     const float ratio = aspectRatio / currentAR;
     124             : 
     125             :     // Same as resizeHorizontal, but C&P since we have u_2 already
     126           0 :     const Vector3f delta = u_2 * (ratio - 1.f);
     127           0 :     bottomLeft  -= delta;
     128           0 :     bottomRight += delta;
     129           0 :     topLeft     -= delta;
     130           0 : }
     131             : 
     132           4 : void Wall::moveFocus( const Vector3f& eye, const float ratio )
     133             : {
     134           4 :     if( ratio == 1.0f )
     135           8 :         return;
     136             : 
     137           0 :     bottomLeft  = eye + ( bottomLeft - eye ) * ratio;
     138           0 :     bottomRight = eye + ( bottomRight - eye ) * ratio;
     139           0 :     topLeft     = eye + ( topLeft - eye ) * ratio;
     140             : }
     141             : 
     142         254 : void Wall::apply( const Viewport& viewport )
     143             : {
     144         254 :     const Vector3f u = bottomRight - bottomLeft;
     145         254 :     const Vector3f v = topLeft - bottomLeft;
     146             : 
     147         254 :     bottomLeft  = bottomLeft + u * viewport.x + v * viewport.y;
     148         254 :     bottomRight = bottomLeft + u * viewport.w;
     149         254 :     topLeft     = bottomLeft + v * viewport.h;
     150         254 : }
     151             : 
     152           4 : void Wall::scale( const float ratio )
     153             : {
     154           4 :     if( ratio == 1.0f )
     155           8 :         return;
     156             : 
     157           0 :     bottomLeft *= ratio;
     158           0 :     bottomRight *= ratio;
     159           0 :     topLeft *= ratio;
     160             : }
     161             : 
     162          22 : Wall& Wall::operator = ( const Projection& projection )
     163             : {
     164          44 :     const float width  = fabs( projection.distance * 2.0 *
     165          44 :                                tanf(DEG2RAD( .5f * projection.fov[0] )));
     166          44 :     const float height = fabs( projection.distance * 2.0 *
     167          44 :                                tanf(DEG2RAD( .5f * projection.fov[1] )));
     168             : 
     169          22 :     bottomLeft[0]  = -width * 0.5f;
     170          22 :     bottomLeft[1]  = -height * 0.5f;
     171          22 :     bottomLeft[2]  = 0;
     172          22 :     bottomRight[0] = width * 0.5f;
     173          22 :     bottomRight[1] = -height * 0.5f;
     174          22 :     bottomRight[2] = 0;
     175          22 :     topLeft[0]     = -width * 0.5f;
     176          22 :     topLeft[1]     = height * 0.5f;
     177          22 :     topLeft[2]     = 0;
     178             : 
     179          22 :     const float cosP = cos(DEG2RAD( projection.hpr[1] ));
     180          22 :     const float sinP = sin(DEG2RAD( projection.hpr[1] ));
     181          22 :     const float cosH = cos(DEG2RAD( projection.hpr[0] ));
     182          22 :     const float sinH = sin(DEG2RAD( projection.hpr[0] ));
     183          22 :     const float cosR = cos(DEG2RAD( projection.hpr[2] ));
     184          22 :     const float sinR = sin(DEG2RAD( projection.hpr[2] ));
     185             : 
     186          22 :     Matrix3f  mat ;
     187          22 :     const float cosPsinH = cosP * sinH;
     188          22 :     const float sinPsinH = sinP * sinH;
     189             : 
     190          22 :     mat.array[0] =  cosH * cosR;
     191          22 :     mat.array[1] = -cosH * sinR;
     192          22 :     mat.array[2] = -sinH;
     193          22 :     mat.array[3] = -sinPsinH * cosR + cosP * sinR;
     194          22 :     mat.array[4] =  sinPsinH * sinR + cosP * cosR;
     195          22 :     mat.array[5] = -sinP * cosH;
     196          22 :     mat.array[6] =  cosPsinH * cosR + sinP * sinR;
     197          22 :     mat.array[7] = -cosPsinH * sinR + sinP * cosR;
     198          22 :     mat.array[8] =  cosP * cosH;
     199             : 
     200          22 :     bottomLeft  = mat * bottomLeft;
     201          22 :     bottomRight = mat * bottomRight;
     202          22 :     topLeft     = mat * topLeft;
     203             : 
     204          22 :     Vector3f w( mat.array[6], mat.array[7], mat.array[8] );
     205             : 
     206          22 :     bottomLeft  = bottomLeft  + projection.origin  + w *  projection.distance;
     207          22 :     bottomRight = bottomRight + projection.origin  + w *  projection.distance;
     208          22 :     topLeft     = topLeft     + projection.origin  + w *  projection.distance;
     209             : 
     210          22 :     return *this;
     211             : }
     212             : 
     213           2 : Wall& Wall::operator = ( const Matrix4f& xfm )
     214             : {
     215           2 :     bottomLeft  = xfm * Vector4f( -1.0f, -1.0f, -1.0f, 1.0f );
     216           2 :     bottomRight = xfm * Vector4f(  1.0f, -1.0f, -1.0f, 1.0f );
     217           2 :     topLeft     = xfm * Vector4f( -1.0f,  1.0f, -1.0f, 1.0f );
     218           2 :     return *this;
     219             : }
     220             : 
     221        2622 : bool Wall::operator == ( const Wall& rhs ) const
     222             : {
     223        4012 :     return ( bottomLeft.equals( rhs.bottomLeft, 0.0001f )   &&
     224        3996 :              bottomRight.equals( rhs.bottomRight, 0.0001f ) &&
     225        3996 :              topLeft.equals( rhs.topLeft, 0.0001f ));
     226             : }
     227             : 
     228           0 : bool Wall::operator != ( const Wall& rhs ) const
     229             : {
     230           0 :     return ( !bottomLeft.equals( rhs.bottomLeft, 0.0001f )   ||
     231           0 :              !bottomRight.equals( rhs.bottomRight, 0.0001f ) ||
     232           0 :              !topLeft.equals( rhs.topLeft, 0.0001f ));
     233             : }
     234             : 
     235         534 : std::ostream& operator << ( std::ostream& os, const Wall& wall )
     236             : {
     237         534 :     const std::ios::fmtflags flags = os.flags();
     238         534 :     os.setf( std::ios::fixed, std::ios::floatfield );
     239             : 
     240         534 :     os << lunchbox::disableHeader << lunchbox::disableFlush
     241         534 :        << "wall" << std::endl
     242         534 :        << "{" << std::endl << lunchbox::indent
     243        1068 :        << "bottom_left  " << wall.bottomLeft << std::endl
     244        1068 :        << "bottom_right " << wall.bottomRight << std::endl
     245        1068 :        << "top_left     " << wall.topLeft << std::endl;
     246         534 :     if( wall.type != Wall::TYPE_FIXED )
     247          12 :         os << "type         " << wall.type << std::endl;
     248         534 :     os << lunchbox::exdent << "}"
     249         534 :        << lunchbox::enableFlush << lunchbox::enableHeader << std::endl;
     250             : 
     251         534 :     os.setf( flags );
     252         534 :     return os;
     253             : }
     254             : 
     255          12 : std::ostream& operator << ( std::ostream& os, const Wall::Type& type )
     256             : {
     257          12 :     switch( type )
     258             :     {
     259             :     case Wall::TYPE_HMD:
     260          12 :         os << "HMD";
     261          12 :         break;
     262             : 
     263             :     default:
     264           0 :         LBASSERT( false );
     265             : 
     266             :     case Wall::TYPE_FIXED:
     267           0 :         os << "fixed";
     268           0 :         break;
     269             :     }
     270          12 :     return os;
     271             : }
     272             : 
     273             : }
     274          84 : }

Generated by: LCOV version 1.11