LCOV - code coverage report
Current view: top level - eq/fabric - projection.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 58 71 81.7 %
Date: 2017-12-16 05:07:20 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 "vmmlib.h"
      20             : #include "wall.h"
      21             : 
      22             : #include <lunchbox/log.h>
      23             : 
      24             : #define DEG2RAD(angle) ((angle) * static_cast<float>(M_PI) / 180.f)
      25             : #define RAD2DEG(angle) ((angle)*180.f / static_cast<float>(M_PI))
      26             : 
      27             : namespace eq
      28             : {
      29             : namespace fabric
      30             : {
      31       12436 : Projection::Projection()
      32             :     : origin(0.f, 0.f, 0.f)
      33             :     , distance(1.f)
      34             :     , fov(77.3196f, 53.1301f)
      35       12436 :     , hpr(0.f, 0.f, 0.f)
      36             : {
      37       12436 : }
      38             : 
      39           0 : void Projection::resizeHorizontal(const float ratio)
      40             : {
      41           0 :     if (ratio == 1.f || ratio < 0.f)
      42           0 :         return;
      43             : 
      44             :     // const float newWidth_2 = ratio * distance * tanf(DEG2RAD( .5f * fov[1]
      45             :     // ));
      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        1326 : Projection& Projection::operator=(const Wall& wall)
      61             : {
      62        1326 :     Vector3f u = wall.bottomRight - wall.bottomLeft;
      63        1326 :     Vector3f v = wall.topLeft - wall.bottomLeft;
      64        1326 :     const float width = u.normalize();
      65        1326 :     const float height = v.normalize();
      66             : 
      67        1326 :     const Vector3f w = vmml::cross(u, v);
      68        2652 :     const Vector3f center((wall.bottomRight[0] + wall.topLeft[0]) * 0.5f,
      69        2652 :                           (wall.bottomRight[1] + wall.topLeft[1]) * 0.5f,
      70        3978 :                           (wall.bottomRight[2] + wall.topLeft[2]) * 0.5f);
      71             : 
      72        1326 :     if (distance <= std::numeric_limits<float>::epsilon())
      73           0 :         distance = center.length();
      74             : 
      75        1326 :     Matrix3f mat;
      76        1326 :     mat.array[0] = u[0];
      77        1326 :     mat.array[1] = u[1];
      78        1326 :     mat.array[2] = u[2];
      79             : 
      80        1326 :     mat.array[3] = v[0];
      81        1326 :     mat.array[4] = v[1];
      82        1326 :     mat.array[5] = v[2];
      83             : 
      84        1326 :     mat.array[6] = w[0];
      85        1326 :     mat.array[7] = w[1];
      86        1326 :     mat.array[8] = w[2];
      87             : 
      88        1326 :     fov[0] = RAD2DEG(atanf(0.5f * width / distance)) * 2.0f;
      89        1326 :     fov[1] = RAD2DEG(atanf(0.5f * height / distance)) * 2.0f;
      90             : 
      91        1326 :     hpr[0] = -asinf(mat.array[2]);
      92        1326 :     const float cosH = cosf(hpr[0]);
      93        1326 :     hpr[0] = RAD2DEG(hpr[0]);
      94             : 
      95        1326 :     if (fabs(cosH) > std::numeric_limits<float>::epsilon())
      96             :     {
      97        1292 :         float tr_x = mat.array[8] / cosH;
      98        1292 :         float tr_y = -mat.array[5] / cosH;
      99        1292 :         hpr[1] = RAD2DEG(atan2f(tr_y, tr_x));
     100             : 
     101        1292 :         tr_x = mat.array[0] / cosH;
     102        1292 :         tr_y = -mat.array[1] / cosH;
     103        1292 :         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        1326 :     origin = center - w * distance;
     116        1326 :     return *this;
     117             : }
     118             : 
     119         142 : bool Projection::operator==(const Projection& rhs) const
     120             : {
     121         148 :     return (origin.equals(rhs.origin, 0.0001f) &&
     122          12 :             (fabsf(distance - rhs.distance) < 0.0001f) &&
     123         154 :             fov.equals(rhs.fov, 0.0001f) && hpr.equals(rhs.hpr, 0.0001f));
     124             : }
     125             : 
     126           0 : bool Projection::operator!=(const Projection& rhs) const
     127             : {
     128           0 :     return (!origin.equals(rhs.origin, 0.0001f) ||
     129           0 :             (fabsf(distance - rhs.distance) >= 0.0001f) ||
     130           0 :             !fov.equals(rhs.fov, 0.0001f) || !hpr.equals(rhs.hpr, 0.0001f));
     131             : }
     132             : 
     133          34 : std::ostream& operator<<(std::ostream& os, const Projection& projection)
     134             : {
     135          34 :     const std::ios::fmtflags flags = os.flags();
     136          34 :     os.setf(std::ios::fixed, std::ios::floatfield);
     137             : 
     138          34 :     os << "projection" << std::endl
     139          34 :        << "{" << std::endl
     140          68 :        << lunchbox::indent << "origin   " << projection.origin << std::endl
     141          68 :        << "distance " << projection.distance << std::endl
     142          68 :        << "fov      " << projection.fov << std::endl
     143          68 :        << "hpr      " << projection.hpr << std::endl
     144          34 :        << lunchbox::exdent << "}";
     145             : 
     146          34 :     os.setf(flags);
     147          34 :     return os;
     148             : }
     149             : }
     150          60 : }

Generated by: LCOV version 1.11