Source

dbsdev / sources / opengl2_samples / test7_simplerenderer / GLTrackballManipulator.h

Full commit
#ifndef __DBGLTrackBallManipulator__
#define __DBGLTrackBallManipulator__
// /////////////////////////////////////////////////////////////////////// //
// Copyright (c) 2012, Davide Bacchet (davide.bacchet@gmail.com)           //
// All rights reserved.                                                    //
//                                                                         //
// The software is released under the Creative Commons Attribution         //
// NonCommercial (CC BY-NC) license. The full license text is available    //
// at http://creativecommons.org/licenses/by-nc/3.0/legalcode              //
//                                                                         //
// You are free to distribute and adapt the work under the conditions:     //
// * Redistributions of source code must retain the above copyright notice //
// * You must attribute the work in the manner specified by the author     //
// * You may not use this work for commercial purposes.                    //
//                                                                         //
// Commercial Usage:                                                       //
// To use this software as part of a commercial product, you must          //
// obtain a written agreement from the author.                             //
// /////////////////////////////////////////////////////////////////////// //

// trackball manipulator; add the pan/zoom functionality to the standard trackball


#include "vmath.h"

#include "GLTrackball.h"


/// @class GLTrackballManipulator 
/// trackball 
template <typename real_type=float>
class GLTrackballManipulator
{
public:

    enum eMode {
            evRotate,   ///< rotate mode
            evPan,      ///< pan the manipulator
            evZoom,     ///< zoom mode
            evModeNum
    };

public:

    /// standard constructor
    GLTrackballManipulator()
    : trackball()
    , currMode(evRotate)
    , radius(1.0)
    {}
    /// destructor
    virtual ~GLTrackballManipulator()
    {}
    
    /// begin the dragging
    virtual void beginDrag(real_type x, real_type y)
    {
        if (currMode==evRotate)
            trackball.beginDrag(x,y);
        else if (currMode==evPan || currMode==evZoom)
        {
            anchorPan = center; // set anchor point to the current position
            anchorPanSS = Vector3<real_type>(x,y,0.0);
            incremPan = Vector3<real_type>(0,0,0);
        }
    }
    
    /// mouse drag
    virtual void drag(real_type x, real_type y)
    {
        if (currMode==evRotate)
            trackball.drag(x,y);
        else if (currMode==evPan)
        {
            Vector3<real_type> delta = Vector3<real_type>(x,y,0.0)-anchorPanSS;
            incremPan = delta*radius; // compensate with radius to 'normalize' the translation (effective when connected to a camera) 
            incremPan = trackball.getRotation()*incremPan; // to use object local orientation
            center = anchorPan+incremPan;
        }
        else if (currMode==evZoom)
        {
            radius += radius*(anchorPanSS.y-y)/100; // too minimalistic zoom implementation
        }
    }
    
    /// get current center
    Vector3<real_type> getCenter( void ) 
    {
        return center;
    }
    /// get current rotation
    Matrix4<real_type> getRotation( void ) 
    {
        return trackball.getRotation();
    }
    /// get current transformation
    Matrix4<real_type> getTransformation( void ) 
    {
        currentTransf = trackball.getRotation();
        Vector3<real_type> offsetRad = currentTransf*Vector3<real_type>(0.0,0.0,radius); // radius offset in local orientation
        currentTransf.setTranslation(center+offsetRad);
        return currentTransf;
    }

    void setMode( eMode mode )
    { 
        currMode = mode;
    }

protected:
    
    // member variables
    eMode currMode;               ///< manipulator current mode
    
    real_type           radius;      ///< trackball radius
    Vector3<real_type>  center;      ///< trackball center (current pan value)
    Vector3<real_type>  anchorPan;   ///< anchor point for pan
    Vector3<real_type>  anchorPanSS; ///< anchor point for pan (screen-space)
    Vector3<real_type>  incremPan;   ///< increment for pan

    Matrix4<real_type>  currentTransf;  ///< current transformation matrix

    GLTrackball<real_type> trackball;   ///< manage rotations
        
};


typedef GLTrackballManipulator<float>  GLTrackballManipulatorf;
typedef GLTrackballManipulator<double> GLTrackballManipulatord;

#endif