MetricGrid.cpp 9.19 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 *	(c) LSIIT, UMR CNRS/UdS
 *	Authors: O. Gnevaux, F. Larue.
 *
 *	See licence.txt for additional information.
 */


#include "GLViewer.h"
#include "MetricGrid.h"
#include <cmath>
#include <sstream>




void MetricGrid::displayGrid( GLViewer *viewer,
                              const double spacing,
                              const GLubyte alpha )
{
21 22
    const QVector3D camCenter = viewer->viewpointLocation();
    const QVector3D camFront  = viewer->viewRotationMatrix().row(2).toVector3D();
23
    const QVector3D camView   = camCenter.normalized();
24

25 26 27
    const double spacing2 = 2.0 * spacing;
    const double step = 0.1 * spacing;

28
    float alphaX = 1.0f - std::abs(camView.x());
29
    alphaX = std::max( 0.0f, std::min( 1.0f, (alphaX-0.025f)*10.0f ) );
30
    float alphaY = 1.0f - std::abs(camView.y());
31
    alphaY = std::max( 0.0f, std::min( 1.0f, (alphaY-0.025f)*10.0f ) );
32
    float alphaZ = 1.0f - std::abs(camView.z());
33 34
    alphaZ = std::max( 0.0f, std::min( 1.0f, (alphaZ-0.025f)*10.0f ) );

35 36 37 38 39
    // Display the points representing the current grid scale.
    glPointSize( 5.0f );
    glBegin( GL_POINTS );
        if( isAxisEnabled(X) )
        {
40
            glColor4ub( 255, 100, 100, alpha*alphaX );
41 42 43 44 45
            glVertex3d(  spacing, 0, 0 );
            glVertex3d( -spacing, 0, 0 );
        }
        if( isAxisEnabled(Y) )
        {
46
            glColor4ub( 100, 255, 100, alpha*alphaY );
47 48 49 50 51
            glVertex3d( 0,  spacing, 0 );
            glVertex3d( 0, -spacing, 0 );
        }
        if( isAxisEnabled(Z) )
        {
52
            glColor4ub( 100, 100, 255, alpha*alphaZ );
53 54 55 56 57 58
            glVertex3d( 0, 0,  spacing );
            glVertex3d( 0, 0, -spacing );
        }
    glEnd();

    // display the lines corresponding to the colored axis.
59
    glLineWidth( 1.5f );
60 61 62
    glBegin( GL_LINES );
        if( isAxisEnabled(X) )
        {
63
            glColor4ub( 255, 100, 100, 128 );
64 65
            glVertex3d( -0.1*spacing2, 0, 0 );
            glVertex3d(  0.1*spacing2, 0, 0 );
66
            glColor4ub( 255, 100, 100, alpha/2 );
67 68 69 70 71 72 73
            glVertex3d( -spacing2, 0, 0 );
            glVertex3d( -0.1*spacing2, 0, 0 );
            glVertex3d(  0.1*spacing2, 0, 0 );
            glVertex3d(  spacing2, 0, 0 );
        }
        else if( isGridEnabled(XY) || isGridEnabled(ZX) )
        {
74
            glColor4ub( 220, 220, 220, 128 );
75 76
            glVertex3d( -0.1*spacing2, 0, 0 );
            glVertex3d(  0.1*spacing2, 0, 0 );
77
            glColor4ub( 220, 220, 220, alpha/2 );
78 79 80 81 82 83 84
            glVertex3d( -spacing2, 0, 0 );
            glVertex3d( -0.1*spacing2, 0, 0 );
            glVertex3d(  0.1*spacing2, 0, 0 );
            glVertex3d(  spacing2, 0, 0 );
        }
        if( isAxisEnabled(Y) )
        {
85
            glColor4ub( 100, 255, 100, 128 );
86 87
            glVertex3d( 0, -0.1*spacing2, 0 );
            glVertex3d( 0,  0.1*spacing2, 0 );
88
            glColor4ub( 100, 255, 100, alpha/2 );
89 90 91 92 93 94 95
            glVertex3d( 0, -spacing2, 0 );
            glVertex3d( 0, -0.1*spacing2, 0 );
            glVertex3d( 0,  0.1*spacing2, 0 );
            glVertex3d( 0,  spacing2, 0 );
        }
        else if( isGridEnabled(XY) || isGridEnabled(YZ) )
        {
96
            glColor4ub( 220, 220, 220, 128 );
97 98
            glVertex3d( 0, -0.1*spacing2, 0 );
            glVertex3d( 0,  0.1*spacing2, 0 );
99
            glColor4ub( 220, 220, 220, alpha/2 );
100 101 102 103 104 105 106
            glVertex3d( 0, -spacing2, 0 );
            glVertex3d( 0, -0.1*spacing2, 0 );
            glVertex3d( 0,  0.1*spacing2, 0 );
            glVertex3d( 0,  spacing2, 0 );
        }
        if( isAxisEnabled(Z) )
        {
107
            glColor4ub( 100, 100, 255, 128 );
108 109
            glVertex3d( 0, 0, -0.1*spacing2 );
            glVertex3d( 0, 0,  0.1*spacing2 );
110
            glColor4ub( 100, 100, 255, alpha/2 );
111 112 113 114 115 116 117
            glVertex3d( 0, 0, -spacing2 );
            glVertex3d( 0, 0, -0.1*spacing2 );
            glVertex3d( 0, 0,  0.1*spacing2 );
            glVertex3d( 0, 0,  spacing2 );
        }
        else if( isGridEnabled(YZ) || isGridEnabled(ZX) )
        {
118
            glColor4ub( 220, 220, 220, 128 );
119 120
            glVertex3d( 0, 0, -0.1*spacing2 );
            glVertex3d( 0, 0,  0.1*spacing2 );
121
            glColor4ub( 220, 220, 220, alpha/2 );
122 123 124 125 126 127 128 129 130
            glVertex3d( 0, 0, -spacing2 );
            glVertex3d( 0, 0, -0.1*spacing2 );
            glVertex3d( 0, 0,  0.1*spacing2 );
            glVertex3d( 0, 0,  spacing2 );
        }
    glEnd();

    // Display lines corresponding to the grid spacing.
    glLineWidth( 1.0f );
131
    glColor4ub( 220, 220, 220, alpha/4 );
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
    glBegin( GL_LINES );
    if( isGridEnabled(XY) )
        for( int i=1; i<=9; ++i )
        {
            double f = i * step;
            glVertex3d( -spacing, f, 0 );
            glVertex3d(  spacing, f, 0 );
            glVertex3d( f, -spacing, 0 );
            glVertex3d( f,  spacing, 0 );
            glVertex3d( -spacing, -f, 0 );
            glVertex3d(  spacing, -f, 0 );
            glVertex3d( -f, -spacing, 0 );
            glVertex3d( -f,  spacing, 0 );
        }
    if( isGridEnabled(YZ) )
        for( int i=1; i<=9; ++i )
        {
            double f = i * step;
            glVertex3d( 0, -spacing, f );
            glVertex3d( 0,  spacing, f );
            glVertex3d( 0, f, -spacing );
            glVertex3d( 0, f,  spacing );
            glVertex3d( 0, -spacing, -f );
            glVertex3d( 0,  spacing, -f );
            glVertex3d( 0, -f, -spacing );
            glVertex3d( 0, -f,  spacing );
        }
    if( isGridEnabled(ZX) )
        for( int i=1; i<=9; ++i )
        {
            double f = i * step;
            glVertex3d( -spacing, 0, f );
            glVertex3d(  spacing, 0, f );
            glVertex3d( f, 0, -spacing );
            glVertex3d( f, 0,  spacing );
            glVertex3d( -spacing, 0, -f );
            glVertex3d(  spacing, 0, -f );
            glVertex3d( -f, 0, -spacing );
            glVertex3d( -f, 0,  spacing );
        }
    glEnd();

    // Display labels representing the current grid scale.
    std::stringstream strStream;
    strStream << spacing;
    QString spacingStr = QString::fromStdString( strStream.str() );

179
    if( isAxisEnabled(X)  &&  QVector3D::dotProduct( QVector3D(spacing,0,0)-camCenter, camFront ) < 0.0f )
180
    {
181
        glColor4ub( 255, 130, 130, alpha*alphaX );
182
        viewer->renderText( spacing, spacing/40.0, spacing/40.0, "X = "+spacingStr, QApplication::font() );
183
    }
184
    if( isAxisEnabled(Y)  &&  QVector3D::dotProduct( QVector3D(0,spacing,0)-camCenter, camFront ) < 0.0f )
185
    {
186
        glColor4ub( 200, 255, 200, alpha*alphaY );
187
        viewer->renderText( spacing/40.0, spacing, spacing/40.0, "Y = "+spacingStr, QApplication::font() );
188
    }
189
    if( isAxisEnabled(Z)  &&  QVector3D::dotProduct( QVector3D(0,0,spacing)-camCenter, camFront ) < 0.0f )
190
    {
191
        glColor4ub( 130, 130, 255, alpha*alphaZ );
192
        viewer->renderText( spacing/40.0, spacing/40.0, spacing, "Z = "+spacingStr, QApplication::font() );
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
    }
}


