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

    // display the lines corresponding to the colored axis.
62
    glLineWidth( 1.5f );
63 64 65
    glBegin( GL_LINES );
        if( isAxisEnabled(X) )
        {
66
            glColor4ub( 255, 100, 100, 128 );
67 68
            glVertex3d( -0.1*spacing2, 0, 0 );
            glVertex3d(  0.1*spacing2, 0, 0 );
69
            glColor4ub( 255, 100, 100, alpha/2 );
70 71 72 73 74 75 76
            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) )
        {
77
            glColor4ub( 220, 220, 220, 128 );
78 79
            glVertex3d( -0.1*spacing2, 0, 0 );
            glVertex3d(  0.1*spacing2, 0, 0 );
80
            glColor4ub( 220, 220, 220, alpha/2 );
81 82 83 84 85 86 87
            glVertex3d( -spacing2, 0, 0 );
            glVertex3d( -0.1*spacing2, 0, 0 );
            glVertex3d(  0.1*spacing2, 0, 0 );
            glVertex3d(  spacing2, 0, 0 );
        }
        if( isAxisEnabled(Y) )
        {
88
            glColor4ub( 100, 255, 100, 128 );
89 90
            glVertex3d( 0, -0.1*spacing2, 0 );
            glVertex3d( 0,  0.1*spacing2, 0 );
91
            glColor4ub( 100, 255, 100, alpha/2 );
92 93 94 95 96 97 98
            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) )
        {
99
            glColor4ub( 220, 220, 220, 128 );
100 101
            glVertex3d( 0, -0.1*spacing2, 0 );
            glVertex3d( 0,  0.1*spacing2, 0 );
102
            glColor4ub( 220, 220, 220, alpha/2 );
103 104 105 106 107 108 109
            glVertex3d( 0, -spacing2, 0 );
            glVertex3d( 0, -0.1*spacing2, 0 );
            glVertex3d( 0,  0.1*spacing2, 0 );
            glVertex3d( 0,  spacing2, 0 );
        }
        if( isAxisEnabled(Z) )
        {
110
            glColor4ub( 100, 100, 255, 128 );
111 112
            glVertex3d( 0, 0, -0.1*spacing2 );
            glVertex3d( 0, 0,  0.1*spacing2 );
113
            glColor4ub( 100, 100, 255, alpha/2 );
114 115 116 117 118 119 120
            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) )
        {
121
            glColor4ub( 220, 220, 220, 128 );
122 123
            glVertex3d( 0, 0, -0.1*spacing2 );
            glVertex3d( 0, 0,  0.1*spacing2 );
124
            glColor4ub( 220, 220, 220, alpha/2 );
125 126 127 128 129 130 131 132 133
            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 );
134
    glColor4ub( 220, 220, 220, alpha/4 );
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
    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.
178
    if( m_EnableLabels )
179
    {
180 181
        std::stringstream strStream;
        strStream << spacing;
182
        QString spacingStr = QString::fromStdString( strStream.str() ) + " " + m_Suffix;
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198

        if( isAxisEnabled(X)  &&  QVector3D::dotProduct( QVector3D(spacing,0,0)-camCenter, camFront ) < 0.0f )
        {
            glColor4ub( 255, 130, 130, alpha*alphaX );
            viewer->renderText( spacing, spacing/40.0, spacing/40.0, "X = "+spacingStr, QApplication::font() );
        }
        if( isAxisEnabled(Y)  &&  QVector3D::dotProduct( QVector3D(0,spacing,0)-camCenter, camFront ) < 0.0f )
        {
            glColor4ub( 200, 255, 200, alpha*alphaY );
            viewer->renderText( spacing/40.0, spacing, spacing/40.0, "Y = "+spacingStr, QApplication::font() );
        }
        if( isAxisEnabled(Z)  &&  QVector3D::dotProduct( QVector3D(0,0,spacing)-camCenter, camFront ) < 0.0f )
        {
            glColor4ub( 130, 130, 255, alpha*alphaZ );
            viewer->renderText( spacing/40.0, spacing/40.0, spacing, "Z = "+spacingStr, QApplication::font() );
        }
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
    }
}


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.
214

215 216 217 218 219 220
    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.
221

222 223 224 225 226 227 228 229 230 231 232
    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;


233 234 235 236 237 238 239 240 241 242
    // 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 )
        {
243 244
            m_EnabledGrids = m_EnableGridsOnAlignedOrtho * YZ;
            m_EnabledAxis  = m_EnableAxisOnAlignedOrtho * (Y|Z);
245 246 247
        }
        else if( std::abs(front.y()) == 1.0f )
        {
248 249
            m_EnabledGrids = m_EnableGridsOnAlignedOrtho * ZX;
            m_EnabledAxis  = m_EnableAxisOnAlignedOrtho * (Z|X);
250 251 252
        }
        else if( std::abs(front.z()) == 1.0f )
        {
253 254
            m_EnabledGrids = m_EnableGridsOnAlignedOrtho * XY;
            m_EnabledAxis  = m_EnableAxisOnAlignedOrtho * (X|Y);
255 256 257 258
        }
    }


259
    // Display the grid using three different grid spacings.
260

261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
    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 );


277 278 279 280 281 282 283 284
    // Restore the previously backed up state.

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

285 286
    glPopAttrib();
}