----------------------------------------------------------------------------
ABOUT THE NAME
----------------------------------------------------------------------------
This application was first developped with the intention of
creating a small 3D-modeller, hence the name "sceneEditor".

In its current form, however, the application supports no
file i/o, and can only sculpt triangle meshes.

----------------------------------------------------------------------------
UI SUMMARY
----------------------------------------------------------------------------
Abbreviations used:
   LMB - left mouse button (on the primary mouse)
   MMB - middle mouse button (on the primary mouse)
   RMB - right mouse button (on the primary mouse)
   LMB2 - left mouse button on the second (serial) mouse
   MMB2 - middle mouse button on the second (serial) mouse
   RMB2 - right mouse button on the second (serial) mouse

Selection:
   LMB click         : selects everything along the picked ray,
                       and unselects everything else
   Shift+LMB click   : objects along the picked ray are added/removed
                       to the current selection, depending on whether
                       they aren't/are already part of the current selection

Camera Navigation:
   Alt+LMB drag      : orbit
   Alt+MMB drag      : pan
   Alt+LMB+MMB drag  : dolly
   Ctrl+LMB drag     : pitch & yaw
   Ctrl+MMB drag     : zoom
   Ctrl+LMB+MMB drag : roll
   'l'               : look at centre of current selection
   'r'               : reset camera

   LMB2 drag         : orbit
   MMB2 drag         : pan
   LMB2+MMB2 drag    : dolly

Other Options:
   'd'               : cycle display mode (wireframe and flat/smooth shaded)
   delete            : delete the currently selected object(s)
   space bar         : switch between Manipulator mode and Brush mode
   RMB               : menu of options, showing hotkeys

How to use the Manipulator:
   The Manipulator is used to translate, rotate, or scale
   the currently selected object(s).

   - Create a cube (with F2).  When created, it should be selected
     by default.  If it's no longer selected, click on it.
   - Make sure you are in Manipulator mode, and not Brush mode
     (you should see a triad of 3 red or green arrows --
     if you don't, try hitting the space bar).
   - If you pass the pointer over one of the arrows, it should hilite.
     Clicking and dragging the arrow (with LMB) will translate the
     selected object(s).  Clicking and dragging with MMB or LMB+MMB will
     rotate or scale the object(s), respectively.
     Note that scaling is buggy and could cause problems.
   - Hit 's' to switch between local and world space.
     The colour of the arrows should switch between green and red.
     (Note that local space is not available when many objects
     are selected.)
   - Hit 'p' to transform only the pivot point
     (the Manipulator's triad of arrows should look dashed),
     and hit 'p' again to leave this mode.
   - Sometimes the Manipulator may be mostly or completely obscured
     by the object's surrounding geometry.  If this happens,
     try dollying the camera back (the Manipulator maintains a constant
     size in screen space), or try switching to wireframe mode
     by hitting 'd'.
   - In summary,
     LMB drag     : translate
     MMB drag     : rotate
     LMB+MMB drag : scale
     s            : local/world space
     p            : transform pivot point/geometry

How to use the Brush:
   The Brush is used to sculpt triangle meshes.

   - Create an object with lots of triangles, such as a plane
     (F5) or a sphere (F6), and make sure it's selected.
   - Make sure you are in Brush mode and not Manipulator mode
     (you should see a bell-shaped or hat-shaped red thing when
     you pass the pointer over the surface of the selected object --
     if you don't, try hitting the space bar).
   - Click and release or click and drag with the LMB to pull the
     surface of the object out in the shape of the brush.
     Click MMB to push in.
   - If you have a serial mouse connected to act as a second mouse,
     click RMB2 and drag up/down to change the amplitude of the brush,
     or drag left/right to change the radius of the brush.
     You can, of course, use both mice simultaneously,
     to adjust the brush as you sculpt.  You can also orbit with
     the second mouse, using LMB2, as you sculpt with the first mouse.

     If you don't have a serial mouse, you can use Ctrl+Alt+LMB to
     change the amplitude and radius of the brush.

   - In summary,
     LMB            : pull
     MMB            : push
     Ctrl+Alt+LMB   : adjust brush amplitude and radius

     RMB2           : adjust brush amplitude and radius
     LMB2 drag      : orbit
     MMB2 drag      : pan
     LMB2+MMB2 drag : dolly

2-handed camera navigation:
   This is an experimental mode that doesn't work very well.

   Hit 'c' to go into 2-handed camera navigation mode,
   hit 'c' again to leave the mode.

   In 2-handed camera navigation mode, use

      LMB drag                  : pitch & yaw
      second mouse (no buttons) : pan

   Moving both mice in opposite directions simultaneously
   will effectively orbit the camera around a centre of interest.
   The relative speed of the user's motions will determine
   the distance of the centre of interest.

----------------------------------------------------------------------------
NOTES ON USING A SERIAL MOUSE
----------------------------------------------------------------------------
Part of the purpose of this application is to explore
2-handed interfaces.  The application is capable of
reading input from 2 mice at once.  The first mouse
(or primary mouse) is the one already supported by
GLUT, and hence the one supported by X, Windows, or
another OS, depending on what platform you're using.

To make input possible with a second mouse, I used
a serial mouse, and designed this application to read
input directly from the serial port, essentially
by-passing the OS.

If you're running Linux or UNIX, you should be able to
connect any "Mouse Systems"-compatible serial mouse
(as opposed to a Microsoft-compatible serial mouse)
to the serial port and have it work with this application.
(In practice, you may have to try 2 or 3 different
models of serial mice before you find one that works.
Personnally, a 3-button Logitech serial mouse
worked well for me.)

If you have problems,
- Make sure the application is reading the correct port.
  By default, the application reads /dev/ttyS0, which
  corresponds to serial port 1 on Redhat Linux.
  You might also try /dev/ttyS1 for serial port 2.
  If you're running Irix, try reading from
  /dev/ttyd1 or /dev/ttyd2.

  Grep for "/dev/tty" in the source code for the appropriate
  line of code to change.

- If you're running UNIX or Linux, make sure you have
  permission to read from the serial port.
  Check that the read permission bit(s) are set for /dev/ttyS0,
  or whatever device file you want to read.

- Try typing
     cat /dev/ttyS0
  (or whatever the appropriate device file is) at a UNIX shell prompt,
  and moving the serial mouse *as you hit enter* ...
  If you see garbage get printed out, it's a good sign.

- Make sure that your hardware is configured to enable the
  serial port (you may have to reboot your machine to check this).

----------------------------------------------------------------------------
SUMMARY OF CONTENTS OF SOURCE FILES
----------------------------------------------------------------------------
SerialMouse.{h,cc}
   class SerialMouse, which is used to read input from a serial mouse

global.h
   defines some ASSERTion macros

mathutil.{h,cc}
   class Vector3
   class Point3
   class Matrix
   class Ray
   class AlignedBox
   class LineSegment

drawutil.{h,cc}
   defines some subroutines for drawing things

Camera.{h,cc}
   class Camera

Object.{h,cc}
   class Triangle
   class VertexInfo
   class Object

Scene.{h,cc}
   class Scene, which contains an array of Objects

WorkSpace.{h,cc}
   class WorkSpace, which contains a Scene and some selection information

Tool.h
   class Tool

Manipulator.{h,cc}
   class Manipulator, derived from Tool

Brush.{h,cc}
   class Brush, derived from Tool

main.cc
   instantiates a SerialMouse, a Camera, a WorkSpace,
     a Manipulator, and a Brush
   uses GLUT to open a window
   contains the input event handlers