void MetricGrid::display( GLViewer *viewer )
{
    glPushAttrib( GL_LIGHTING         |
                  GL_CURRENT_BIT      |
                  GL_LINE_BIT         |
                  GL_POINT_BIT        |
                  GL_HINT_BIT         |
                  GL_COLOR_BUFFER_BIT );


    // Determine the current grid spacing wrt. the distance between the viewpoint and the focus point.
208

209 210 211 212 213 214
    double log10Dist = std::log10( 1.75*viewer->distToFocusPoint() );
    int log10DistI = (int) std::floor( log10Dist );
    double scaleFactor = std::pow( 10.0, (double)log10DistI );


    // Determine the alpha value for smooth transitions between successive grid scales.
215

216 217 218 219 220 221 222 223 224 225 226
    GLubyte alpha;
    if( log10Dist-log10DistI < 0.5 )
    {
        double t = (log10Dist-log10DistI) / 0.5;
        t = 0.5 + 0.5*std::cos( t*3.1415926535897932384626433832795 );
        alpha = (GLubyte)( 255.0*t*t );
    }
    else
        alpha = 0;


227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
    // If the viewer use an orthographic projection and the view direction is aligned with one of the axes, display the grid and axes corresponding to the other two.

    int gridsBackup = m_EnabledGrids;
    int axisBackup  = m_EnabledAxis;

    if( viewer->isProjectionOrthographic() )
    {
        QVector3D front = viewer->frontAxis();
        if( std::abs(front.x()) == 1.0f )
        {
            m_EnabledGrids = YZ;
            m_EnabledAxis  = Y | Z;
        }
        else if( std::abs(front.y()) == 1.0f )
        {
            m_EnabledGrids = ZX;
            m_EnabledAxis  = Z | X;
        }
        else if( std::abs(front.z()) == 1.0f )
        {
            m_EnabledGrids = XY;
            m_EnabledAxis  = X | Y;
        }
    }


253
    // Display the grid using three different grid spacings.
254

255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
    glDisable( GL_LIGHTING );
    glEnable( GL_LINE_SMOOTH );
    glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
    glEnable( GL_POINT_SMOOTH );
    glHint( GL_POINT_SMOOTH_HINT, GL_NICEST );

    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    if( alpha != 255 )
        displayGrid( viewer, 10.0*scaleFactor, 255-alpha );
    displayGrid( viewer, scaleFactor, 255 );
    if( alpha )
        displayGrid( viewer, 0.1*scaleFactor, alpha );


271 272 273 274 275 276 277 278
    // Restore the previously backed up state.

    if( viewer->isProjectionOrthographic() )
    {
        m_EnabledGrids = gridsBackup;
        m_EnabledAxis  = axisBackup;
    }

279 280
    glPopAttrib();
}