libgfx: Interactive Rotation Control
Author: Michael Garland

## Interactive Rotation Control

The `libgfx` library provides a fairly simple facility for interactive inspection of 3-D objects. The interface is designed for applications where a user is inspecting an object by spinning it and by translating the camera to provide a better view. All of the user interaction is implemented through mouse motion:

- Left mouse drag — rotate object about its centroid
- Right mouse drag — translate camera forward/backward
- Middle mouse drag — translate camera parallel to image plane

The classes used to implement this functionality are based on a fairly standard paradigm. Two subsequent mouse positions are projected onto a notional surface "below" the window. The cross product of these projected vectors defines an axis of rotation and the angle between them defines the rotation angle.

### Ball Types

The library currently supports two control classes:

> Arcball The Arcball controller is based on the article Arcball Rotation Control written by Ken Shoemake in Graphics Gems IV published by Academic Press. The underlying surface of projection is a hemisphere.

> Trackball Implements the mechanism used in the SGI 3-D demo programs. This approach was originally developed by Gavin Bell. The underlying surface of projection is a hybrid of a hemisphere and a hyperbolic sheet.

### Public Interface

The two controller types both implement the same public interface, and can be freely interchanged in the application program. The interfaces for these controllers are defined in the following header files:

- `class Arcball` — `<gfx/arcball.h>`
- `class Trackball` — `<gfx/trackball.h>`

To use one of the controllers, you need to include the appropriate header and create an instance of the appropriate class.

#### Initialization

Before using a rotation controller, you must initialize it by providing the bounding sphere of the object to be controlled. This is done using the templated method:

        template<class T>
        void bounding_sphere(const TVec3<T>& center, T radius);

The specified sphere `center` will be the point about which the object will rotate.

#### Interaction

Once initialized, the controller is meant to be interfaced directly with the event handlers of an application built using the `libgfx` GUI framework. Each of the following controller methods should be called from the event handlers of your application.

        virtual void update_animation();
        virtual bool mouse_down(int *where, int which);
        virtual bool mouse_up(int *where, int which);
        virtual bool mouse_drag(int *where, int *last, int which);

#### Applying Results

For the rotation to take effect, you must apply it in the rendering loop of the application. Before drawing your scene, you should call the method:

        virtual void apply_transform();

This will set up the appropriate transform on the `ModelView` matrix stack. Similarly, when done drawing, you should call the method:

        virtual void unapply_transform();

which will clean up the `ModelView` matrix stack.