LCOV - code coverage report
Current view: top level - eq/fabric - wall.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 113 154 73.4 %
Date: 2017-12-16 05:07:20 Functions: 15 20 75.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 "pixelViewport.h"
      21             : #include "projection.h"
      22             : #include "vmmlib.h"
      23             : 
      24             : #include <lunchbox/log.h>
      25             : 
      26             : #define DEG2RAD(angle) ((angle) * static_cast<float>(M_PI) / 180.f)
      27             : 
      28             : namespace eq
      29             : {
      30             : namespace fabric
      31             : {
      32       13730 : Wall::Wall()
      33             :     : bottomLeft(-.8f, -.5f, -1.f)
      34             :     , bottomRight(.8f, -.5f, -1.f)
      35             :     , topLeft(-.8f, .5f, -1.f)
      36       13730 :     , type(TYPE_FIXED)
      37             : {
      38       13730 : }
      39             : 
      40          12 : Wall::Wall(const Vector3f& bl, const Vector3f& br, const Vector3f& tl)
      41             :     : bottomLeft(bl)
      42             :     , bottomRight(br)
      43             :     , topLeft(tl)
      44          12 :     , type(TYPE_FIXED)
      45             : {
      46          12 : }
      47             : 
      48           4 : void Wall::resizeHorizontal(const float ratio)
      49             : {
      50           4 :     if (ratio == 1.f || ratio < 0.f)
      51           0 :         return;
      52             : 
      53           4 :     const Vector3f u_2 = (bottomRight - bottomLeft) * .5f;
      54           4 :     const Vector3f delta = u_2 * (ratio - 1.f);
      55           4 :     bottomLeft -= delta;
      56           4 :     bottomRight += delta;
      57           4 :     topLeft -= delta;
      58             : }
      59             : 
      60           2 : void Wall::resizeVertical(const float ratio)
      61             : {
      62           2 :     if (ratio == 1.f || ratio < 0.f)
      63           0 :         return;
      64             : 
      65           2 :     const Vector3f v_2 = (topLeft - bottomLeft) * .5f;
      66           2 :     const Vector3f delta = v_2 * (ratio - 1.f);
      67           2 :     bottomLeft -= delta;
      68           2 :     bottomRight -= delta;
      69           2 :     topLeft += delta;
      70             : }
      71             : 
      72           0 : void Wall::resizeLeft(const float ratio)
      73             : {
      74           0 :     if (ratio == 1.f || ratio < 0.f)
      75           0 :         return;
      76             : 
      77           0 :     const Vector3f u = bottomRight - bottomLeft;
      78           0 :     const Vector3f delta = u * (ratio - 1.f);
      79           0 :     bottomLeft -= delta;
      80           0 :     topLeft -= delta;
      81             : }
      82             : 
      83           0 : void Wall::resizeRight(const float ratio)
      84             : {
      85           0 :     if (ratio == 1.f || ratio < 0.f)
      86           0 :         return;
      87             : 
      88           0 :     const Vector3f u = bottomRight - bottomLeft;
      89           0 :     const Vector3f delta = u * (ratio - 1.f);
      90           0 :     bottomRight += delta;
      91             : }
      92             : 
      93           0 : void Wall::resizeTop(const float ratio)
      94             : {
      95           0 :     if (ratio == 1.f || ratio < 0.f)
      96           0 :         return;
      97             : 
      98           0 :     const Vector3f v = topLeft - bottomLeft;
      99           0 :     const Vector3f delta = v * (ratio - 1.f);
     100           0 :     topLeft += delta;
     101             : }
     102             : 
     103           0 : void Wall::resizeBottom(const float ratio)
     104             : {
     105           0 :     if (ratio == 1.f || ratio < 0.f)
     106           0 :         return;
     107             : 
     108           0 :     const Vector3f v = topLeft - bottomLeft;
     109           0 :     const Vector3f delta = v * (ratio - 1.f);
     110           0 :     bottomLeft -= delta;
     111           0 :     bottomRight -= delta;
     112             : }
     113             : 
     114           2 : void Wall::resizeHorizontalToAR(const float aspectRatio)
     115             : {
     116           2 :     const Vector3f u_2 = (bottomRight - bottomLeft) * .5f;
     117           2 :     const Vector3f v_2 = (topLeft - bottomLeft) * .5f;
     118             : 
     119           2 :     const float currentAR = u_2.length() / v_2.length();
     120           2 :     const float ratio = aspectRatio / currentAR;
     121             : 
     122             :     // Same as resizeHorizontal, but C&P since we have u_2 already
     123           2 :     const Vector3f delta = u_2 * (ratio - 1.f);
     124           2 :     bottomLeft -= delta;
     125           2 :     bottomRight += delta;
     126           2 :     topLeft -= delta;
     127           2 : }
     128             : 
     129         118 : void Wall::moveFocus(const Vector3f& eye, const float ratio)
     130             : {
     131         118 :     if (ratio == 1.0f)
     132         118 :         return;
     133             : 
     134           0 :     bottomLeft = eye + (bottomLeft - eye) * ratio;
     135           0 :     bottomRight = eye + (bottomRight - eye) * ratio;
     136           0 :     topLeft = eye + (topLeft - eye) * ratio;
     137             : }
     138             : 
     139         422 : void Wall::apply(const Viewport& viewport)
     140             : {
     141         422 :     const Vector3f u = bottomRight - bottomLeft;
     142         422 :     const Vector3f v = topLeft - bottomLeft;
     143             : 
     144         422 :     bottomLeft = bottomLeft + u * viewport.x + v * viewport.y;
     145         422 :     bottomRight = bottomLeft + u * viewport.w;
     146         422 :     topLeft = bottomLeft + v * viewport.h;
     147         422 : }
     148             : 
     149         118 : void Wall::scale(const float ratio)
     150             : {
     151         118 :     if (ratio == 1.0f)
     152         118 :         return;
     153             : 
     154           0 :     bottomLeft *= ratio;
     155           0 :     bottomRight *= ratio;
     156           0 :     topLeft *= ratio;
     157             : }
     158             : 
     159          78 : Wall& Wall::operator=(const Projection& projection)
     160             : {
     161         156 :     const float width = fabs(projection.distance * 2.0 *
     162         156 :                              tanf(DEG2RAD(.5f * projection.fov[0])));
     163         156 :     const float height = fabs(projection.distance * 2.0 *
     164         156 :                               tanf(DEG2RAD(.5f * projection.fov[1])));
     165             : 
     166          78 :     bottomLeft[0] = -width * 0.5f;
     167          78 :     bottomLeft[1] = -height * 0.5f;
     168          78 :     bottomLeft[2] = 0;
     169          78 :     bottomRight[0] = width * 0.5f;
     170          78 :     bottomRight[1] = -height * 0.5f;
     171          78 :     bottomRight[2] = 0;
     172          78 :     topLeft[0] = -width * 0.5f;
     173          78 :     topLeft[1] = height * 0.5f;
     174          78 :     topLeft[2] = 0;
     175             : 
     176          78 :     const float cosP = cos(DEG2RAD(projection.hpr[1]));
     177          78 :     const float sinP = sin(DEG2RAD(projection.hpr[1]));
     178          78 :     const float cosH = cos(DEG2RAD(projection.hpr[0]));
     179          78 :     const float sinH = sin(DEG2RAD(projection.hpr[0]));
     180          78 :     const float cosR = cos(DEG2RAD(projection.hpr[2]));
     181          78 :     const float sinR = sin(DEG2RAD(projection.hpr[2]));
     182             : 
     183          78 :     Matrix3f mat;
     184          78 :     const float cosPsinH = cosP * sinH;
     185          78 :     const float sinPsinH = sinP * sinH;
     186             : 
     187          78 :     mat.array[0] = cosH * cosR;
     188          78 :     mat.array[1] = -cosH * sinR;
     189          78 :     mat.array[2] = -sinH;
     190          78 :     mat.array[3] = -sinPsinH * cosR + cosP * sinR;
     191          78 :     mat.array[4] = sinPsinH * sinR + cosP * cosR;
     192          78 :     mat.array[5] = -sinP * cosH;
     193          78 :     mat.array[6] = cosPsinH * cosR + sinP * sinR;
     194          78 :     mat.array[7] = -cosPsinH * sinR + sinP * cosR;
     195          78 :     mat.array[8] = cosP * cosH;
     196             : 
     197          78 :     bottomLeft = mat * bottomLeft;
     198          78 :     bottomRight = mat * bottomRight;
     199          78 :     topLeft = mat * topLeft;
     200             : 
     201          78 :     Vector3f w(mat.array[6], mat.array[7], mat.array[8]);
     202             : 
     203          78 :     bottomLeft = bottomLeft + projection.origin + w * projection.distance;
     204          78 :     bottomRight = bottomRight + projection.origin + w * projection.distance;
     205          78 :     topLeft = topLeft + projection.origin + w * projection.distance;
     206             : 
     207          78 :     return *this;
     208             : }
     209             : 
     210           2 : Wall& Wall::operator=(const Matrix4f& xfm)
     211             : {
     212           2 :     bottomLeft = xfm * Vector4f(-1.0f, -1.0f, -1.0f, 1.0f);
     213           2 :     bottomRight = xfm * Vector4f(1.0f, -1.0f, -1.0f, 1.0f);
     214           2 :     topLeft = xfm * Vector4f(-1.0f, 1.0f, -1.0f, 1.0f);
     215           2 :     return *this;
     216             : }
     217             : 
     218        2808 : bool Wall::operator==(const Wall& rhs) const
     219             : {
     220        4240 :     return (bottomLeft.equals(rhs.bottomLeft, 0.0001f) &&
     221        4208 :             bottomRight.equals(rhs.bottomRight, 0.0001f) &&
     222        4208 :             topLeft.equals(rhs.topLeft, 0.0001f));
     223             : }
     224             : 
     225           0 : bool Wall::operator!=(const Wall& rhs) const
     226             : {
     227           0 :     return (!bottomLeft.equals(rhs.bottomLeft, 0.0001f) ||
     228           0 :             !bottomRight.equals(rhs.bottomRight, 0.0001f) ||
     229           0 :             !topLeft.equals(rhs.topLeft, 0.0001f));
     230             : }
     231             : 
     232         556 : std::ostream& operator<<(std::ostream& os, const Wall& wall)
     233             : {
     234         556 :     const std::ios::fmtflags flags = os.flags();
     235         556 :     os.setf(std::ios::fixed, std::ios::floatfield);
     236             : 
     237         556 :     os << lunchbox::disableHeader << lunchbox::disableFlush << "wall"
     238         556 :        << std::endl
     239         556 :        << "{" << std::endl
     240        1112 :        << lunchbox::indent << "bottom_left  " << wall.bottomLeft << std::endl
     241        1112 :        << "bottom_right " << wall.bottomRight << std::endl
     242        1112 :        << "top_left     " << wall.topLeft << std::endl;
     243         556 :     if (wall.type != Wall::TYPE_FIXED)
     244          12 :         os << "type         " << wall.type << std::endl;
     245         556 :     os << lunchbox::exdent << "}" << lunchbox::enableFlush
     246         556 :        << lunchbox::enableHeader << std::endl;
     247             : 
     248         556 :     os.setf(flags);
     249         556 :     return os;
     250             : }
     251             : 
     252          12 : std::ostream& operator<<(std::ostream& os, const Wall::Type& type)
     253             : {
     254          12 :     switch (type)
     255             :     {
     256             :     case Wall::TYPE_HMD:
     257          12 :         os << "HMD";
     258          12 :         break;
     259             : 
     260             :     default:
     261           0 :         LBASSERT(false);
     262             : 
     263             :     case Wall::TYPE_FIXED:
     264           0 :         os << "fixed";
     265           0 :         break;
     266             :     }
     267          12 :     return os;
     268             : }
     269             : }
     270          60 : }

Generated by: LCOV version 1.11