10.3. Creating a Constrained Viewer

The SoXtConstrainedViewer base class adds the notion of a world up-direction, with methods like setUpDirection() and getUpDirection(). New viewers that require the notion of an up-direction should be derived from this base class. With the notion of a world up-direction (which defaults to +y), a viewer can constrain the camera to prevent the user from looking upside down. This constraint is currently used in SoXtFlyViewer and SoXtWalkViewer .

SoXtConstrainedViewer redefines some of the routines, such as saveHomePosition() and resetToHomePosition(), to save and restore the original camera up-direction. This base class redefines the paste() and setCamera() methods to guarantee that the original camera up-direction is preserved whenever new camera values are given. SoXtConstrainedViewer also provides some convenience routines to allow the user to interactively specify the world up-direction (the findUpDirection() method) and constrain the camera to the current up-direction (the checkForCameraUpConstrain() method).

The world up-direction can be changed with the setUpDirection() method and can also be changed interactively by the user while viewing a model using the findUpDirection() method, defined in SoXtConstrainedViewer .

The base class SoXtConstrainedViewer also provides a convenient way to check that the current camera values are consistent with the up-direction and to tilt the camera up or down while constraining to +/- 90 degrees from the eye-level plane. This prevents the camera from ever looking upside down. Those protected methods are as follows:

void checkForCameraUpConstrain();

checks the camera orientation and makes sure that the current right vector and ideal right vector (cross between the view vector and world up-direction) are the same and corrects it if they are not the same. This method keeps the up-direction valid.

virtual void tiltCamera(float deltaAngle);

tilts the camera, restraining it to within 180 degrees from the up-direction. A positive angle tilts the camera up.

For convenience, SoXtConstrainedViewer defines the decoration thumbwheels, which can also be redefined by subclasses. These are defined as follows:

virtual void bottomWheelMotion(float newVal);

rotates the camera around the world up-direction

virtual void leftWheelMotion(float newVal);

tilts the camera up and down, constraining it to within 180 degrees of the world up-direction

virtual void rightWheelMotion(float newVal);

moves the camera forward and backward

A viewer that is constrained to a world up-direction should always rotate the camera around that world up-direction when rotating left and right. It is important to rotate around the world up-direction—as opposed to the current camera up-value, which is not the same if the camera is tilted up or down—to prevent rolling. This rolling disturbs the camera alignment and eventually causes the camera to look upside down.