Click here to Skip to main content
15,881,852 members
Articles / Multimedia / OpenGL
Article

A virtual trackball rotation controller

Rate me:
Please Sign up or sign in to vote.
4.75/5 (9 votes)
1 Dec 19994 min read 173.7K   4K   30   19
  • Download source files - 16 Kb
  • Intro

    This piece of code was born inside an (unfinished) project of mine: a graphical curve editor with a real time 3D preview using OpenGL libraries.

    At first to let the user see the object being constructed from different points of view in the 3D window I simply linked mouse movement with rotation about two axes (usually X and Y when the camera is along Z).

    This method become unsatisfactory after a brief period of use cause it presented an odd effect when the object was "upside-down": moving the mouse to the right caused an apparent left rotation and vice-versa.

    The oddity was caused by the fact that the rotation has to be referred to the local object coordinate system, in the latter example the object is actually turning right while being upside-down.

    In computer graphics literature there are several papers about "intuitive" rotation controllers; I think K. Shoemake's arcball controller represents one of the best solutions: the idea is to project mouse movement on an hypothetical sphere filling the 3D window and to apply the rotation resulting from the sphere being manipulated when the mouse button is pressed to the object.

    Internals

    The global rotation is internally represented and adjusted by using quaternions instead of rotation matrices since this approach is more numerically stable when dealing with small, incremental rotations.

    This trackball is a features merging among the original arcball C code (rewritten in OO style) and a virtual trackball controller by J.Childs (used in his GLcube project) which is in turn derived from some code in M.J.Kilgard's GLUT library.

    The two code presented several similarities (such as the use of quaternions) but different sphere projection algorithms therefore I decided to retain both: J.Childs' controller project mouse movement on a parabolic sheet when it is outside the sphere while K.Shoemake's one project mouse movement on a plane; the first method (the default one) is somewhat more natural because it's effect is continuous while the second one is abruptly interrupted when the mouse leave/enters the virtual sphere.

    In the code I've (re)used a set of math classes which are part of my frequently used graphics programming tools, it's well commented and contains some documentation which can be extracted using Doxygen.

    Use

    The trackball code is demonstrated in the companion article CGLEnabledView - An MDI view class supporting OpenGL

    To use a CBallController in your programs follow these steps:

    1. Include BallController.h where needed.
    2. Construct a CBallController somewhere in your application (I suggest the view class) and specify at construction time the radius of the virtual sphere varying from 0.1 to 1.0 (a radius of 1.0 means that the sphere completely fills the window).
    3. [optional] Call SetAlternateMethod or ToggleMethod member functions to set a project-to-sphere method.
    4. Call the ClientAreaResize method in your window resize handler routine (which should be called before showing the window for the first time too) passing the size of your client area.
    5. [optional but recommended] Call the Key method passing the character code in your key press handler to enable manipulation trough keyboard (see below for the key bindings).
    6. [optional] Set the constraint axes via the UseConstraints method, constraints drawing can be controlled via SetDrawConstraints method.
    7. Call the MouseDown, MouseMove and MouseMove methods in your mouse handlers routines passing the mouse coordinates represented in local window coordinates (origin in upper left corner); it may be a good idea to capture mouse movements outside the windows during mouse button dragging.
    8. Call the IssueGLrotation method just before (re)drawing the scene.
    9. [optional] Call the DrawBall method after drawing the scene to let the BallController show some feedback during rotations using the alternate method.

    Other methods
    With GetDrawConstraints and you can check if constraint drawing is activated. GetAngleKeyIncrement and SetAngleKeyIncrement allow to respectively retrieve and set the angle increment used in keyboard interactions. GetColorV, GetColor, SetColor and SetColorV specify or retrieve the color used in DrawBall method, the color can be passed using a COLORREF structure or a vector of [0-1] ranging floats.
    Keys

    EscInterrupts current rotation operation (a rotation operation starts at every mouse button press)
    Canc or Numpad 5Resets the current rotation (corresponds to an identity rotation matrix)
    Right arrow or Numpad 6rotates +keyIncrement degrees about X axis
    Left arrow or Numpad 4rotates -keyIncrement degrees about X axis
    Up arrow or Numpad 8rotates +keyIncrement degrees about Y axis
    Down arrow or Numpad 2rotates -keyIncrement degrees about Y axis
    Page Up or Numpad 9rotates +keyIncrement degrees about Z axis
    Home or Numpad 7rotates -keyIncrement degrees about Z axis
    TABduring a constrained rotation swicth the constrain axis

    History

    RevisionDescription
    0.2Initial public release
    0.1Personal development release

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    Software Developer (Senior)
    Italy Italy
    Male.
    Living in Rome, Italy
    Computer addict since 12 years old (first computer: Commodore 64).
    Master degree in Computer Science.
    Very interested in computer generated graphics both real time (mainly OpenGL) and photorealistic rendering.

    Comments and Discussions

     
    Questioni know that this thread is old but ... Pin
    Lassade13-Nov-11 8:29
    Lassade13-Nov-11 8:29 
    Generalchange center point Pin
    Omar dddd1-Mar-06 17:23
    Omar dddd1-Mar-06 17:23 
    QuestionSounds interesting, but where are the screenshots? Pin
    Shawn Poulson17-Feb-06 3:20
    Shawn Poulson17-Feb-06 3:20 
    GeneralSorry, But... Pin
    raaar28-Jan-05 14:24
    raaar28-Jan-05 14:24 
    Generalthanks Pin
    caesar2211-Nov-04 2:44
    caesar2211-Nov-04 2:44 
    QuestionHow to run 2 different(or same) OpenGL objects in one DialogBox? Pin
    werter15-Jun-04 21:53
    werter15-Jun-04 21:53 
    AnswerRe: How to run 2 different(or same) OpenGL objects in one DialogBox? Pin
    barto3-Aug-04 5:13
    barto3-Aug-04 5:13 
    GeneralRe: I believe it's missing a file. Pin
    dotnetcoders28-Sep-03 8:09
    dotnetcoders28-Sep-03 8:09 
    GeneralRe: I believe it's missing a file. Pin
    raaar28-Jan-05 14:33
    raaar28-Jan-05 14:33 
    GeneralRe: I believe it's missing a file. Pin
    raaar28-Jan-05 14:39
    raaar28-Jan-05 14:39 
    Actually, BallController.h references a class "CRect" which is also defined in atltypes.h -- so maybe that's the missing file after all. But including atltypes.h in 3dmath.h turned into a fiasco for me... blah
    GeneralSilky smooth rotation Pin
    AORD11-Aug-03 13:29
    AORD11-Aug-03 13:29 
    GeneralGreat piece of work Pin
    Domagoj Baronica27-Jul-03 2:06
    Domagoj Baronica27-Jul-03 2:06 
    GeneralI believe it's missing a file. Pin
    WREY28-Jun-03 3:49
    WREY28-Jun-03 3:49 
    GeneralRe: I believe it's missing a file. Pin
    Domagoj Baronica27-Jul-03 2:12
    Domagoj Baronica27-Jul-03 2:12 
    GeneralIt's not worth the effort. Pin
    WREY27-Jul-03 8:07
    WREY27-Jul-03 8:07 
    GeneralRe: It's not worth the effort. Pin
    AORD11-Aug-03 13:41
    AORD11-Aug-03 13:41 
    GeneralZoom Pin
    Ali Khanlarkhani18-Jan-03 19:59
    Ali Khanlarkhani18-Jan-03 19:59 
    GeneralEn general Pin
    Jose Gabriel Martinez10-Jul-00 8:30
    sussJose Gabriel Martinez10-Jul-00 8:30 
    GeneralRe: En general Pin
    8-Aug-01 10:28
    suss8-Aug-01 10:28 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.