Added Doxygen documentation.

This commit is contained in:
Paolo Cignoni 2007-07-14 12:43:44 +00:00
parent 787cfbe93f
commit b2e7a9e03b
2 changed files with 1096 additions and 239 deletions

View File

@ -2,8 +2,7 @@
* VCGLib o o * * VCGLib o o *
* Visual and Computer Graphics Library o o * * Visual and Computer Graphics Library o o *
* _ O _ * * _ O _ *
* Copyright(C) 2004 * Copyright(C) 2004 \/)\/ *
\/)\/ *
* Visual Computing Lab /\/| * * Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | * * ISTI - Italian National Research Council | *
* \ * * \ *
@ -25,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.15 2007/06/13 17:15:08 benedetti
Added one-level undo system and sticky trackmodes.
Revision 1.14 2007/05/15 15:00:47 benedetti Revision 1.14 2007/05/15 15:00:47 benedetti
Moved the drawing code to trackmodes, some other minor changes Moved the drawing code to trackmodes, some other minor changes
@ -72,52 +74,6 @@ Adding copyright.
****************************************************************************/ ****************************************************************************/
/****************************************************************************
Short usage note:
The trackball is a manipulator of an object
Center specify the center of rotation and scaling of the trackball and usually
is set by the program and do not interactively change
Radius specify the radius of the interactive ball shaped icon to specify rotation.
It is in absolute unit but it should be in screen related units like the previoous
one it is not changed during interaction.
When you specify a traslation with the trackball the trackball center remain UNCHANGED,
in other words it means that the object move out of the trackball icon.
Similarly when you apply a scaling the size of the iconshaped ball do not change.
Typical use:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, float(width())/float(height()), 1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,3, 0,0,0, 0,1,0);
trackball.center=Point3f(0, 0, 0);
trackball.radius= 1;
trackball.GetView();
trackball.Apply();
float d=1.0f/mesh.bbox.Diag();
glScale(d);
glTranslate(-mesh.bbox.Center());
mesh->Render();
Note on the typical use:
Perspective and gllookat are choosed to frame the origin centered 1-radius
trackball.
The final scale and translate are just to fit a generic mesh to the 1sized
origin centered where the trackball stays box.
The trackball works also on Orthographic projections
BUT that are not centered around origin (just move it back along the Z)
****************************************************************************/
#ifndef TRACKBALL_H #ifndef TRACKBALL_H
#define TRACKBALL_H #define TRACKBALL_H
@ -130,25 +86,80 @@ BUT that are not centered around origin (just move it back along the Z)
#include <map> #include <map>
namespace vcg { namespace vcg {
/* A trackball stores a transformation called 'track' that effectively rotate the object. /*!
the rotation center, and size are kept in center and radius. @brief The base class for Trackball.
This class is useful for using a Trackball instance in a scene graph,
as a sort of interactive transform.
*/ */
class Transform { class Transform {
public: public:
Transform(); /*!
Similarityf track; @brief The constructor.
/// track position in model space. default is 0,0,0 Initialize:
- track to the identity transform.
- center to origin 0,0,0.
- radius to unit size.
*/
Transform();
/// A trackball stores a transformation called 'track' that effectively rototranslate the object.
Similarityf track;
/// track position in model space.
Point3f center; Point3f center;
/// size of the widget in model space. /// size of the widget in model space.
float radius; float radius;
}; };
/*!
@brief Computes the linear interpolation between 2 transforms.
@param a The first transform.
@param b The second transform.
@param t The interpolation value (0: just a, 0.5: middle from a to b, 1: just b).
@return The linear interpolation.
*/
Transform interpolate(const Transform &a, const Transform &b, float t); Transform interpolate(const Transform &a, const Transform &b, float t);
class TrackMode; class TrackMode;
/*!
@brief The manipulator manager system.
<em>Short usage note:</em>
- Center specify the center of rotation and scaling of the trackball and usually is set by the program and do not interactively change
- Radius specify the radius of the interactive ball shaped icon to specify rotation. It is in absolute unit.
- Like the previous one it is not changed during interaction.
When you specify a translation with the trackball the trackball center remain \b unchanged, in other words it means that the object move out of the trackball icon. Similarly when you apply a scaling the size of the manipulator icon do not change.
Typical use:
<pre>
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, float(width())/float(height()), 1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,3, 0,0,0, 0,1,0)
trackball.center=Point3f(0, 0, 0);
trackball.radius= 1;
trackball.GetView();
trackball.Apply(true); //false if you want an invisible trackball
float d=1.0f/mesh.bbox.Diag();
glScale(d);
glTranslate(-mesh.bbox.Center());
mesh->Render();
</pre>
Note on the typical use:
- Perspective and glulookat are choosed to frame the origin centered 1-radius trackball.
- The final scale and translate are just to fit a generic mesh to the 1sized origin centered where the trackball stays box.
- The trackball works also on Orthographic projections \b but that are not centered around origin (just move it back along the Z)
*/
class Trackball: public Transform { class Trackball: public Transform {
public: public:
// the drawing code has been moved to the trackmodes // the drawing code has been moved to the trackmodes
@ -156,35 +167,105 @@ namespace vcg {
// DrawingHint DH; // DrawingHint DH;
/// The componibile states of the manipulator system.
enum Button { BUTTON_NONE = 0x0000, ///< No mouse button pressed.
BUTTON_LEFT = 0x0001, ///< Left mouse button pressed.
BUTTON_MIDDLE = 0x0002, ///< Middle mouse button pressed.
BUTTON_RIGHT = 0x0004, ///< Right mouse button pressed.
WHEEL = 0x0008, ///< Mouse wheel activated.
KEY_SHIFT = 0x0010, ///< Shift key pressed.
KEY_CTRL = 0x0020, ///< Ctrl key pressed.
KEY_ALT = 0x0040, ///< Alt key pressed.
HANDLE = 0x0080 ///< Application-defined state activated.
};
enum Button { BUTTON_NONE = 0x0000, /*!
BUTTON_LEFT = 0x0001, @brief The constructor.
BUTTON_MIDDLE = 0x0002,
BUTTON_RIGHT = 0x0004,
WHEEL = 0x0008,
KEY_SHIFT = 0x0010,
KEY_CTRL = 0x0020,
KEY_ALT = 0x0040,
HANDLE = 0x0080 };
Initialize the internal state with default values
and call setDefaultMapping().
*/
Trackball(); Trackball();
/*!
@brief The destructor.
@warning The destructor <b>does not</b> deallocate the memory allocated by setDefaultMapping(), because the application can change the modes map. This can lead to small memory leaks, so please explicitally delete any manipulator in the modes map if you are going to repeatly allocate and deallocate Trackball instances.
*/
~Trackball(); ~Trackball();
/*!
@brief Reset the trackball.
Equivalent to Reset().
*/
void SetIdentity(); void SetIdentity();
/*!
@brief Set the position of the trackball.
@param c The new position of the trackball.
@param millisec Currently not in use.
*/
void SetPosition(const Point3f &c, int millisec = 0); void SetPosition(const Point3f &c, int millisec = 0);
/*!
@brief Currently not in use.
@param s Currently not in use.
*/
void SetScale(const float s) {radius=s;}; void SetScale(const float s) {radius=s;};
/*!
@brief Currently not in use.
@param transform Currently not in use.
@param millisec Currently not in use.
*/
void SetTransform(const Transform &transform, int millisec = 0); void SetTransform(const Transform &transform, int millisec = 0);
/*!
@brief Apply a translation on the current transformation.
@param tr The translation vector.
*/
void Translate(Point3f tr); void Translate(Point3f tr);
/*!
@brief Apply a scaling on the current transformation.
@param f The scale factor.
*/
void Scale(const float f); void Scale(const float f);
//operating //operating
/*!
@brief Initialize the camera instance.
*/
void GetView(); void GetView();
/*!
@brief Apply the current transformation on the OpenGL modelview matrix.
@param Draw true if has to call DrawPostApply() after the application.
*/
void Apply(bool Draw); void Apply(bool Draw);
/*!
@brief Old application of the transformation.
@warning This function does \b not call DrawPostApply() after the application.
*/
void Apply (); void Apply ();
/*!
@brief Draw the current manipulator.
Call the draw function of the current manipulator.
If no manipulator is selected call the draw function of the manipulator associated to inactive_mode.
@warning This function assumes that the OpenGL modelview matrix has been initialized with Apply ().
*/
void DrawPostApply(); void DrawPostApply();
/*!
@brief Apply the \b inverse of current transformation on the OpenGL modelview matrix.
*/
void ApplyInverse(); void ApplyInverse();
// DrawIcon() has been moved to trackutils.h // DrawIcon() has been moved to trackutils.h
//void DrawIcon(); //void DrawIcon();
/*!
@brief Reset the transformation and every mapped manipulator.
*/
void Reset(); void Reset();
// DrawCircle (), DrawPlane(), DrawPlaneHandle() has been moved to trackutils.h // DrawCircle (), DrawPlane(), DrawPlaneHandle() has been moved to trackutils.h
@ -194,31 +275,126 @@ namespace vcg {
// void DrawPlaneHandle(); // void DrawPlaneHandle();
//interface //interface
/*!
@brief Interface function relative to mouse down event in QT/SDL.
@param button The new state.
*/
void MouseDown(/*Button*/ int button); void MouseDown(/*Button*/ int button);
/*!
@brief Interface function relative to mouse down event in QT/SDL.
@param x The horizontal coordinate of the mouse pointer.
@param y The vertical coordinate of the mouse pointer.
@param button The new state.
*/
void MouseDown(int x, int y, /*Button*/ int button); void MouseDown(int x, int y, /*Button*/ int button);
/*!
@brief Interface function relative to mouse down event in QT/SDL.
@param x The horizontal coordinate of the mouse pointer.
@param y The vertical coordinate of the mouse pointer.
*/
void MouseMove(int x, int y); void MouseMove(int x, int y);
/*!
@brief Interface function relative to mouse down event in QT/SDL.
@param x The horizontal coordinate of the mouse pointer.
@param y The vertical coordinate of the mouse pointer.
@param button The new state.
*/
void MouseUp(int x, int y, /*Button */ int button); void MouseUp(int x, int y, /*Button */ int button);
void MouseWheel(float notch); // it assumes that a notch of 1.0 is a single step of the wheel /*!
@brief Old interface function relative to mouse down event in QT/SDL.
@param notch The mouse wheel notch (1: one forward step, -1: one backward step).
*/
void MouseWheel(float notch);
/*!
@brief Interface function relative to mouse down event in QT/SDL.
@param notch The mouse wheel notch (1: one forward step, -1: one backward step).
@param button The new state.
*/
void MouseWheel (float notch, /*Button */ int button); void MouseWheel (float notch, /*Button */ int button);
/*!
@brief Interface function relative to key down event in QT/SDL.
@param button the new state.
*/
void ButtonUp(Button button); void ButtonUp(Button button);
/*!
@brief Interface function relative to key up event in QT/SDL.
@param button the new state.
*/
void ButtonDown(Button button); void ButtonDown(Button button);
/*!
@brief Undo function for manipulator system.
A call of this function restores the state before last user action.
This function calls %Undo() on every mapped manipulator.
*/
void Undo(); void Undo();
//default sensitivity 1 //default sensitivity 1
/*!
@brief Currently not in use.
@param s Currently not in use.
*/
void SetSensitivity(float s); void SetSensitivity(float s);
//spinning interface //spinning interface
/*!
@brief Currently not in use.
@param on Currently not in use.
*/
void SetSpinnable(bool on); void SetSpinnable(bool on);
/*!
@brief Currently not in use.
@return A meaningless boolean value.
*/
bool IsSpinnable(); bool IsSpinnable();
/*!
@brief Currently not in use.
@param spin Currently not in use.
*/
void SetSpinning(Quaternionf &spin); void SetSpinning(Quaternionf &spin);
/*!
@brief Currently not in use.
*/
void StopSpinning(); void StopSpinning();
/*!
@brief Currently not in use.
@return A meaningless boolean value.
*/
bool IsSpinning(); bool IsSpinning();
//interfaccia navigation: //interfaccia navigation:
/*!
@brief Currently not in use.
*/
void Back(); void Back();
/*!
@brief Currently not in use.
*/
void Forward(); void Forward();
/*!
@brief Currently not in use.
*/
void Home(); void Home();
/*!
@brief Currently not in use.
*/
void Store(); void Store();
/*!
@brief Currently not in use.
*/
void HistorySize(int lenght); void HistorySize(int lenght);
/* //internals // commented out no more used this stuff! /* //internals // commented out no more used this stuff!
@ -237,45 +413,83 @@ namespace vcg {
}; };
*/ */
// loads/stores current status from/to ascii stings // loads/stores current status from/to ascii stings
/*!
@brief Currently not in use.
@param st Currently not in use.
*/
void ToAscii(char * st); void ToAscii(char * st);
/*!
@brief Currently not in use.
@param st Currently not in use.
@return A meaningless boolean value.
*/
bool SetFromAscii(char * st); bool SetFromAscii(char * st);
//protected: //protected:
/// The reference for point projection and unprojection from screen space to modelspace.
View<float> camera; View<float> camera;
/*!
@brief Prepare Trackball and every mapped TrackMode for an user action.
This function is called automatically when an user action begins.
*/
void SetCurrentAction(); void SetCurrentAction();
/// Current state composition.
int current_button; int current_button;
/// The selected manipulator.
TrackMode *current_mode; TrackMode *current_mode;
// inactive_mode is used to draw the inactive trackball /// The inactive manipulator. It is drawed when Trackball is inactive.
// can be assigned, for example, to draw an area or a path
// even when the user is not interacting with it
TrackMode *inactive_mode; TrackMode *inactive_mode;
// reset modes to default mapping. /*!
@brief Reset modes to default mapping.
Set the default modes mapping.
The default mapping is:
- \b LEFT : SphereMode.
- \b LEFT+CTRL or \b MIDDLE : PanMode.
- \b LEFT+SHIFT or \b WHEEL : ScaleMode.
- \b LEFT+ALT : ZMode.
@warning The memory allocated by this function <b>is not</b> automatically deallocated. see ~Trackball().
*/
void setDefaultMapping (); void setDefaultMapping ();
/// The manipulator mapping. Needs to be explicitally managed for custom mappings.
std::map<int, TrackMode *> modes; std::map<int, TrackMode *> modes;
Similarityf last_track;
// undo_track and last_track have different meanings.. // undo_track and last_track have different meanings..
/// Transformation before current user action.
Similarityf last_track;
/// track after an Undo() call.
Similarityf undo_track; Similarityf undo_track;
/// Currently not in use.
Similarityf last_view; Similarityf last_view;
/// Mouse cursor coordinates before current action.
Point3f last_point; Point3f last_point;
/// Currently not in use.
std::vector<Point3f> Hits; std::vector<Point3f> Hits;
/// Currently not in use.
bool dragging; bool dragging;
/// Currently not in use.
int button_mask; int button_mask;
/// Currently not in use.
Quaternionf spin; Quaternionf spin;
/// Currently not in use.
bool spinnable; bool spinnable;
/// Currently not in use.
bool spinning; bool spinning;
/// Currently not in use.
std::list<Transform> history; std::list<Transform> history;
/// Currently not in use.
int history_size; int history_size;
/// Manipulators needs full access to this class.
friend class TrackMode; friend class TrackMode;
}; };

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.14 2007/07/09 22:47:18 benedetti
Removed using namespace std and modified accordingly.
Revision 1.13 2007/06/25 10:21:38 fiorin Revision 1.13 2007/06/25 10:21:38 fiorin
Added some std:: here and there Added some std:: here and there
@ -76,31 +79,111 @@ namespace vcg {
class Trackball; class Trackball;
// Base class for all the track modes. /*!
// This class' functions does nothing. @brief Base class for all the manipulators.
Functions in this class implements the default
behaviour of a manipulator: <em>doing nothing</em>.
Every manipulator must be subclass of this class.
*/
class TrackMode { class TrackMode {
public: public:
/*!
@brief The default virtual destructor
*/
virtual ~TrackMode () { virtual ~TrackMode () {
} }
/*!
@brief The default manipulator application for mouse drags.
This default application does nothing.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
virtual void Apply (Trackball * trackball, Point3f new_point); virtual void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief The default manipulator application for mouse scrolls.
This default application does nothing.
@param trackball the manipulator manager.
@param WheelNotch the mouse wheel notch.
*/
virtual void Apply (Trackball * trackball, float WheelNotch); virtual void Apply (Trackball * trackball, float WheelNotch);
/*!
@brief The default manipulator's begin action function.
This default implementation does nothing.
*/
virtual void SetAction (); virtual void SetAction ();
/*!
@brief The default manipulator's reset function.
If a manipulator has a state, it can be reset to the inital state calling this function.
*/
virtual void Reset (); virtual void Reset ();
/*!
@brief The default manipulator's name.
@return the constant string "TrackMode"
*/
virtual const char *Name (){ virtual const char *Name (){
return "TrackMode"; return "TrackMode";
}; };
/*!
@brief The default manipulator's render function.
@param trackball the manipulator manager.
*/
virtual void Draw (Trackball * trackball); virtual void Draw (Trackball * trackball);
/*!
@brief The default avaibility to manipulator changes inside an action.
Every manipulator class can choose if the manipulator manager can switch
between it and another manipulator in the middle of an user action,
e.g. switching Trackball's current_mode without releasing the mouse button.
The default behaviour is to allow the switch.
Blocking switches is useful for stateful manipulators, regarding state
consistency respect to Trackball's %Undo() calls.
@return false if manipulator permits the switch.
*/
virtual bool isSticky(); virtual bool isSticky();
/*!
@brief The default manipulator's undo function.
If a manipulator has a state, it must be undoable with a call of this function.
The undo must recreate the state present before the last Apply() call.
This default implementation does nothing.
*/
virtual void Undo(); virtual void Undo();
}; };
// Inactive mode. /*!
// useful only for drawing the inactive trackball @brief An inactive manipulator.
This manipulator is useful only for drawing the inactive trackball
and for feeding occasional Trackball's modes with inactive manipulators.
*/
class InactiveMode:public TrackMode { class InactiveMode:public TrackMode {
public: public:
/*!
@brief Return this manipulator's name.
@return the constant string "InactiveMode"
*/
const char *Name () { const char *Name () {
return "InactiveMode"; return "InactiveMode";
}; };
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
}; };
@ -125,146 +208,460 @@ class ScaleMode: public TrackMode {
*/ */
// Sphere mode. // Sphere mode.
// The classic trackball. /*!
@brief The classic \e arcball manipulator.
This class implements the classic free rotation manipulator,
called \e arcball or \e trackball.
This is a stateless manipulator, result of the Apply function is
determined only by the mouse coordinates.
*/
class SphereMode:public TrackMode { class SphereMode:public TrackMode {
public: public:
/*!
@brief Apply a rotation, function of the user mouse drag action.
Map a mouse drag action on a rotation, and apply the rotation to the manipulated objects.
If the user does not hit the sphere that surrounds the manipulated object(s),
a rotational hyperboloid is used to compute the rotation.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
void Apply (Trackball * trackball, Point3f new_point); void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief Return this manipulator's name.
@return the constant string "SphereMode"
*/
const char *Name () { const char *Name () {
return "SphereMode"; return "SphereMode";
}; };
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
}; };
// Panning mode. // Panning mode.
// The user can drag the model on the view plane. /*!
@brief The panning manipulator.
This manipulator implements a bidimensional translation
on the view plane.
This is a stateless manipulator, result of the Apply function is
determined only by the mouse coordinates.
*/
class PanMode:public TrackMode { class PanMode:public TrackMode {
public: public:
/*!
@brief Apply a translation, function of the user mouse drag action.
The manipulated object is dragged in the plane parallel to the screen.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
void Apply (Trackball * trackball, Point3f new_point); void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief Return this manipulator's name.
@return the constant string "PanMode"
*/
const char *Name () { const char *Name () {
return "PanMode"; return "PanMode";
}; };
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
}; };
// Z mode. // Z mode.
// Dragging the mouse up and down or scrolling the /*!
// mouse wheel will move the object along the Z of the camera. @brief The Z-directional manipulator.
This manipulator implements a monodimensional translation
on the axis normal to the view plane.
Dragging the mouse up and down or scrolling the
mouse wheel will move the object along the Z of the camera.
This is a stateless manipulator, result of the Apply functions is
determined only either by the mouse coordinates or by the mouse wheel notch.
*/
class ZMode:public TrackMode { class ZMode:public TrackMode {
public: public:
/*!
@brief Return this manipulator's name.
@return the constant string "ZMode"
*/
const char *Name () { const char *Name () {
return "ZMode"; return "ZMode";
}; };
/*!
@brief Apply a translation, function of the user mouse drag action.
The manipulated object is moved along the Z of the camera:
- Dragging the mouse down will move the object nearer to the camera.
- Dragging the mouse up will move the object farther from the camera.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
void Apply (Trackball * trackball, Point3f new_point); void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief Apply a translation, function of the user mouse wheel action.
The manipulated object is moved along the Z of the camera:
- Scrolling the mouse wheel down will move the object nearer to the camera.
- Scrolling the mouse wheel up will move the object farther from the camera.
@param trackball the manipulator manager.
@param WheelNotch the mouse wheel notch.
*/
void Apply (Trackball * trackball, float WheelNotch); void Apply (Trackball * trackball, float WheelNotch);
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
}; };
// Scale Mode. // Scale Mode.
// Dragging the mouse up and down or scrolling the /*!
// mouse wheel will scale the object. @brief The scale manipulator.
This manipulator implements a scaling transformation.
Dragging the mouse up and down or scrolling the
mouse wheel will scale the object.
This is a stateless manipulator, result of the Apply functions is
determined only either by the mouse coordinates or by the mouse wheel notch.
*/
class ScaleMode:public TrackMode { class ScaleMode:public TrackMode {
public: public:
/*!
@brief Return this manipulator's name.
@return the constant string "ScaleMode"
*/
const char *Name () { const char *Name () {
return "ScaleMode"; return "ScaleMode";
}; };
/*!
@brief Apply a scaling, function of the user mouse drag action.
The manipulated object is scaled in this way:
- Dragging the mouse up will scale the object to a smaller dimension.
- Dragging the mouse down will scale the object to a greater dimension.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
void Apply (Trackball * trackball, Point3f new_point); void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief Apply a scaling, function of the user mouse wheel action.
The manipulated object is scaled in this way:
- Scrolling the mouse wheel up will scale the object to a smaller dimension.
- Scrolling the mouse wheel down will scale the object to a greater dimension.
@param trackball the manipulator manager.
@param WheelNotch the mouse wheel notch.
*/
void Apply (Trackball * trackball, float WheelNotch); void Apply (Trackball * trackball, float WheelNotch);
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
}; };
// Axis mode. // Axis mode.
// Moves the object in a costrained direction. /*!
// The user can either drag the mouse or scroll the wheel. @brief The one-directional manipulator.
// The direction can be specified either with a line
// or a origin and a direction. This manipulator implements a monodimensional translation
// the object posistion is not needed to be on the line. on a constrained direction.
Dragging the mouse up and down or scrolling the
mouse wheel will move the object along the direction.
This is a stateless manipulator, result of the Apply functions is
determined only either by the mouse coordinates or by the mouse wheel notch.
*/
class AxisMode:public TrackMode { class AxisMode:public TrackMode {
public: public:
/*!
@brief The line constructor.
This manipulator needs to be initialized with a direction.
This constructor can initialize it with a Line3f.
The line will be normalized.
@param ln the line that represent the direction.
*/
AxisMode (const Line3f & ln) AxisMode (const Line3f & ln)
: axis (ln) { : axis (ln) {
} }
/*!
@brief The origin-direction constructor.
This manipulator needs to be initialized with a direction.
This constructor can initialize it with two Point3f,
representing a point and a vector.
@param origin a point on the line.
@param direction the line direction.
*/
AxisMode (const Point3f & origin, const Point3f & direction) { AxisMode (const Point3f & origin, const Point3f & direction) {
axis = Line3fN (origin, direction); axis = Line3fN (origin, direction);
} }
/*!
@brief Return this manipulator's name.
@return the constant string "AxisMode"
*/
const char *Name () { const char *Name () {
return "AxisMode"; return "AxisMode";
}; };
/*!
@brief Apply a translation, function of the user mouse drag action.
The manipulated object is moved along the direction.
If the pointer ray is divergent from the direction the
object is not moved.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
void Apply (Trackball * trackball, Point3f new_point); void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief Apply a translation, function of the user mouse wheel action.
The manipulated object is moved along the direction.
@param trackball the manipulator manager.
@param WheelNotch the mouse wheel notch.
*/
void Apply (Trackball * trackball, float WheelNotch); void Apply (Trackball * trackball, float WheelNotch);
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
private: private:
/// The direction, stored as a normalized line.
Line3fN axis; Line3fN axis;
}; };
// Plane mode. // Plane mode.
// The user can drag the object in a costrained plane. /*!
// The plane can be specified either with a plane @brief The planar manipulator.
// or the plane's equation parameters
// the object posistion is not needed to be on the plane. This manipulator implements a bidimensional translation
on a constrained plane.
This is a stateless manipulator, result of the Apply function is
determined only by the mouse coordinates.
*/
class PlaneMode:public TrackMode { class PlaneMode:public TrackMode {
public: public:
/*!
@brief The plane costants constructor.
This manipulator needs to be initialized with a plane.
This constructor can initialize it with the four coefficients
of the plane equation \f$ ax + by + cz + d = 0 \f$.
@param a the first coefficient of the plane equation.
@param b the second coefficient of the plane equation.
@param c the third coefficient of the plane equation.
@param d the fourth coefficient of the plane equation.
*/
PlaneMode (float a, float b, float c, float d) PlaneMode (float a, float b, float c, float d)
: plane(Plane3f(d,Point3f(a,b,c))){ : plane(Plane3f(d,Point3f(a,b,c))){
} }
/*!
@brief The plane constructor.
This manipulator needs to be initialized with a plane.
This constructor can initialize it with a Plane3f.
@param pl the plane.
*/
PlaneMode (Plane3f & pl) PlaneMode (Plane3f & pl)
: plane(pl) { : plane(pl) {
} }
/*!
@brief Return this manipulator's name.
@return the constant string "PlaneMode"
*/
const char *Name () { const char *Name () {
return "PlaneMode"; return "PlaneMode";
}; };
/*!
@brief Apply a translation, function of the user mouse drag action.
The manipulated object is dragged in the plane.
If the pointer ray is divergent from the plane the
object is not moved.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
void Apply (Trackball * trackball, Point3f new_point); void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
private: private:
/// The plane.
Plane3f plane; Plane3f plane;
}; };
// Cylinder mode. // Cylinder mode.
// Rotates the object along a fixed axis /*!
// The user can either drag the mouse or scroll the wheel, @brief The constrained rotation manipulator.
// in either cases the rotation's angle is influenced by
// the radius of the trackball. This manipulator implements a rotation manipulator, that
// The axis can be specified either with a line make the rotation constrained around a given axis.
// or a origin and a direction
// when the user drags the mouse, if the axis is too The user can either drag the mouse or scroll the wheel,
// perpendicular to view plane, the angle is specified in either cases the rotation's angle is influenced by
// only by the vertical component of the mouse drag and the radius. the radius of the trackball.
This is a stateless manipulator, result of the Apply functions is
determined only either by the mouse coordinates or by the mouse wheel notch.
*/
class CylinderMode:public TrackMode { class CylinderMode:public TrackMode {
public: public:
/*!
@brief The line constructor.
This manipulator needs to be initialized with an axis.
This constructor can initialize it with a Line3f.
The line will be normalized.
@param ln the line that represent the axis.
*/
CylinderMode (Line3fN & ln) CylinderMode (Line3fN & ln)
: axis (ln){ : axis (ln){
} }
/*!
@brief The origin-direction constructor.
This manipulator needs to be initialized with a axis.
This constructor can initialize it with two Point3f,
representing a point and a vector.
@param origin a point on the axis.
@param direction the axis direction.
*/
CylinderMode (const Point3f & origin, const Point3f & direction) CylinderMode (const Point3f & origin, const Point3f & direction)
: axis (Line3fN(origin,direction)){ : axis (Line3fN(origin,direction)){
} }
/*!
@brief Return this manipulator's name.
@return the constant string "CylinderMode"
*/
const char *Name () { const char *Name () {
return "CylinderMode"; return "CylinderMode";
}; };
/*!
@brief Apply a rotation, function of the user mouse drag action.
The manipulated object is rotated around the axis.
if the axis is too perpendicular to view plane, the angle is specified
only by the vertical component of the mouse drag and the radius.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
void Apply (Trackball * trackball, Point3f new_point); void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief Apply a rotation, function of the user mouse wheel action.
The manipulated object is rotated around the axis.
@param trackball the manipulator manager.
@param WheelNotch the mouse wheel notch.
*/
void Apply (Trackball * trackball, float WheelNotch); void Apply (Trackball * trackball, float WheelNotch);
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
private: private:
/// The axis, stored as a normalized line.
Line3fN axis; Line3fN axis;
}; };
// Path mode. // Path mode.
// move the object along an eventually closed path. /*!
// The user can either drag the mouse or scroll the wheel, @brief The path constrained manipulator.
// when the user drags the mouse, the object tries to slide toward it.
// if the path is a simple segment, it can be specified just with the endpoints, This manipulator moves the object along an eventually closed path.
// otherwise it's specified with a point vector and, eventually, a boolean value used for closing the path.
// the object is assumed to initially be on the same position of the first point on the path. The user can either drag the mouse or scroll the wheel,
// you can try to set the starting point calling SetStartNear(Point3f) when the user drags the mouse, the object tries to slide toward it.
// the path is NOT assumed to have 0-length segments, so, if you want to close the path, please DO NOT add
// a copy of the first point on the end of the vector... The object is assumed to initially be on the same position
// the vector passed to build the path is copied locally. of the first point on the path.
This is a \b stateful manipulator, result of the Apply functions is
determined by the objects's position along the path and
by either the mouse coordinates or the mouse wheel notch.
*/
class PathMode:public TrackMode { class PathMode:public TrackMode {
public: public:
/*!
@brief The vector-boolean constructor.
The vector passed to build the path is copied locally.
The boolean value specifies if the path is to be closed.
If the boolean value is not specified, the path is not closed.
@warning the path is \b not assumed to have 0-length segments, so, if you want to close the path, please <b>do not</b> add a copy of the first point on the end of the vector.
@param pts the path nodes.
@param w a boolean value that closes the path.
*/
PathMode ( const std::vector < Point3f > &pts, bool w = false) PathMode ( const std::vector < Point3f > &pts, bool w = false)
: points(), wrap(w), current_state(0), initial_state(0), old_hitpoint() : points(), wrap(w), current_state(0), initial_state(0), old_hitpoint()
{ {
Init(pts); Init(pts);
assert(min_seg_length > 0.0f); assert(min_seg_length > 0.0f);
} }
/*!
@brief The segment constructor.
If the path is a simple segment, it can be specified just with the endpoints.
@param start the starting point.
@param end the ending point.
*/
PathMode ( const Point3f &start, const Point3f &end ) PathMode ( const Point3f &start, const Point3f &end )
: points(), wrap(false), current_state(0), initial_state(0), old_hitpoint() : points(), wrap(false), current_state(0), initial_state(0), old_hitpoint()
{ {
@ -274,91 +671,337 @@ public:
min_seg_length=path_length; min_seg_length=path_length;
assert(min_seg_length > 0.0f); assert(min_seg_length > 0.0f);
} }
/*!
@brief Return this manipulator's name.
@return the constant string "PathMode"
*/
const char *Name () { const char *Name () {
return "PathMode"; return "PathMode";
}; };
/*!
@brief Apply a translation, function of the user mouse drag action.
The manipulated object is moved along the path.
This function implements an algorithm that makes
the object try to slide on the path towards the
mouse pointer.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
void Apply (Trackball * trackball, Point3f new_point); void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief Apply a translation, function of the user mouse wheel action.
The manipulated object is moved along the path.
A step of the mouse wheel makes the object slide
by a distance equal to the half of the shortest
segment on the path.
@param trackball the manipulator manager.
@param WheelNotch the mouse wheel notch.
*/
void Apply (Trackball * trackball, float WheelNotch); void Apply (Trackball * trackball, float WheelNotch);
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
/*!
@brief The begin action function.
This function is to be called at the begin of an user action.
*/
void SetAction (); void SetAction ();
/*!
@brief The reset function.
This function reset the object position to the initial point.
*/
void Reset (); void Reset ();
/*!
@brief Try to set the inital point.
This function try to set the starting point in the point
passed as parameter, if the point passed does not reside
on the path, the start is put on the closest point on it.
@param p the point wished for the start.
@return the starting point on the path.
*/
Point3f SetStartNear(Point3f p); Point3f SetStartNear(Point3f p);
/*!
@brief The (non) avaibility to manipulator changes inside an action.
This manipulator has an internal state and does not allow a
switch in the middle of a function.
@return the costant boolean true.
*/
bool isSticky(); bool isSticky();
/*!
@brief The undo function.
This function recreates the state present before the last Apply() call.
*/
void Undo(); void Undo();
private: private:
/*!
@brief The data initializer.
Initialize the internal state and checks params validity.
@param points the path nodes.
*/
void Init(const std::vector < Point3f > &points); void Init(const std::vector < Point3f > &points);
/*!
@brief The state interpreter.
Given the state, return the current point, the previous node and
the next node on the path.
The algoritm is linear in the node paths.
@param state the given state.
@param point is set to the current point.
@param prev_point is set to the point of current point's previous node.
@param next_point is set to the point of current point's next node.
*/
void GetPoints(float state, Point3f & point, Point3f & prev_point, Point3f & next_point); void GetPoints(float state, Point3f & point, Point3f & prev_point, Point3f & next_point);
/*!
@brief The state normalizer.
Normalize a given state in the right interval:
- \f$ [0 \ldots 1] \f$ if the path is open.
- \f$ [0 \ldots 1) \f$ if the path is closed (because it wraps).
@param state the given state.
*/
float Normalize(float state); float Normalize(float state);
/*!
@brief Compute the new point and the \f$\Delta\f$-state.
Given a state and the mouse coords ray, computes the new
state point and return the \f$\Delta\f$-state.
The algoritm is linear in the node paths.
@param state the given state.
@param ray the ray relative to mouse coords.
@param hit_point is set to the new state point.
@return the \f$\Delta\f$-state.
*/
float HitPoint(float state, Ray3fN ray, Point3f &hit_point); float HitPoint(float state, Ray3fN ray, Point3f &hit_point);
/*!
@brief Compute the verse to follow for slide nearer to a given point.
Given the current state point, the point of previus and
next node and a reference point, compute the verse to
follow for the object to come closer to the reference point.
@param reference_point
@param current_point
@param prev_point
@param next_point
@return -1, 0 or 1 if the verse is respectively towars the startpoint, null or towards the endpoint.
*/
int Verse(Point3f reference_point,Point3f current_point,Point3f prev_point,Point3f next_point); int Verse(Point3f reference_point,Point3f current_point,Point3f prev_point,Point3f next_point);
/// The node vector.
std::vector < Point3f > points; std::vector < Point3f > points;
/// True if the path is closed, false otherwise.
bool wrap; bool wrap;
/// The current state.
float current_state; float current_state;
/// The initial state.
float initial_state; float initial_state;
/// The path length.
float path_length; float path_length;
/// The length of the shostest path segment
float min_seg_length; float min_seg_length;
/// The point relative to the old state.
Point3f old_hitpoint; Point3f old_hitpoint;
/// current_state after an Undo() call.
float undo_current_state; float undo_current_state;
/// old_hitpoint after an Undo() call.
Point3f undo_old_hitpoint; Point3f undo_old_hitpoint;
}; };
// Area mode. // Area mode.
// The user can drag the object inside a planar area, defined by a polygon. /*!
// the polygon can be non convex, and is specified with a vector of vertexes @brief The area constrained manipulator.
// if the object's trajectory intersects some poligon side, it tries to slide
// around it, in a "rubber band flavoured" way.
// for the vertexes vector its calculated the plane of the polygon, and then
// every point in the vector is projected on this plane.
// the object is assumed to initially be on the same position of the first vertex.
// you can try to set the starting point calling SetStartNear(Point3f)
// the vector is assumed to be formed of NON collinear points
// the polygon is NOT assumed to have 0-length sides, so please DO NOT add
// a copy of the first point on the end of the vector...
// the vector passed to build the polygon is copied locally.
This manipulator moves the object inside a poligonal area.
The user can drag the object inside a planar area, defined by a polygon.
The polygon can be non convex, and is specified with a vector of vertexes.
If the object's trajectory intersects some poligon side, it tries to slide
around it, in a <em>"rubber band flavoured"</em> way.
The object is assumed to initially be on the same position of the
first vertex.
This is a \b stateful manipulator, result of the Apply function is
determined by the objects's position inside the area and
by the mouse coordinates.
*/
class AreaMode:public TrackMode { class AreaMode:public TrackMode {
public: public:
/*!
@brief The constructor.
From the given vector, is calculated the plane of the polygon, then
every point in the vector is projected on this plane.
The vector passed to build the polygon is copied locally.
@warning The vector is assumed to be formed of \b non collinear points.
@warning The polygon is \b not assumed to have 0-length sides, so please <b>do not</b> add a copy of the first point on the end of the vector.
@param pts the vertexes vector.
*/
AreaMode (const std::vector < Point3f > &pts) AreaMode (const std::vector < Point3f > &pts)
{ {
Init(pts); Init(pts);
assert(min_side_length > 0.0f); assert(min_side_length > 0.0f);
} }
/*!
@brief Return this manipulator's name.
@return the constant string "AreaMode"
*/
const char *Name () { const char *Name () {
return "AreaMode"; return "AreaMode";
}; };
/*!
@brief Apply a translation, function of the user mouse drag action.
The manipulated object is moved inside the poligon.
This function implements an algorithm that makes
the object try to slide around the polygon borders.
@param trackball the manipulator manager.
@param new_point the new mouse pointer coordinate.
*/
void Apply (Trackball * trackball, Point3f new_point); void Apply (Trackball * trackball, Point3f new_point);
/*!
@brief Render this manipulator.
@param trackball the manipulator manager.
*/
void Draw (Trackball * trackball); void Draw (Trackball * trackball);
/*!
@brief The begin action function.
This function is to be called at the begin of an user action.
*/
void SetAction (); void SetAction ();
/*!
@brief The reset function.
This function reset the object position to the initial point.
*/
void Reset (); void Reset ();
/*!
@brief Try to set the inital point.
This function try to set the starting point in the point
passed as parameter, if the point passed does not reside
in the area, the start is put in the closest point on it.
@param p the point wished for the start.
@return the starting point in the area.
*/
Point3f SetStartNear(Point3f p); Point3f SetStartNear(Point3f p);
/*!
@brief The (non) avaibility to manipulator changes inside an action.
This manipulator has an internal state and does not allow a
switch in the middle of a function.
@return The costant boolean true.
*/
bool isSticky(); bool isSticky();
/*!
@brief The undo function.
This function recreates the state present before the last Apply() call.
*/
void Undo(); void Undo();
private: private:
/*!
@brief The data initializer.
Initialize the internal state and checks params validity.
@param pts The polygon vertexes.
*/
void Init(const std::vector < Point3f > &pts); void Init(const std::vector < Point3f > &pts);
/*!
@brief Point in Polygon test.
Checks if a given point relies inside the poligon area,
using the ray tracing algorithm, linear in the number
of vertexes.
@param point The point to test.
@return true if the point is inside the polygon, false otherwise.
*/
bool Inside(Point3f point); bool Inside(Point3f point);
/*!
@brief Try to move the object inside the polygon
Given a point inside the area and a destination in the
poligon plane, try to move the point toward the destination,
sliding on any evenual border of the polygon.
The object can be imagined tied with a rubber attached to
destination, so it won't go back from it to slide around a border.
The algorithm is quadratic in the number of vertexes
(worst case, really really unlikely).
@param start the starting point <b>assumed inside</b>.
@param end the destination <b>assumed in the plane</b>.
@return the final move vector.
*/
Point3f Move(Point3f start,Point3f end); Point3f Move(Point3f start,Point3f end);
/// The vertexes vector.
std::vector < Point3f > points; std::vector < Point3f > points;
/// True in time inteval between a call to SetAction () and a call to Apply()
bool begin_action; bool begin_action;
/// One of the two dimensions used during the point in polygon test.
int first_coord_kept; int first_coord_kept;
/// One of the two dimensions used during the point in polygon test.
int second_coord_kept; int second_coord_kept;
/// The length of the shortest border
float min_side_length; float min_side_length;
/// The current status.
Point3f status; Point3f status;
/// The screen space differenve between the object and the cursor during an action.
Point3f delta_mouse; Point3f delta_mouse;
/// The old status.
Point3f old_status; Point3f old_status;
/// The initial status.
Point3f initial_status; Point3f initial_status;
/// The polygon plane
Plane3f plane; Plane3f plane;
/// The rubberband handle (current destination in Move())
Point3f rubberband_handle ; Point3f rubberband_handle ;
/// Current action's object trace
std::vector < Point3f > path; std::vector < Point3f > path;
/// begin_action after an Undo() call.
bool undo_begin_action; bool undo_begin_action;
/// status after an Undo() call.
Point3f undo_status; Point3f undo_status;
/// delta_mouse after an Undo() call.
Point3f undo_delta_mouse; Point3f undo_delta_mouse;
/// old_status after an Undo() call.
Point3f undo_old_status; Point3f undo_old_status;
/// rubberband_handle after an Undo() call.
Point3f undo_rubberband_handle; Point3f undo_rubberband_handle;
/// path endpoint after an Undo() call.
unsigned int undo_path_index; unsigned int undo_path_index;
}; };