15,901,853 members
Articles / Multimedia / OpenGL
Article

# A virtual trackball rotation controller

Rate me:
1 Dec 19994 min read 174.1K   4K   30   19
• ## 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

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

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

## History

RevisionDescription
0.2Initial public release
0.1Personal development release

A list of licenses authors might use can be found here

Written By
Software Developer (Senior)
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.

 First Prev Next
 change center point Omar dddd1-Mar-06 17:23 Omar dddd 1-Mar-06 17:23
 Sounds interesting, but where are the screenshots? Shawn Poulson17-Feb-06 3:20 Shawn Poulson 17-Feb-06 3:20
 Sorry, But... raaar28-Jan-05 14:24 raaar 28-Jan-05 14:24
 thanks caesar2211-Nov-04 2:44 caesar22 11-Nov-04 2:44
 How to run 2 different(or same) OpenGL objects in one DialogBox? werter15-Jun-04 21:53 werter1 5-Jun-04 21:53
 Re: How to run 2 different(or same) OpenGL objects in one DialogBox? barto3-Aug-04 5:13 barto 3-Aug-04 5:13
 Re: I believe it's missing a file. dotnetcoders28-Sep-03 8:09 dotnetcoders 28-Sep-03 8:09
 Re: I believe it's missing a file. raaar28-Jan-05 14:33 raaar 28-Jan-05 14:33
 Re: I believe it's missing a file. raaar28-Jan-05 14:39 raaar 28-Jan-05 14:39
 Silky smooth rotation AORD11-Aug-03 13:29 AORD 11-Aug-03 13:29
 Great piece of work Domagoj Baronica27-Jul-03 2:06 Domagoj Baronica 27-Jul-03 2:06
 I believe it's missing a file. WREY28-Jun-03 3:49 WREY 28-Jun-03 3:49
 Re: I believe it's missing a file. Domagoj Baronica27-Jul-03 2:12 Domagoj Baronica 27-Jul-03 2:12
 It's not worth the effort. WREY27-Jul-03 8:07 WREY 27-Jul-03 8:07
 Re: It's not worth the effort. AORD11-Aug-03 13:41 AORD 11-Aug-03 13:41
 Zoom Ali Khanlarkhani18-Jan-03 19:59 Ali Khanlarkhani 18-Jan-03 19:59
 En general Jose Gabriel Martinez10-Jul-00 8:30 Jose Gabriel Martinez 10-Jul-00 8:30
 Re: En general 8-Aug-01 10:28 8-Aug-01 10:28
 Last Visit: 31-Dec-99 18:00     Last Update: 20-May-24 2:52 Refresh 1