camera.h   camera.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 30 skipping to change at line 30
*************************************************************************** **/ *************************************************************************** **/
#ifndef QGLVIEWER_CAMERA_H #ifndef QGLVIEWER_CAMERA_H
#define QGLVIEWER_CAMERA_H #define QGLVIEWER_CAMERA_H
#include "manipulatedCameraFrame.h" #include "manipulatedCameraFrame.h"
#include "keyFrameInterpolator.h" #include "keyFrameInterpolator.h"
namespace qglviewer { namespace qglviewer {
/*! \brief A perspective or orthographic camera. /*! \brief A perspective or orthographic camera.
\class Camera camera.h QGLViewer/camera.h \class Camera camera.h QGLViewer/camera.h
A Camera defines some intrinsic parameters (fieldOfView(), position(), vi ewDirection(), A Camera defines some intrinsic parameters (fieldOfView(), position(), vi ewDirection(),
upVector()...) and useful positioning tools that ease its placement (show EntireScene(), upVector()...) and useful positioning tools that ease its placement (show EntireScene(),
fitSphere(), lookAt()...). It exports its associated OpenGL projection an d modelview matrices and fitSphere(), lookAt()...). It exports its associated OpenGL projection an d modelview matrices and
can interactively be modified using the mouse. can interactively be modified using the mouse.
<h3>Mouse manipulation</h3> <h3>Mouse manipulation</h3>
The position() and orientation() of the Camera are defined by a Manipulat edCameraFrame (retrieved The position() and orientation() of the Camera are defined by a Manipulat edCameraFrame (retrieved
skipping to change at line 81 skipping to change at line 81
Use cameraCoordinatesOf() and worldCoordinatesOf() to convert to and from the Camera frame() Use cameraCoordinatesOf() and worldCoordinatesOf() to convert to and from the Camera frame()
coordinate system. projectedCoordinatesOf() and unprojectedCoordinatesOf( ) will convert from coordinate system. projectedCoordinatesOf() and unprojectedCoordinatesOf( ) will convert from
screen to 3D coordinates. convertClickToLine() is very useful for analyti cal object selection. screen to 3D coordinates. convertClickToLine() is very useful for analyti cal object selection.
Stereo display is possible on machines with quad buffer capabilities (wit h Camera::PERSPECTIVE Stereo display is possible on machines with quad buffer capabilities (wit h Camera::PERSPECTIVE
type() only). Test the <a href="../examples/stereoViewer.html">stereoView er example</a> to check. type() only). Test the <a href="../examples/stereoViewer.html">stereoView er example</a> to check.
A Camera can also be used outside of a QGLViewer or even without OpenGL f or its coordinate system A Camera can also be used outside of a QGLViewer or even without OpenGL f or its coordinate system
conversion capabilities. Note however that some of them explicitly rely o n the presence of a conversion capabilities. Note however that some of them explicitly rely o n the presence of a
Z-buffer. \nosubgrouping */ Z-buffer. \nosubgrouping */
class QGLVIEWER_EXPORT Camera : public QObject class QGLVIEWER_EXPORT Camera : public QObject
{ {
#ifndef DOXYGEN #ifndef DOXYGEN
friend class ::QGLViewer; friend class ::QGLViewer;
#endif #endif
Q_OBJECT Q_OBJECT
public: public:
Camera(); Camera();
virtual ~Camera(); virtual ~Camera();
Camera(const Camera& camera);
Camera& operator=(const Camera& camera);
/*! Enumerates the two possible types of Camera.
See type() and setType(). This type mainly defines different Camera pro
jection matrix (see
loadProjectionMatrix()). Many other methods (pointUnderPixel(), convert
ClickToLine(),
projectedCoordinatesOf(), pixelGLRatio()...) take this Type into accoun
t. */
enum Type { PERSPECTIVE, ORTHOGRAPHIC };
/*! @name Position and orientation */
//@{
public:
/*! Returns the Camera position (the eye), defined in the world coordin
ate system.
Use setPosition() to set the Camera position. Other convenient methods
are showEntireScene() or
fitSphere(). Actually returns \c frame()->position().
This position corresponds to the projection center of a Camera::PERSPEC
TIVE Camera. It is not
located in the image plane, which is at a zNear() distance ahead. */
Vec position() const { return frame()->position(); };
/*! Returns the normalized up vector of the Camera, defined in the worl
d coordinate system.
Set using setUpVector() or setOrientation(). It is orthogonal to viewDi
rection() and to
rightVector().
It corresponds to the Y axis of the associated frame() (actually return
s
frame()->inverseTransformOf(Vec(0.0, 1.0, 0.0)) ). */
Vec upVector() const
{
return frame()->inverseTransformOf(Vec(0.0, 1.0, 0.0));
}
/*! Returns the normalized view direction of the Camera, defined in the
world coordinate system.
Change this value using setViewDirection(), lookAt() or setOrientation(
). It is orthogonal to
upVector() and to rightVector().
This corresponds to the negative Z axis of the frame() ( frame()->inver
seTransformOf(Vec(0.0,
0.0, -1.0)) ). */
Vec viewDirection() const { return frame()->inverseTransformOf(Vec(0.0,
0.0, -1.0)); };
/*! Returns the normalized right vector of the Camera, defined in the w
orld coordinate system.
This vector lies in the Camera horizontal plane, directed along the X a
xis (orthogonal to
upVector() and to viewDirection()). Set using setUpVector(), lookAt() o
r setOrientation().
Simply returns frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0)). */
Vec rightVector() const
{
return frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0));
}
/*! Returns the Camera orientation, defined in the world coordinate sys
tem.
Actually returns \c frame()->orientation(). Use setOrientation(), setUp
Vector() or lookAt() to
set the Camera orientation. */
Quaternion orientation() const { return frame()->orientation(); };
void setFromModelViewMatrix(const GLdouble* const modelViewMatrix);
void setFromProjectionMatrix(const float matrix[12]);
public Q_SLOTS:
/*! Sets the Camera position() (the eye), defined in the world coordina
te system. */
void setPosition(const Vec& pos) { frame()->setPosition(pos); };
void setOrientation(const Quaternion& q);
void setOrientation(float theta, float phi);
void setUpVector(const Vec& up, bool noMove=true);
void setViewDirection(const Vec& direction);
//@}
/*! @name Positioning tools */
//@{
public Q_SLOTS:
void lookAt(const Vec& target);
void showEntireScene();
void fitSphere(const Vec& center, float radius);
void fitBoundingBox(const Vec& min, const Vec& max);
void fitScreenRegion(const QRect& rectangle);
void centerScene();
void interpolateToZoomOnPixel(const QPoint& pixel);
void interpolateToFitScene();
void interpolateTo(const Frame& fr, float duration);
//@}
/*! @name Frustum */
//@{
public:
/*! Returns the Camera::Type of the Camera.
Set by setType(). Mainly used by loadProjectionMatrix().
A Camera::PERSPECTIVE Camera uses a classical projection mainly defined
by its fieldOfView().
With a Camera::ORTHOGRAPHIC type(), the fieldOfView() is meaningless an
d the width and height of
the Camera frustum are inferred from the distance to the revolveAroundP
oint() using
getOrthoWidthHeight().
Both types use zNear() and zFar() (to define their clipping planes) and
aspectRatio() (for
frustum shape). */
Type type() const { return type_; };
/*! Returns the vertical field of view of the Camera (in radians).
Value is set using setFieldOfView(). Default value is pi/4 radians. Thi
s value is meaningless if
the Camera type() is Camera::ORTHOGRAPHIC.
The field of view corresponds the one used in \c gluPerspective (see ma
nual). It sets the Y
(vertical) aperture of the Camera. The X (horizontal) angle is inferred
from the window aspect
ratio (see aspectRatio() and horizontalFieldOfView()).
Use setFOVToFitScene() to adapt the fieldOfView() to a given scene. */
float fieldOfView() const { return fieldOfView_; };
/*! Returns the horizontal field of view of the Camera (in radians).
Value is set using setHorizontalFieldOfView() or setFieldOfView(). Thes
e values
are always linked by:
\code
horizontalFieldOfView() = 2.0 * atan ( tan(fieldOfView()/2.0) * aspectR
atio() ).
\endcode */
float horizontalFieldOfView() const { return 2.0 * atan ( tan(fieldOfVi
ew()/2.0) * aspectRatio() ); };
/*! Returns the Camera aspect ratio defined by screenWidth() / screenHe
ight().
When the Camera is attached to a QGLViewer, these values and hence the
aspectRatio() are
automatically fitted to the viewer's window aspect ratio using setScree
nWidthAndHeight(). */
float aspectRatio() const { return static_cast<float>(screenWidth_)/sta
tic_cast<float>(screenHeight_); };
/*! Returns the width (in pixels) of the Camera screen.
Set using setScreenWidthAndHeight(). This value is automatically fitted
to the QGLViewer's
window dimensions when the Camera is attached to a QGLViewer. See also
QGLWidget::width() */
int screenWidth() const { return screenWidth_; };
/*! Returns the height (in pixels) of the Camera screen.
Set using setScreenWidthAndHeight(). This value is automatically fitted
to the QGLViewer's
window dimensions when the Camera is attached to a QGLViewer. See also
QGLWidget::height() */
int screenHeight() const { return screenHeight_; };
void getViewport(GLint viewport[4]) const;
float pixelGLRatio(const Vec& position) const;
/*! Returns the coefficient which is used to set zNear() when the Camer
a is inside the sphere
defined by sceneCenter() and zClippingCoefficient() * sceneRadius().
In that case, the zNear() value is set to zNearCoefficient() * zClippin
gCoefficient() *
sceneRadius(). See the zNear() documentation for details.
Default value is 0.005, which is appropriate for most applications. In
case you need a high
dynamic ZBuffer precision, you can increase this value (~0.1). A lower
value will prevent
clipping of very close objects at the expense of a worst Z precision.
Only meaningful when Camera type is Camera::PERSPECTIVE. */
float zNearCoefficient() const { return zNearCoef_; };
/*! Returns the coefficient used to position the near and far clipping
planes.
The near (resp. far) clipping plane is positioned at a distance equal t
o zClippingCoefficient() *
sceneRadius() in front of (resp. behind) the sceneCenter(). This garant
ees an optimal use of
the z-buffer range and minimizes aliasing. See the zNear() and zFar() d
ocumentations.
Default value is square root of 3.0 (so that a cube of size sceneRadius
() is not clipped).
However, since the sceneRadius() is used for other purposes (see showEn
tireScene(), flySpeed(),
...) and you may want to change this value to define more precisely the
location of the clipping
planes. See also zNearCoefficient().
For a total control on clipping planes' positions, an other option is t
o overload the zNear()
and zFar() methods. See the <a href="../examples/standardCamera.html">s
tandardCamera example</a>.
\attention When QGLViewer::cameraPathAreEdited(), this value is set to
5.0 so that the Camera
paths are not clipped. The previous zClippingCoefficient() value is res
tored back when you leave
this mode. */
float zClippingCoefficient() const { return zClippingCoef_; }
virtual float zNear() const;
virtual float zFar() const;
virtual void getOrthoWidthHeight(GLdouble& halfWidth, GLdouble& halfHei
ght) const;
void getFrustumPlanesCoefficients(GLdouble coef[6][4]) const;
public Q_SLOTS:
void setType(Type type);
/*! Sets the vertical fieldOfView() of the Camera (in radians).
Note that focusDistance() is set to sceneRadius() / tan(fieldOfView()/2
) by this method. */
void setFieldOfView(float fov) { fieldOfView_ = fov; setFocusDistance(s
ceneRadius() / tan(fov/2.0)); };
/*! Sets the horizontalFieldOfView() of the Camera (in radians).
horizontalFieldOfView() and fieldOfView() are linked by the aspectRatio
(). This method actually
calls setFieldOfView(( 2.0 * atan (tan(hfov / 2.0) / aspectRatio()) ))
so that a call to
horizontalFieldOfView() returns the expected value. */
void setHorizontalFieldOfView(float hfov) { setFieldOfView( 2.0 * atan
(tan(hfov / 2.0) / aspectRatio()) ); };
void setFOVToFitScene();
/*! Defines the Camera aspectRatio().
This value is actually inferred from the screenWidth() / screenHeight()
ratio. You should use
setScreenWidthAndHeight() instead.
This method might however be convenient when the Camera is not associat
ed with a QGLViewer. It
actually sets the screenHeight() to 100 and the screenWidth() according
ly. See also
setFOVToFitScene().
\note If you absolutely need an aspectRatio() that does not correspond
to your viewer's window
dimensions, overload loadProjectionMatrix() or multiply the created GL_
PROJECTION matrix by a
scaled diagonal matrix in your QGLViewer::draw() method. */
void setAspectRatio(float aspect) { setScreenWidthAndHeight(int(100.0*a
spect), 100); };
void setScreenWidthAndHeight(int width, int height);
/*! Sets the zNearCoefficient() value. */
void setZNearCoefficient(float coef) { zNearCoef_ = coef; };
/*! Sets the zClippingCoefficient() value. */
void setZClippingCoefficient(float coef) { zClippingCoef_ = coef; }
//@}
/*! @name Scene radius and center */
//@{
public:
/*! Returns the radius of the scene observed by the Camera.
You need to provide such an approximation of the scene dimensions so th
at the Camera can adapt
its zNear() and zFar() values. See the sceneCenter() documentation.
See also setSceneBoundingBox().
Note that QGLViewer::sceneRadius() (resp. QGLViewer::setSceneRadius())
simply call this method
(resp. setSceneRadius()) on its associated QGLViewer::camera(). */
float sceneRadius() const { return sceneRadius_; };
/*! Returns the position of the scene center, defined in the world coor
dinate system.
The scene observed by the Camera should be roughly centered on this pos
ition, and included in a
sceneRadius() sphere. This approximate description of the scene permits
a zNear() and zFar()
clipping planes definition, and allows convenient positioning methods s
uch as showEntireScene().
Default value is (0,0,0) (world origin). Use setSceneCenter() to change
it. See also
setSceneBoundingBox().
Note that QGLViewer::sceneCenter() (resp. QGLViewer::setSceneCenter())
simply call this method
(resp. setSceneCenter()) on its associated QGLViewer::camera(). */
Vec sceneCenter() const { return sceneCenter_; };
float distanceToSceneCenter() const;
public Q_SLOTS:
void setSceneRadius(float radius);
void setSceneCenter(const Vec& center);
bool setSceneCenterFromPixel(const QPoint& pixel);
void setSceneBoundingBox(const Vec& min, const Vec& max);
//@}
/*! @name Revolve Around Point */
//@{
public Q_SLOTS:
void setRevolveAroundPoint(const Vec& rap);
bool setRevolveAroundPointFromPixel(const QPoint& pixel);
public:
/*! The point the Camera revolves around with the QGLViewer::ROTATE mou
se binding. Defined in world coordinate system.
Default value is the sceneCenter().
\attention setSceneCenter() changes this value. */
Vec revolveAroundPoint() const { return frame()->revolveAroundPoint();
};
//@}
/*! @name Associated frame */
//@{
public:
/*! Returns the ManipulatedCameraFrame attached to the Camera.
This ManipulatedCameraFrame defines its position() and orientation() an
d can translate mouse
events into Camera displacement. Set using setFrame(). */
ManipulatedCameraFrame* frame() const { return frame_; };
public Q_SLOTS:
void setFrame(ManipulatedCameraFrame* const mcf);
//@}
/*! @name KeyFramed paths */
//@{
public:
KeyFrameInterpolator* keyFrameInterpolator(int i) const;
Camera(const Camera& camera);
Camera& operator=(const Camera& camera);
/*! Enumerates the two possible types of Camera.
See type() and setType(). This type mainly defines different Camera
projection matrix (see
loadProjectionMatrix()). Many other methods (pointUnderPixel(), conv
ertClickToLine(),
projectedCoordinatesOf(), pixelGLRatio()...) take this Type into acc
ount. */
enum Type { PERSPECTIVE, ORTHOGRAPHIC };
/*! @name Position and orientation */
//@{
public:
/*! Returns the Camera position (the eye), defined in the world coor
dinate system.
Use setPosition() to set the Camera position. Other convenient metho
ds are showEntireScene() or
fitSphere(). Actually returns \c frame()->position().
This position corresponds to the projection center of a Camera::PERS
PECTIVE Camera. It is not
located in the image plane, which is at a zNear() distance ahead. */
Vec position() const { return frame()->position(); }
/*! Returns the normalized up vector of the Camera, defined in the w
orld coordinate system.
Set using setUpVector() or setOrientation(). It is orthogonal to vie
wDirection() and to
rightVector().
It corresponds to the Y axis of the associated frame() (actually ret
urns
frame()->inverseTransformOf(Vec(0.0, 1.0, 0.0)) ). */
Vec upVector() const
{
return frame()->inverseTransformOf(Vec(0.0, 1.0, 0.0));
}
/*! Returns the normalized view direction of the Camera, defined in
the world coordinate system.
Change this value using setViewDirection(), lookAt() or setOrientati
on(). It is orthogonal to
upVector() and to rightVector().
This corresponds to the negative Z axis of the frame() ( frame()->in
verseTransformOf(Vec(0.0,
0.0, -1.0)) ). */
Vec viewDirection() const { return frame()->inverseTransformOf(Vec(0
.0, 0.0, -1.0)); }
/*! Returns the normalized right vector of the Camera, defined in th
e world coordinate system.
This vector lies in the Camera horizontal plane, directed along the
X axis (orthogonal to
upVector() and to viewDirection()). Set using setUpVector(), lookAt(
) or setOrientation().
Simply returns frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0)). */
Vec rightVector() const
{
return frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0));
}
/*! Returns the Camera orientation, defined in the world coordinate
system.
Actually returns \c frame()->orientation(). Use setOrientation(), se
tUpVector() or lookAt() to
set the Camera orientation. */
Quaternion orientation() const { return frame()->orientation(); }
void setFromModelViewMatrix(const GLdouble* const modelViewMatrix);
void setFromProjectionMatrix(const float matrix[12]);
public Q_SLOTS:
/*! Sets the Camera position() (the eye), defined in the world coord
inate system. */
void setPosition(const Vec& pos) { frame()->setPosition(pos); }
void setOrientation(const Quaternion& q);
void setOrientation(float theta, float phi);
void setUpVector(const Vec& up, bool noMove=true);
void setViewDirection(const Vec& direction);
//@}
/*! @name Positioning tools */
//@{
public Q_SLOTS:
void lookAt(const Vec& target);
void showEntireScene();
void fitSphere(const Vec& center, float radius);
void fitBoundingBox(const Vec& min, const Vec& max);
void fitScreenRegion(const QRect& rectangle);
void centerScene();
void interpolateToZoomOnPixel(const QPoint& pixel);
void interpolateToFitScene();
void interpolateTo(const Frame& fr, float duration);
//@}
/*! @name Frustum */
//@{
public:
/*! Returns the Camera::Type of the Camera.
Set by setType(). Mainly used by loadProjectionMatrix().
A Camera::PERSPECTIVE Camera uses a classical projection mainly defi
ned by its fieldOfView().
With a Camera::ORTHOGRAPHIC type(), the fieldOfView() is meaningless
and the width and height of
the Camera frustum are inferred from the distance to the revolveArou
ndPoint() using
getOrthoWidthHeight().
Both types use zNear() and zFar() (to define their clipping planes)
and aspectRatio() (for
frustum shape). */
Type type() const { return type_; }
/*! Returns the vertical field of view of the Camera (in radians).
Value is set using setFieldOfView(). Default value is pi/4 radians.
This value is meaningless if
the Camera type() is Camera::ORTHOGRAPHIC.
The field of view corresponds the one used in \c gluPerspective (see
manual). It sets the Y
(vertical) aperture of the Camera. The X (horizontal) angle is infer
red from the window aspect
ratio (see aspectRatio() and horizontalFieldOfView()).
Use setFOVToFitScene() to adapt the fieldOfView() to a given scene.
*/
float fieldOfView() const { return fieldOfView_; }
/*! Returns the horizontal field of view of the Camera (in radians).
Value is set using setHorizontalFieldOfView() or setFieldOfView(). T
hese values
are always linked by:
\code
horizontalFieldOfView() = 2.0 * atan ( tan(fieldOfView()/2.0) * aspe
ctRatio() ).
\endcode */
float horizontalFieldOfView() const { return 2.0 * atan ( tan(fieldO
fView()/2.0) * aspectRatio() ); }
/*! Returns the Camera aspect ratio defined by screenWidth() / scree
nHeight().
When the Camera is attached to a QGLViewer, these values and hence t
he aspectRatio() are
automatically fitted to the viewer's window aspect ratio using setSc
reenWidthAndHeight(). */
float aspectRatio() const { return static_cast<float>(screenWidth_)/
static_cast<float>(screenHeight_); }
/*! Returns the width (in pixels) of the Camera screen.
Set using setScreenWidthAndHeight(). This value is automatically fit
ted to the QGLViewer's
window dimensions when the Camera is attached to a QGLViewer. See al
so QGLWidget::width() */
int screenWidth() const { return screenWidth_; }
/*! Returns the height (in pixels) of the Camera screen.
Set using setScreenWidthAndHeight(). This value is automatically fit
ted to the QGLViewer's
window dimensions when the Camera is attached to a QGLViewer. See al
so QGLWidget::height() */
int screenHeight() const { return screenHeight_; }
void getViewport(GLint viewport[4]) const;
float pixelGLRatio(const Vec& position) const;
/*! Returns the coefficient which is used to set zNear() when the Ca
mera is inside the sphere
defined by sceneCenter() and zClippingCoefficient() * sceneRadius().
In that case, the zNear() value is set to zNearCoefficient() * zClip
pingCoefficient() *
sceneRadius(). See the zNear() documentation for details.
Default value is 0.005, which is appropriate for most applications.
In case you need a high
dynamic ZBuffer precision, you can increase this value (~0.1). A low
er value will prevent
clipping of very close objects at the expense of a worst Z precision
.
Only meaningful when Camera type is Camera::PERSPECTIVE. */
float zNearCoefficient() const { return zNearCoef_; }
/*! Returns the coefficient used to position the near and far clippi
ng planes.
The near (resp. far) clipping plane is positioned at a distance equa
l to zClippingCoefficient() *
sceneRadius() in front of (resp. behind) the sceneCenter(). This gar
antees an optimal use of
the z-buffer range and minimizes aliasing. See the zNear() and zFar(
) documentations.
Default value is square root of 3.0 (so that a cube of size sceneRad
ius() is not clipped).
However, since the sceneRadius() is used for other purposes (see sho
wEntireScene(), flySpeed(),
...) and you may want to change this value to define more precisely
the location of the clipping
planes. See also zNearCoefficient().
For a total control on clipping planes' positions, an other option i
s to overload the zNear()
and zFar() methods. See the <a href="../examples/standardCamera.html
">standardCamera example</a>.
\attention When QGLViewer::cameraPathAreEdited(), this value is set
to 5.0 so that the Camera
paths are not clipped. The previous zClippingCoefficient() value is
restored back when you leave
this mode. */
float zClippingCoefficient() const { return zClippingCoef_; }
virtual float zNear() const;
virtual float zFar() const;
virtual void getOrthoWidthHeight(GLdouble& halfWidth, GLdouble& half
Height) const;
void getFrustumPlanesCoefficients(GLdouble coef[6][4]) const;
public Q_SLOTS:
void setType(Type type);
void setFieldOfView(float fov);
/*! Sets the horizontalFieldOfView() of the Camera (in radians).
horizontalFieldOfView() and fieldOfView() are linked by the aspectRa
tio(). This method actually
calls setFieldOfView(( 2.0 * atan (tan(hfov / 2.0) / aspectRatio())
)) so that a call to
horizontalFieldOfView() returns the expected value. */
void setHorizontalFieldOfView(float hfov) { setFieldOfView( 2.0 * at
an (tan(hfov / 2.0) / aspectRatio()) ); }
void setFOVToFitScene();
/*! Defines the Camera aspectRatio().
This value is actually inferred from the screenWidth() / screenHeigh
t() ratio. You should use
setScreenWidthAndHeight() instead.
This method might however be convenient when the Camera is not assoc
iated with a QGLViewer. It
actually sets the screenHeight() to 100 and the screenWidth() accord
ingly. See also
setFOVToFitScene().
\note If you absolutely need an aspectRatio() that does not correspo
nd to your viewer's window
dimensions, overload loadProjectionMatrix() or multiply the created
GL_PROJECTION matrix by a
scaled diagonal matrix in your QGLViewer::draw() method. */
void setAspectRatio(float aspect) { setScreenWidthAndHeight(int(100.
0*aspect), 100); }
void setScreenWidthAndHeight(int width, int height);
/*! Sets the zNearCoefficient() value. */
void setZNearCoefficient(float coef) { zNearCoef_ = coef; projection
MatrixIsUpToDate_ = false; }
/*! Sets the zClippingCoefficient() value. */
void setZClippingCoefficient(float coef) { zClippingCoef_ = coef; pr
ojectionMatrixIsUpToDate_ = false; }
//@}
/*! @name Scene radius and center */
//@{
public:
/*! Returns the radius of the scene observed by the Camera.
You need to provide such an approximation of the scene dimensions so
that the Camera can adapt
its zNear() and zFar() values. See the sceneCenter() documentation.
See also setSceneBoundingBox().
Note that QGLViewer::sceneRadius() (resp. QGLViewer::setSceneRadius(
)) simply call this method
(resp. setSceneRadius()) on its associated QGLViewer::camera(). */
float sceneRadius() const { return sceneRadius_; }
/*! Returns the position of the scene center, defined in the world c
oordinate system.
The scene observed by the Camera should be roughly centered on this
position, and included in a
sceneRadius() sphere. This approximate description of the scene perm
its a zNear() and zFar()
clipping planes definition, and allows convenient positioning method
s such as showEntireScene().
Default value is (0,0,0) (world origin). Use setSceneCenter() to cha
nge it. See also
setSceneBoundingBox().
Note that QGLViewer::sceneCenter() (resp. QGLViewer::setSceneCenter(
)) simply call this method
(resp. setSceneCenter()) on its associated QGLViewer::camera(). */
Vec sceneCenter() const { return sceneCenter_; }
float distanceToSceneCenter() const;
public Q_SLOTS:
void setSceneRadius(float radius);
void setSceneCenter(const Vec& center);
bool setSceneCenterFromPixel(const QPoint& pixel);
void setSceneBoundingBox(const Vec& min, const Vec& max);
//@}
/*! @name Revolve Around Point */
//@{
public Q_SLOTS: public Q_SLOTS:
void setKeyFrameInterpolator(int i, KeyFrameInterpolator* const kfi); void setRevolveAroundPoint(const Vec& rap);
bool setRevolveAroundPointFromPixel(const QPoint& pixel);
virtual void addKeyFrameToPath(int i); public:
virtual void playPath(int i); /*! The point the Camera revolves around with the QGLViewer::ROTATE
virtual void deletePath(int i); mouse binding. Defined in world coordinate system.
virtual void resetPath(int i);
virtual void drawAllPaths();
//@}
/*! @name OpenGL matrices */
//@{
public:
virtual void loadProjectionMatrix(bool reset=true) const;
virtual void loadModelViewMatrix(bool reset=true) const;
void computeProjectionMatrix() const;
void computeModelViewMatrix() const;
virtual void loadProjectionMatrixStereo(bool leftBuffer=true) const; Default value is the sceneCenter().
virtual void loadModelViewMatrixStereo(bool leftBuffer=true) const;
void getProjectionMatrix(GLdouble m[16]) const; \attention setSceneCenter() changes this value. */
void getModelViewMatrix(GLdouble m[16]) const; Vec revolveAroundPoint() const { return frame()->revolveAroundPoint(
); }
//@}
/*! @name Associated frame */
//@{
public:
/*! Returns the ManipulatedCameraFrame attached to the Camera.
This ManipulatedCameraFrame defines its position() and orientation()
and can translate mouse
events into Camera displacement. Set using setFrame(). */
ManipulatedCameraFrame* frame() const { return frame_; }
public Q_SLOTS:
void setFrame(ManipulatedCameraFrame* const mcf);
//@}
/*! @name KeyFramed paths */
//@{
public:
KeyFrameInterpolator* keyFrameInterpolator(int i) const;
public Q_SLOTS:
void setKeyFrameInterpolator(int i, KeyFrameInterpolator* const kfi)
;
virtual void addKeyFrameToPath(int i);
virtual void playPath(int i);
virtual void deletePath(int i);
virtual void resetPath(int i);
virtual void drawAllPaths();
//@}
/*! @name OpenGL matrices */
//@{
public:
virtual void loadProjectionMatrix(bool reset=true) const;
virtual void loadModelViewMatrix(bool reset=true) const;
void computeProjectionMatrix() const;
void computeModelViewMatrix() const;
virtual void loadProjectionMatrixStereo(bool leftBuffer=true) const;
virtual void loadModelViewMatrixStereo(bool leftBuffer=true) const;
void getProjectionMatrix(GLdouble m[16]) const;
void getModelViewMatrix(GLdouble m[16]) const;
void getModelViewProjectionMatrix(GLdouble m[16]) const; void getModelViewProjectionMatrix(GLdouble m[16]) const;
#ifndef DOXYGEN #ifndef DOXYGEN
// Required for windows which otherwise silently fills // Required for windows which otherwise silently fills
void getProjectionMatrix(GLfloat m[16]) const; void getProjectionMatrix(GLfloat m[16]) const;
void getModelViewMatrix(GLfloat m[16]) const; void getModelViewMatrix(GLfloat m[16]) const;
#endif #endif
//@} //@}
/*! @name Drawing */ /*! @name Drawing */
//@{ //@{
#ifndef DOXYGEN #ifndef DOXYGEN
static void drawCamera(float scale=1.0, float aspectRatio=1.33, float f ieldOfView=M_PI/4.0); static void drawCamera(float scale=1.0, float aspectRatio=1.33, floa t fieldOfView=M_PI/4.0);
#endif #endif
virtual void draw(bool drawFarPlane=true, float scale=1.0) const; virtual void draw(bool drawFarPlane=true, float scale=1.0) const;
//@} //@}
/*! @name World to Camera coordinate systems conversions */ /*! @name World to Camera coordinate systems conversions */
//@{ //@{
public: public:
/*! Returns the Camera frame coordinates of a point \p src defined in w /*! Returns the Camera frame coordinates of a point \p src defined i
orld coordinates. n world coordinates.
worldCoordinatesOf() performs the inverse transformation. worldCoordinatesOf() performs the inverse transformation.
Note that the point coordinates are simply converted in a different coo Note that the point coordinates are simply converted in a different
rdinate system. They are coordinate system. They are
not projected on screen. Use projectedCoordinatesOf() for that. */ not projected on screen. Use projectedCoordinatesOf() for that. */
Vec cameraCoordinatesOf(const Vec& src) const { return frame()->coordin Vec cameraCoordinatesOf(const Vec& src) const { return frame()->coor
atesOf(src); }; dinatesOf(src); }
/*! Returns the world coordinates of the point whose position \p src is /*! Returns the world coordinates of the point whose position \p src
defined in the Camera is defined in the Camera
coordinate system. coordinate system.
cameraCoordinatesOf() performs the inverse transformation. */ cameraCoordinatesOf() performs the inverse transformation. */
Vec worldCoordinatesOf(const Vec& src) const { return frame()->inverseC Vec worldCoordinatesOf(const Vec& src) const { return frame()->inver
oordinatesOf(src); }; seCoordinatesOf(src); }
void getCameraCoordinatesOf(const float src[3], float res[3]) const; void getCameraCoordinatesOf(const float src[3], float res[3]) const;
void getWorldCoordinatesOf(const float src[3], float res[3]) const; void getWorldCoordinatesOf(const float src[3], float res[3]) const;
//@} //@}
/*! @name 2D screen to 3D world coordinate systems conversions */ /*! @name 2D screen to 3D world coordinate systems conversions */
//@{ //@{
public: public:
Vec projectedCoordinatesOf(const Vec& src, const Frame* frame=NULL) con Vec projectedCoordinatesOf(const Vec& src, const Frame* frame=NULL)
st; const;
Vec unprojectedCoordinatesOf(const Vec& src, const Frame* frame=NULL) c Vec unprojectedCoordinatesOf(const Vec& src, const Frame* frame=NULL
onst; ) const;
void getProjectedCoordinatesOf(const float src[3], float res[3], const void getProjectedCoordinatesOf(const float src[3], float res[3], con
Frame* frame=NULL) const; st Frame* frame=NULL) const;
void getUnprojectedCoordinatesOf(const float src[3], float res[3], cons void getUnprojectedCoordinatesOf(const float src[3], float res[3], c
t Frame* frame=NULL) const; onst Frame* frame=NULL) const;
void convertClickToLine(const QPoint& pixel, Vec& orig, Vec& dir) const void convertClickToLine(const QPoint& pixel, Vec& orig, Vec& dir) co
; nst;
Vec pointUnderPixel(const QPoint& pixel, bool& found) const; Vec pointUnderPixel(const QPoint& pixel, bool& found) const;
//@} //@}
/*! @name Fly speed */ /*! @name Fly speed */
//@{ //@{
public: public:
/*! Returns the fly speed of the Camera. /*! Returns the fly speed of the Camera.
Simply returns frame()->flySpeed(). See the ManipulatedCameraFrame::fly Simply returns frame()->flySpeed(). See the ManipulatedCameraFrame::
Speed() documentation. flySpeed() documentation.
This value is only meaningful when the MouseAction bindings is QGLViewe This value is only meaningful when the MouseAction bindings is QGLVi
r::MOVE_FORWARD or ewer::MOVE_FORWARD or
QGLViewer::MOVE_BACKWARD. QGLViewer::MOVE_BACKWARD.
Set to 1% of the sceneRadius() by setSceneRadius(). See also setFlySpee Set to 1% of the sceneRadius() by setSceneRadius(). See also setFlyS
d(). */ peed(). */
float flySpeed() const { return frame()->flySpeed(); }; float flySpeed() const { return frame()->flySpeed(); }
public Q_SLOTS: public Q_SLOTS:
/*! Sets the Camera flySpeed(). /*! Sets the Camera flySpeed().
\attention This value is modified by setSceneRadius(). */ \attention This value is modified by setSceneRadius(). */
void setFlySpeed(float speed) { frame()->setFlySpeed(speed); }; void setFlySpeed(float speed) { frame()->setFlySpeed(speed); }
//@} //@}
/*! @name Stereo parameters */ /*! @name Stereo parameters */
//@{ //@{
public: public:
/*! Returns the user's inter-ocular distance (in meters). Default value /*! Returns the user's inter-ocular distance (in meters). Default va
is 0.062m, which fits most people. lue is 0.062m, which fits most people.
loadProjectionMatrixStereo() uses this value to define the Camera offse loadProjectionMatrixStereo() uses this value to define the Camera of
t and frustum. See fset and frustum. See
setIODistance(). */ setIODistance(). */
float IODistance() const { return IODistance_; }; float IODistance() const { return IODistance_; }
/*! Returns the physical distance between the user's eyes and the scree /*! Returns the physical distance between the user's eyes and the sc
n (in meters). reen (in meters).
physicalDistanceToScreen() and focusDistance() represent the same dista physicalDistanceToScreen() and focusDistance() represent the same di
nce. The former is stance. The former is
expressed in physical real world units, while the latter is expressed i expressed in physical real world units, while the latter is expresse
n OpenGL virtual world d in OpenGL virtual world
units. units.
This is a helper function. It simply returns physicalScreenWidth() / 2.0 / tan(horizontalFieldOfView() / 2.0); */ This is a helper function. It simply returns physicalScreenWidth() / 2.0 / tan(horizontalFieldOfView() / 2.0); */
float physicalDistanceToScreen() const { return physicalScreenWidth() / 2.0f / tan(horizontalFieldOfView() / 2.0); }; float physicalDistanceToScreen() const { return physicalScreenWidth( ) / 2.0f / tan(horizontalFieldOfView() / 2.0); }
/*! Returns the physical screen width, in meters. Default value is 0.5m (average monitor width). /*! Returns the physical screen width, in meters. Default value is 0 .5m (average monitor width).
Used for stereo display only (see loadModelViewMatrixStereo() and loadP Used for stereo display only (see loadModelViewMatrixStereo() and lo
rojectionMatrixStereo()). adProjectionMatrixStereo()).
Set using setPhysicalScreenWidth(). */ Set using setPhysicalScreenWidth(). */
float physicalScreenWidth() const { return physicalScreenWidth_; }; float physicalScreenWidth() const { return physicalScreenWidth_; }
/*! Returns the focus distance used by stereo display, expressed in Ope nGL units. /*! Returns the focus distance used by stereo display, expressed in OpenGL units.
This is the distance in the virtual world between the Camera and the pl This is the distance in the virtual world between the Camera and the
ane where the horizontal plane where the horizontal
stereo parallax is null (the stereo left and right cameras' lines of si stereo parallax is null (the stereo left and right cameras' lines of
gth cross at this distance). sigth cross at this distance).
This distance is the virtual world equivalent of the real-world physica lDistanceToScreen(). This distance is the virtual world equivalent of the real-world phys icalDistanceToScreen().
\attention This value is modified by QGLViewer::setSceneRadius(), setSc \attention This value is modified by QGLViewer::setSceneRadius(), se
eneRadius() and tSceneRadius() and
setFieldOfView(). When one of these values is modified, focusDistance() setFieldOfView(). When one of these values is modified, focusDistanc
is set to sceneRadius() e() is set to sceneRadius()
/ tan(fieldOfView()/2), which provides good results. */ / tan(fieldOfView()/2), which provides good results. */
float focusDistance() const { return focusDistance_; }; float focusDistance() const { return focusDistance_; }
public Q_SLOTS: public Q_SLOTS:
/*! Sets the IODistance(). */ /*! Sets the IODistance(). */
void setIODistance(float distance) { IODistance_ = distance; }; void setIODistance(float distance) { IODistance_ = distance; }
#ifndef DOXYGEN #ifndef DOXYGEN
/*! This method is deprecated. Use setPhysicalScreenWidth() instead. */ /*! This method is deprecated. Use setPhysicalScreenWidth() instead. */
void setPhysicalDistanceToScreen(float distance) { Q_UNUSED(distance ); qWarning("setPhysicalDistanceToScreen is deprecated, use setPhysicalScre enWidth instead"); }; void setPhysicalDistanceToScreen(float distance) { Q_UNUSED(distance ); qWarning("setPhysicalDistanceToScreen is deprecated, use setPhysicalScre enWidth instead"); }
#endif #endif
/*! Sets the physical screen (monitor or projected wall) width (in mete /*! Sets the physical screen (monitor or projected wall) width (in m
rs). */ eters). */
void setPhysicalScreenWidth(float width) { physicalScreenWidth_ = width void setPhysicalScreenWidth(float width) { physicalScreenWidth_ = wi
; }; dth; }
/*! Sets the focusDistance(), in OpenGL scene units. */
void setFocusDistance(float distance) { focusDistance_ = distance; }
//@}
/*! @name XML representation */
//@{
public:
virtual QDomElement domElement(const QString& name, QDomDocument& do
cument) const;
public Q_SLOTS:
virtual void initFromDOMElement(const QDomElement& element);
//@}
private Q_SLOTS:
void onFrameModified();
/*! Sets the focusDistance(), in OpenGL scene units. */ private:
void setFocusDistance(float distance) { focusDistance_ = distance; }; // F r a m e
//@} ManipulatedCameraFrame* frame_;
/*! @name XML representation */ // C a m e r a p a r a m e t e r s
//@{ int screenWidth_, screenHeight_; // size of the window, in pixels
public: float fieldOfView_; // in radians
virtual QDomElement domElement(const QString& name, QDomDocument& docum Vec sceneCenter_;
ent) const; float sceneRadius_; // OpenGL units
public Q_SLOTS: float zNearCoef_;
virtual void initFromDOMElement(const QDomElement& element); float zClippingCoef_;
//@} float orthoCoef_;
Type type_; // PERSPECTIVE or ORTHOGRAPHIC
private: mutable GLdouble modelViewMatrix_[16]; // Buffered model view matrix
// F r a m e .
ManipulatedCameraFrame* frame_; mutable bool modelViewMatrixIsUpToDate_;
mutable GLdouble projectionMatrix_[16]; // Buffered projection matri
// C a m e r a p a r a m e t e r s x.
int screenWidth_, screenHeight_; // size of the window, in pixels mutable bool projectionMatrixIsUpToDate_;
float fieldOfView_; // in radians
Vec sceneCenter_; // S t e r e o p a r a m e t e r s
float sceneRadius_; // OpenGL units float IODistance_; // inter-ocular distance, in me
float zNearCoef_; ters
float zClippingCoef_; float focusDistance_; // in scene units
float orthoCoef_; float physicalScreenWidth_; // in meters
Type type_; // PERSPECTIVE or ORTHOGRAPHIC
mutable GLdouble modelViewMatrix_[16]; // Buffered model view matrix. // P o i n t s o f V i e w s a n d K e y F r a m e s
mutable GLdouble projectionMatrix_[16]; // Buffered projection matrix. QMap<int, KeyFrameInterpolator*> kfi_;
KeyFrameInterpolator* interpolationKfi_;
// S t e r e o p a r a m e t e r s };
float IODistance_; // inter-ocular distance, in meters
float focusDistance_; // in scene units
float physicalScreenWidth_; // in meters
// P o i n t s o f V i e w s a n d K e y F r a m e s
QMap<int, KeyFrameInterpolator*> kfi_;
KeyFrameInterpolator* interpolationKfi_;
};
} // namespace qglviewer } // namespace qglviewer
#endif // QGLVIEWER_CAMERA_H #endif // QGLVIEWER_CAMERA_H
 End of changes. 27 change blocks. 
539 lines changed or deleted 547 lines changed or added


 config.h   config.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 31 skipping to change at line 31
*************************************************************************** **/ *************************************************************************** **/
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
// libQGLViewer configuration file // // libQGLViewer configuration file //
// Modify these settings according to your local configuration // // Modify these settings according to your local configuration //
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
#ifndef QGLVIEWER_CONFIG_H #ifndef QGLVIEWER_CONFIG_H
#define QGLVIEWER_CONFIG_H #define QGLVIEWER_CONFIG_H
#define QGLVIEWER_VERSION 0x020400 #define QGLVIEWER_VERSION 0x020500
// Needed for Qt < 4 (?) // Needed for Qt < 4 (?)
#ifndef QT_CLEAN_NAMESPACE #ifndef QT_CLEAN_NAMESPACE
# define QT_CLEAN_NAMESPACE # define QT_CLEAN_NAMESPACE
#endif #endif
// Get QT_VERSION and other Qt flags // Get QT_VERSION and other Qt flags
#include <qglobal.h> #include <qglobal.h>
#if QT_VERSION < 0x030000 #if QT_VERSION < 0x030000
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 constraint.h   constraint.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 30 skipping to change at line 30
*************************************************************************** **/ *************************************************************************** **/
#ifndef QGLVIEWER_CONSTRAINT_H #ifndef QGLVIEWER_CONSTRAINT_H
#define QGLVIEWER_CONSTRAINT_H #define QGLVIEWER_CONSTRAINT_H
#include "vec.h" #include "vec.h"
#include "quaternion.h" #include "quaternion.h"
namespace qglviewer { namespace qglviewer {
class Frame; class Frame;
class Camera; class Camera;
/*! \brief An interface class for Frame constraints. /*! \brief An interface class for Frame constraints.
\class Constraint constraint.h QGLViewer/constraint.h \class Constraint constraint.h QGLViewer/constraint.h
This class defines the interface for the Constraints that can be applied to a Frame to limit its This class defines the interface for the Constraints that can be applied to a Frame to limit its
motion. Use Frame::setConstraint() to associate a Constraint to a Frame ( default is a \c NULL motion. Use Frame::setConstraint() to associate a Constraint to a Frame ( default is a \c NULL
Frame::constraint()). Frame::constraint()).
<h3>How does it work ?</h3> <h3>How does it work ?</h3>
The Constraint acts as a filter on the translation and rotation Frame inc rements. The Constraint acts as a filter on the translation and rotation Frame inc rements.
constrainTranslation() and constrainRotation() should be overloaded to sp ecify the constraint constrainTranslation() and constrainRotation() should be overloaded to sp ecify the constraint
behavior: the desired displacement is given as a parameter that can optio nally be modified. behavior: the desired displacement is given as a parameter that can optio nally be modified.
Here is how the Frame::translate() and Frame::rotate() methods use the Co nstraint: Here is how the Frame::translate() and Frame::rotate() methods use the Co nstraint:
\code \code
Frame::translate(Vec& T) Frame::translate(Vec& T)
{ {
if (constraint()) if (constraint())
constraint()->constrainTranslation(T, this); constraint()->constrainTranslation(T, this);
t += T; t += T;
} }
Frame::rotate(Quaternion& Q) Frame::rotate(Quaternion& Q)
{ {
if (constraint()) if (constraint())
constraint()->constrainRotation(Q, this); constraint()->constrainRotation(Q, this);
q *= Q; q *= Q;
} }
\endcode \endcode
The default behavior of constrainTranslation() and constrainRotation() is empty (meaning no The default behavior of constrainTranslation() and constrainRotation() is empty (meaning no
filtering). filtering).
The Frame which uses the Constraint is passed as a parameter to the const rainTranslation() and The Frame which uses the Constraint is passed as a parameter to the const rainTranslation() and
constrainRotation() methods, so that they can have access to its current state (mainly constrainRotation() methods, so that they can have access to its current state (mainly
Frame::position() and Frame::orientation()). It is not \c const for versa tility reasons, but Frame::position() and Frame::orientation()). It is not \c const for versa tility reasons, but
directly modifying it should be avoided. directly modifying it should be avoided.
skipping to change at line 91 skipping to change at line 91
href="../examples/constrainedCamera.html">constrainedCamera</a> examples for an illustration. href="../examples/constrainedCamera.html">constrainedCamera</a> examples for an illustration.
<h3>Creating new Constraints</h3> <h3>Creating new Constraints</h3>
The implementation of a new Constraint class simply consists in overloadi ng the filtering methods: The implementation of a new Constraint class simply consists in overloadi ng the filtering methods:
\code \code
// This Constraint enforces that the Frame cannot have a negative z world coordinate. // This Constraint enforces that the Frame cannot have a negative z world coordinate.
class myConstraint : public Constraint class myConstraint : public Constraint
{ {
public: public:
virtual void constrainTranslation(Vec& t, Frame * const fr) virtual void constrainTranslation(Vec& t, Frame * const fr)
{ {
// Express t in the world coordinate system. // Express t in the world coordinate system.
const Vec tWorld = fr->inverseTransformOf(t); const Vec tWorld = fr->inverseTransformOf(t);
if (fr->position().z + tWorld.z < 0.0) // check the new fr z coordin ate if (fr->position().z + tWorld.z < 0.0) // check the new fr z coordin ate
t.z = fr->transformOf(-fr->position().z); // t.z is clamped so tha t next z position is 0.0 t.z = fr->transformOf(-fr->position().z); // t.z is clamped so tha t next z position is 0.0
} }
}; };
\endcode \endcode
Note that the translation (resp. rotation) parameter passed to constrainT ranslation() (resp. Note that the translation (resp. rotation) parameter passed to constrainT ranslation() (resp.
constrainRotation()) is expressed in the \e local Frame coordinate system . Here, we use the constrainRotation()) is expressed in the \e local Frame coordinate system . Here, we use the
Frame::transformOf() and Frame::inverseTransformOf() method to convert it to and from the world Frame::transformOf() and Frame::inverseTransformOf() method to convert it to and from the world
coordinate system. coordinate system.
Combined constraints can easily be achieved by creating a new class that applies the different Combined constraints can easily be achieved by creating a new class that applies the different
constraint filters: constraint filters:
\code \code
myConstraint::constrainTranslation(Vec& v, Frame* const fr) myConstraint::constrainTranslation(Vec& v, Frame* const fr)
{ {
constraint1->constrainTranslation(v, fr); constraint1->constrainTranslation(v, fr);
constraint2->constrainTranslation(v, fr); constraint2->constrainTranslation(v, fr);
// and so on, with possible branches, tests, loops... // and so on, with possible branches, tests, loops...
} }
\endcode \endcode
*/ */
class QGLVIEWER_EXPORT Constraint class QGLVIEWER_EXPORT Constraint
{ {
public: public:
/*! Virtual destructor. Empty. */ /*! Virtual destructor. Empty. */
virtual ~Constraint() {}; virtual ~Constraint() {}
/*! Filters the translation applied to the \p frame. This default imple /*! Filters the translation applied to the \p frame. This default im
mentation is empty (no plementation is empty (no
filtering). filtering).
Overload this method in your own Constraint class to define a new tr
anslation constraint. \p
frame is the Frame to which is applied the translation. It is not de
fined \c const, but you
should refrain from directly changing its value in the constraint. U
se its Frame::position() and
update the \p translation accordingly instead.
\p translation is expressed in local frame coordinate system. Use Fr
ame::inverseTransformOf() to
express it in the world coordinate system if needed. */
virtual void constrainTranslation(Vec& translation, Frame* const fra
me) { Q_UNUSED(translation); Q_UNUSED(frame); }
/*! Filters the rotation applied to the \p frame. This default imple
mentation is empty (no
filtering).
Overload this method in your own Constraint class to define a new ro
tation constraint. See
constrainTranslation() for details.
Use Frame::inverseTransformOf() on the \p rotation Quaternion::axis(
) to express \p rotation in
the world coordinate system if needed. */
virtual void constrainRotation(Quaternion& rotation, Frame* const fr
ame) { Q_UNUSED(rotation); Q_UNUSED(frame); }
};
Overload this method in your own Constraint class to define a new trans /*!
lation constraint. \p
frame is the Frame to which is applied the translation. It is not defin
ed \c const, but you
should refrain from directly changing its value in the constraint. Use
its Frame::position() and
update the \p translation accordingly instead.
\p translation is expressed in local frame coordinate system. Use Frame
::inverseTransformOf() to
express it in the world coordinate system if needed. */
virtual void constrainTranslation(Vec& translation, Frame* const frame)
{ Q_UNUSED(translation); Q_UNUSED(frame); };
/*! Filters the rotation applied to the \p frame. This default implemen
tation is empty (no
filtering).
Overload this method in your own Constraint class to define a new rotat
ion constraint. See
constrainTranslation() for details.
Use Frame::inverseTransformOf() on the \p rotation Quaternion::axis() t
o express \p rotation in
the world coordinate system if needed. */
virtual void constrainRotation(Quaternion& rotation, Frame* const frame
) { Q_UNUSED(rotation); Q_UNUSED(frame); };
};
/*!
\brief An abstract class for Frame Constraints defined by an axis or a p lane. \brief An abstract class for Frame Constraints defined by an axis or a p lane.
\class AxisPlaneConstraint constraint.h QGLViewer/constraint.h \class AxisPlaneConstraint constraint.h QGLViewer/constraint.h
AxisPlaneConstraint is an interface for (translation and/or rotation) Co nstraint that are defined AxisPlaneConstraint is an interface for (translation and/or rotation) Co nstraint that are defined
by a direction. translationConstraintType() and rotationConstraintType() define how this by a direction. translationConstraintType() and rotationConstraintType() define how this
direction should be interpreted: as an axis (AxisPlaneConstraint::AXIS) or as a plane normal direction should be interpreted: as an axis (AxisPlaneConstraint::AXIS) or as a plane normal
(AxisPlaneConstraint::PLANE). See the Type() documentation for details. (AxisPlaneConstraint::PLANE). See the Type() documentation for details.
The three implementations of this class: LocalConstraint, WorldConstrain t and CameraConstraint The three implementations of this class: LocalConstraint, WorldConstrain t and CameraConstraint
differ by the coordinate system in which this direction is expressed. differ by the coordinate system in which this direction is expressed.
skipping to change at line 168 skipping to change at line 168
<a href="../examples/constrainedCamera.html">contrainedCamera</a> and <a href="../examples/constrainedCamera.html">contrainedCamera</a> and
<a href="../examples/constrainedFrame.html">constrainedFrame</a> example s. <a href="../examples/constrainedFrame.html">constrainedFrame</a> example s.
\attention When applied, the rotational Constraint may not intuitively f ollow the mouse \attention When applied, the rotational Constraint may not intuitively f ollow the mouse
displacement. A solution would be to directly measure the rotation angle in screen coordinates, displacement. A solution would be to directly measure the rotation angle in screen coordinates,
but that would imply to know the QGLViewer::camera(), so that we can com pute the projected but that would imply to know the QGLViewer::camera(), so that we can com pute the projected
coordinates of the rotation center (as is done with the QGLViewer::SCREE N_ROTATE binding). coordinates of the rotation center (as is done with the QGLViewer::SCREE N_ROTATE binding).
However, adding an extra pointer to the QGLViewer::camera() in all the A xisPlaneConstraint However, adding an extra pointer to the QGLViewer::camera() in all the A xisPlaneConstraint
derived classes (which the user would have to update in a multi-viewer a pplication) was judged as derived classes (which the user would have to update in a multi-viewer a pplication) was judged as
an overkill. */ an overkill. */
class QGLVIEWER_EXPORT AxisPlaneConstraint : public Constraint class QGLVIEWER_EXPORT AxisPlaneConstraint : public Constraint
{ {
public: public:
AxisPlaneConstraint(); AxisPlaneConstraint();
/*! Virtual destructor. Empty. */ /*! Virtual destructor. Empty. */
virtual ~AxisPlaneConstraint() {}; virtual ~AxisPlaneConstraint() {}
/*! Type lists the different types of translation and rotation constrai /*! Type lists the different types of translation and rotation const
nts that are available. raints that are available.
It specifies the meaning of the constraint direction (see translationCo It specifies the meaning of the constraint direction (see translatio
nstraintDirection() and nConstraintDirection() and
rotationConstraintDirection()): as an axis direction (AxisPlaneConstrai rotationConstraintDirection()): as an axis direction (AxisPlaneConst
nt::AXIS) or a plane raint::AXIS) or a plane
normal (AxisPlaneConstraint::PLANE). AxisPlaneConstraint::FREE means no normal (AxisPlaneConstraint::PLANE). AxisPlaneConstraint::FREE means
constraint while no constraint while
AxisPlaneConstraint::FORBIDDEN completely forbids the translation and/o AxisPlaneConstraint::FORBIDDEN completely forbids the translation an
r the rotation. d/or the rotation.
See translationConstraintType() and rotationConstraintType(). See translationConstraintType() and rotationConstraintType().
\attention The AxisPlaneConstraint::PLANE Type is not valid for rotatio \attention The AxisPlaneConstraint::PLANE Type is not valid for rota
nal constraint. tional constraint.
New derived classes can use their own extended enum for specific constr New derived classes can use their own extended enum for specific con
aints: straints:
\code \code
class MyAxisPlaneConstraint : public AxisPlaneConstraint class MyAxisPlaneConstraint : public AxisPlaneConstraint
{
public:
enum MyType { FREE, AXIS, PLANE, FORBIDDEN, CUSTOM };
virtual void constrainTranslation(Vec &translation, Frame *const fram
e)
{
// translationConstraintType() is simply an int. CUSTOM Type is han
dled seamlessly.
switch (translationConstraintType())
{ {
case MyAxisPlaneConstraint::FREE: ... break; public:
case MyAxisPlaneConstraint::CUSTOM: ... break; enum MyType { FREE, AXIS, PLANE, FORBIDDEN, CUSTOM };
} virtual void constrainTranslation(Vec &translation, Frame *const f
}; rame)
{
MyAxisPlaneConstraint* c = new MyAxisPlaneConstraint(); // translationConstraintType() is simply an int. CUSTOM Type
// Note the Type conversion is handled seamlessly.
c->setTranslationConstraintType(AxisPlaneConstraint::Type(MyAxisPlane switch (translationConstraintType())
Constraint::CUSTOM)); {
}; case MyAxisPlaneConstraint::FREE: ... break;
\endcode */ case MyAxisPlaneConstraint::CUSTOM: ... break;
enum Type { FREE, AXIS, PLANE, FORBIDDEN }; }
};
/*! @name Translation constraint */
//@{ MyAxisPlaneConstraint* c = new MyAxisPlaneConstraint();
/*! Overloading of Constraint::constrainTranslation(). Empty */ // Note the Type conversion
virtual void constrainTranslation(Vec& translation, Frame* const frame) c->setTranslationConstraintType(AxisPlaneConstraint::Type(MyAxisPl
{ Q_UNUSED(translation); Q_UNUSED(frame); }; aneConstraint::CUSTOM));
};
void setTranslationConstraint(Type type, const Vec& direction); \endcode */
/*! Sets the Type() of the translationConstraintType(). Default is Axis enum Type { FREE, AXIS, PLANE, FORBIDDEN };
PlaneConstraint::FREE. */
void setTranslationConstraintType(Type type) { translationConstraintTyp /*! @name Translation constraint */
e_ = type; }; //@{
void setTranslationConstraintDirection(const Vec& direction); /*! Overloading of Constraint::constrainTranslation(). Empty */
virtual void constrainTranslation(Vec& translation, Frame* const fra
/*! Returns the translation constraint Type(). me) { Q_UNUSED(translation); Q_UNUSED(frame); };
Depending on this value, the Frame will freely translate (AxisPlaneCons void setTranslationConstraint(Type type, const Vec& direction);
traint::FREE), will only /*! Sets the Type() of the translationConstraintType(). Default is A
be able to translate along an axis direction (AxisPlaneConstraint::AXIS xisPlaneConstraint::FREE. */
), will be forced to stay void setTranslationConstraintType(Type type) { translationConstraint
into a plane (AxisPlaneConstraint::PLANE) or will not able to translate Type_ = type; };
at all void setTranslationConstraintDirection(const Vec& direction);
(AxisPlaneConstraint::FORBIDDEN).
/*! Returns the translation constraint Type().
Use Frame::setPosition() to define the position of the constrained Fram
e before it gets Depending on this value, the Frame will freely translate (AxisPlaneC
constrained. */ onstraint::FREE), will only
Type translationConstraintType() const { return translationConstraintTy be able to translate along an axis direction (AxisPlaneConstraint::A
pe_; }; XIS), will be forced to stay
/*! Returns the direction used by the translation constraint. into a plane (AxisPlaneConstraint::PLANE) or will not able to transl
ate at all
It represents the axis direction (AxisPlaneConstraint::AXIS) or the pla (AxisPlaneConstraint::FORBIDDEN).
ne normal
(AxisPlaneConstraint::PLANE) depending on the translationConstraintType Use Frame::setPosition() to define the position of the constrained F
(). It is undefined for rame before it gets
AxisPlaneConstraint::FREE or AxisPlaneConstraint::FORBIDDEN. constrained. */
Type translationConstraintType() const { return translationConstrain
The AxisPlaneConstraint derived classes express this direction in diffe tType_; };
rent coordinate system /*! Returns the direction used by the translation constraint.
(camera for CameraConstraint, local for LocalConstraint, and world for
WorldConstraint). This It represents the axis direction (AxisPlaneConstraint::AXIS) or the
value can be modified with setTranslationConstraintDirection(). */ plane normal
Vec translationConstraintDirection() const { return translationConstrai (AxisPlaneConstraint::PLANE) depending on the translationConstraintT
ntDir_; }; ype(). It is undefined for
//@} AxisPlaneConstraint::FREE or AxisPlaneConstraint::FORBIDDEN.
/*! @name Rotation constraint */ The AxisPlaneConstraint derived classes express this direction in di
//@{ fferent coordinate system
/*! Overloading of Constraint::constrainRotation(). Empty. */ (camera for CameraConstraint, local for LocalConstraint, and world f
virtual void constrainRotation(Quaternion& rotation, Frame* const frame or WorldConstraint). This
) { Q_UNUSED(rotation); Q_UNUSED(frame); }; value can be modified with setTranslationConstraintDirection(). */
Vec translationConstraintDirection() const { return translationConst
void setRotationConstraint(Type type, const Vec& direction); raintDir_; };
void setRotationConstraintType(Type type); //@}
void setRotationConstraintDirection(const Vec& direction);
/*! @name Rotation constraint */
/*! Returns the rotation constraint Type(). */ //@{
Type rotationConstraintType() const { return rotationConstraintType_; } /*! Overloading of Constraint::constrainRotation(). Empty. */
; virtual void constrainRotation(Quaternion& rotation, Frame* const fr
/*! Returns the axis direction used by the rotation constraint. ame) { Q_UNUSED(rotation); Q_UNUSED(frame); };
This direction is defined only when rotationConstraintType() is AxisPla void setRotationConstraint(Type type, const Vec& direction);
neConstraint::AXIS. void setRotationConstraintType(Type type);
void setRotationConstraintDirection(const Vec& direction);
The AxisPlaneConstraint derived classes express this direction in diffe
rent coordinate system /*! Returns the rotation constraint Type(). */
(camera for CameraConstraint, local for LocalConstraint, and world for Type rotationConstraintType() const { return rotationConstraintType_
WorldConstraint). This ; };
value can be modified with setRotationConstraintDirection(). */ /*! Returns the axis direction used by the rotation constraint.
Vec rotationConstraintDirection() const { return rotationConstraintDir_
; }; This direction is defined only when rotationConstraintType() is Axis
//@} PlaneConstraint::AXIS.
private: The AxisPlaneConstraint derived classes express this direction in di
// int and not Type to allow for overloading and new types definition. fferent coordinate system
Type translationConstraintType_; (camera for CameraConstraint, local for LocalConstraint, and world f
Type rotationConstraintType_; or WorldConstraint). This
value can be modified with setRotationConstraintDirection(). */
Vec translationConstraintDir_; Vec rotationConstraintDirection() const { return rotationConstraintD
Vec rotationConstraintDir_; ir_; };
}; //@}
private:
// int and not Type to allow for overloading and new types definitio
n.
Type translationConstraintType_;
Type rotationConstraintType_;
Vec translationConstraintDir_;
Vec rotationConstraintDir_;
};
/*! \brief An AxisPlaneConstraint defined in the Frame local coordinate s ystem. /*! \brief An AxisPlaneConstraint defined in the Frame local coordinate sys tem.
\class LocalConstraint constraint.h QGLViewer/constraint.h \class LocalConstraint constraint.h QGLViewer/constraint.h
The translationConstraintDirection() and rotationConstraintDirection() ar e expressed in the Frame The translationConstraintDirection() and rotationConstraintDirection() ar e expressed in the Frame
local coordinate system (see Frame::referenceFrame()). local coordinate system (see Frame::referenceFrame()).
See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> example for an illustration. */ See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> example for an illustration. */
class QGLVIEWER_EXPORT LocalConstraint : public AxisPlaneConstraint class QGLVIEWER_EXPORT LocalConstraint : public AxisPlaneConstraint
{ {
public: public:
/*! Virtual destructor. Empty. */ /*! Virtual destructor. Empty. */
virtual ~LocalConstraint() {}; virtual ~LocalConstraint() {};
virtual void constrainTranslation(Vec& translation, Frame* const
frame);
virtual void constrainRotation (Quaternion& rotation, Frame* const
frame);
};
virtual void constrainTranslation(Vec& translation, Frame* const fr /*! \brief An AxisPlaneConstraint defined in the world coordinate system.
ame); \class WorldConstraint constraint.h QGLViewer/constraint.h
virtual void constrainRotation (Quaternion& rotation, Frame* const fr
ame);
};
/*! \brief An AxisPlaneConstraint defined in the world coordinate system.
\class WorldConstraint constraint.h QGLViewer/constraint.h
The translationConstraintDirection() and rotationConstraintDirection() ar e expressed in world The translationConstraintDirection() and rotationConstraintDirection() ar e expressed in world
coordinate system. coordinate system.
See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a
href="../examples/multiView.html">multiView</a> examples for an illustrat ion. */ href="../examples/multiView.html">multiView</a> examples for an illustrat ion. */
class QGLVIEWER_EXPORT WorldConstraint : public AxisPlaneConstraint class QGLVIEWER_EXPORT WorldConstraint : public AxisPlaneConstraint
{ {
public: public:
/*! Virtual destructor. Empty. */ /*! Virtual destructor. Empty. */
virtual ~WorldConstraint() {}; virtual ~WorldConstraint() {};
virtual void constrainTranslation(Vec& translation, Frame* const
frame);
virtual void constrainRotation (Quaternion& rotation, Frame* const
frame);
};
virtual void constrainTranslation(Vec& translation, Frame* const fr /*! \brief An AxisPlaneConstraint defined in the camera coordinate system.
ame);
virtual void constrainRotation (Quaternion& rotation, Frame* const fr
ame);
};
/*! \brief An AxisPlaneConstraint defined in the camera coordinate system
.
\class CameraConstraint constraint.h QGLViewer/constraint.h \class CameraConstraint constraint.h QGLViewer/constraint.h
The translationConstraintDirection() and rotationConstraintDirection() ar e expressed in the The translationConstraintDirection() and rotationConstraintDirection() ar e expressed in the
associated camera() coordinate system. associated camera() coordinate system.
See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a
href="../examples/constrainedCamera.html">constrainedCamera</a> examples for an illustration. */ href="../examples/constrainedCamera.html">constrainedCamera</a> examples for an illustration. */
class QGLVIEWER_EXPORT CameraConstraint : public AxisPlaneConstraint class QGLVIEWER_EXPORT CameraConstraint : public AxisPlaneConstraint
{ {
public: public:
explicit CameraConstraint(const Camera* const camera); explicit CameraConstraint(const Camera* const camera);
/*! Virtual destructor. Empty. */ /*! Virtual destructor. Empty. */
virtual ~CameraConstraint() {}; virtual ~CameraConstraint() {};
virtual void constrainTranslation(Vec& translation, Frame* const fr virtual void constrainTranslation(Vec& translation, Frame* const
ame); frame);
virtual void constrainRotation (Quaternion& rotation, Frame* const fr virtual void constrainRotation (Quaternion& rotation, Frame* const
ame); frame);
/*! Returns the associated Camera. Set using the CameraConstraint const /*! Returns the associated Camera. Set using the CameraConstraint co
ructor. */ nstructor. */
const Camera* camera() const { return camera_; }; const Camera* camera() const { return camera_; };
private: private:
const Camera* const camera_; const Camera* const camera_;
}; };
} // namespace qglviewer } // namespace qglviewer
#endif // QGLVIEWER_CONSTRAINT_H #endif // QGLVIEWER_CONSTRAINT_H
 End of changes. 18 change blocks. 
232 lines changed or deleted 232 lines changed or added


 domUtils.h   domUtils.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 46 skipping to change at line 46
#endif #endif
#include <math.h> #include <math.h>
#ifndef DOXYGEN #ifndef DOXYGEN
// QDomElement loading with syntax checking. // QDomElement loading with syntax checking.
class DomUtils class DomUtils
{ {
private: private:
static void warning(const QString& message) static void warning(const QString& message)
{ {
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
qWarning("%s", message.toLatin1().constData()); qWarning("%s", message.toLatin1().constData());
#else #else
qWarning("%s", message.latin1()); qWarning("%s", message.latin1());
#endif #endif
} }
public: public:
static float floatFromDom(const QDomElement& e, const QString& attribute, static float floatFromDom(const QDomElement& e, const QString& attri
float defValue) bute, float defValue)
{ {
float value = defValue; float value = defValue;
if (e.hasAttribute(attribute)) { if (e.hasAttribute(attribute)) {
const QString s = e.attribute(attribute); const QString s = e.attribute(attribute);
bool ok; bool ok;
value = s.toFloat(&ok); value = s.toFloat(&ok);
if (!ok) { if (!ok) {
warning("Bad float syntax for attribute \""+attribute+"\" in init warning("Bad float syntax for attribute \""+
ialization of \""+e.tagName()+"\". Setting value to "+QString::number(value attribute+"\" in initialization of \""+e.tagName()+"\". Setting value to "+
)+"."); QString::number(value)+".");
value = defValue; value = defValue;
} }
} else } else
warning("\""+attribute+"\" attribute missing in initialization of \"" warning("\""+attribute+"\" attribute missing in init
+e.tagName()+"\". Setting value to "+QString::number(value)+"."); ialization of \""+e.tagName()+"\". Setting value to "+QString::number(value
)+".");
#if defined(isnan) #if defined(isnan)
// The "isnan" method may not be available on all platforms. // The "isnan" method may not be available on all platforms.
// Find its equivalent or simply remove these two lines // Find its equivalent or simply remove these two lines
if (isnan(value)) if (isnan(value))
warning("Warning, attribute \""+attribute+"\" initialized to Not a Nu warning("Warning, attribute \""+attribute+"\" initia
mber in \""+e.tagName()+"\""); lized to Not a Number in \""+e.tagName()+"\"");
#endif #endif
return value; return value;
} }
static double doubleFromDom(const QDomElement& e, const QString& attribut static double doubleFromDom(const QDomElement& e, const QString& att
e, double defValue) ribute, double defValue)
{ {
double value = defValue; double value = defValue;
if (e.hasAttribute(attribute)) { if (e.hasAttribute(attribute)) {
const QString s = e.attribute(attribute); const QString s = e.attribute(attribute);
bool ok; bool ok;
value = s.toDouble(&ok); value = s.toDouble(&ok);
if (!ok) { if (!ok) {
warning("Bad double syntax for attribute \""+attribute+"\" in initi warning("Bad double syntax for attribute \""
alization of \""+e.tagName()+"\". Setting value to "+QString::number(value) +attribute+"\" in initialization of \""+e.tagName()+"\". Setting value to "
+"."); +QString::number(value)+".");
value = defValue; value = defValue;
} }
} else } else
warning("\""+attribute+"\" attribute missing in initialization of \"" warning("\""+attribute+"\" attribute missing in init
+e.tagName()+"\". Setting value to "+QString::number(value)+"."); ialization of \""+e.tagName()+"\". Setting value to "+QString::number(value
)+".");
#if defined(isnan) #if defined(isnan)
// The "isnan" method may not be available on all platforms. // The "isnan" method may not be available on all platforms.
// Find its equivalent or simply remove these two lines // Find its equivalent or simply remove these two lines
if (isnan(value)) if (isnan(value))
warning("Warning, attribute \""+attribute+"\" initialized to Not a Nu warning("Warning, attribute \""+attribute+"\" initia
mber in \""+e.tagName()+"\""); lized to Not a Number in \""+e.tagName()+"\"");
#endif #endif
return value; return value;
} }
static int intFromDom(const QDomElement& e, const QString& attribute, int static int intFromDom(const QDomElement& e, const QString& attribute
defValue) , int defValue)
{ {
int value = defValue; int value = defValue;
if (e.hasAttribute(attribute)) if (e.hasAttribute(attribute))
{ {
const QString s = e.attribute(attribute); const QString s = e.attribute(attribute);
bool ok; bool ok;
s.toInt(&ok); s.toInt(&ok);
if (ok) if (ok)
value = s.toInt(); value = s.toInt();
else else
warning("Bad integer syntax for attribute \""+attribute+"\" in initia warning("Bad integer syntax for attribute \"
lization of \""+e.tagName()+"\". Setting value to "+QString::number(value)+ "+attribute+"\" in initialization of \""+e.tagName()+"\". Setting value to
"."); "+QString::number(value)+".");
} }
else else
warning("\""+attribute+"\" attribute missing in initialization of \"" warning("\""+attribute+"\" attribute missing in init
+e.tagName()+"\". Setting value to "+QString::number(value)+"."); ialization of \""+e.tagName()+"\". Setting value to "+QString::number(value
return value; )+".");
} return value;
}
static bool boolFromDom(const QDomElement& e, const QString& attribute, b
ool defValue) static bool boolFromDom(const QDomElement& e, const QString& attribu
{ te, bool defValue)
bool value = defValue; {
if (e.hasAttribute(attribute)) bool value = defValue;
{ if (e.hasAttribute(attribute))
const QString s = e.attribute(attribute); {
const QString s = e.attribute(attribute);
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
if (s.toLower() == QString("true")) if (s.toLower() == QString("true"))
#else #else
if (s.lower() == QString("true")) if (s.lower() == QString("true"))
#endif #endif
value = true; value = true;
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
else if (s.toLower() == QString("false")) else if (s.toLower() == QString("false"))
#else #else
else if (s.lower() == QString("false")) else if (s.lower() == QString("false"))
#endif #endif
value = false; value = false;
else else
{ {
warning("Bad boolean syntax for attribute \""+attribute+"\" in init warning("Bad boolean syntax for attribute \"
ialization of \""+e.tagName()+"\" (should be \"true\" or \"false\")."); "+attribute+"\" in initialization of \""+e.tagName()+"\" (should be \"true\
warning("Setting value to "+(value?QString("true."):QString("false. " or \"false\").");
"))); warning("Setting value to "+(value?QString("
} true."):QString("false.")));
} }
else }
warning("\""+attribute+"\" attribute missing in initialization of \"" else
+e.tagName()+"\". Setting value to "+(value?QString("true."):QString("false warning("\""+attribute+"\" attribute missing in init
."))); ialization of \""+e.tagName()+"\". Setting value to "+(value?QString("true.
return value; "):QString("false.")));
} return value;
}
static QDomElement QColorDomElement(const QColor& color, const QString& n
ame, QDomDocument& doc) static QDomElement QColorDomElement(const QColor& color, const QStri
{ ng& name, QDomDocument& doc)
QDomElement de = doc.createElement(name); {
de.setAttribute("red", QString::number(color.red())); QDomElement de = doc.createElement(name);
de.setAttribute("green", QString::number(color.green())); de.setAttribute("red", QString::number(color.red()));
de.setAttribute("blue", QString::number(color.blue())); de.setAttribute("green", QString::number(color.green()));
return de; de.setAttribute("blue", QString::number(color.blue()));
} return de;
}
static QColor QColorFromDom(const QDomElement& e)
{ static QColor QColorFromDom(const QDomElement& e)
int color[3]; {
QStringList attribute; int color[3];
attribute << "red" << "green" << "blue"; QStringList attribute;
attribute << "red" << "green" << "blue";
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
for (int i=0; i<attribute.count(); ++i) for (int i=0; i<attribute.count(); ++i)
#else #else
for (unsigned int i=0; i<attribute.count(); ++i) for (unsigned int i=0; i<attribute.count(); ++i)
#endif #endif
color[i] = DomUtils::intFromDom(e, attribute[i], 0); color[i] = DomUtils::intFromDom(e, attribute[i], 0);
return QColor(color[0], color[1], color[2]); return QColor(color[0], color[1], color[2]);
} }
}; };
#endif // DOXYGEN #endif // DOXYGEN
 End of changes. 17 change blocks. 
130 lines changed or deleted 134 lines changed or added


 frame.h   frame.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 38 skipping to change at line 38
# include <QString> # include <QString>
#else #else
# include <qobject.h> # include <qobject.h>
# include <qstring.h> # include <qstring.h>
#endif #endif
#include "constraint.h" #include "constraint.h"
// #include "GL/gl.h" is now included in config.h for ease of configuration // #include "GL/gl.h" is now included in config.h for ease of configuration
namespace qglviewer { namespace qglviewer {
/*! \brief The Frame class represents a coordinate system, defined by a p osition and an /*! \brief The Frame class represents a coordinate system, defined by a pos ition and an
orientation. \class Frame frame.h QGLViewer/frame.h orientation. \class Frame frame.h QGLViewer/frame.h
A Frame is a 3D coordinate system, represented by a position() and an ori entation(). The order of A Frame is a 3D coordinate system, represented by a position() and an ori entation(). The order of
these transformations is important: the Frame is first translated \e and \e then rotated around these transformations is important: the Frame is first translated \e and \e then rotated around
the new translated origin. the new translated origin.
A Frame is useful to define the position and orientation of a 3D rigid ob ject, using its matrix() A Frame is useful to define the position and orientation of a 3D rigid ob ject, using its matrix()
method, as shown below: method, as shown below:
\code \code
// Builds a Frame at position (0.5,0,0) and oriented such that its Y axis is along the (1,1,1) // Builds a Frame at position (0.5,0,0) and oriented such that its Y axis is along the (1,1,1)
skipping to change at line 126 skipping to change at line 126
Classical constraints are provided for convenience (see LocalConstraint, WorldConstraint and Classical constraints are provided for convenience (see LocalConstraint, WorldConstraint and
CameraConstraint) and new constraints can very easily be implemented. CameraConstraint) and new constraints can very easily be implemented.
<h3>Derived classes</h3> <h3>Derived classes</h3>
The ManipulatedFrame class inherits Frame and implements a mouse motion c onvertion, so that a The ManipulatedFrame class inherits Frame and implements a mouse motion c onvertion, so that a
Frame (and hence an object) can be manipulated in the scene with the mous e. Frame (and hence an object) can be manipulated in the scene with the mous e.
\nosubgrouping */ \nosubgrouping */
class QGLVIEWER_EXPORT Frame : public QObject class QGLVIEWER_EXPORT Frame : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Frame(); Frame();
/*! Virtual destructor. Empty. */ /*! Virtual destructor. Empty. */
virtual ~Frame() {}; virtual ~Frame() {}
Frame(const Frame& frame); Frame(const Frame& frame);
Frame& operator=(const Frame& frame); Frame& operator=(const Frame& frame);
Q_SIGNALS: Q_SIGNALS:
/*! This signal is emitted whenever the position() or the orientation() /*! This signal is emitted whenever the position() or the orientatio
of the Frame is modified. n() of the Frame is modified.
Connect this signal to any object that must be notified: Connect this signal to any object that must be notified:
\code \code
QObject::connect(myFrame, SIGNAL(modified()), myObject, SLOT(update())) QObject::connect(myFrame, SIGNAL(modified()), myObject, SLOT(update(
; )));
\endcode \endcode
Use the QGLViewer::QGLViewerPool() to connect the signal to all the vie Use the QGLViewer::QGLViewerPool() to connect the signal to all the
wers. viewers.
\note If your Frame is part of a Frame hierarchy (see referenceFrame()) \note If your Frame is part of a Frame hierarchy (see referenceFrame
, a modification of one ()), a modification of one
of the parents of this Frame will \e not emit this signal. Use code lik of the parents of this Frame will \e not emit this signal. Use code
e this to change this like this to change this
behavior (you can do this recursively for all the referenceFrame() unti behavior (you can do this recursively for all the referenceFrame() u
l the \c NULL world root ntil the \c NULL world root
frame is encountered): frame is encountered):
\code \code
// Emits the Frame modified() signal when its referenceFrame() is modif // Emits the Frame modified() signal when its referenceFrame() is mo
ied(). dified().
connect(myFrame->referenceFrame(), SIGNAL(modified()), myFrame, SIGNAL( connect(myFrame->referenceFrame(), SIGNAL(modified()), myFrame, SIGN
modified())); AL(modified()));
\endcode \endcode
\attention Connecting this signal to a QGLWidget::updateGL() slot (or a \attention Connecting this signal to a QGLWidget::update() slot (or
method that calls it) a method that calls it)
will prevent you from modifying the Frame \e inside your QGLViewer::dra will prevent you from modifying the Frame \e inside your QGLViewer::
w() method as it would draw() method as it would
result in an infinite loop. However, QGLViewer::draw() should not modif result in an infinite loop. However, QGLViewer::draw() should not mo
y the scene. dify the scene.
\note For efficiency reasons, this signal is emitted even if the Frame \note For efficiency reasons, this signal is emitted even if the Fra
is not actually modified, for me is not actually modified, for
instance with translate(Vec(0,0,0)) or setPosition(position()). */ instance with translate(Vec(0,0,0)) or setPosition(position()). */
void modified(); void modified();
/*! This signal is emitted when the Frame is interpolated by a KeyFrame /*! This signal is emitted when the Frame is interpolated by a KeyFr
Interpolator. ameInterpolator.
See the KeyFrameInterpolator documentation for details. See the KeyFrameInterpolator documentation for details.
If a KeyFrameInterpolator is used to successively interpolate several F If a KeyFrameInterpolator is used to successively interpolate severa
rames in your scene, l Frames in your scene,
connect the KeyFrameInterpolator::interpolated() signal instead (identi connect the KeyFrameInterpolator::interpolated() signal instead (ide
cal, but independent of ntical, but independent of
the interpolated Frame). */ the interpolated Frame). */
void interpolated(); void interpolated();
public: public:
/*! @name World coordinates position and orientation */ /*! @name World coordinates position and orientation */
//@{ //@{
Frame(const Vec& position, const Quaternion& orientation); Frame(const Vec& position, const Quaternion& orientation);
void setPosition(const Vec& position); void setPosition(const Vec& position);
void setPosition(float x, float y, float z); void setPosition(float x, float y, float z);
void setPositionWithConstraint(Vec& position); void setPositionWithConstraint(Vec& position);
void setOrientation(const Quaternion& orientation); void setOrientation(const Quaternion& orientation);
void setOrientation(double q0, double q1, double q2, double q3); void setOrientation(double q0, double q1, double q2, double q3);
void setOrientationWithConstraint(Quaternion& orientation); void setOrientationWithConstraint(Quaternion& orientation);
void setPositionAndOrientation(const Vec& position, const Quaternion& o void setPositionAndOrientation(const Vec& position, const Quaternion
rientation); & orientation);
void setPositionAndOrientationWithConstraint(Vec& position, Quaternion& void setPositionAndOrientationWithConstraint(Vec& position, Quaterni
orientation); on& orientation);
/*! Returns the position of the Frame, defined in the world coordinate /*! Returns the position of the Frame, defined in the world coordina
system. See also te system. See also
orientation(), setPosition() and translation(). */ orientation(), setPosition() and translation(). */
Vec position() const { return inverseCoordinatesOf(Vec(0.0,0.0,0.0)); } Vec position() const { return inverseCoordinatesOf(Vec(0.0,0.0,0.0))
; ; }
Quaternion orientation() const; Quaternion orientation() const;
void getPosition(float& x, float& y, float& z) const; void getPosition(float& x, float& y, float& z) const;
void getOrientation(double& q0, double& q1, double& q2, double& q3) con void getOrientation(double& q0, double& q1, double& q2, double& q3)
st; const;
//@} //@}
public: public:
/*! @name Local translation and rotation w/r reference Frame */ /*! @name Local translation and rotation w/r reference Frame */
//@{ //@{
/*! Sets the translation() of the frame, locally defined with respect t /*! Sets the translation() of the frame, locally defined with respec
o the referenceFrame(). t to the referenceFrame().
Emits the modified() signal. Emits the modified() signal.
Use setPosition() to define the world coordinates position(). Use Use setPosition() to define the world coordinates position(). Use
setTranslationWithConstraint() to take into account the potential const setTranslationWithConstraint() to take into account the potential co
raint() of the Frame. */ nstraint() of the Frame. */
void setTranslation(const Vec& translation) { t_ = translation; Q_EMIT void setTranslation(const Vec& translation) { t_ = translation; Q_EM
modified(); }; IT modified(); }
void setTranslation(float x, float y, float z); void setTranslation(float x, float y, float z);
void setTranslationWithConstraint(Vec& translation); void setTranslationWithConstraint(Vec& translation);
/*! Set the current rotation Quaternion. See rotation() and the differe /*! Set the current rotation Quaternion. See rotation() and the diff
nt Quaternion erent Quaternion
constructors. Emits the modified() signal. See also setTranslation() an constructors. Emits the modified() signal. See also setTranslation()
d and
setRotationWithConstraint(). */ setRotationWithConstraint(). */
/*! Sets the rotation() of the Frame, locally defined with respect to t /*! Sets the rotation() of the Frame, locally defined with respect t
he referenceFrame(). o the referenceFrame().
Emits the modified() signal. Emits the modified() signal.
Use setOrientation() to define the world coordinates orientation(). Th Use setOrientation() to define the world coordinates orientation().
e potential The potential
constraint() of the Frame is not taken into account, use setRotationWi constraint() of the Frame is not taken into account, use setRotatio
thConstraint() nWithConstraint()
instead. */ instead. */
void setRotation(const Quaternion& rotation) { q_ = rotation; Q_EMIT mo void setRotation(const Quaternion& rotation) { q_ = rotation; Q_EMIT
dified(); }; modified(); }
void setRotation(double q0, double q1, double q2, double q3); void setRotation(double q0, double q1, double q2, double q3);
void setRotationWithConstraint(Quaternion& rotation); void setRotationWithConstraint(Quaternion& rotation);
void setTranslationAndRotation(const Vec& translation, const Quaternion void setTranslationAndRotation(const Vec& translation, const Quatern
& rotation); ion& rotation);
void setTranslationAndRotationWithConstraint(Vec& translation, Quaterni void setTranslationAndRotationWithConstraint(Vec& translation, Quate
on& rotation); rnion& rotation);
/*! Returns the Frame translation, defined with respect to the referenc /*! Returns the Frame translation, defined with respect to the refer
eFrame(). enceFrame().
Use position() to get the result in the world coordinates. These two va Use position() to get the result in the world coordinates. These two
lues are identical values are identical
when the referenceFrame() is \c NULL (default). when the referenceFrame() is \c NULL (default).
See also setTranslation() and setTranslationWithConstraint(). */ See also setTranslation() and setTranslationWithConstraint(). */
Vec translation() const { return t_; }; Vec translation() const { return t_; }
/*! Returns the Frame rotation, defined with respect to the referenceFr /*! Returns the Frame rotation, defined with respect to the referenc
ame(). eFrame().
Use orientation() to get the result in the world coordinates. These two Use orientation() to get the result in the world coordinates. These
values are identical two values are identical
when the referenceFrame() is \c NULL (default). when the referenceFrame() is \c NULL (default).
See also setRotation() and setRotationWithConstraint(). */ See also setRotation() and setRotationWithConstraint(). */
/*! Returns the current Quaternion orientation. See setRotation(). */ /*! Returns the current Quaternion orientation. See setRotation(). *
Quaternion rotation() const { return q_; }; /
Quaternion rotation() const { return q_; }
void getTranslation(float& x, float& y, float& z) const;
void getRotation(double& q0, double& q1, double& q2, double& q3) const; void getTranslation(float& x, float& y, float& z) const;
//@} void getRotation(double& q0, double& q1, double& q2, double& q3) con
st;
public: //@}
/*! @name Frame hierarchy */
//@{ public:
/*! Returns the reference Frame, in which coordinates system the Frame /*! @name Frame hierarchy */
is defined. //@{
/*! Returns the reference Frame, in which coordinates system the Fra
The translation() and rotation() of the Frame are defined with respect me is defined.
to the referenceFrame()
coordinate system. A \c NULL referenceFrame() (default value) means tha The translation() and rotation() of the Frame are defined with respe
t the Frame is defined in ct to the referenceFrame()
the world coordinate system. coordinate system. A \c NULL referenceFrame() (default value) means
that the Frame is defined in
Use position() and orientation() to recursively convert values along th the world coordinate system.
e referenceFrame() chain
and to get values expressed in the world coordinate system. The values Use position() and orientation() to recursively convert values along
match when the the referenceFrame() chain
referenceFrame() is \c NULL. and to get values expressed in the world coordinate system. The valu
es match when the
Use setReferenceFrame() to set this value and create a Frame hierarchy. referenceFrame() is \c NULL.
Convenient functions
allow you to convert 3D coordinates from one Frame to an other: see coo Use setReferenceFrame() to set this value and create a Frame hierarc
rdinatesOf(), hy. Convenient functions
localCoordinatesOf(), coordinatesOfIn() and their inverse functions. allow you to convert 3D coordinates from one Frame to an other: see
coordinatesOf(),
Vectors can also be converted using transformOf(), transformOfIn, local localCoordinatesOf(), coordinatesOfIn() and their inverse functions.
TransformOf() and their
inverse functions. */ Vectors can also be converted using transformOf(), transformOfIn, lo
const Frame* referenceFrame() const { return referenceFrame_; }; calTransformOf() and their
void setReferenceFrame(const Frame* const refFrame); inverse functions. */
bool settingAsReferenceFrameWillCreateALoop(const Frame* const frame); const Frame* referenceFrame() const { return referenceFrame_; }
//@} void setReferenceFrame(const Frame* const refFrame);
bool settingAsReferenceFrameWillCreateALoop(const Frame* const frame
/*! @name Frame modification */ );
//@{ //@}
void translate(Vec& t);
void translate(const Vec& t); /*! @name Frame modification */
// Some compilers complain about "overloading cannot distinguish from p //@{
revious declaration" void translate(Vec& t);
// Simply comment out the following method and its associated implement void translate(const Vec& t);
ation // Some compilers complain about "overloading cannot distinguish fro
void translate(float x, float y, float z); m previous declaration"
void translate(float& x, float& y, float& z); // Simply comment out the following method and its associated implem
entation
void rotate(Quaternion& q); void translate(float x, float y, float z);
void rotate(const Quaternion& q); void translate(float& x, float& y, float& z);
// Some compilers complain about "overloading cannot distinguish from p
revious declaration" void rotate(Quaternion& q);
// Simply comment out the following method and its associated implement void rotate(const Quaternion& q);
ation // Some compilers complain about "overloading cannot distinguish fro
void rotate(double q0, double q1, double q2, double q3); m previous declaration"
void rotate(double& q0, double& q1, double& q2, double& q3); // Simply comment out the following method and its associated implem
entation
void rotateAroundPoint(Quaternion& rotation, const Vec& point); void rotate(double q0, double q1, double q2, double q3);
void rotateAroundPoint(const Quaternion& rotation, const Vec& point); void rotate(double& q0, double& q1, double& q2, double& q3);
void alignWithFrame(const Frame* const frame, bool move=false, float th void rotateAroundPoint(Quaternion& rotation, const Vec& point);
reshold=0.85f); void rotateAroundPoint(const Quaternion& rotation, const Vec& point)
void projectOnLine(const Vec& origin, const Vec& direction); ;
//@}
void alignWithFrame(const Frame* const frame, bool move=false, float
/*! @name Coordinate system transformation of 3D coordinates */ threshold=0.85f);
//@{ void projectOnLine(const Vec& origin, const Vec& direction);
Vec coordinatesOf(const Vec& src) const; //@}
Vec inverseCoordinatesOf(const Vec& src) const;
Vec localCoordinatesOf(const Vec& src) const; /*! @name Coordinate system transformation of 3D coordinates */
Vec localInverseCoordinatesOf(const Vec& src) const; //@{
Vec coordinatesOfIn(const Vec& src, const Frame* const in) const; Vec coordinatesOf(const Vec& src) const;
Vec coordinatesOfFrom(const Vec& src, const Frame* const from) const; Vec inverseCoordinatesOf(const Vec& src) const;
Vec localCoordinatesOf(const Vec& src) const;
void getCoordinatesOf(const float src[3], float res[3]) const; Vec localInverseCoordinatesOf(const Vec& src) const;
void getInverseCoordinatesOf(const float src[3], float res[3]) const; Vec coordinatesOfIn(const Vec& src, const Frame* const in) const;
void getLocalCoordinatesOf(const float src[3], float res[3]) const; Vec coordinatesOfFrom(const Vec& src, const Frame* const from) const
void getLocalInverseCoordinatesOf(const float src[3], float res[3]) con ;
st;
void getCoordinatesOfIn(const float src[3], float res[3], const Frame* void getCoordinatesOf(const float src[3], float res[3]) const;
const in) const; void getInverseCoordinatesOf(const float src[3], float res[3]) const
void getCoordinatesOfFrom(const float src[3], float res[3], const Frame ;
* const from) const; void getLocalCoordinatesOf(const float src[3], float res[3]) const;
//@} void getLocalInverseCoordinatesOf(const float src[3], float res[3])
const;
/*! @name Coordinate system transformation of vectors */ void getCoordinatesOfIn(const float src[3], float res[3], const Fram
// A frame is as a new coordinate system, defined with respect to a ref e* const in) const;
erence frame (the world void getCoordinatesOfFrom(const float src[3], float res[3], const Fr
// coordinate system by default, see the "Composition of frame" section ame* const from) const;
). //@}
// The transformOf() (resp. inverseTransformOf()) functions transform a /*! @name Coordinate system transformation of vectors */
3D vector from (resp. // A frame is as a new coordinate system, defined with respect to a
// to) the world coordinates system. This section defines the 3D vector reference frame (the world
transformation // coordinate system by default, see the "Composition of frame" sect
// functions. See the Coordinate system transformation of 3D points abo ion).
ve for the transformation
// of 3D points. The difference between the two sets of functions is si // The transformOf() (resp. inverseTransformOf()) functions transfor
mple: for vectors, only m a 3D vector from (resp.
// the rotational part of the transformations is taken into account, wh // to) the world coordinates system. This section defines the 3D vec
ile translation is also tor transformation
// considered for 3D points. // functions. See the Coordinate system transformation of 3D points
above for the transformation
// The length of the resulting transformed vector is identical to the o // of 3D points. The difference between the two sets of functions is
ne of the source vector simple: for vectors, only
// for all the described functions. // the rotational part of the transformations is taken into account,
while translation is also
// When local is prepended to the names of the functions, the functions // considered for 3D points.
simply transform from
// (and to) the reference frame. // The length of the resulting transformed vector is identical to th
e one of the source vector
// When In (resp. From) is appended to the names, the functions transfo // for all the described functions.
rm from (resp. To) the
// frame that is given as an argument. The frame does not need to be in // When local is prepended to the names of the functions, the functi
the same branch or the ons simply transform from
// hierarchical tree, and can be \c NULL (the world coordinates system) // (and to) the reference frame.
.
// When In (resp. From) is appended to the names, the functions tran
// Combining any of these functions with its inverse (in any order) lea sform from (resp. To) the
ds to the identity. // frame that is given as an argument. The frame does not need to be
//@{ in the same branch or the
Vec transformOf(const Vec& src) const; // hierarchical tree, and can be \c NULL (the world coordinates syst
Vec inverseTransformOf(const Vec& src) const; em).
Vec localTransformOf(const Vec& src) const;
Vec localInverseTransformOf(const Vec& src) const; // Combining any of these functions with its inverse (in any order)
Vec transformOfIn(const Vec& src, const Frame* const in) const; leads to the identity.
Vec transformOfFrom(const Vec& src, const Frame* const from) const; //@{
Vec transformOf(const Vec& src) const;
void getTransformOf(const float src[3], float res[3]) const; Vec inverseTransformOf(const Vec& src) const;
void getInverseTransformOf(const float src[3], float res[3]) const; Vec localTransformOf(const Vec& src) const;
void getLocalTransformOf(const float src[3], float res[3]) const; Vec localInverseTransformOf(const Vec& src) const;
void getLocalInverseTransformOf(const float src[3], float res[3]) const Vec transformOfIn(const Vec& src, const Frame* const in) const;
; Vec transformOfFrom(const Vec& src, const Frame* const from) const;
void getTransformOfIn(const float src[3], float res[3], const Frame* co
nst in) const; void getTransformOf(const float src[3], float res[3]) const;
void getTransformOfFrom(const float src[3], float res[3], const Frame* void getInverseTransformOf(const float src[3], float res[3]) const;
const from) const; void getLocalTransformOf(const float src[3], float res[3]) const;
//@} void getLocalInverseTransformOf(const float src[3], float res[3]) co
nst;
/*! @name Constraint on the displacement */ void getTransformOfIn(const float src[3], float res[3], const Frame*
//@{ const in) const;
/*! Returns the current constraint applied to the Frame. void getTransformOfFrom(const float src[3], float res[3], const Fram
e* const from) const;
A \c NULL value (default) means that no Constraint is used to filter Fr //@}
ame translation and
rotation. See the Constraint class documentation for details. /*! @name Constraint on the displacement */
//@{
You may have to use a \c dynamic_cast to convert the result to a Constr /*! Returns the current constraint applied to the Frame.
aint derived class. */
Constraint* constraint() const { return constraint_; } A \c NULL value (default) means that no Constraint is used to filter
/*! Sets the constraint() attached to the Frame. Frame translation and
rotation. See the Constraint class documentation for details.
A \c NULL value means no constraint. The previous constraint() should b
e deleted by the calling You may have to use a \c dynamic_cast to convert the result to a Con
method if needed. */ straint derived class. */
void setConstraint(Constraint* const constraint) { constraint_ = constr Constraint* constraint() const { return constraint_; }
aint; } /*! Sets the constraint() attached to the Frame.
//@}
A \c NULL value means no constraint. The previous constraint() shoul
/*! @name Associated matrices */ d be deleted by the calling
//@{ method if needed. */
public: void setConstraint(Constraint* const constraint) { constraint_ = con
const GLdouble* matrix() const; straint; }
void getMatrix(GLdouble m[4][4]) const; //@}
void getMatrix(GLdouble m[16]) const;
/*! @name Associated matrices */
const GLdouble* worldMatrix() const; //@{
void getWorldMatrix(GLdouble m[4][4]) const; public:
void getWorldMatrix(GLdouble m[16]) const; const GLdouble* matrix() const;
void getMatrix(GLdouble m[4][4]) const;
void setFromMatrix(const GLdouble m[4][4]); void getMatrix(GLdouble m[16]) const;
void setFromMatrix(const GLdouble m[16]);
//@} const GLdouble* worldMatrix() const;
void getWorldMatrix(GLdouble m[4][4]) const;
/*! @name Inversion of the transformation */ void getWorldMatrix(GLdouble m[16]) const;
//@{
Frame inverse() const; void setFromMatrix(const GLdouble m[4][4]);
/*! Returns the inverse() of the Frame world transformation. void setFromMatrix(const GLdouble m[16]);
//@}
The orientation() of the new Frame is the Quaternion::inverse() of the
original orientation. /*! @name Inversion of the transformation */
Its position() is the negated and inverse rotated image of the original //@{
position. Frame inverse() const;
/*! Returns the inverse() of the Frame world transformation.
The result Frame has a \c NULL referenceFrame() and a \c NULL constrain
t(). The orientation() of the new Frame is the Quaternion::inverse() of t
he original orientation.
Use inverse() for a local (i.e. with respect to referenceFrame()) trans Its position() is the negated and inverse rotated image of the origi
formation inverse. */ nal position.
Frame worldInverse() const { return Frame(-(orientation().inverseRotate
(position())), orientation().inverse()); } The result Frame has a \c NULL referenceFrame() and a \c NULL constr
//@} aint().
/*! @name XML representation */ Use inverse() for a local (i.e. with respect to referenceFrame()) tr
//@{ ansformation inverse. */
public: Frame worldInverse() const { return Frame(-(orientation().inverseRot
virtual QDomElement domElement(const QString& name, QDomDocument& docum ate(position())), orientation().inverse()); }
ent) const; //@}
public Q_SLOTS:
virtual void initFromDOMElement(const QDomElement& element); /*! @name XML representation */
//@} //@{
public:
private: virtual QDomElement domElement(const QString& name, QDomDocument& do
// P o s i t i o n a n d o r i e n t a t i o n cument) const;
Vec t_; public Q_SLOTS:
Quaternion q_; virtual void initFromDOMElement(const QDomElement& element);
//@}
// C o n s t r a i n t s
Constraint* constraint_; private:
// P o s i t i o n a n d o r i e n t a t i o n
// F r a m e c o m p o s i t i o n Vec t_;
const Frame* referenceFrame_; Quaternion q_;
};
// C o n s t r a i n t s
Constraint* constraint_;
// F r a m e c o m p o s i t i o n
const Frame* referenceFrame_;
};
} // namespace qglviewer } // namespace qglviewer
#endif // QGLVIEWER_FRAME_H #endif // QGLVIEWER_FRAME_H
 End of changes. 3 change blocks. 
368 lines changed or deleted 374 lines changed or added


 keyFrameInterpolator.h   keyFrameInterpolator.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 43 skipping to change at line 43
#include "quaternion.h" #include "quaternion.h"
// Not actually needed, but some bad compilers (Microsoft VS6) complain. // Not actually needed, but some bad compilers (Microsoft VS6) complain.
#include "frame.h" #include "frame.h"
// If you compiler complains about incomplete type, uncomment the next line // If you compiler complains about incomplete type, uncomment the next line
// #include "frame.h" // #include "frame.h"
// and comment "class Frame;" 3 lines below // and comment "class Frame;" 3 lines below
namespace qglviewer { namespace qglviewer {
class Camera; class Camera;
class Frame; class Frame;
/*! \brief A keyFrame Catmull-Rom Frame interpolator. /*! \brief A keyFrame Catmull-Rom Frame interpolator.
\class KeyFrameInterpolator keyFrameInterpolator.h QGLViewer/keyFrameInte rpolator.h \class KeyFrameInterpolator keyFrameInterpolator.h QGLViewer/keyFrameInte rpolator.h
A KeyFrameInterpolator holds keyFrames (that define a path) and a pointer to a Frame of your A KeyFrameInterpolator holds keyFrames (that define a path) and a pointer to a Frame of your
application (which will be interpolated). When the user startInterpolatio n(), the application (which will be interpolated). When the user startInterpolatio n(), the
KeyFrameInterpolator regularly updates the frame() position and orientati on along the path. KeyFrameInterpolator regularly updates the frame() position and orientati on along the path.
Here is a typical utilization example (see also the <a href="../examples/ keyFrames.html">keyFrames Here is a typical utilization example (see also the <a href="../examples/ keyFrames.html">keyFrames
example</a>): example</a>):
\code \code
init() init()
{ {
// The KeyFrameInterpolator kfi is given the Frame that it will drive o // The KeyFrameInterpolator kfi is given the Frame that it will driv
ver time. e over time.
kfi = new KeyFrameInterpolator( new Frame() ); kfi = new KeyFrameInterpolator( new Frame() );
kfi->addKeyFrame( Frame( Vec(1,0,0), Quaternion() ) ); kfi->addKeyFrame( Frame( Vec(1,0,0), Quaternion() ) );
kfi->addKeyFrame( new Frame( Vec(2,1,0), Quaternion() ) ); kfi->addKeyFrame( new Frame( Vec(2,1,0), Quaternion() ) );
// ...and so on for all the keyFrames. // ...and so on for all the keyFrames.
// Ask for a display update after each update of the KeyFrameInterpolat // Ask for a display update after each update of the KeyFrameInterpo
or lator
connect(kfi, SIGNAL(interpolated()), SLOT(updateGL())); connect(kfi, SIGNAL(interpolated()), SLOT(update()));
kfi->startInterpolation(); kfi->startInterpolation();
} }
draw() draw()
{ {
glPushMatrix(); glPushMatrix();
glMultMatrixd( kfi->frame()->matrix() ); glMultMatrixd( kfi->frame()->matrix() );
// Draw your object here. Its position and orientation are interpolated // Draw your object here. Its position and orientation are interpola
. ted.
glPopMatrix(); glPopMatrix();
} }
\endcode \endcode
The keyFrames are defined by a Frame and a time, expressed in seconds. Th e Frame can be provided The keyFrames are defined by a Frame and a time, expressed in seconds. Th e Frame can be provided
as a const reference or as a pointer to a Frame (see the addKeyFrame() me thods). In the latter as a const reference or as a pointer to a Frame (see the addKeyFrame() me thods). In the latter
case, the path will automatically be updated when the Frame is modified ( using the case, the path will automatically be updated when the Frame is modified ( using the
Frame::modified() signal). Frame::modified() signal).
The time has to be monotonously increasing over keyFrames. When interpola tionSpeed() equals 1.0 The time has to be monotonously increasing over keyFrames. When interpola tionSpeed() equals 1.0
(default value), these times correspond to actual user's seconds during i nterpolation (provided (default value), these times correspond to actual user's seconds during i nterpolation (provided
skipping to change at line 100 skipping to change at line 100
When the user startInterpolation(), a timer is started which will update the frame()'s position When the user startInterpolation(), a timer is started which will update the frame()'s position
and orientation every interpolationPeriod() milliseconds. This update inc reases the and orientation every interpolationPeriod() milliseconds. This update inc reases the
interpolationTime() by interpolationPeriod() * interpolationSpeed() milli seconds. interpolationTime() by interpolationPeriod() * interpolationSpeed() milli seconds.
Note that this mechanism ensures that the number of interpolation steps i s constant and equal to Note that this mechanism ensures that the number of interpolation steps i s constant and equal to
the total path duration() divided by the interpolationPeriod() * interpol ationSpeed(). This is the total path duration() divided by the interpolationPeriod() * interpol ationSpeed(). This is
especially useful for benchmarking or movie creation (constant number of snapshots). especially useful for benchmarking or movie creation (constant number of snapshots).
During the interpolation, the KeyFrameInterpolator emits an interpolated( ) signal, which will During the interpolation, the KeyFrameInterpolator emits an interpolated( ) signal, which will
usually be connected to the QGLViewer::updateGL() slot. The interpolation is stopped when usually be connected to the QGLViewer::update() slot. The interpolation i s stopped when
interpolationTime() is greater than the lastTime() (unless loopInterpolat ion() is \c true) and the interpolationTime() is greater than the lastTime() (unless loopInterpolat ion() is \c true) and the
endReached() signal is then emitted. endReached() signal is then emitted.
Note that a Camera has Camera::keyFrameInterpolator(), that can be used t o drive the Camera along a Note that a Camera has Camera::keyFrameInterpolator(), that can be used t o drive the Camera along a
path, or to restore a saved position (a path made of a single keyFrame). Press Alt+Fx to define a path, or to restore a saved position (a path made of a single keyFrame). Press Alt+Fx to define a
new keyFrame for path x. Pressing Fx plays/pauses path interpolation. See QGLViewer::pathKey() and new keyFrame for path x. Pressing Fx plays/pauses path interpolation. See QGLViewer::pathKey() and
the <a href="../keyboard.html">keyboard page</a> for details. the <a href="../keyboard.html">keyboard page</a> for details.
\attention If a Constraint is attached to the frame() (see Frame::constra int()), it should be \attention If a Constraint is attached to the frame() (see Frame::constra int()), it should be
deactivated before interpolationIsStarted(), otherwise the interpolated m otion (computed as if deactivated before interpolationIsStarted(), otherwise the interpolated m otion (computed as if
skipping to change at line 124 skipping to change at line 124
This code defines a KeyFrameInterpolator, and displays the positions that will be followed by the This code defines a KeyFrameInterpolator, and displays the positions that will be followed by the
frame() along the path: frame() along the path:
\code \code
KeyFrameInterpolator kfi( new Frame() ); KeyFrameInterpolator kfi( new Frame() );
// calls to kfi.addKeyFrame() to define the path. // calls to kfi.addKeyFrame() to define the path.
const float deltaTime = 0.04; // output a position every deltaTime second s const float deltaTime = 0.04; // output a position every deltaTime second s
for (float time=kfi.firstTime(); time<=kfi.lastTime(); time += deltaTime) for (float time=kfi.firstTime(); time<=kfi.lastTime(); time += deltaTime)
{ {
kfi.interpolateAtTime(time); kfi.interpolateAtTime(time);
cout << "t=" << time << "\tpos=" << kfi.frame()->position() << endl; cout << "t=" << time << "\tpos=" << kfi.frame()->position() << endl;
} }
\endcode \endcode
You may want to temporally disconnect the \c kfi interpolated() signal fr om the You may want to temporally disconnect the \c kfi interpolated() signal fr om the
QGLViewer::updateGL() slot before calling this code. \nosubgrouping */ QGLViewer::update() slot before calling this code. \nosubgrouping */
class QGLVIEWER_EXPORT KeyFrameInterpolator : public QObject class QGLVIEWER_EXPORT KeyFrameInterpolator : public QObject
{ {
// todo closedPath, insertKeyFrames, deleteKeyFrame, replaceKeyFrame // todo closedPath, insertKeyFrames, deleteKeyFrame, replaceKeyFrame
Q_OBJECT Q_OBJECT
public: public:
KeyFrameInterpolator(Frame* fr=NULL); KeyFrameInterpolator(Frame* fr=NULL);
virtual ~KeyFrameInterpolator(); virtual ~KeyFrameInterpolator();
Q_SIGNALS: Q_SIGNALS:
/*! This signal is emitted whenever the frame() state is interpolated. /*! This signal is emitted whenever the frame() state is interpolate
d.
The emission of this signal triggers the synchronous emission of the fr
ame() The emission of this signal triggers the synchronous emission of the
Frame::interpolated() signal, which may also be useful. frame()
Frame::interpolated() signal, which may also be useful.
This signal should especially be connected to your QGLViewer::updateGL(
) slot, so that the display This signal should especially be connected to your QGLViewer::update
is updated after every update of the KeyFrameInterpolator frame(): () slot, so that the display
\code is updated after every update of the KeyFrameInterpolator frame():
connect(myKeyFrameInterpolator, SIGNAL(interpolated()), SLOT(updateGL() \code
)); connect(myKeyFrameInterpolator, SIGNAL(interpolated()), SLOT(update(
\endcode )));
Use the QGLViewer::QGLViewerPool() to connect the signal to all the vie \endcode
wers. Use the QGLViewer::QGLViewerPool() to connect the signal to all the
viewers.
Note that the QGLViewer::camera() Camera::keyFrameInterpolator() create
d using QGLViewer::pathKey() Note that the QGLViewer::camera() Camera::keyFrameInterpolator() cre
have their interpolated() signals automatically connected to the QGLVie ated using QGLViewer::pathKey()
wer::updateGL() slot. */ have their interpolated() signals automatically connected to the QGL
void interpolated(); Viewer::update() slot. */
void interpolated();
/*! This signal is emitted when the interpolation reaches the first (wh
en interpolationSpeed() /*! This signal is emitted when the interpolation reaches the first
is negative) or the last keyFrame. (when interpolationSpeed()
is negative) or the last keyFrame.
When loopInterpolation() is \c true, interpolationTime() is reset and t
he interpolation When loopInterpolation() is \c true, interpolationTime() is reset an
continues. It otherwise stops. */ d the interpolation
void endReached(); continues. It otherwise stops. */
void endReached();
/*! @name Path creation */
//@{ /*! @name Path creation */
public Q_SLOTS: //@{
void addKeyFrame(const Frame& frame); public Q_SLOTS:
void addKeyFrame(const Frame& frame, float time); void addKeyFrame(const Frame& frame);
void addKeyFrame(const Frame& frame, float time);
void addKeyFrame(const Frame* const frame);
void addKeyFrame(const Frame* const frame, float time); void addKeyFrame(const Frame* const frame);
void addKeyFrame(const Frame* const frame, float time);
void deletePath();
//@} void deletePath();
//@}
/*! @name Associated Frame */
//@{ /*! @name Associated Frame */
public: //@{
/*! Returns the associated Frame and that is interpolated by the KeyFra public:
meInterpolator. /*! Returns the associated Frame and that is interpolated by the Key
FrameInterpolator.
When interpolationIsStarted(), this Frame's position and orientation wi
ll regularly be updated When interpolationIsStarted(), this Frame's position and orientation
by a timer, so that they follow the KeyFrameInterpolator path. will regularly be updated
by a timer, so that they follow the KeyFrameInterpolator path.
Set using setFrame() or with the KeyFrameInterpolator constructor. */
Frame* frame() const { return frame_; }; Set using setFrame() or with the KeyFrameInterpolator constructor. *
/
public Q_SLOTS: Frame* frame() const { return frame_; }
void setFrame(Frame* const frame);
//@} public Q_SLOTS:
void setFrame(Frame* const frame);
/*! @name Path parameters */ //@}
//@{
public: /*! @name Path parameters */
Frame keyFrame(int index) const; //@{
float keyFrameTime(int index) const; public:
/*! Returns the number of keyFrames used by the interpolation. Use addK Frame keyFrame(int index) const;
eyFrame() to add new keyFrames. */ float keyFrameTime(int index) const;
int numberOfKeyFrames() const { return keyFrame_.count(); }; /*! Returns the number of keyFrames used by the interpolation. Use a
float duration() const; ddKeyFrame() to add new keyFrames. */
float firstTime() const; int numberOfKeyFrames() const { return keyFrame_.count(); }
float lastTime() const; float duration() const;
//@} float firstTime() const;
float lastTime() const;
/*! @name Interpolation parameters */ //@}
//@{
public: /*! @name Interpolation parameters */
/*! Returns the current interpolation time (in seconds) along the KeyFr //@{
ameInterpolator path. public:
/*! Returns the current interpolation time (in seconds) along the Ke
This time is regularly updated when interpolationIsStarted(). Can be se yFrameInterpolator path.
t directly with
setInterpolationTime() or interpolateAtTime(). */ This time is regularly updated when interpolationIsStarted(). Can be
float interpolationTime() const { return interpolationTime_; }; set directly with
/*! Returns the current interpolation speed. setInterpolationTime() or interpolateAtTime(). */
float interpolationTime() const { return interpolationTime_; }
Default value is 1.0, which means keyFrameTime() will be matched during /*! Returns the current interpolation speed.
the interpolation
(provided that your main loop is fast enough). Default value is 1.0, which means keyFrameTime() will be matched dur
ing the interpolation
A negative value will result in a reverse interpolation of the keyFrame (provided that your main loop is fast enough).
s. See also
interpolationPeriod(). */ A negative value will result in a reverse interpolation of the keyFr
float interpolationSpeed() const { return interpolationSpeed_; }; ames. See also
/*! Returns the current interpolation period, expressed in milliseconds interpolationPeriod(). */
. float interpolationSpeed() const { return interpolationSpeed_; }
/*! Returns the current interpolation period, expressed in milliseco
The update of the frame() state will be done by a timer at this period nds.
when
interpolationIsStarted(). The update of the frame() state will be done by a timer at this peri
od when
This period (multiplied by interpolationSpeed()) is added to the interp interpolationIsStarted().
olationTime() at each
update, and the frame() state is modified accordingly (see interpolateA This period (multiplied by interpolationSpeed()) is added to the int
tTime()). Default value erpolationTime() at each
is 40 milliseconds. */ update, and the frame() state is modified accordingly (see interpola
int interpolationPeriod() const { return period_; }; teAtTime()). Default value
/*! Returns \c true when the interpolation is played in an infinite loo is 40 milliseconds. */
p. int interpolationPeriod() const { return period_; }
/*! Returns \c true when the interpolation is played in an infinite
loop.
When \c false (default), the interpolation stops when interpolationTime When \c false (default), the interpolation stops when interpolationT
() reaches firstTime() ime() reaches firstTime()
(with negative interpolationSpeed()) or lastTime(). (with negative interpolationSpeed()) or lastTime().
interpolationTime() is otherwise reset to firstTime() (+ interpolationT interpolationTime() is otherwise reset to firstTime() (+ interpolati
ime() - lastTime()) (and onTime() - lastTime()) (and
inversely for negative interpolationSpeed()) and interpolation continue inversely for negative interpolationSpeed()) and interpolation conti
s. nues.
In both cases, the endReached() signal is emitted. */ In both cases, the endReached() signal is emitted. */
bool loopInterpolation() const { return loopInterpolation_; }; bool loopInterpolation() const { return loopInterpolation_; }
#ifndef DOXYGEN #ifndef DOXYGEN
/*! Whether or not (default) the path defined by the keyFrames is a clo /*! Whether or not (default) the path defined by the keyFrames is a
sed loop. When \c true, closed loop. When \c true,
the last and the first KeyFrame are linked by a new spline segment. the last and the first KeyFrame are linked by a new spline segment.
Use setLoopInterpolation() to create a continuous animation over the en Use setLoopInterpolation() to create a continuous animation over the
tire path. entire path.
\attention The closed path feature is not yet implemented. */ \attention The closed path feature is not yet implemented. */
bool closedPath() const { return closedPath_; }; bool closedPath() const { return closedPath_; }
#endif #endif
public Q_SLOTS: public Q_SLOTS:
/*! Sets the interpolationTime(). /*! Sets the interpolationTime().
\attention The frame() state is not affected by this method. Use this f \attention The frame() state is not affected by this method. Use thi
unction to define the s function to define the
starting time of a future interpolation (see startInterpolation()). Use starting time of a future interpolation (see startInterpolation()).
interpolateAtTime() to Use interpolateAtTime() to
actually interpolate at a given time. */ actually interpolate at a given time. */
void setInterpolationTime(float time) { interpolationTime_ = time; }; void setInterpolationTime(float time) { interpolationTime_ = time; }
/*! Sets the interpolationSpeed(). Negative or null values are allowed. /*! Sets the interpolationSpeed(). Negative or null values are allow
*/ ed. */
void setInterpolationSpeed(float speed) { interpolationSpeed_ = speed; void setInterpolationSpeed(float speed) { interpolationSpeed_ = spee
}; d; }
/*! Sets the interpolationPeriod(). */ /*! Sets the interpolationPeriod(). */
void setInterpolationPeriod(int period) { period_ = period; }; void setInterpolationPeriod(int period) { period_ = period; }
/*! Sets the loopInterpolation() value. */ /*! Sets the loopInterpolation() value. */
void setLoopInterpolation(bool loop=true) { loopInterpolation_ = loop; void setLoopInterpolation(bool loop=true) { loopInterpolation_ = loo
}; p; }
#ifndef DOXYGEN #ifndef DOXYGEN
/*! Sets the closedPath() value. \attention The closed path feature is /*! Sets the closedPath() value. \attention The closed path feature
not yet implemented. */ is not yet implemented. */
void setClosedPath(bool closed=true) { closedPath_ = closed; }; void setClosedPath(bool closed=true) { closedPath_ = closed; }
#endif #endif
//@} //@}
/*! @name Interpolation */ /*! @name Interpolation */
//@{ //@{
public: public:
/*! Returns \c true when the interpolation is being performed. Use star /*! Returns \c true when the interpolation is being performed. Use s
tInterpolation(), tartInterpolation(),
stopInterpolation() or toggleInterpolation() to modify this state. */ stopInterpolation() or toggleInterpolation() to modify this state. *
bool interpolationIsStarted() const { return interpolationStarted_; }; /
public Q_SLOTS: bool interpolationIsStarted() const { return interpolationStarted_;
void startInterpolation(int period = -1); }
void stopInterpolation(); public Q_SLOTS:
void resetInterpolation(); void startInterpolation(int period = -1);
/*! Calls startInterpolation() or stopInterpolation(), depending on int void stopInterpolation();
erpolationIsStarted(). */ void resetInterpolation();
void toggleInterpolation() { if (interpolationIsStarted()) stopInterpol /*! Calls startInterpolation() or stopInterpolation(), depending on
ation(); else startInterpolation(); }; interpolationIsStarted(). */
virtual void interpolateAtTime(float time); void toggleInterpolation() { if (interpolationIsStarted()) stopInter
//@} polation(); else startInterpolation(); }
virtual void interpolateAtTime(float time);
/*! @name Path drawing */ //@}
//@{
public: /*! @name Path drawing */
virtual void drawPath(int mask=1, int nbFrames=6, float scale=1.0f); //@{
//@} public:
virtual void drawPath(int mask=1, int nbFrames=6, float scale=1.0f);
/*! @name XML representation */ //@}
//@{
public: /*! @name XML representation */
virtual QDomElement domElement(const QString& name, QDomDocument& docum //@{
ent) const; public:
virtual void initFromDOMElement(const QDomElement& element); virtual QDomElement domElement(const QString& name, QDomDocument& do
//@} cument) const;
virtual void initFromDOMElement(const QDomElement& element);
private Q_SLOTS: //@}
virtual void update();
virtual void invalidateValues() { valuesAreValid_ = false; pathIsValid_ private Q_SLOTS:
= false; splineCacheIsValid_ = false; }; virtual void update();
virtual void invalidateValues() { valuesAreValid_ = false; pathIsVal
private: id_ = false; splineCacheIsValid_ = false; }
// Copy constructor and opertor= are declared private and undefined
// Prevents everyone from trying to use them private:
// KeyFrameInterpolator(const KeyFrameInterpolator& kfi); // Copy constructor and opertor= are declared private and undefined
// KeyFrameInterpolator& operator=(const KeyFrameInterpolator& kfi); // Prevents everyone from trying to use them
// KeyFrameInterpolator(const KeyFrameInterpolator& kfi);
void updateCurrentKeyFrameForTime(float time); // KeyFrameInterpolator& operator=(const KeyFrameInterpolator& kfi);
void updateModifiedFrameValues();
void updateSplineCache(); void updateCurrentKeyFrameForTime(float time);
void updateModifiedFrameValues();
void updateSplineCache();
#ifndef DOXYGEN #ifndef DOXYGEN
// Internal private KeyFrame representation // Internal private KeyFrame representation
class KeyFrame class KeyFrame
{ {
public: public:
KeyFrame(const Frame& fr, float t); KeyFrame(const Frame& fr, float t);
KeyFrame(const Frame* fr, float t); KeyFrame(const Frame* fr, float t);
Vec position() const { return p_; } Vec position() const { return p_; }
Quaternion orientation() const { return q_; } Quaternion orientation() const { return q_; }
Vec tgP() const { return tgP_; } Vec tgP() const { return tgP_; }
Quaternion tgQ() const { return tgQ_; } Quaternion tgQ() const { return tgQ_; }
float time() const { return time_; } float time() const { return time_; }
const Frame* frame() const { return frame_; } const Frame* frame() const { return frame_; }
void updateValuesFromPointer(); void updateValuesFromPointer();
void flipOrientationIfNeeded(const Quaternion& prev); void flipOrientationIfNeeded(const Quaternion& prev);
void computeTangent(const KeyFrame* const prev, const KeyFrame* const void computeTangent(const KeyFrame* const prev, const KeyFra
next); me* const next);
private: private:
Vec p_, tgP_; Vec p_, tgP_;
Quaternion q_, tgQ_; Quaternion q_, tgQ_;
float time_; float time_;
const Frame* const frame_; const Frame* const frame_;
}; };
#endif #endif
// K e y F r a m e s // K e y F r a m e s
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
mutable QList<KeyFrame*> keyFrame_; mutable QList<KeyFrame*> keyFrame_;
QMutableListIterator<KeyFrame*>* currentFrame_[4]; QMutableListIterator<KeyFrame*>* currentFrame_[4];
QList<Frame> path_; QList<Frame> path_;
#else #else
mutable QPtrList<KeyFrame> keyFrame_; mutable QPtrList<KeyFrame> keyFrame_;
// 4 succesive frames. interpolationTime_ is between index 1 and 2. // 4 succesive frames. interpolationTime_ is between index 1 and 2.
QPtrListIterator<KeyFrame>* currentFrame_[4]; QPtrListIterator<KeyFrame>* currentFrame_[4];
# if QT_VERSION >= 0x030000 # if QT_VERSION >= 0x030000
// Cached path computed values (for drawPath()). // Cached path computed values (for drawPath()).
QValueVector<Frame> path_; QValueVector<Frame> path_;
# else # else
QVector<Frame> path_; QVector<Frame> path_;
# endif # endif
#endif #endif
// A s s o c i a t e d f r a m e // A s s o c i a t e d f r a m e
Frame* frame_; Frame* frame_;
// R h y t h m // R h y t h m
QTimer timer_; QTimer timer_;
int period_; int period_;
float interpolationTime_; float interpolationTime_;
float interpolationSpeed_; float interpolationSpeed_;
bool interpolationStarted_; bool interpolationStarted_;
// M i s c // M i s c
bool closedPath_; bool closedPath_;
bool loopInterpolation_; bool loopInterpolation_;
// C a c h e d v a l u e s a n d f l a g s // C a c h e d v a l u e s a n d f l a g s
bool pathIsValid_; bool pathIsValid_;
bool valuesAreValid_; bool valuesAreValid_;
bool currentFrameValid_; bool currentFrameValid_;
bool splineCacheIsValid_; bool splineCacheIsValid_;
Vec v1, v2; Vec v1, v2;
}; };
} // namespace qglviewer } // namespace qglviewer
#endif // QGLVIEWER_KEY_FRAME_INTERPOLATOR_H #endif // QGLVIEWER_KEY_FRAME_INTERPOLATOR_H
 End of changes. 27 change blocks. 
277 lines changed or deleted 281 lines changed or added


 manipulatedCameraFrame.h   manipulatedCameraFrame.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 29 skipping to change at line 29
WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*************************************************************************** **/ *************************************************************************** **/
#ifndef QGLVIEWER_MANIPULATED_CAMERA_FRAME_H #ifndef QGLVIEWER_MANIPULATED_CAMERA_FRAME_H
#define QGLVIEWER_MANIPULATED_CAMERA_FRAME_H #define QGLVIEWER_MANIPULATED_CAMERA_FRAME_H
#include "manipulatedFrame.h" #include "manipulatedFrame.h"
namespace qglviewer { namespace qglviewer {
/*! \brief The ManipulatedCameraFrame class represents a ManipulatedFrame with Camera specific mouse bindings. /*! \brief The ManipulatedCameraFrame class represents a ManipulatedFrame w ith Camera specific mouse bindings.
\class ManipulatedCameraFrame manipulatedCameraFrame.h QGLViewer/manipula tedCameraFrame.h \class ManipulatedCameraFrame manipulatedCameraFrame.h QGLViewer/manipula tedCameraFrame.h
A ManipulatedCameraFrame is a specialization of a ManipulatedFrame, desig ned to be set as the A ManipulatedCameraFrame is a specialization of a ManipulatedFrame, desig ned to be set as the
Camera::frame(). Mouse motions are basically interpreted in a negated way : when the mouse goes to Camera::frame(). Mouse motions are basically interpreted in a negated way : when the mouse goes to
the right, the ManipulatedFrame translation goes to the right, while the ManipulatedCameraFrame the right, the ManipulatedFrame translation goes to the right, while the ManipulatedCameraFrame
has to go to the \e left, so that the \e scene seems to move to the right . has to go to the \e left, so that the \e scene seems to move to the right .
A ManipulatedCameraFrame rotates around its revolveAroundPoint(), which c orresponds to the A ManipulatedCameraFrame rotates around its revolveAroundPoint(), which c orresponds to the
associated Camera::revolveAroundPoint(). associated Camera::revolveAroundPoint().
A ManipulatedCameraFrame can also "fly" in the scene. It basically moves forward, and turns A ManipulatedCameraFrame can also "fly" in the scene. It basically moves forward, and turns
according to the mouse motion. See flySpeed(), flyUpVector() and the QGLV iewer::MOVE_FORWARD and according to the mouse motion. See flySpeed(), flyUpVector() and the QGLV iewer::MOVE_FORWARD and
QGLViewer::MOVE_BACKWARD QGLViewer::MouseAction. QGLViewer::MOVE_BACKWARD QGLViewer::MouseAction.
See the <a href="../mouse.html">mouse page</a> for a description of the p ossible actions that can See the <a href="../mouse.html">mouse page</a> for a description of the p ossible actions that can
be performed using the mouse and their bindings. be performed using the mouse and their bindings.
\nosubgrouping */ \nosubgrouping */
class QGLVIEWER_EXPORT ManipulatedCameraFrame : public ManipulatedFrame class QGLVIEWER_EXPORT ManipulatedCameraFrame : public ManipulatedFrame
{ {
#ifndef DOXYGEN #ifndef DOXYGEN
friend class Camera; friend class Camera;
friend class ::QGLViewer; friend class ::QGLViewer;
#endif #endif
Q_OBJECT Q_OBJECT
public: public:
ManipulatedCameraFrame(); ManipulatedCameraFrame();
/*! Virtual destructor. Empty. */ /*! Virtual destructor. Empty. */
virtual ~ManipulatedCameraFrame() {}; virtual ~ManipulatedCameraFrame() {}
ManipulatedCameraFrame(const ManipulatedCameraFrame& mcf); ManipulatedCameraFrame(const ManipulatedCameraFrame& mcf);
ManipulatedCameraFrame& operator=(const ManipulatedCameraFrame& mcf); ManipulatedCameraFrame& operator=(const ManipulatedCameraFrame& mcf)
;
/*! @name Revolve around point */
//@{ /*! @name Revolve around point */
public: //@{
/*! Returns the point the ManipulatedCameraFrame revolves around when r public:
otated. /*! Returns the point the ManipulatedCameraFrame revolves around whe
n rotated.
It is defined in the world coordinate system. Default value is (0,0,0).
It is defined in the world coordinate system. Default value is (0,0,
When the ManipulatedCameraFrame is associated to a Camera, Camera::revo 0).
lveAroundPoint() also
returns this value. This point can interactively be changed using the m When the ManipulatedCameraFrame is associated to a Camera, Camera::r
ouse (see evolveAroundPoint() also
QGLViewer::RAP_FROM_PIXEL and QGLViewer::RAP_IS_CENTER in the <a href=" returns this value. This point can interactively be changed using th
../mouse.html">mouse e mouse (see
page</a>). */ QGLViewer::RAP_FROM_PIXEL and QGLViewer::RAP_IS_CENTER in the <a hre
Vec revolveAroundPoint() const { return revolveAroundPoint_; } f="../mouse.html">mouse
/*! Sets the revolveAroundPoint(), defined in the world coordinate syst page</a>). */
em. */ Vec revolveAroundPoint() const { return revolveAroundPoint_; }
void setRevolveAroundPoint(const Vec& revolveAroundPoint) { revolveArou /*! Sets the revolveAroundPoint(), defined in the world coordinate s
ndPoint_ = revolveAroundPoint; } ystem. */
//@} void setRevolveAroundPoint(const Vec& revolveAroundPoint) { revolveA
roundPoint_ = revolveAroundPoint; }
/*! @name Fly parameters */ //@}
//@{
public Q_SLOTS: /*! @name Fly parameters */
/*! Sets the flySpeed(), defined in OpenGL units. //@{
public Q_SLOTS:
Default value is 0.0, but it is modified according to the QGLViewer::sc /*! Sets the flySpeed(), defined in OpenGL units.
eneRadius() when the
ManipulatedCameraFrame is set as the Camera::frame(). */ Default value is 0.0, but it is modified according to the QGLViewer:
void setFlySpeed(float speed) { flySpeed_ = speed; }; :sceneRadius() when the
ManipulatedCameraFrame is set as the Camera::frame(). */
/*! Sets the flyUpVector(), defined in the world coordinate system. void setFlySpeed(float speed) { flySpeed_ = speed; }
Default value is (0,1,0), but it is updated by the Camera when set as i /*! Sets the flyUpVector(), defined in the world coordinate system.
ts Camera::frame(). Use
Camera::setUpVector() instead in that case. */ Default value is (0,1,0), but it is updated by the Camera when set a
void setFlyUpVector(const Vec& up) { flyUpVector_ = up; }; s its Camera::frame(). Use
Camera::setUpVector() instead in that case. */
public: void setFlyUpVector(const Vec& up) { flyUpVector_ = up; }
/*! Returns the fly speed, expressed in OpenGL units.
public:
It corresponds to the incremental displacement that is periodically app /*! Returns the fly speed, expressed in OpenGL units.
lied to the
ManipulatedCameraFrame position when a QGLViewer::MOVE_FORWARD or QGLVi It corresponds to the incremental displacement that is periodically
ewer::MOVE_BACKWARD applied to the
QGLViewer::MouseAction is proceeded. ManipulatedCameraFrame position when a QGLViewer::MOVE_FORWARD or QG
LViewer::MOVE_BACKWARD
\attention When the ManipulatedCameraFrame is set as the Camera::frame( QGLViewer::MouseAction is proceeded.
), this value is set
according to the QGLViewer::sceneRadius() by QGLViewer::setSceneRadius( \attention When the ManipulatedCameraFrame is set as the Camera::fra
). */ me(), this value is set
float flySpeed() const { return flySpeed_; }; according to the QGLViewer::sceneRadius() by QGLViewer::setSceneRadi
us(). */
/*! Returns the up vector used in fly mode, expressed in the world coor float flySpeed() const { return flySpeed_; }
dinate system.
/*! Returns the up vector used in fly mode, expressed in the world c
Fly mode corresponds to the QGLViewer::MOVE_FORWARD and QGLViewer::MOVE oordinate system.
_BACKWARD
QGLViewer::MouseAction bindings. In these modes, horizontal displacemen Fly mode corresponds to the QGLViewer::MOVE_FORWARD and QGLViewer::M
ts of the mouse rotate OVE_BACKWARD
the ManipulatedCameraFrame around this vector. Vertical displacements r QGLViewer::MouseAction bindings. In these modes, horizontal displace
otate always around the ments of the mouse rotate
Camera \c X axis. the ManipulatedCameraFrame around this vector. Vertical displacement
s rotate always around the
Default value is (0,1,0), but it is updated by the Camera when set as i Camera \c X axis.
ts Camera::frame().
Camera::setOrientation() and Camera::setUpVector()) modify this value a Default value is (0,1,0), but it is updated by the Camera when set a
nd should be used s its Camera::frame().
instead. */ Camera::setOrientation() and Camera::setUpVector()) modify this valu
Vec flyUpVector() const { return flyUpVector_; }; e and should be used
//@} instead. */
Vec flyUpVector() const { return flyUpVector_; }
/*! @name Mouse event handlers */ //@}
//@{
protected: /*! @name Mouse event handlers */
virtual void mouseReleaseEvent(QMouseEvent* const event, Camera* const //@{
camera); protected:
virtual void mouseMoveEvent (QMouseEvent* const event, Camera* const virtual void mouseReleaseEvent(QMouseEvent* const event, Camera* con
camera); st camera);
virtual void wheelEvent (QWheelEvent* const event, Camera* const virtual void mouseMoveEvent (QMouseEvent* const event, Camera* con
camera); st camera);
//@} virtual void wheelEvent (QWheelEvent* const event, Camera* con
st camera);
/*! @name Spinning */ //@}
//@{
protected Q_SLOTS: /*! @name Spinning */
virtual void spin(); //@{
//@} protected Q_SLOTS:
virtual void spin();
/*! @name XML representation */ //@}
//@{
public: /*! @name XML representation */
virtual QDomElement domElement(const QString& name, QDomDocument& docum //@{
ent) const; public:
public Q_SLOTS: virtual QDomElement domElement(const QString& name, QDomDocument& do
virtual void initFromDOMElement(const QDomElement& element); cument) const;
//@} public Q_SLOTS:
virtual void initFromDOMElement(const QDomElement& element);
//@}
#ifndef DOXYGEN #ifndef DOXYGEN
protected: protected:
virtual void startAction(int ma, bool withConstraint=true); // int is r virtual void startAction(int ma, bool withConstraint=true); // int i
eally a QGLViewer::MouseAction s really a QGLViewer::MouseAction
#endif #endif
private Q_SLOTS: private Q_SLOTS:
virtual void flyUpdate(); virtual void flyUpdate();
private: private:
void updateFlyUpVector(); void updateFlyUpVector();
Quaternion turnQuaternion(int x, const Camera* const camera); Quaternion turnQuaternion(int x, const Camera* const camera);
Quaternion pitchYawQuaternion(int x, int y, const Camera* const camera) Quaternion pitchYawQuaternion(int x, int y, const Camera* const came
; ra);
private: private:
// Fly mode data // Fly mode data
float flySpeed_; float flySpeed_;
float driveSpeed_; float driveSpeed_;
Vec flyUpVector_; Vec flyUpVector_;
QTimer flyTimer_; QTimer flyTimer_;
Vec revolveAroundPoint_; Vec revolveAroundPoint_;
}; };
} // namespace qglviewer } // namespace qglviewer
#endif // QGLVIEWER_MANIPULATED_CAMERA_FRAME_H #endif // QGLVIEWER_MANIPULATED_CAMERA_FRAME_H
 End of changes. 10 change blocks. 
132 lines changed or deleted 134 lines changed or added


 manipulatedFrame.h   manipulatedFrame.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 40 skipping to change at line 40
# include <QString> # include <QString>
# include <QTimer> # include <QTimer>
# include <QDateTime> # include <QDateTime>
#else #else
# include <qstring.h> # include <qstring.h>
# include <qtimer.h> # include <qtimer.h>
# include <qdatetime.h> # include <qdatetime.h>
#endif #endif
namespace qglviewer { namespace qglviewer {
/*! \brief A ManipulatedFrame is a Frame that can be rotated and translat ed using the mouse. /*! \brief A ManipulatedFrame is a Frame that can be rotated and translated using the mouse.
\class ManipulatedFrame manipulatedFrame.h QGLViewer/manipulatedFrame.h \class ManipulatedFrame manipulatedFrame.h QGLViewer/manipulatedFrame.h
It converts the mouse motion into a translation and an orientation update s. A ManipulatedFrame is It converts the mouse motion into a translation and an orientation update s. A ManipulatedFrame is
used to move an object in the scene. Combined with object selection, its MouseGrabber properties used to move an object in the scene. Combined with object selection, its MouseGrabber properties
and a dynamic update of the scene, the ManipulatedFrame introduces a grea t reactivity in your and a dynamic update of the scene, the ManipulatedFrame introduces a grea t reactivity in your
applications. applications.
A ManipulatedFrame is attached to a QGLViewer using QGLViewer::setManipul atedFrame(): A ManipulatedFrame is attached to a QGLViewer using QGLViewer::setManipul atedFrame():
\code \code
init() { setManipulatedFrame( new ManipulatedFrame() ); } init() { setManipulatedFrame( new ManipulatedFrame() ); }
draw() draw()
{ {
glPushMatrix(); glPushMatrix();
glMultMatrixd(manipulatedFrame()->matrix()); glMultMatrixd(manipulatedFrame()->matrix());
// draw the manipulated object here // draw the manipulated object here
glPopMatrix(); glPopMatrix();
} }
\endcode \endcode
See the <a href="../examples/manipulatedFrame.html">manipulatedFrame exam ple</a> for a complete See the <a href="../examples/manipulatedFrame.html">manipulatedFrame exam ple</a> for a complete
application. application.
Mouse events are normally sent to the QGLViewer::camera(). You have to pr ess the QGLViewer::FRAME Mouse events are normally sent to the QGLViewer::camera(). You have to pr ess the QGLViewer::FRAME
state key (default is \c Control) to move the QGLViewer::manipulatedFrame () instead. See the <a state key (default is \c Control) to move the QGLViewer::manipulatedFrame () instead. See the <a
href="../mouse.html">mouse page</a> for a description of mouse button bin dings. href="../mouse.html">mouse page</a> for a description of mouse button bin dings.
<h3>Inherited functionalities</h3> <h3>Inherited functionalities</h3>
skipping to change at line 94 skipping to change at line 94
in the scene, you simply have to keep a list of the different Manipulated Frames, and to activate in the scene, you simply have to keep a list of the different Manipulated Frames, and to activate
the right one (using QGLViewer::setManipulatedFrame()) when needed. This can for instance be done the right one (using QGLViewer::setManipulatedFrame()) when needed. This can for instance be done
according to an object selection: see the <a href="../examples/luxo.html" >luxo example</a> for an according to an object selection: see the <a href="../examples/luxo.html" >luxo example</a> for an
illustration. illustration.
When the ManipulatedFrame is being manipulated using the mouse (mouse pre ssed and not yet When the ManipulatedFrame is being manipulated using the mouse (mouse pre ssed and not yet
released), isManipulated() returns \c true. This might be used to trigger a specific action or released), isManipulated() returns \c true. This might be used to trigger a specific action or
display (as is done with QGLViewer::fastDraw()). display (as is done with QGLViewer::fastDraw()).
The ManipulatedFrame also emits a manipulated() signal each time its stat e is modified by the The ManipulatedFrame also emits a manipulated() signal each time its stat e is modified by the
mouse. This signal is automatically connected to the QGLViewer::updateGL( ) slot when the mouse. This signal is automatically connected to the QGLViewer::update() slot when the
ManipulatedFrame is attached to a viewer using QGLViewer::setManipulatedF rame(). ManipulatedFrame is attached to a viewer using QGLViewer::setManipulatedF rame().
You can make the ManipulatedFrame spin() if you release the rotation mous e button while moving the You can make the ManipulatedFrame spin() if you release the rotation mous e button while moving the
mouse fast enough (see spinningSensitivity()). See also translationSensit ivity() and mouse fast enough (see spinningSensitivity()). See also translationSensit ivity() and
rotationSensitivity() for sensitivity tuning. \nosubgrouping */ rotationSensitivity() for sensitivity tuning. \nosubgrouping */
class QGLVIEWER_EXPORT ManipulatedFrame : public Frame, public MouseGrabb class QGLVIEWER_EXPORT ManipulatedFrame : public Frame, public MouseGrabber
er {
{
#ifndef DOXYGEN #ifndef DOXYGEN
friend class Camera; friend class Camera;
friend class ::QGLViewer; friend class ::QGLViewer;
#endif #endif
Q_OBJECT Q_OBJECT
public: public:
ManipulatedFrame(); ManipulatedFrame();
/*! Virtual destructor. Empty. */ /*! Virtual destructor. Empty. */
virtual ~ManipulatedFrame() {}; virtual ~ManipulatedFrame() {}
ManipulatedFrame(const ManipulatedFrame& mf); ManipulatedFrame(const ManipulatedFrame& mf);
ManipulatedFrame& operator=(const ManipulatedFrame& mf); ManipulatedFrame& operator=(const ManipulatedFrame& mf);
Q_SIGNALS: Q_SIGNALS:
/*! This signal is emitted when ever the ManipulatedFrame is manipulate /*! This signal is emitted when ever the ManipulatedFrame is manipul
d (i.e. rotated or ated (i.e. rotated or
translated) using the mouse. Connect this signal to any object that sho translated) using the mouse. Connect this signal to any object that
uld be notified. should be notified.
Note that this signal is automatically connected to the QGLViewer::upda Note that this signal is automatically connected to the QGLViewer::u
teGL() slot, when the pdate() slot, when the
ManipulatedFrame is attached to a viewer using QGLViewer::setManipulate ManipulatedFrame is attached to a viewer using QGLViewer::setManipul
dFrame(), which is atedFrame(), which is
probably all you need. probably all you need.
Use the QGLViewer::QGLViewerPool() if you need to connect this signal t Use the QGLViewer::QGLViewerPool() if you need to connect this signa
o all the viewers. l to all the viewers.
See also the spun(), modified(), interpolated() and KeyFrameInterpolato See also the spun(), modified(), interpolated() and KeyFrameInterpol
r::interpolated() ator::interpolated()
signals' documentations. */ signals' documentations. */
void manipulated(); void manipulated();
/*! This signal is emitted when the ManipulatedFrame isSpinning(). /*! This signal is emitted when the ManipulatedFrame isSpinning().
Note that for the QGLViewer::manipulatedFrame(), this signal is automat Note that for the QGLViewer::manipulatedFrame(), this signal is auto
ically connected to the matically connected to the
QGLViewer::updateGL() slot. QGLViewer::update() slot.
Connect this signal to any object that should be notified. Use the QGLV Connect this signal to any object that should be notified. Use the Q
iewer::QGLViewerPool() if GLViewer::QGLViewerPool() if
you need to connect this signal to all the viewers. you need to connect this signal to all the viewers.
See also the manipulated(), modified(), interpolated() and KeyFrameInte See also the manipulated(), modified(), interpolated() and KeyFrameI
rpolator::interpolated() nterpolator::interpolated()
signals' documentations. */ signals' documentations. */
void spun(); void spun();
/*! @name Manipulation sensitivity */ /*! @name Manipulation sensitivity */
//@{ //@{
public Q_SLOTS: public Q_SLOTS:
/*! Defines the rotationSensitivity(). */ /*! Defines the rotationSensitivity(). */
void setRotationSensitivity(float sensitivity) { rotSensitivity_ = sens void setRotationSensitivity(float sensitivity) { rotSensitivity_ = s
itivity; }; ensitivity; }
/*! Defines the translationSensitivity(). */ /*! Defines the translationSensitivity(). */
void setTranslationSensitivity(float sensitivity) { transSensitivity_ = void setTranslationSensitivity(float sensitivity) { transSensitivity
sensitivity; }; _ = sensitivity; }
/*! Defines the spinningSensitivity(), in pixels per milliseconds. */ /*! Defines the spinningSensitivity(), in pixels per milliseconds. *
void setSpinningSensitivity(float sensitivity) { spinningSensitivity_ = /
sensitivity; }; void setSpinningSensitivity(float sensitivity) { spinningSensitivity
/*! Defines the wheelSensitivity(). */ _ = sensitivity; }
void setWheelSensitivity(float sensitivity) { wheelSensitivity_ = sensi /*! Defines the wheelSensitivity(). */
tivity; }; void setWheelSensitivity(float sensitivity) { wheelSensitivity_ = se
public: nsitivity; }
/*! Returns the influence of a mouse displacement on the ManipulatedFra public:
me rotation. /*! Returns the influence of a mouse displacement on the Manipulated
Frame rotation.
Default value is 1.0. With an identical mouse displacement, a higher va
lue will generate a Default value is 1.0. With an identical mouse displacement, a higher
larger rotation (and inversely for lower values). A 0.0 value will forb value will generate a
id ManipulatedFrame mouse larger rotation (and inversely for lower values). A 0.0 value will f
rotation (see also constraint()). orbid ManipulatedFrame mouse
rotation (see also constraint()).
See also setRotationSensitivity(), translationSensitivity(), spinningSe
nsitivity() and See also setRotationSensitivity(), translationSensitivity(), spinnin
wheelSensitivity(). */ gSensitivity() and
float rotationSensitivity() const { return rotSensitivity_; }; wheelSensitivity(). */
/*! Returns the influence of a mouse displacement on the ManipulatedFra float rotationSensitivity() const { return rotSensitivity_; }
me translation. /*! Returns the influence of a mouse displacement on the Manipulated
Frame translation.
Default value is 1.0. You should not have to modify this value, since w
ith 1.0 the Default value is 1.0. You should not have to modify this value, sinc
ManipulatedFrame precisely stays under the mouse cursor. e with 1.0 the
ManipulatedFrame precisely stays under the mouse cursor.
With an identical mouse displacement, a higher value will generate a la
rger translation (and With an identical mouse displacement, a higher value will generate a
inversely for lower values). A 0.0 value will forbid ManipulatedFrame m larger translation (and
ouse translation (see inversely for lower values). A 0.0 value will forbid ManipulatedFram
also constraint()). e mouse translation (see
also constraint()).
\note When the ManipulatedFrame is used to move a \e Camera (see the Ma
nipulatedCameraFrame \note When the ManipulatedFrame is used to move a \e Camera (see the
class documentation), after zooming on a small region of your scene, th ManipulatedCameraFrame
e camera may translate class documentation), after zooming on a small region of your scene,
too fast. For a camera, it is the Camera::revolveAroundPoint() that exa the camera may translate
ctly matches the mouse too fast. For a camera, it is the Camera::revolveAroundPoint() that
displacement. Hence, instead of changing the translationSensitivity(), exactly matches the mouse
solve the problem by displacement. Hence, instead of changing the translationSensitivity(
(temporarily) setting the Camera::revolveAroundPoint() to a point on th ), solve the problem by
e zoomed region (see the (temporarily) setting the Camera::revolveAroundPoint() to a point on
QGLViewer::RAP_FROM_PIXEL mouse binding in the <a href="../mouse.html"> the zoomed region (see the
mouse page</a>). QGLViewer::RAP_FROM_PIXEL mouse binding in the <a href="../mouse.htm
l">mouse page</a>).
See also setTranslationSensitivity(), rotationSensitivity(), spinningSe
nsitivity() and See also setTranslationSensitivity(), rotationSensitivity(), spinnin
wheelSensitivity(). */ gSensitivity() and
float translationSensitivity() const { return transSensitivity_; }; wheelSensitivity(). */
/*! Returns the minimum mouse speed required (at button release) to mak float translationSensitivity() const { return transSensitivity_; }
e the ManipulatedFrame /*! Returns the minimum mouse speed required (at button release) to
spin(). make the ManipulatedFrame
spin().
See spin(), spinningQuaternion() and startSpinning() for details.
See spin(), spinningQuaternion() and startSpinning() for details.
Mouse speed is expressed in pixels per milliseconds. Default value is 0
.3 (300 pixels per Mouse speed is expressed in pixels per milliseconds. Default value i
second). Use setSpinningSensitivity() to tune this value. A higher valu s 0.3 (300 pixels per
e will make spinning more second). Use setSpinningSensitivity() to tune this value. A higher v
difficult (a value of 100.0 forbids spinning in practice). alue will make spinning more
difficult (a value of 100.0 forbids spinning in practice).
See also setSpinningSensitivity(), translationSensitivity(), rotationSe
nsitivity() and See also setSpinningSensitivity(), translationSensitivity(), rotatio
wheelSensitivity(). */ nSensitivity() and
float spinningSensitivity() const { return spinningSensitivity_; }; wheelSensitivity(). */
/*! Returns the mouse wheel sensitivity. float spinningSensitivity() const { return spinningSensitivity_; }
/*! Returns the mouse wheel sensitivity.
Default value is 1.0. A higher value will make the wheel action more ef
ficient (usually meaning Default value is 1.0. A higher value will make the wheel action more
a faster zoom). Use a negative value to invert the zoom in and out dire efficient (usually meaning
ctions. a faster zoom). Use a negative value to invert the zoom in and out d
irections.
See also setWheelSensitivity(), translationSensitivity(), rotationSensi
tivity() and See also setWheelSensitivity(), translationSensitivity(), rotationSe
spinningSensitivity(). */ nsitivity() and
float wheelSensitivity() const { return wheelSensitivity_; }; spinningSensitivity(). */
//@} float wheelSensitivity() const { return wheelSensitivity_; }
//@}
/*! @name Spinning */
//@{ /*! @name Spinning */
public: //@{
/*! Returns \c true when the ManipulatedFrame is spinning. public:
/*! Returns \c true when the ManipulatedFrame is spinning.
During spinning, spin() rotates the ManipulatedFrame by its spinningQua
ternion() at a frequency During spinning, spin() rotates the ManipulatedFrame by its spinning
defined when the ManipulatedFrame startSpinning(). Quaternion() at a frequency
defined when the ManipulatedFrame startSpinning().
Use startSpinning() and stopSpinning() to change this state. Default va
lue is \c false. */ Use startSpinning() and stopSpinning() to change this state. Default
bool isSpinning() const { return isSpinning_; }; value is \c false. */
/*! Returns the incremental rotation that is applied by spin() to the M bool isSpinning() const { return isSpinning_; }
anipulatedFrame /*! Returns the incremental rotation that is applied by spin() to th
orientation when it isSpinning(). e ManipulatedFrame
orientation when it isSpinning().
Default value is a null rotation (identity Quaternion). Use setSpinnin
gQuaternion() to change Default value is a null rotation (identity Quaternion). Use setSpin
this value. ningQuaternion() to change
this value.
The spinningQuaternion() axis is defined in the ManipulatedFrame coord
inate system. You can use The spinningQuaternion() axis is defined in the ManipulatedFrame co
Frame::transformOfFrom() to convert this axis from an other Frame coor ordinate system. You can use
dinate system. */ Frame::transformOfFrom() to convert this axis from an other Frame c
Quaternion spinningQuaternion() const { return spinningQuaternion_; } oordinate system. */
public Q_SLOTS: Quaternion spinningQuaternion() const { return spinningQuaternion_;
/*! Defines the spinningQuaternion(). Its axis is defined in the Manipula }
tedFrame coordinate public Q_SLOTS:
system. */ /*! Defines the spinningQuaternion(). Its axis is defined in the Man
void setSpinningQuaternion(const Quaternion& spinningQuaternion) { spin ipulatedFrame coordinate
ningQuaternion_ = spinningQuaternion; } system. */
virtual void startSpinning(int updateInterval); void setSpinningQuaternion(const Quaternion& spinningQuaternion) { s
/*! Stops the spinning motion started using startSpinning(). isSpinning pinningQuaternion_ = spinningQuaternion; }
() will return \c false virtual void startSpinning(int updateInterval);
after this call. */ /*! Stops the spinning motion started using startSpinning(). isSpinn
virtual void stopSpinning() { spinningTimer_.stop(); isSpinning_ = fals ing() will return \c false
e; }; after this call. */
protected Q_SLOTS: virtual void stopSpinning() { spinningTimer_.stop(); isSpinning_ = f
virtual void spin(); alse; }
private Q_SLOTS: protected Q_SLOTS:
void spinUpdate(); virtual void spin();
//@} private Q_SLOTS:
void spinUpdate();
/*! @name Mouse event handlers */ //@}
//@{
protected: /*! @name Mouse event handlers */
virtual void mousePressEvent (QMouseEvent* const event, Camera* co //@{
nst camera); protected:
virtual void mouseMoveEvent (QMouseEvent* const event, Camera* co virtual void mousePressEvent (QMouseEvent* const event, Camera*
nst camera); const camera);
virtual void mouseReleaseEvent (QMouseEvent* const event, Camera* co virtual void mouseMoveEvent (QMouseEvent* const event, Camera*
nst camera); const camera);
virtual void mouseDoubleClickEvent(QMouseEvent* const event, Camera* co virtual void mouseReleaseEvent (QMouseEvent* const event, Camera*
nst camera); const camera);
virtual void wheelEvent (QWheelEvent* const event, Camera* co virtual void mouseDoubleClickEvent(QMouseEvent* const event, Camera*
nst camera); const camera);
//@} virtual void wheelEvent (QWheelEvent* const event, Camera*
const camera);
public: //@}
/*! @name Current state */
//@{ public:
bool isManipulated() const; /*! @name Current state */
//@} //@{
bool isManipulated() const;
/*! @name MouseGrabber implementation */ //@}
//@{
public: /*! @name MouseGrabber implementation */
virtual void checkIfGrabsMouse(int x, int y, const Camera* const camera //@{
); public:
//@} virtual void checkIfGrabsMouse(int x, int y, const Camera* const cam
era);
/*! @name XML representation */ //@}
//@{
public: /*! @name XML representation */
virtual QDomElement domElement(const QString& name, QDomDocument& docum //@{
ent) const; public:
public Q_SLOTS: virtual QDomElement domElement(const QString& name, QDomDocument& do
virtual void initFromDOMElement(const QDomElement& element); cument) const;
//@} public Q_SLOTS:
virtual void initFromDOMElement(const QDomElement& element);
//@}
#ifndef DOXYGEN #ifndef DOXYGEN
protected: protected:
Quaternion deformedBallQuaternion(int x, int y, float cx, float cy, con Quaternion deformedBallQuaternion(int x, int y, float cx, float cy,
st Camera* const camera); const Camera* const camera);
int action_; // Should be a QGLViewer::MouseAction, but include loop int action_; // Should be a QGLViewer::MouseAction, but include loop
Constraint* previousConstraint_; // When manipulation is without Contra Constraint* previousConstraint_; // When manipulation is without Con
int. traint.
virtual void startAction(int ma, bool withConstraint=true); // int is r virtual void startAction(int ma, bool withConstraint=true); // int i
eally a QGLViewer::MouseAction s really a QGLViewer::MouseAction
void computeMouseSpeed(const QMouseEvent* const e); void computeMouseSpeed(const QMouseEvent* const e);
int mouseOriginalDirection(const QMouseEvent* const e); int mouseOriginalDirection(const QMouseEvent* const e);
// Previous mouse position (used for incremental updates) and mouse pre // Previous mouse position (used for incremental updates) and mouse
ss position. press position.
QPoint prevPos_, pressPos_; QPoint prevPos_, pressPos_;
#endif // DOXYGEN #endif // DOXYGEN
private: private:
// Sensitivity // Sensitivity
float rotSensitivity_; float rotSensitivity_;
float transSensitivity_; float transSensitivity_;
float spinningSensitivity_; float spinningSensitivity_;
float wheelSensitivity_; float wheelSensitivity_;
// Mouse speed and spinning // Mouse speed and spinning
QTime last_move_time; QTime last_move_time;
float mouseSpeed_; float mouseSpeed_;
int delay_; int delay_;
bool isSpinning_; bool isSpinning_;
QTimer spinningTimer_; QTimer spinningTimer_;
Quaternion spinningQuaternion_; Quaternion spinningQuaternion_;
// Whether the SCREEN_TRANS direction (horizontal or vertical) is fixed // Whether the SCREEN_TRANS direction (horizontal or vertical) is fi
or not. xed or not.
bool dirIsFixed_; bool dirIsFixed_;
// MouseGrabber // MouseGrabber
bool keepsGrabbingMouse_; bool keepsGrabbingMouse_;
}; };
} // namespace qglviewer } // namespace qglviewer
#endif // QGLVIEWER_MANIPULATED_FRAME_H #endif // QGLVIEWER_MANIPULATED_FRAME_H
 End of changes. 13 change blocks. 
258 lines changed or deleted 259 lines changed or added


 mouseGrabber.h   mouseGrabber.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 37 skipping to change at line 37
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
# include <QEvent> # include <QEvent>
#else #else
# include <qevent.h> # include <qevent.h>
#endif #endif
class QGLViewer; class QGLViewer;
namespace qglviewer { namespace qglviewer {
class Camera; class Camera;
/*! \brief Abstract class for objects that grab mouse focus in a QGLViewe r. /*! \brief Abstract class for objects that grab mouse focus in a QGLViewer.
\class MouseGrabber mouseGrabber.h QGLViewer/mouseGrabber.h \class MouseGrabber mouseGrabber.h QGLViewer/mouseGrabber.h
MouseGrabber are objects which react to the mouse cursor, usually when it hovers over them. This MouseGrabber are objects which react to the mouse cursor, usually when it hovers over them. This
abstract class only provides an interface for all these objects: their ac tual behavior has to be abstract class only provides an interface for all these objects: their ac tual behavior has to be
defined in a derived class. defined in a derived class.
<h3>How does it work ?</h3> <h3>How does it work ?</h3>
All the created MouseGrabber are grouped in a MouseGrabberPool(). The QGL Viewers parse this pool, All the created MouseGrabber are grouped in a MouseGrabberPool(). The QGL Viewers parse this pool,
calling all the MouseGrabbers' checkIfGrabsMouse() methods that setGrabsM ouse() if desired. calling all the MouseGrabbers' checkIfGrabsMouse() methods that setGrabsM ouse() if desired.
skipping to change at line 91 skipping to change at line 91
MouseGrabberPool() (note however that ManipulatedCameraFrame are not inse rted). MouseGrabberPool() (note however that ManipulatedCameraFrame are not inse rted).
<h3>Example</h3> <h3>Example</h3>
Here is for instance a draft version of a MovableObject class. Instances of these class can freely Here is for instance a draft version of a MovableObject class. Instances of these class can freely
be moved on screen using the mouse, as movable post-it-like notes: be moved on screen using the mouse, as movable post-it-like notes:
\code \code
class MovableObject : public MouseGrabber class MovableObject : public MouseGrabber
{ {
public: public:
MovableObject() : pos(0,0), moved(false) {}; MovableObject() : pos(0,0), moved(false) {}
void checkIfGrabsMouse(int x, int y, const qglviewer::Camera* const) void checkIfGrabsMouse(int x, int y, const qglviewer::Camera* const)
{ {
// MovableObject is active in a region of 5 pixels around its pos. // MovableObject is active in a region of 5 pixels around its pos.
// May depend on the actual shape of the object. Customize as desired // May depend on the actual shape of the object. Customize as desi
. red.
// Once clicked (moved = true), it keeps grabbing mouse until button // Once clicked (moved = true), it keeps grabbing mouse until butt
is released. on is released.
setGrabsMouse( moved || ((pos-QPoint(x,y)).manhattanLength() < 5) ); setGrabsMouse( moved || ((pos-QPoint(x,y)).manhattanLength() < 5)
} );
}
void mousePressEvent( QMouseEvent* const e, Camera* const) { prevPos =
e->pos(); moved = true; } void mousePressEvent( QMouseEvent* const e, Camera* const) { prevPos
= e->pos(); moved = true; }
void mouseMoveEvent(QMouseEvent* const e, const Camera* const)
{ void mouseMoveEvent(QMouseEvent* const e, const Camera* const)
if (moved) {
{ if (moved)
// Add position delta to current pos {
pos += e->pos() - prevPos; // Add position delta to current pos
prevPos = e->pos(); pos += e->pos() - prevPos;
} prevPos = e->pos();
} }
}
void mouseReleaseEvent(QMouseEvent* const, Camera* const) { moved = fal
se; } void mouseReleaseEvent(QMouseEvent* const, Camera* const) { moved =
false; }
void draw()
{ void draw()
// The object is drawn centered on its pos, with different possible a {
spects: // The object is drawn centered on its pos, with different possibl
if (grabsMouse()) e aspects:
if (moved) if (grabsMouse())
if (moved)
// Object being moved, maybe a transparent display // Object being moved, maybe a transparent display
else else
// Object ready to be moved, maybe a highlighted visual feedback // Object ready to be moved, maybe a highlighted visual feedback
else else
// Normal display // Normal display
} }
private: private:
QPoint pos, prevPos; QPoint pos, prevPos;
bool moved; bool moved;
}; };
\endcode \endcode
Note that the different event callback methods are called only once the M ouseGrabber grabsMouse(). Note that the different event callback methods are called only once the M ouseGrabber grabsMouse().
\nosubgrouping */ \nosubgrouping */
class QGLVIEWER_EXPORT MouseGrabber class QGLVIEWER_EXPORT MouseGrabber
{ {
#ifndef DOXYGEN #ifndef DOXYGEN
friend class ::QGLViewer; friend class ::QGLViewer;
#endif #endif
public: public:
MouseGrabber(); MouseGrabber();
/*! Virtual destructor. Removes the MouseGrabber from the MouseGrabberP /*! Virtual destructor. Removes the MouseGrabber from the MouseGrabb
ool(). */ erPool(). */
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
virtual ~MouseGrabber() { MouseGrabber::MouseGrabberPool_.removeAll(thi s); }; virtual ~MouseGrabber() { MouseGrabber::MouseGrabberPool_.removeAll( this); }
#else #else
virtual ~MouseGrabber() { MouseGrabber::MouseGrabberPool_.removeRef(thi s); }; virtual ~MouseGrabber() { MouseGrabber::MouseGrabberPool_.removeRef( this); }
#endif #endif
/*! @name Mouse grabbing detection */ /*! @name Mouse grabbing detection */
//@{ //@{
public: public:
/*! Pure virtual method, called by the QGLViewers before they test if t /*! Pure virtual method, called by the QGLViewers before they test i
he MouseGrabber f the MouseGrabber
grabsMouse(). Should setGrabsMouse() according to the mouse position. grabsMouse(). Should setGrabsMouse() according to the mouse positi
on.
This is the core method of the MouseGrabber. It has to be overloaded
in your derived class.
Its goal is to update the grabsMouse() flag according to the mouse a
nd MouseGrabber current
positions, using setGrabsMouse().
grabsMouse() is usually set to \c true when the mouse cursor is clos
e enough to the MouseGrabber
position. It should also be set to \c false when the mouse cursor le
aves this region in order to
release the mouse focus.
\p x and \p y are the mouse cursor coordinates (Qt coordinate system
: (0,0) corresponds to the upper
left corner).
A typical implementation will look like:
\code
// (posX,posY) is the position of the MouseGrabber on screen.
// Here, distance to mouse must be less than 10 pixels to activate t
he MouseGrabber.
setGrabsMouse( sqrt((x-posX)*(x-posX) + (y-posY)*(y-posY)) < 10);
\endcode
If the MouseGrabber position is defined in 3D, use the \p camera par
ameter, corresponding to
the calling QGLViewer Camera. Project on screen and then compare the
projected coordinates:
\code
Vec proj = camera->projectedCoordinatesOf(myMouseGrabber->frame()->p
osition());
setGrabsMouse((fabs(x-proj.x) < 5) && (fabs(y-proj.y) < 2)); // Rect
angular region
\endcode
See examples in the <a href="#_details">detailed description</a> sec
tion and in the <a
href="../examples/mouseGrabber.html">mouseGrabber example</a>. */
virtual void checkIfGrabsMouse(int x, int y, const Camera* const cam
era) = 0;
/*! Returns \c true when the MouseGrabber grabs the QGLViewer's mous
e events.
This flag is set with setGrabsMouse() by the checkIfGrabsMouse() met
hod. */
bool grabsMouse() const { return grabsMouse_; }
protected:
/*! Sets the grabsMouse() flag. Normally used by checkIfGrabsMouse()
. */
void setGrabsMouse(bool grabs) { grabsMouse_ = grabs; }
//@}
/*! @name MouseGrabber pool */
//@{
public:
/*! Returns a list containing pointers to all the active MouseGrabbe
rs.
This is the core method of the MouseGrabber. It has to be overloaded in Used by the QGLViewer to parse all the MouseGrabbers and to check if
your derived class. any of them grabsMouse()
Its goal is to update the grabsMouse() flag according to the mouse and using checkIfGrabsMouse().
MouseGrabber current
positions, using setGrabsMouse().
grabsMouse() is usually set to \c true when the mouse cursor is close e
nough to the MouseGrabber
position. It should also be set to \c false when the mouse cursor leave
s this region in order to
release the mouse focus.
\p x and \p y are the mouse cursor coordinates (Qt coordinate system: (
0,0) corresponds to the upper
left corner).
A typical implementation will look like:
\code
// (posX,posY) is the position of the MouseGrabber on screen.
// Here, distance to mouse must be less than 10 pixels to activate the
MouseGrabber.
setGrabsMouse( sqrt((x-posX)*(x-posX) + (y-posY)*(y-posY)) < 10);
\endcode
If the MouseGrabber position is defined in 3D, use the \p camera parame
ter, corresponding to
the calling QGLViewer Camera. Project on screen and then compare the pr
ojected coordinates:
\code
Vec proj = camera->projectedCoordinatesOf(myMouseGrabber->frame()->posi
tion());
setGrabsMouse((fabs(x-proj.x) < 5) && (fabs(y-proj.y) < 2)); // Rectang
ular region
\endcode
See examples in the <a href="#_details">detailed description</a> sectio
n and in the <a
href="../examples/mouseGrabber.html">mouseGrabber example</a>. */
virtual void checkIfGrabsMouse(int x, int y, const Camera* const camera
) = 0;
/*! Returns \c true when the MouseGrabber grabs the QGLViewer's mouse e
vents.
This flag is set with setGrabsMouse() by the checkIfGrabsMouse() method
. */
bool grabsMouse() const { return grabsMouse_; };
protected:
/*! Sets the grabsMouse() flag. Normally used by checkIfGrabsMouse(). *
/
void setGrabsMouse(bool grabs) { grabsMouse_ = grabs; };
//@}
/*! @name MouseGrabber pool */
//@{
public:
/*! Returns a list containing pointers to all the active MouseGrabbers.
Used by the QGLViewer to parse all the MouseGrabbers and to check if an You should not have to directly use this list. Use removeFromMouseGr
y of them grabsMouse() abberPool() and
using checkIfGrabsMouse(). addInMouseGrabberPool() to modify this list.
You should not have to directly use this list. Use removeFromMouseGrabb \attention This method returns a \c QPtrList<MouseGrabber> with Qt 3
erPool() and and a \c QList<MouseGrabber> with Qt 2. */
addInMouseGrabberPool() to modify this list.
\attention This method returns a \c QPtrList<MouseGrabber> with Qt 3 an
d a \c QList<MouseGrabber> with Qt 2. */
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
static const QList<MouseGrabber*>& MouseGrabberPool() { return MouseGra bber::MouseGrabberPool_; }; static const QList<MouseGrabber*>& MouseGrabberPool() { return Mouse Grabber::MouseGrabberPool_; }
#else #else
# if QT_VERSION >= 0x030000 # if QT_VERSION >= 0x030000
static const QPtrList<MouseGrabber>& MouseGrabberPool() { return MouseG rabber::MouseGrabberPool_; }; static const QPtrList<MouseGrabber>& MouseGrabberPool() { return Mou seGrabber::MouseGrabberPool_; }
# else # else
static const QList<MouseGrabber>& MouseGrabberPool() { return MouseGrab ber::MouseGrabberPool_; }; static const QList<MouseGrabber>& MouseGrabberPool() { return MouseG rabber::MouseGrabberPool_; }
# endif # endif
#endif #endif
/*! Returns \c true if the MouseGrabber is currently in the MouseGrabbe rPool() list. /*! Returns \c true if the MouseGrabber is currently in the MouseGra bberPool() list.
Default value is \c true. When set to \c false using removeFromMouseGra Default value is \c true. When set to \c false using removeFromMouse
bberPool(), the GrabberPool(), the
QGLViewers no longer checkIfGrabsMouse() on this MouseGrabber. Use addI QGLViewers no longer checkIfGrabsMouse() on this MouseGrabber. Use a
nMouseGrabberPool() to ddInMouseGrabberPool() to
insert it back. */ insert it back. */
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
bool isInMouseGrabberPool() const { return MouseGrabber::MouseGrabberPo ol_.contains(const_cast<MouseGrabber*>(this)); }; bool isInMouseGrabberPool() const { return MouseGrabber::MouseGrabbe rPool_.contains(const_cast<MouseGrabber*>(this)); }
#else #else
bool isInMouseGrabberPool() const { return MouseGrabber::MouseGrabberPo ol_.findRef(this) != -1; }; bool isInMouseGrabberPool() const { return MouseGrabber::MouseGrabbe rPool_.findRef(this) != -1; }
#endif #endif
void addInMouseGrabberPool(); void addInMouseGrabberPool();
void removeFromMouseGrabberPool(); void removeFromMouseGrabberPool();
void clearMouseGrabberPool(bool autoDelete=false); void clearMouseGrabberPool(bool autoDelete=false);
//@} //@}
/*! @name Mouse event handlers */ /*! @name Mouse event handlers */
//@{ //@{
protected: protected:
/*! Callback method called when the MouseGrabber grabsMouse() and a mou /*! Callback method called when the MouseGrabber grabsMouse() and a
se button is pressed. mouse button is pressed.
The MouseGrabber will typically start an action or change its state whe The MouseGrabber will typically start an action or change its state
n a mouse button is when a mouse button is
pressed. mouseMoveEvent() (called at each mouse displacement) will then pressed. mouseMoveEvent() (called at each mouse displacement) will t
update the MouseGrabber hen update the MouseGrabber
accordingly and mouseReleaseEvent() (called when the mouse button is re accordingly and mouseReleaseEvent() (called when the mouse button is
leased) will terminate released) will terminate
this action. this action.
Use the \p event QMouseEvent::state() and QMouseEvent::button() to test Use the \p event QMouseEvent::state() and QMouseEvent::button() to t
the keyboard est the keyboard
and button state and possibly change the MouseGrabber behavior accordin and button state and possibly change the MouseGrabber behavior accor
gly. dingly.
See the <a href="#_details">detailed description section</a> and the <a See the <a href="#_details">detailed description section</a> and the
href="../examples/mouseGrabber.html">mouseGrabber example</a> for examp <a
les. href="../examples/mouseGrabber.html">mouseGrabber example</a> for ex
amples.
See the \c QGLWidget::mousePressEvent() and the \c QMouseEvent document
ations for details. */ See the \c QGLWidget::mousePressEvent() and the \c QMouseEvent docum
virtual void mousePressEvent(QMouseEvent* const event, Camera* const ca entations for details. */
mera) { Q_UNUSED(event) Q_UNUSED(camera) }; virtual void mousePressEvent(QMouseEvent* const event, Camera* const
/*! Callback method called when the MouseGrabber grabsMouse() and a mou camera) { Q_UNUSED(event) Q_UNUSED(camera) }
se button is double clicked. /*! Callback method called when the MouseGrabber grabsMouse() and a
mouse button is double clicked.
See the \c QGLWidget::mouseDoubleClickEvent() and the \c QMouseEvent do
cumentations for details. */ See the \c QGLWidget::mouseDoubleClickEvent() and the \c QMouseEvent
virtual void mouseDoubleClickEvent(QMouseEvent* const event, Camera* co documentations for details. */
nst camera) { Q_UNUSED(event) Q_UNUSED(camera) }; virtual void mouseDoubleClickEvent(QMouseEvent* const event, Camera*
/*! Mouse release event callback method. See mousePressEvent(). */ const camera) { Q_UNUSED(event) Q_UNUSED(camera) }
virtual void mouseReleaseEvent(QMouseEvent* const event, Camera* const /*! Mouse release event callback method. See mousePressEvent(). */
camera) { Q_UNUSED(event) Q_UNUSED(camera) }; virtual void mouseReleaseEvent(QMouseEvent* const event, Camera* con
/*! Callback method called when the MouseGrabber grabsMouse() and the m st camera) { Q_UNUSED(event) Q_UNUSED(camera) }
ouse is moved while a /*! Callback method called when the MouseGrabber grabsMouse() and th
button is pressed. e mouse is moved while a
button is pressed.
This method will typically update the state of the MouseGrabber from th
e mouse displacement. See This method will typically update the state of the MouseGrabber from
the mousePressEvent() documentation for details. */ the mouse displacement. See
virtual void mouseMoveEvent(QMouseEvent* const event, Camera* const cam the mousePressEvent() documentation for details. */
era) { Q_UNUSED(event) Q_UNUSED(camera) }; virtual void mouseMoveEvent(QMouseEvent* const event, Camera* const
/*! Callback method called when the MouseGrabber grabsMouse() and the m camera) { Q_UNUSED(event) Q_UNUSED(camera) }
ouse wheel is used. /*! Callback method called when the MouseGrabber grabsMouse() and th
e mouse wheel is used.
See the \c QGLWidget::wheelEvent() and the \c QWheelEvent documentation
s for details. */ See the \c QGLWidget::wheelEvent() and the \c QWheelEvent documentat
virtual void wheelEvent(QWheelEvent* const event, Camera* const camera) ions for details. */
{ Q_UNUSED(event) Q_UNUSED(camera) }; virtual void wheelEvent(QWheelEvent* const event, Camera* const came
//@} ra) { Q_UNUSED(event) Q_UNUSED(camera) }
//@}
private:
// Copy constructor and opertor= are declared private and undefined private:
// Prevents everyone from trying to use them // Copy constructor and opertor= are declared private and undefined
MouseGrabber(const MouseGrabber&); // Prevents everyone from trying to use them
MouseGrabber& operator=(const MouseGrabber&); MouseGrabber(const MouseGrabber&);
MouseGrabber& operator=(const MouseGrabber&);
bool grabsMouse_; bool grabsMouse_;
// Q G L V i e w e r p o o l // Q G L V i e w e r p o o l
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
static QList<MouseGrabber*> MouseGrabberPool_; static QList<MouseGrabber*> MouseGrabberPool_;
#else #else
static QPtrList<MouseGrabber> MouseGrabberPool_; static QPtrList<MouseGrabber> MouseGrabberPool_;
#endif #endif
}; };
} // namespace qglviewer } // namespace qglviewer
#endif // QGLVIEWER_MOUSE_GRABBER_H #endif // QGLVIEWER_MOUSE_GRABBER_H
 End of changes. 30 change blocks. 
205 lines changed or deleted 209 lines changed or added


 qglviewer.h   qglviewer.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 39 skipping to change at line 39
# include <QMap> # include <QMap>
# include <QClipboard> # include <QClipboard>
#else #else
# include <qmap.h> # include <qmap.h>
# include <qclipboard.h> # include <qclipboard.h>
#endif #endif
class QTabWidget; class QTabWidget;
namespace qglviewer { namespace qglviewer {
class MouseGrabber; class MouseGrabber;
} }
#if QT_VERSION < 0x040000 #if QT_VERSION < 0x040000
# define Qt::KeyboardModifiers Qt::ButtonState # define Qt::KeyboardModifiers Qt::ButtonState
# define Qt::MouseButtons Qt::ButtonState # define Qt::MouseButtons Qt::ButtonState
# define Qt::WindowFlags Qt::WFlags # define Qt::WindowFlags Qt::WFlags
#endif #endif
/*! \brief A versatile 3D OpenGL viewer based on QGLWidget. /*! \brief A versatile 3D OpenGL viewer based on QGLWidget.
\class QGLViewer qglviewer.h QGLViewer/qglviewer.h \class QGLViewer qglviewer.h QGLViewer/qglviewer.h
skipping to change at line 78 skipping to change at line 78
\nosubgrouping */ \nosubgrouping */
class QGLVIEWER_EXPORT QGLViewer : public QGLWidget class QGLVIEWER_EXPORT QGLViewer : public QGLWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
// Complete implementation is provided so that the constructor is de fined with QT3_SUPPORT when .h is included. // Complete implementation is provided so that the constructor is de fined with QT3_SUPPORT when .h is included.
// (Would not be available otherwise since lib is compiled without Q T3_SUPPORT). // (Would not be available otherwise since lib is compiled without Q T3_SUPPORT).
#if QT_VERSION < 0x040000 || defined QT3_SUPPORT #if QT_VERSION < 0x040000 || defined QT3_SUPPORT
explicit QGLViewer(QWidget* parent=NULL, const char* name=0, const QGLW idget* shareWidget=0, Qt::WindowFlags flags=0) explicit QGLViewer(QWidget* parent=NULL, const char* name=0, const Q GLWidget* shareWidget=0, Qt::WindowFlags flags=0)
: QGLWidget(parent, name, shareWidget, flags) : QGLWidget(parent, name, shareWidget, flags)
{ defaultConstructor(); } { defaultConstructor(); }
explicit QGLViewer(const QGLFormat& format, QWidget* parent=0, const ch ar* name=0, const QGLWidget* shareWidget=0,Qt::WindowFlags flags=0) explicit QGLViewer(const QGLFormat& format, QWidget* parent=0, const char* name=0, const QGLWidget* shareWidget=0,Qt::WindowFlags flags=0)
: QGLWidget(format, parent, name, shareWidget, flags) : QGLWidget(format, parent, name, shareWidget, flags)
{ defaultConstructor(); } { defaultConstructor(); }
QGLViewer(QGLContext* context, QWidget* parent, const char* name=0, con st QGLWidget* shareWidget=0, Qt::WindowFlags flags=0) QGLViewer(QGLContext* context, QWidget* parent, const char* name=0, const QGLWidget* shareWidget=0, Qt::WindowFlags flags=0)
# if QT_VERSION >= 0x030200 # if QT_VERSION >= 0x030200
: QGLWidget(context, parent, name, shareWidget, flags) { : QGLWidget(context, parent, name, shareWidget, flags) {
# else # else
// MOC_SKIP_BEGIN // MOC_SKIP_BEGIN
: QGLWidget(parent, name, shareWidget, flags) { : QGLWidget(parent, name, shareWidget, flags) {
Q_UNUSED(context); Q_UNUSED(context);
// MOC_SKIP_END // MOC_SKIP_END
# endif # endif
defaultConstructor(); } defaultConstructor(); }
#else #else
explicit QGLViewer(QWidget* parent=0, const QGLWidget* shareWidget=0, Q explicit QGLViewer(QWidget* parent=0, const QGLWidget* shareWidget=0
t::WindowFlags flags=0); , Qt::WindowFlags flags=0);
explicit QGLViewer(QGLContext *context, QWidget* parent=0, const QGLWid explicit QGLViewer(QGLContext *context, QWidget* parent=0, const QGL
get* shareWidget=0, Qt::WindowFlags flags=0); Widget* shareWidget=0, Qt::WindowFlags flags=0);
explicit QGLViewer(const QGLFormat& format, QWidget* parent=0, const QG explicit QGLViewer(const QGLFormat& format, QWidget* parent=0, const
LWidget* shareWidget=0, Qt::WindowFlags flags=0); QGLWidget* shareWidget=0, Qt::WindowFlags flags=0);
#endif #endif
virtual ~QGLViewer(); virtual ~QGLViewer();
/*! @name Display of visual hints */ /*! @name Display of visual hints */
//@{ //@{
public: public:
/*! Returns \c true if the world axis is drawn by the viewer. /*! Returns \c true if the world axis is drawn by the viewer.
Set by setAxisIsDrawn() or toggleAxisIsDrawn(). Default value is \c false. */ Set by setAxisIsDrawn() or toggleAxisIsDrawn(). Default value is \c false. */
bool axisIsDrawn() const { return axisIsDrawn_; }; bool axisIsDrawn() const { return axisIsDrawn_; }
/*! Returns \c true if a XY grid is drawn by the viewer. /*! Returns \c true if a XY grid is drawn by the viewer.
Set by setGridIsDrawn() or toggleGridIsDrawn(). Default value is \c false. */ Set by setGridIsDrawn() or toggleGridIsDrawn(). Default value is \c false. */
bool gridIsDrawn() const { return gridIsDrawn_; }; bool gridIsDrawn() const { return gridIsDrawn_; }
/*! Returns \c true if the viewer displays the current frame rate (F rames Per Second). /*! Returns \c true if the viewer displays the current frame rate (F rames Per Second).
Use QApplication::setFont() to define the display font (see drawText ()). Use QApplication::setFont() to define the display font (see drawText ()).
Set by setFPSIsDisplayed() or toggleFPSIsDisplayed(). Use currentFPS () to get the current FPS. Set by setFPSIsDisplayed() or toggleFPSIsDisplayed(). Use currentFPS () to get the current FPS.
Default value is \c false. */ Default value is \c false. */
bool FPSIsDisplayed() const { return FPSIsDisplayed_; }; bool FPSIsDisplayed() const { return FPSIsDisplayed_; }
/*! Returns \c true if text display (see drawText()) is enabled. /*! Returns \c true if text display (see drawText()) is enabled.
Set by setTextIsEnabled() or toggleTextIsEnabled(). This feature con veniently removes all the Set by setTextIsEnabled() or toggleTextIsEnabled(). This feature con veniently removes all the
possibly displayed text, cleaning display. Default value is \c true. */ possibly displayed text, cleaning display. Default value is \c true. */
bool textIsEnabled() const { return textIsEnabled_; }; bool textIsEnabled() const { return textIsEnabled_; }
/*! Returns \c true if the camera() is being edited in the viewer. /*! Returns \c true if the camera() is being edited in the viewer.
Set by setCameraIsEdited() or toggleCameraIsEdited(). Default value is \p false. Set by setCameraIsEdited() or toggleCameraIsEdited(). Default value is \p false.
The current implementation is limited: the defined camera() paths (s ee The current implementation is limited: the defined camera() paths (s ee
qglviewer::Camera::keyFrameInterpolator()) are simply displayed usin g qglviewer::Camera::keyFrameInterpolator()) are simply displayed usin g
qglviewer::Camera::drawAllPaths(). Actual camera and path edition wi ll be implemented in the qglviewer::Camera::drawAllPaths(). Actual camera and path edition wi ll be implemented in the
future. */ future. */
bool cameraIsEdited() const { return cameraIsEdited_; } bool cameraIsEdited() const { return cameraIsEdited_; }
public Q_SLOTS: public Q_SLOTS:
/*! Sets the state of axisIsDrawn(). Emits the axisIsDrawnCh /*! Sets the state of axisIsDrawn(). Emits the axisIsDrawnChanged()
anged() signal. See also toggleAxisIsDrawn(). */ signal. See also toggleAxisIsDrawn(). */
void setAxisIsDrawn(bool draw=true) { axisIsDrawn_ = draw; Q void setAxisIsDrawn(bool draw=true) { axisIsDrawn_ = draw; Q_EMIT ax
_EMIT axisIsDrawnChanged(draw); if (updateGLOK_) updateGL(); }; isIsDrawnChanged(draw); update(); }
/*! Sets the state of gridIsDrawn(). Emits the gridIsDrawnCh /*! Sets the state of gridIsDrawn(). Emits the gridIsDrawnChanged()
anged() signal. See also toggleGridIsDrawn(). */ signal. See also toggleGridIsDrawn(). */
void setGridIsDrawn(bool draw=true) { gridIsDrawn_ = draw; Q void setGridIsDrawn(bool draw=true) { gridIsDrawn_ = draw; Q_EMIT gr
_EMIT gridIsDrawnChanged(draw); if (updateGLOK_) updateGL(); }; idIsDrawnChanged(draw); update(); }
/*! Sets the state of FPSIsDisplayed(). Emits the FPSIsDispl /*! Sets the state of FPSIsDisplayed(). Emits the FPSIsDisplayedChan
ayedChanged() signal. See also toggleFPSIsDisplayed(). */ ged() signal. See also toggleFPSIsDisplayed(). */
void setFPSIsDisplayed(bool display=true) { FPSIsDisplayed_ void setFPSIsDisplayed(bool display=true) { FPSIsDisplayed_ = displa
= display; Q_EMIT FPSIsDisplayedChanged(display); if (updateGLOK_) updateGL y; Q_EMIT FPSIsDisplayedChanged(display); update(); }
(); }; /*! Sets the state of textIsEnabled(). Emits the textIsEnabledChange
/*! Sets the state of textIsEnabled(). Emits the textIsEnabl d() signal. See also toggleTextIsEnabled(). */
edChanged() signal. See also toggleTextIsEnabled(). */ void setTextIsEnabled(bool enable=true) { textIsEnabled_ = enable; Q
void setTextIsEnabled(bool enable=true) { textIsEnabled_ = e _EMIT textIsEnabledChanged(enable); update(); }
nable; Q_EMIT textIsEnabledChanged(enable); if (updateGLOK_) updateGL(); }; void setCameraIsEdited(bool edit=true);
void setCameraIsEdited(bool edit=true);
/*! Toggles the state of axisIsDrawn(). See also setAxisIsDrawn(). *
/*! Toggles the state of axisIsDrawn(). See also setAxisIsDr /
awn(). */ void toggleAxisIsDrawn() { setAxisIsDrawn(!axisIsDrawn()); }
void toggleAxisIsDrawn() { setAxisIsDrawn(!axisIsDrawn()); } /*! Toggles the state of gridIsDrawn(). See also setGridIsDrawn(). *
; /
/*! Toggles the state of gridIsDrawn(). See also setGridIsDr void toggleGridIsDrawn() { setGridIsDrawn(!gridIsDrawn()); }
awn(). */ /*! Toggles the state of FPSIsDisplayed(). See also setFPSIsDisplaye
void toggleGridIsDrawn() { setGridIsDrawn(!gridIsDrawn()); } d(). */
; void toggleFPSIsDisplayed() { setFPSIsDisplayed(!FPSIsDisplayed());
/*! Toggles the state of FPSIsDisplayed(). See also setFPSIs }
Displayed(). */ /*! Toggles the state of textIsEnabled(). See also setTextIsEnabled(
void toggleFPSIsDisplayed() { setFPSIsDisplayed(!FPSIsDispla ). */
yed()); }; void toggleTextIsEnabled() { setTextIsEnabled(!textIsEnabled()); }
/*! Toggles the state of textIsEnabled(). See also setTextIs /*! Toggles the state of cameraIsEdited(). See also setCameraIsEdite
Enabled(). */ d(). */
void toggleTextIsEnabled() { setTextIsEnabled(!textIsEnabled void toggleCameraIsEdited() { setCameraIsEdited(!cameraIsEdited());
()); }; }
/*! Toggles the state of cameraIsEdited(). See also setCamer //@}
aIsEdited(). */
void toggleCameraIsEdited() { setCameraIsEdited(!cameraIsEdi
ted()); };
//@}
/*! @name Viewer's colors */ /*! @name Viewer's colors */
//@{ //@{
public: public:
/*! Returns the background color of the viewer. /*! Returns the background color of the viewer.
This method is provided for convenience since the background color i s an OpenGL state variable This method is provided for convenience since the background color i s an OpenGL state variable
set with \c glClearColor(). However, this internal representation ha s the advantage that it is set with \c glClearColor(). However, this internal representation ha s the advantage that it is
saved (resp. restored) with saveStateToFile() (resp. restoreStateFro mFile()). saved (resp. restored) with saveStateToFile() (resp. restoreStateFro mFile()).
Use setBackgroundColor() to define and activate a background color. Use setBackgroundColor() to define and activate a background color.
\attention Each QColor component is an integer ranging from 0 to 255 . This differs from the float \attention Each QColor component is an integer ranging from 0 to 255 . This differs from the float
values used by \c glClearColor() which are in the 0.0-1.0 range. Def ault value is (51, 51, 51) values used by \c glClearColor() which are in the 0.0-1.0 range. Def ault value is (51, 51, 51)
(dark gray). You may have to change foregroundColor() accordingly. (dark gray). You may have to change foregroundColor() accordingly.
\attention This method does not return the current OpenGL clear colo r as \c glGet() does. Instead, \attention This method does not return the current OpenGL clear colo r as \c glGet() does. Instead,
it returns the QGLViewer internal variable. If you directly use \c g lClearColor() or \c it returns the QGLViewer internal variable. If you directly use \c g lClearColor() or \c
qglClearColor() instead of setBackgroundColor(), the two results wil l differ. */ qglClearColor() instead of setBackgroundColor(), the two results wil l differ. */
QColor backgroundColor() const { return backgroundColor_; }; QColor backgroundColor() const { return backgroundColor_; }
/*! Returns the foreground color used by the viewer. /*! Returns the foreground color used by the viewer.
This color is used when FPSIsDisplayed(), gridIsDrawn(), to display the camera paths when the This color is used when FPSIsDisplayed(), gridIsDrawn(), to display the camera paths when the
cameraIsEdited(). cameraIsEdited().
\attention Each QColor component is an integer in the range 0-255. T his differs from the float \attention Each QColor component is an integer in the range 0-255. T his differs from the float
values used by \c glColor3f() which are in the range 0-1. Default va lue is (180, 180, 180) (light values used by \c glColor3f() which are in the range 0-1. Default va lue is (180, 180, 180) (light
gray). gray).
Use \c qglColor(foregroundColor()) to set the current OpenGL color t o the foregroundColor(). Use \c qglColor(foregroundColor()) to set the current OpenGL color t o the foregroundColor().
See also backgroundColor(). */ See also backgroundColor(). */
QColor foregroundColor() const { return foregroundColor_; }; QColor foregroundColor() const { return foregroundColor_; }
public Q_SLOTS: public Q_SLOTS:
/*! Sets the backgroundColor() of the viewer and calls \c qg /*! Sets the backgroundColor() of the viewer and calls \c qglClearCo
lClearColor(). See also lor(). See also
setForegroundColor(). */ setForegroundColor(). */
void setBackgroundColor(const QColor& color) { backgroundCol void setBackgroundColor(const QColor& color) { backgroundColor_=colo
or_=color; qglClearColor(color); }; r; qglClearColor(color); }
/*! Sets the foregroundColor() of the viewer, used to draw v /*! Sets the foregroundColor() of the viewer, used to draw visual hi
isual hints. See also setBackgroundColor(). */ nts. See also setBackgroundColor(). */
void setForegroundColor(const QColor& color) { foregroundCol void setForegroundColor(const QColor& color) { foregroundColor_ = co
or_ = color; }; lor; }
//@} //@}
/*! @name Scene dimensions */ /*! @name Scene dimensions */
//@{ //@{
public: public:
/*! Returns the scene radius. /*! Returns the scene radius.
The entire displayed scene should be included in a sphere of radius sceneRadius(), centered on The entire displayed scene should be included in a sphere of radius sceneRadius(), centered on
sceneCenter(). sceneCenter().
This approximate value is used by the camera() to set qglviewer::Cam era::zNear() and This approximate value is used by the camera() to set qglviewer::Cam era::zNear() and
qglviewer::Camera::zFar(). It is also used to showEntireScene() or t o scale the world axis qglviewer::Camera::zFar(). It is also used to showEntireScene() or t o scale the world axis
display.. display..
skipping to change at line 229 skipping to change at line 229
/*! Returns the scene center, defined in world coordinates. /*! Returns the scene center, defined in world coordinates.
See sceneRadius() for details. See sceneRadius() for details.
Default value is (0,0,0). Simply a wrapper for camera()->sceneCenter (). Set using Default value is (0,0,0). Simply a wrapper for camera()->sceneCenter (). Set using
setSceneCenter(). setSceneCenter().
Do not mismatch this value (that only depends on the scene) with the qglviewer::Camera::revolveAroundPoint(). */ Do not mismatch this value (that only depends on the scene) with the qglviewer::Camera::revolveAroundPoint(). */
qglviewer::Vec sceneCenter() const { return camera()->sceneCenter(); } qglviewer::Vec sceneCenter() const { return camera()->sceneCenter(); }
public Q_SLOTS: public Q_SLOTS:
/*! Sets the sceneRadius(). /*! Sets the sceneRadius().
The camera() qglviewer::Camera::flySpeed() is set to 1% of t his value by this method. Simple The camera() qglviewer::Camera::flySpeed() is set to 1% of t his value by this method. Simple
wrapper around camera()->setSceneRadius(). */ wrapper around camera()->setSceneRadius(). */
virtual void setSceneRadius(float radius) { camera()->setSce neRadius(radius); } virtual void setSceneRadius(float radius) { camera()->setSceneRadius (radius); }
/*! Sets the sceneCenter(), defined in world coordinates. /*! Sets the sceneCenter(), defined in world coordinates.
\attention The qglviewer::Camera::revolveAroundPoint() is se t to the sceneCenter() value by this \attention The qglviewer::Camera::revolveAroundPoint() is se t to the sceneCenter() value by this
method. */ method. */
virtual void setSceneCenter(const qglviewer::Vec& center) { camera()->setSceneCenter(center); } virtual void setSceneCenter(const qglviewer::Vec& center) { camera() ->setSceneCenter(center); }
/*! Convenient way to call setSceneCenter() and setSceneRadi us() from a (world axis aligned) bounding box of the scene. /*! Convenient way to call setSceneCenter() and setSceneRadius() fro m a (world axis aligned) bounding box of the scene.
This is equivalent to: This is equivalent to:
\code \code
setSceneCenter((min+max) / 2.0); setSceneCenter((min+max) / 2.0);
setSceneRadius((max-min).norm() / 2.0); setSceneRadius((max-min).norm() / 2.0);
\endcode */ \endcode */
void setSceneBoundingBox(const qglviewer::Vec& min, const qg lviewer::Vec& max) { camera()->setSceneBoundingBox(min,max); } void setSceneBoundingBox(const qglviewer::Vec& min, const qglviewer: :Vec& max) { camera()->setSceneBoundingBox(min,max); }
/*! Moves the camera so that the entire scene is visible. /*! Moves the camera so that the entire scene is visible.
Simple wrapper around qglviewer::Camera::showEntireScene(). */ Simple wrapper around qglviewer::Camera::showEntireScene(). */
void showEntireScene() { camera()->showEntireScene(); if (up void showEntireScene() { camera()->showEntireScene(); update(); }
dateGLOK_) updateGL(); } //@}
//@}
/*! @name Associated objects */ /*! @name Associated objects */
//@{ //@{
public: public:
/*! Returns the associated qglviewer::Camera, never \c NULL. */ /*! Returns the associated qglviewer::Camera, never \c NULL. */
qglviewer::Camera* camera() const { return camera_; }; qglviewer::Camera* camera() const { return camera_; }
/*! Returns the viewer's qglviewer::ManipulatedFrame. /*! Returns the viewer's qglviewer::ManipulatedFrame.
This qglviewer::ManipulatedFrame can be moved with the mouse when th e associated mouse bindings This qglviewer::ManipulatedFrame can be moved with the mouse when th e associated mouse bindings
are used (default is when pressing the \c Control key with any mouse button). Use are used (default is when pressing the \c Control key with any mouse button). Use
setMouseBinding() to define new bindings. setMouseBinding() to define new bindings.
See the <a href="../examples/manipulatedFrame.html">manipulatedFrame example</a> for a complete See the <a href="../examples/manipulatedFrame.html">manipulatedFrame example</a> for a complete
implementation. implementation.
Default value is \c NULL, meaning that no qglviewer::ManipulatedFram e is set. */ Default value is \c NULL, meaning that no qglviewer::ManipulatedFram e is set. */
qglviewer::ManipulatedFrame* manipulatedFrame() const { return manip ulatedFrame_; }; qglviewer::ManipulatedFrame* manipulatedFrame() const { return manip ulatedFrame_; }
public Q_SLOTS: public Q_SLOTS:
void setCamera(qglviewer::Camera* const camera); void setCamera(qglviewer::Camera* const camera);
void setManipulatedFrame(qglviewer::ManipulatedFrame* frame) void setManipulatedFrame(qglviewer::ManipulatedFrame* frame);
; //@}
//@}
/*! @name Mouse grabbers */ /*! @name Mouse grabbers */
//@{ //@{
public: public:
/*! Returns the current qglviewer::MouseGrabber, or \c NULL if no qg lviewer::MouseGrabber /*! Returns the current qglviewer::MouseGrabber, or \c NULL if no qg lviewer::MouseGrabber
currently grabs mouse events. currently grabs mouse events.
When qglviewer::MouseGrabber::grabsMouse(), the different mouse even ts are sent to the When qglviewer::MouseGrabber::grabsMouse(), the different mouse even ts are sent to the
mouseGrabber() instead of their usual targets (camera() or manipulat edFrame()). mouseGrabber() instead of their usual targets (camera() or manipulat edFrame()).
See the qglviewer::MouseGrabber documentation for details on MouseGr abber's mode of operation. See the qglviewer::MouseGrabber documentation for details on MouseGr abber's mode of operation.
In order to use MouseGrabbers, you need to enable mouse tracking (so that mouseMoveEvent() is In order to use MouseGrabbers, you need to enable mouse tracking (so that mouseMoveEvent() is
called even when no mouse button is pressed). Add this line in init( ) or in your viewer called even when no mouse button is pressed). Add this line in init( ) or in your viewer
constructor: constructor:
\code \code
setMouseTracking(true); setMouseTracking(true);
\endcode \endcode
Note that mouse tracking is disabled by default. Use QWidget::hasMou seTracking() to Note that mouse tracking is disabled by default. Use QWidget::hasMou seTracking() to
retrieve current state. */ retrieve current state. */
qglviewer::MouseGrabber* mouseGrabber() const { return mouseGrabber_ ; }; qglviewer::MouseGrabber* mouseGrabber() const { return mouseGrabber_ ; }
void setMouseGrabberIsEnabled(const qglviewer::MouseGrabber* const m ouseGrabber, bool enabled=true); void setMouseGrabberIsEnabled(const qglviewer::MouseGrabber* const m ouseGrabber, bool enabled=true);
/*! Returns \c true if \p mouseGrabber is enabled. /*! Returns \c true if \p mouseGrabber is enabled.
Default value is \c true for all MouseGrabbers. When set to \c false using Default value is \c true for all MouseGrabbers. When set to \c false using
setMouseGrabberIsEnabled(), the specified \p mouseGrabber will never become the mouseGrabber() of setMouseGrabberIsEnabled(), the specified \p mouseGrabber will never become the mouseGrabber() of
this QGLViewer. This is useful when you use several viewers: some Mo useGrabbers may only have a this QGLViewer. This is useful when you use several viewers: some Mo useGrabbers may only have a
meaning for some specific viewers and should not be selectable in ot hers. meaning for some specific viewers and should not be selectable in ot hers.
You can also use qglviewer::MouseGrabber::removeFromMouseGrabberPool () to completely disable a You can also use qglviewer::MouseGrabber::removeFromMouseGrabberPool () to completely disable a
MouseGrabber in all the QGLViewers. */ MouseGrabber in all the QGLViewers. */
bool mouseGrabberIsEnabled(const qglviewer::MouseGrabber* const mous bool mouseGrabberIsEnabled(const qglviewer::MouseGrabber* const mous
eGrabber) { return !disabledMouseGrabbers_.contains(reinterpret_cast<size_t eGrabber) { return !disabledMouseGrabbers_.contains(reinterpret_cast<size_t
>(mouseGrabber)); }; >(mouseGrabber)); }
public Q_SLOTS: public Q_SLOTS:
void setMouseGrabber(qglviewer::MouseGrabber* mouseGrabber); void setMouseGrabber(qglviewer::MouseGrabber* mouseGrabber);
//@} //@}
/*! @name State of the viewer */ /*! @name State of the viewer */
//@{ //@{
public: public:
/*! Returns the aspect ratio of the viewer's widget (width() / heigh t()). */ /*! Returns the aspect ratio of the viewer's widget (width() / heigh t()). */
float aspectRatio() const { return static_cast<float>(width())/stati c_cast<float>(height()); }; float aspectRatio() const { return static_cast<float>(width())/stati c_cast<float>(height()); }
/*! Returns the current averaged viewer frame rate. /*! Returns the current averaged viewer frame rate.
This value is computed and averaged over 20 successive frames. It on ly changes every 20 draw() This value is computed and averaged over 20 successive frames. It on ly changes every 20 draw()
(previously computed value is otherwise returned). (previously computed value is otherwise returned).
This method is useful for true real-time applications that may adapt their computational load This method is useful for true real-time applications that may adapt their computational load
accordingly in order to maintain a given frequency. accordingly in order to maintain a given frequency.
This value is meaningful only when draw() is regularly called, eithe r using a \c QTimer, when This value is meaningful only when draw() is regularly called, eithe r using a \c QTimer, when
animationIsStarted() or when the camera is manipulated with the mous e. */ animationIsStarted() or when the camera is manipulated with the mous e. */
float currentFPS() { return f_p_s_; }; float currentFPS() { return f_p_s_; }
/*! Returns \c true if the viewer is in fullScreen mode. /*! Returns \c true if the viewer is in fullScreen mode.
Default value is \c false. Set by setFullScreen() or toggleFullScree n(). Default value is \c false. Set by setFullScreen() or toggleFullScree n().
Note that if the QGLViewer is embedded in an other QWidget, it retur ns \c true when the top level Note that if the QGLViewer is embedded in an other QWidget, it retur ns \c true when the top level
widget is in full screen mode. */ widget is in full screen mode. */
bool isFullScreen() const { return fullScreen_; }; bool isFullScreen() const { return fullScreen_; }
/*! Returns \c true if the viewer displays in stereo. /*! Returns \c true if the viewer displays in stereo.
The QGLViewer object must be created with a stereo format to handle stereovision: The QGLViewer object must be created with a stereo format to handle stereovision:
\code \code
QGLFormat format; QGLFormat format;
format.setStereoDisplay( TRUE ); format.setStereoDisplay( TRUE );
QGLViewer viewer(format); QGLViewer viewer(format);
\endcode \endcode
The hardware needs to support stereo display. Try the <a The hardware needs to support stereo display. Try the <a
href="../examples/stereoViewer.html">stereoViewer example</a> to che ck. href="../examples/stereoViewer.html">stereoViewer example</a> to che ck.
skipping to change at line 362 skipping to change at line 362
Stereo is performed using the Parallel axis asymmetric frustum persp ective projection method. Stereo is performed using the Parallel axis asymmetric frustum persp ective projection method.
See Camera::loadProjectionMatrixStereo() and Camera::loadModelViewMa trixStereo(). See Camera::loadProjectionMatrixStereo() and Camera::loadModelViewMa trixStereo().
The stereo parameters are defined by the camera(). See qglviewer::Ca mera::setIODistance(), The stereo parameters are defined by the camera(). See qglviewer::Ca mera::setIODistance(),
qglviewer::Camera::setPhysicalScreenWidth() and qglviewer::Camera::setPhysicalScreenWidth() and
qglviewer::Camera::setFocusDistance(). */ qglviewer::Camera::setFocusDistance(). */
bool displaysInStereo() const { return stereo_; } bool displaysInStereo() const { return stereo_; }
/*! Returns the recommended size for the QGLViewer. Default value is 600x400 pixels. */ /*! Returns the recommended size for the QGLViewer. Default value is 600x400 pixels. */
virtual QSize sizeHint() const { return QSize(600, 400); } virtual QSize sizeHint() const { return QSize(600, 400); }
public Q_SLOTS: public Q_SLOTS:
void setFullScreen(bool fullScreen=true); void setFullScreen(bool fullScreen=true);
void setStereoDisplay(bool stereo=true); void setStereoDisplay(bool stereo=true);
/*! Toggles the state of isFullScreen(). See also setFullScr /*! Toggles the state of isFullScreen(). See also setFullScreen(). *
een(). */ /
void toggleFullScreen() { setFullScreen(!isFullScreen()); }; void toggleFullScreen() { setFullScreen(!isFullScreen()); }
/*! Toggles the state of displaysInStereo(). See setStereoDi /*! Toggles the state of displaysInStereo(). See setStereoDisplay().
splay(). */ */
void toggleStereoDisplay() { setStereoDisplay(!stereo_); }; void toggleStereoDisplay() { setStereoDisplay(!stereo_); }
void toggleCameraMode(); void toggleCameraMode();
private: private:
bool cameraIsInRevolveMode() const; bool cameraIsInRevolveMode() const;
//@} //@}
/*! @name Display methods */ /*! @name Display methods */
//@{ //@{
public: public:
static void drawArrow(float length=1.0f, float radius=-1.0f, int nbS ubdivisions=12); static void drawArrow(float length=1.0f, float radius=-1.0f, int nbS ubdivisions=12);
static void drawArrow(const qglviewer::Vec& from, const qglviewer::V ec& to, float radius=-1.0f, int nbSubdivisions=12); static void drawArrow(const qglviewer::Vec& from, const qglviewer::V ec& to, float radius=-1.0f, int nbSubdivisions=12);
skipping to change at line 396 skipping to change at line 396
void drawText(int x, int y, const QString& text, const QFont& fnt=QF ont()); void drawText(int x, int y, const QString& text, const QFont& fnt=QF ont());
void displayMessage(const QString& message, int delay=2000); void displayMessage(const QString& message, int delay=2000);
// void draw3DText(const qglviewer::Vec& pos, const qglviewer::Vec& normal, const QString& string, GLfloat height=0.1f); // void draw3DText(const qglviewer::Vec& pos, const qglviewer::Vec& normal, const QString& string, GLfloat height=0.1f);
protected: protected:
virtual void drawLight(GLenum light, float scale = 1.0f) const; virtual void drawLight(GLenum light, float scale = 1.0f) const;
private: private:
void displayFPS(); void displayFPS();
/*! Vectorial rendering callback method. */ /*! Vectorial rendering callback method. */
void drawVectorial() { paintGL(); }; void drawVectorial() { paintGL(); }
#ifndef DOXYGEN #ifndef DOXYGEN
friend void drawVectorial(void* param); friend void drawVectorial(void* param);
#endif #endif
//@} //@}
#ifdef DOXYGEN #ifdef DOXYGEN
/*! @name Useful inherited methods */ /*! @name Useful inherited methods */
//@{ //@{
public: public:
skipping to change at line 434 skipping to change at line 434
constructor. See QGLWidget documentation. */ constructor. See QGLWidget documentation. */
bool isSharing() const; bool isSharing() const;
/*! Makes this widget's rendering context the current OpenGL renderi ng context. Useful with /*! Makes this widget's rendering context the current OpenGL renderi ng context. Useful with
several viewers. See QGLWidget documentation. */ several viewers. See QGLWidget documentation. */
virtual void makeCurrent(); virtual void makeCurrent();
/*! Returns \c true if mouseMoveEvent() is called even when no mouse button is pressed. /*! Returns \c true if mouseMoveEvent() is called even when no mouse button is pressed.
You need to setMouseTracking() to \c true in order to use MouseGrabb er (see mouseGrabber()). See You need to setMouseTracking() to \c true in order to use MouseGrabb er (see mouseGrabber()). See
details in the QWidget documentation. */ details in the QWidget documentation. */
bool hasMouseTracking () const; bool hasMouseTracking () const;
public Q_SLOTS: public Q_SLOTS:
/*! Resizes the widget to size \p width by \p height pixels. /*! Resizes the widget to size \p width by \p height pixels. See als
See also width() and height(). */ o width() and height(). */
virtual void resize(int width, int height); virtual void resize(int width, int height);
/*! Sets the hasMouseTracking() value. */ /*! Sets the hasMouseTracking() value. */
virtual void setMouseTracking(bool enable); virtual void setMouseTracking(bool enable);
protected: protected:
/*! Returns \c true when buffers are automatically swapped (default) . See details in the QGLWidget /*! Returns \c true when buffers are automatically swapped (default) . See details in the QGLWidget
documentation. */ documentation. */
bool autoBufferSwap() const; bool autoBufferSwap() const;
protected Q_SLOTS: protected Q_SLOTS:
/*! Sets the autoBufferSwap() value. */ /*! Sets the autoBufferSwap() value. */
void setAutoBufferSwap(bool on); void setAutoBufferSwap(bool on);
//@} //@}
#endif #endif
/*! @name Snapshots */ /*! @name Snapshots */
//@{ //@{
public: public:
#if QT_VERSION < 0x030000 #if QT_VERSION < 0x030000
virtual QImage grabFrameBuffer(bool withAlpha=false); virtual QImage grabFrameBuffer(bool withAlpha=false);
#endif #endif
/*! Returns the snapshot file name used by saveSnapshot(). /*! Returns the snapshot file name used by saveSnapshot().
This value is used in \p automatic mode (see saveSnapshot()). A dial og is otherwise popped-up to This value is used in \p automatic mode (see saveSnapshot()). A dial og is otherwise popped-up to
set it. set it.
You can also directly provide a file name using saveSnapshot(const Q String&, bool). You can also directly provide a file name using saveSnapshot(const Q String&, bool).
If the file name is relative, the current working directory at the m oment of the method call is If the file name is relative, the current working directory at the m oment of the method call is
used. Set using setSnapshotFileName(). */ used. Set using setSnapshotFileName(). */
const QString& snapshotFileName() const { return snapshotFileName_; }; const QString& snapshotFileName() const { return snapshotFileName_; }
#ifndef DOXYGEN #ifndef DOXYGEN
const QString& snapshotFilename() const; const QString& snapshotFilename() const;
#endif #endif
/*! Returns the snapshot file format used by saveSnapshot(). /*! Returns the snapshot file format used by saveSnapshot().
This value is used when saveSnapshot() is passed the \p automatic fl ag. It is defined using a This value is used when saveSnapshot() is passed the \p automatic fl ag. It is defined using a
saveAs pop-up dialog otherwise. saveAs pop-up dialog otherwise.
The available formats are those handled by Qt. Classical values are \c "JPEG", \c "PNG", The available formats are those handled by Qt. Classical values are \c "JPEG", \c "PNG",
\c "PPM", \c "BMP". Use the following code to get the actual list: \c "PPM", \c "BMP". Use the following code to get the actual list:
skipping to change at line 496 skipping to change at line 496
Note that the VRender library has some limitations: vertex shader ef fects are not reproduced and Note that the VRender library has some limitations: vertex shader ef fects are not reproduced and
\c PASS_THROUGH tokens are not handled so one can not change point a nd line size in the middle of \c PASS_THROUGH tokens are not handled so one can not change point a nd line size in the middle of
a drawing. a drawing.
Default value is the first supported among "JPEG, PNG, EPS, PS, PPM, BMP", in that order. Default value is the first supported among "JPEG, PNG, EPS, PS, PPM, BMP", in that order.
This value is set using setSnapshotFormat() or with openSnapshotForm atDialog(). This value is set using setSnapshotFormat() or with openSnapshotForm atDialog().
\attention No verification is performed on the provided format valid ity. The next call to \attention No verification is performed on the provided format valid ity. The next call to
saveSnapshot() may fail if the format string is not supported. */ saveSnapshot() may fail if the format string is not supported. */
const QString& snapshotFormat() const { return snapshotFormat_; }; const QString& snapshotFormat() const { return snapshotFormat_; }
/*! Returns the value of the counter used to name snapshots in saveS napshot() when \p automatic is /*! Returns the value of the counter used to name snapshots in saveS napshot() when \p automatic is
\c true. \c true.
Set using setSnapshotCounter(). Default value is 0, and it is increm ented after each \p automatic Set using setSnapshotCounter(). Default value is 0, and it is increm ented after each \p automatic
snapshot. See saveSnapshot() for details. */ snapshot. See saveSnapshot() for details. */
int snapshotCounter() const { return snapshotCounter_; }; int snapshotCounter() const { return snapshotCounter_; }
/*! Defines the image quality of the snapshots produced with saveSna pshot(). /*! Defines the image quality of the snapshots produced with saveSna pshot().
Values must be in the range -1..100. Use 0 for lowest quality and 10 0 for highest quality (and Values must be in the range -1..100. Use 0 for lowest quality and 10 0 for highest quality (and
larger files). -1 means use Qt default quality. Default value is 95. larger files). -1 means use Qt default quality. Default value is 95.
Set using setSnapshotQuality(). See also the QImage::save() document ation. Set using setSnapshotQuality(). See also the QImage::save() document ation.
\note This value has no impact on the images produced in vectorial f ormat. */ \note This value has no impact on the images produced in vectorial f ormat. */
int snapshotQuality() { return snapshotQuality_; }; int snapshotQuality() { return snapshotQuality_; }
// Qt 2.3 does not support double default value parameters in slots. // Qt 2.3 does not support double default value parameters in slots.
// Remove "Q_SLOTS" from the following line to compile with Qt 2.3 // Remove "Q_SLOTS" from the following line to compile with Qt 2.3
public Q_SLOTS: public Q_SLOTS:
void saveSnapshot(bool automatic=true, bool overwrite=false); void saveSnapshot(bool automatic=true, bool overwrite=false);
public Q_SLOTS: public Q_SLOTS:
void saveSnapshot(const QString& fileName, bool overwrite=false); void saveSnapshot(const QString& fileName, bool overwrite=false);
void setSnapshotFileName(const QString& name); void setSnapshotFileName(const QString& name);
/*! Sets the snapshotFormat(). */ /*! Sets the snapshotFormat(). */
void setSnapshotFormat(const QString& format) { snapshotFormat_ = fo rmat; }; void setSnapshotFormat(const QString& format) { snapshotFormat_ = fo rmat; }
/*! Sets the snapshotCounter(). */ /*! Sets the snapshotCounter(). */
void setSnapshotCounter(int counter) { snapshotCounter_ = counter; } ; void setSnapshotCounter(int counter) { snapshotCounter_ = counter; }
/*! Sets the snapshotQuality(). */ /*! Sets the snapshotQuality(). */
void setSnapshotQuality(int quality) { snapshotQuality_ = quality; } ; void setSnapshotQuality(int quality) { snapshotQuality_ = quality; }
bool openSnapshotFormatDialog(); bool openSnapshotFormatDialog();
void snapshotToClipboard(); void snapshotToClipboard();
private: private:
bool saveImageSnapshot(const QString& fileName); bool saveImageSnapshot(const QString& fileName);
#ifndef DOXYGEN #ifndef DOXYGEN
/* This class is used internally for screenshot that require tiling (image size size different /* This class is used internally for screenshot that require tiling (image size size different
from window size). Only in that case, is the private tileRegion_ poi nter non null. from window size). Only in that case, is the private tileRegion_ poi nter non null.
It then contains the current tiled region, which is used by startScr eenCoordinatesSystem It then contains the current tiled region, which is used by startScr eenCoordinatesSystem
skipping to change at line 562 skipping to change at line 562
to generate the snapshot. to generate the snapshot.
All your calls to QGLWidget::renderText() function hence should use this method. All your calls to QGLWidget::renderText() function hence should use this method.
\code \code
renderText(x, y, z, "My Text", scaledFont(QFont())); renderText(x, y, z, "My Text", scaledFont(QFont()));
\endcode \endcode
will guarantee that this text will be properly displayed on arbitrar y sized snapshots. will guarantee that this text will be properly displayed on arbitrar y sized snapshots.
Note that this method is not needed if you use drawText() which alre ady calls it internally. */ Note that this method is not needed if you use drawText() which alre ady calls it internally. */
QFont scaledFont(const QFont& font) const { QFont scaledFont(const QFont& font) const {
if (tileRegion_ == NULL) if (tileRegion_ == NULL)
return font; return font;
else { else {
QFont f(font); QFont f(font);
if (f.pixelSize() == -1) if (f.pixelSize() == -1)
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
f.setPointSizeF(f.pointSizeF() * tileRegion_->textScale); f.setPointSizeF(f.pointSizeF() * tileRegion_ ->textScale);
#else #else
f.setPointSizeFloat(f.pointSizeFloat() * tileRegion_->textScal e); f.setPointSizeFloat(f.pointSizeFloat() * til eRegion_->textScale);
#endif #endif
else else
f.setPixelSize(f.pixelSize() * tileRegion_->textScale); f.setPixelSize(f.pixelSize() * tileRegion_->
return f; textScale);
} return f;
}
} }
//@} //@}
/*! @name Buffer to texture */ /*! @name Buffer to texture */
//@{ //@{
public: public:
GLuint bufferTextureId() const; GLuint bufferTextureId() const;
/*! Returns the texture coordinate corresponding to the u extremum o f the bufferTexture. /*! Returns the texture coordinate corresponding to the u extremum o f the bufferTexture.
The bufferTexture is created by copyBufferToTexture(). The texture s ize has powers of two The bufferTexture is created by copyBufferToTexture(). The texture s ize has powers of two
dimensions and the buffer image hence only fills a part of it. This value corresponds to the u dimensions and the buffer image hence only fills a part of it. This value corresponds to the u
coordinate of the extremum right side of the buffer image. coordinate of the extremum right side of the buffer image.
Use (0,0) to (bufferTextureMaxU(), bufferTextureMaxV()) texture coor dinates to map the entire Use (0,0) to (bufferTextureMaxU(), bufferTextureMaxV()) texture coor dinates to map the entire
texture on a quad. */ texture on a quad. */
float bufferTextureMaxU() const { return bufferTextureMaxU_; }; float bufferTextureMaxU() const { return bufferTextureMaxU_; }
/*! Same as bufferTextureMaxU(), but for the v texture coordinate. * / /*! Same as bufferTextureMaxU(), but for the v texture coordinate. * /
float bufferTextureMaxV() const { return bufferTextureMaxV_; }; float bufferTextureMaxV() const { return bufferTextureMaxV_; }
public Q_SLOTS: public Q_SLOTS:
void copyBufferToTexture(GLint internalFormat, GLenum format void copyBufferToTexture(GLint internalFormat, GLenum format=GL_NONE
=GL_NONE); );
//@} //@}
/*! @name Animation */ /*! @name Animation */
//@{ //@{
public: public:
/*! Return \c true when the animation loop is started. /*! Return \c true when the animation loop is started.
During animation, an infinite loop calls animate() and draw() and th en waits for animationPeriod() During animation, an infinite loop calls animate() and draw() and th en waits for animationPeriod()
milliseconds before calling animate() and draw() again. And again. milliseconds before calling animate() and draw() again. And again.
Use startAnimation(), stopAnimation() or toggleAnimation() to change this value. Use startAnimation(), stopAnimation() or toggleAnimation() to change this value.
See the <a href="../examples/animation.html">animation example</a> f or illustration. */ See the <a href="../examples/animation.html">animation example</a> f or illustration. */
bool animationIsStarted() const { return animationStarted_; }; bool animationIsStarted() const { return animationStarted_; }
/*! The animation loop period, in milliseconds. /*! The animation loop period, in milliseconds.
When animationIsStarted(), this is delay waited after draw() to call animate() and draw() again. When animationIsStarted(), this is delay waited after draw() to call animate() and draw() again.
Default value is 40 milliseconds (25 Hz). Default value is 40 milliseconds (25 Hz).
This value will define the currentFPS() when animationIsStarted() (p rovided that your animate() This value will define the currentFPS() when animationIsStarted() (p rovided that your animate()
and draw() methods are fast enough). and draw() methods are fast enough).
If you want to know the maximum possible frame rate of your machine on a given scene, If you want to know the maximum possible frame rate of your machine on a given scene,
setAnimationPeriod() to \c 0, and startAnimation() (keyboard shortcu t is \c Enter). The display setAnimationPeriod() to \c 0, and startAnimation() (keyboard shortcu t is \c Enter). The display
will then be updated as often as possible, and the frame rate will b e meaningful. will then be updated as often as possible, and the frame rate will b e meaningful.
\note This value is taken into account only the next time you call s tartAnimation(). If \note This value is taken into account only the next time you call s tartAnimation(). If
animationIsStarted(), you should stopAnimation() first. */ animationIsStarted(), you should stopAnimation() first. */
int animationPeriod() const { return animationPeriod_; }; int animationPeriod() const { return animationPeriod_; }
public Q_SLOTS: public Q_SLOTS:
/*! Sets the animationPeriod(), in milliseconds. */ /*! Sets the animationPeriod(), in milliseconds. */
void setAnimationPeriod(int period) { animationPeriod_ = per void setAnimationPeriod(int period) { animationPeriod_ = period; }
iod; }; virtual void startAnimation();
virtual void startAnimation(); virtual void stopAnimation();
virtual void stopAnimation(); /*! Scene animation method.
/*! Scene animation method.
When animationIsStarted(), this method is in charge of the s cene update before each draw(). When animationIsStarted(), this method is in charge of the s cene update before each draw().
Overload it to define how your scene evolves over time. The time should either be regularly Overload it to define how your scene evolves over time. The time should either be regularly
incremented in this method (frame-rate independent animation ) or computed from actual time (for incremented in this method (frame-rate independent animation ) or computed from actual time (for
instance using QTime::elapsed()) for real-time animations. instance using QTime::elapsed()) for real-time animations.
Note that KeyFrameInterpolator (which regularly updates a F Note that KeyFrameInterpolator (which regula
rame) does not use this method rly updates a Frame) does not use this method
to animate a Frame, but rather rely on a QTimer signal-slot to animate a Frame, but rather rely on a QTi
mechanism. mer signal-slot mechanism.
See the <a href="../examples/animation.html">animation examp le</a> for an illustration. */ See the <a href="../examples/animation.html">animation examp le</a> for an illustration. */
virtual void animate() { Q_EMIT animateNeeded(); }; virtual void animate() { Q_EMIT animateNeeded(); }
/*! Calls startAnimation() or stopAnimation(), depending on /*! Calls startAnimation() or stopAnimation(), depending on animatio
animationIsStarted(). */ nIsStarted(). */
void toggleAnimation() { if (animationIsStarted()) stopAnima void toggleAnimation() { if (animationIsStarted()) stopAnimation();
tion(); else startAnimation(); }; else startAnimation(); }
//@} //@}
public: public:
Q_SIGNALS: Q_SIGNALS:
/*! Signal emitted by the default init() method. /*! Signal emitted by the default init() method.
Connect this signal to the methods that need to be called to initial ize your viewer or overload init(). */ Connect this signal to the methods that need to be called to initial ize your viewer or overload init(). */
void viewerInitialized(); void viewerInitialized();
/*! Signal emitted by the default draw() method. /*! Signal emitted by the default draw() method.
skipping to change at line 725 skipping to change at line 725
\code \code
QString myViewer::helpString() const QString myViewer::helpString() const
{ {
QString text("<h2>M y V i e w e r</h2>"); QString text("<h2>M y V i e w e r</h2>");
text += "Displays a <b>Scene</b> using OpenGL. Move the camera using the mouse."; text += "Displays a <b>Scene</b> using OpenGL. Move the camera using the mouse.";
return text; return text;
} }
\endcode \endcode
See also mouseString() and keyboardString(). */ See also mouseString() and keyboardString(). */
virtual QString helpString() const { return tr("No help available.") ; }; virtual QString helpString() const { return tr("No help available.") ; }
virtual QString mouseString() const; virtual QString mouseString() const;
virtual QString keyboardString() const; virtual QString keyboardString() const;
#ifndef DOXYGEN #ifndef DOXYGEN
/*! This method is deprecated, use mouseString() instead. */ /*! This method is deprecated, use mouseString() instead. */
virtual QString mouseBindingsString () const { return mouseString(); } virtual QString mouseBindingsString () const { return mouseString(); }
/*! This method is deprecated, use keyboardString() instead. */ /*! This method is deprecated, use keyboardString() instead. */
virtual QString shortcutBindingsString () const { return keyboardStr ing(); } virtual QString shortcutBindingsString () const { return keyboardStr ing(); }
#endif #endif
public Q_SLOTS: public Q_SLOTS:
virtual void help(); virtual void help();
virtual void aboutQGLViewer(); virtual void aboutQGLViewer();
protected: protected:
/*! Returns a pointer to the help widget. /*! Returns a pointer to the help widget.
Use this only if you want to directly modify the help widget. Otherw ise use helpString(), Use this only if you want to directly modify the help widget. Otherw ise use helpString(),
setKeyDescription() and setMouseBindingDescription() to customize th e text displayed in the help setKeyDescription() and setMouseBindingDescription() to customize th e text displayed in the help
window tabs. */ window tabs. */
QTabWidget* helpWidget() { return helpWidget_; } QTabWidget* helpWidget() { return helpWidget_; }
//@} //@}
skipping to change at line 773 skipping to change at line 773
Note that initializeGL() modifies the standard OpenGL context. These values can be restored back Note that initializeGL() modifies the standard OpenGL context. These values can be restored back
in this method. in this method.
\attention You should not call updateGL() (or any method that calls it) in this method, as it will \attention You should not call updateGL() (or any method that calls it) in this method, as it will
result in an infinite loop. The different QGLViewer set methods (set AxisIsDrawn(), result in an infinite loop. The different QGLViewer set methods (set AxisIsDrawn(),
setFPSIsDisplayed()...) are protected against this problem and can s afely be called. setFPSIsDisplayed()...) are protected against this problem and can s afely be called.
\note All the OpenGL specific initializations must be done in this m ethod: the OpenGL context is \note All the OpenGL specific initializations must be done in this m ethod: the OpenGL context is
not yet available in your viewer constructor. */ not yet available in your viewer constructor. */
virtual void init() { Q_EMIT viewerInitialized(); }; virtual void init() { Q_EMIT viewerInitialized(); }
virtual void paintGL(); virtual void paintGL();
virtual void preDraw(); virtual void preDraw();
virtual void preDrawStereo(bool leftBuffer=true); virtual void preDrawStereo(bool leftBuffer=true);
/*! The core method of the viewer, that draws the scene. /*! The core method of the viewer, that draws the scene.
If you build a class that inherits from QGLViewer, this is the metho d you want to overload. See If you build a class that inherits from QGLViewer, this is the metho d you want to overload. See
the <a href="../examples/simpleViewer.html">simpleViewer example</a> for an illustration. the <a href="../examples/simpleViewer.html">simpleViewer example</a> for an illustration.
The camera modelView matrix set in preDraw() converts from the world to the camera coordinate The camera modelView matrix set in preDraw() converts from the world to the camera coordinate
systems. Vertices given in draw() can then be considered as being gi ven in the world coordinate systems. Vertices given in draw() can then be considered as being gi ven in the world coordinate
system. The camera is moved in this world using the mouse. This repr esentation is much more system. The camera is moved in this world using the mouse. This repr esentation is much more
intuitive than the default camera-centric OpenGL standard. intuitive than the default camera-centric OpenGL standard.
\attention The \c GL_PROJECTION matrix should not be modified by thi s method, to correctly display \attention The \c GL_PROJECTION matrix should not be modified by thi s method, to correctly display
visual hints (axis, grid, FPS...) in postDraw(). Use push/pop or cal l visual hints (axis, grid, FPS...) in postDraw(). Use push/pop or cal l
camera()->loadProjectionMatrix() at the end of draw() if you need to change the projection matrix camera()->loadProjectionMatrix() at the end of draw() if you need to change the projection matrix
(unlikely). On the other hand, the \c GL_MODELVIEW matrix can be mod ified and left in a arbitrary (unlikely). On the other hand, the \c GL_MODELVIEW matrix can be mod ified and left in a arbitrary
state. */ state. */
virtual void draw() {}; virtual void draw() {}
virtual void fastDraw(); virtual void fastDraw();
virtual void postDraw(); virtual void postDraw();
//@} //@}
/*! @name Mouse, keyboard and event handlers */ /*! @name Mouse, keyboard and event handlers */
//@{ //@{
protected: protected:
virtual void mousePressEvent(QMouseEvent *); virtual void mousePressEvent(QMouseEvent *);
virtual void mouseMoveEvent(QMouseEvent *); virtual void mouseMoveEvent(QMouseEvent *);
virtual void mouseReleaseEvent(QMouseEvent *); virtual void mouseReleaseEvent(QMouseEvent *);
skipping to change at line 822 skipping to change at line 822
/*! @name Object selection */ /*! @name Object selection */
//@{ //@{
public: public:
/*! Returns the name (an integer value) of the entity that was last selected by select(). This /*! Returns the name (an integer value) of the entity that was last selected by select(). This
value is set by endSelection(). See the select() documentation for d etails. value is set by endSelection(). See the select() documentation for d etails.
As a convention, this method returns -1 if the selectBuffer() was em pty, meaning that no object As a convention, this method returns -1 if the selectBuffer() was em pty, meaning that no object
was selected. was selected.
Return value is -1 before the first call to select(). This value is modified using setSelectedName(). */ Return value is -1 before the first call to select(). This value is modified using setSelectedName(). */
int selectedName() const { return selectedObjectId_; }; int selectedName() const { return selectedObjectId_; }
/*! Returns the selectBuffer() size. /*! Returns the selectBuffer() size.
See the select() documentation for details. Use setSelectBufferSize( ) to change this value. See the select() documentation for details. Use setSelectBufferSize( ) to change this value.
Default value is 4000 (i.e. 1000 objects in selection region, since each object pushes 4 values). Default value is 4000 (i.e. 1000 objects in selection region, since each object pushes 4 values).
This size should be over estimated to prevent a buffer overflow when many objects are drawn under This size should be over estimated to prevent a buffer overflow when many objects are drawn under
the mouse cursor. */ the mouse cursor. */
int selectBufferSize() const { return selectBufferSize_; }; int selectBufferSize() const { return selectBufferSize_; }
/*! Returns the width (in pixels) of a selection frustum, centered o n the mouse cursor, that is /*! Returns the width (in pixels) of a selection frustum, centered o n the mouse cursor, that is
used to select objects. used to select objects.
The height of the selection frustum is defined by selectRegionHeight (). The height of the selection frustum is defined by selectRegionHeight ().
The objects that will be drawn in this region by drawWithNames() wil l be recorded in the The objects that will be drawn in this region by drawWithNames() wil l be recorded in the
selectBuffer(). endSelection() then analyzes this buffer and setSele ctedName() to the name of the selectBuffer(). endSelection() then analyzes this buffer and setSele ctedName() to the name of the
closest object. See the gluPickMatrix() documentation for details. closest object. See the gluPickMatrix() documentation for details.
The default value is 3, which is adapted to standard applications. A smaller value results in a The default value is 3, which is adapted to standard applications. A smaller value results in a
more precise selection but the user has to be careful for small feat ure selection. more precise selection but the user has to be careful for small feat ure selection.
See the <a href="../examples/multiSelect.html">multiSelect example</ a> for an illustration. */ See the <a href="../examples/multiSelect.html">multiSelect example</ a> for an illustration. */
int selectRegionWidth() const { return selectRegionWidth_; }; int selectRegionWidth() const { return selectRegionWidth_; }
/*! See the selectRegionWidth() documentation. Default value is 3 pi xels. */ /*! See the selectRegionWidth() documentation. Default value is 3 pi xels. */
int selectRegionHeight() const { return selectRegionHeight_; }; int selectRegionHeight() const { return selectRegionHeight_; }
/*! Returns a pointer to an array of \c GLuint. /*! Returns a pointer to an array of \c GLuint.
This buffer is used by the \c GL_SELECT mode in select() to perform object selection. The buffer This buffer is used by the \c GL_SELECT mode in select() to perform object selection. The buffer
size can be modified using setSelectBufferSize(). If you overload en dSelection(), you will analyze size can be modified using setSelectBufferSize(). If you overload en dSelection(), you will analyze
the content of this buffer. See the \c glSelectBuffer() man page for details. */ the content of this buffer. See the \c glSelectBuffer() man page for details. */
GLuint* selectBuffer() { return selectBuffer_; }; GLuint* selectBuffer() { return selectBuffer_; }
public Q_SLOTS: public Q_SLOTS:
virtual void select(const QMouseEvent* event); virtual void select(const QMouseEvent* event);
virtual void select(const QPoint& point); virtual void select(const QPoint& point);
void setSelectBufferSize(int size); void setSelectBufferSize(int size);
/*! Sets the selectRegionWidth(). */ /*! Sets the selectRegionWidth(). */
void setSelectRegionWidth(int width) { selectRegionWidth_ = void setSelectRegionWidth(int width) { selectRegionWidth_ = width; }
width; }; /*! Sets the selectRegionHeight(). */
/*! Sets the selectRegionHeight(). */ void setSelectRegionHeight(int height) { selectRegionHeight_ = heigh
void setSelectRegionHeight(int height) { selectRegionHeight_ t; }
= height; }; /*! Set the selectedName() value.
/*! Set the selectedName() value.
Used in endSelection() during a selection. You should only c all this method if you overload the Used in endSelection() during a selection. You should only c all this method if you overload the
endSelection() method. */ endSelection() method. */
void setSelectedName(int id) { selectedObjectId_=id; }; void setSelectedName(int id) { selectedObjectId_=id; }
protected: protected:
virtual void beginSelection(const QPoint& point); virtual void beginSelection(const QPoint& point);
/*! This method is called by select() and should draw selectable ent ities. /*! This method is called by select() and should draw selectable ent ities.
Default implementation is empty. Overload and draw the different ele ments of your scene you want Default implementation is empty. Overload and draw the different ele ments of your scene you want
to be able to select. The default select() implementation relies on the \c GL_SELECT, and requires to be able to select. The default select() implementation relies on the \c GL_SELECT, and requires
that each selectable element is drawn within a \c glPushName() - \c glPopName() block. A typical that each selectable element is drawn within a \c glPushName() - \c glPopName() block. A typical
usage would be (see the <a href="../examples/select.html">select exa mple</a>): usage would be (see the <a href="../examples/select.html">select exa mple</a>):
\code \code
void Viewer::drawWithNames() { void Viewer::drawWithNames() {
for (int i=0; i<nbObjects; ++i) { for (int i=0; i<nbObjects; ++i) {
glPushName(i); glPushName(i);
object(i)->draw(); object(i)->draw();
glPopName(); glPopName();
} }
} }
\endcode \endcode
The resulting selected name is computed by endSelection(), which set SelectedName() to the integer The resulting selected name is computed by endSelection(), which set SelectedName() to the integer
id pushed by this method (a value of -1 means no selection). Use sel ectedName() to update your id pushed by this method (a value of -1 means no selection). Use sel ectedName() to update your
selection, probably in the postSelection() method. selection, probably in the postSelection() method.
\attention If your selected objects are points, do not use \c glBegi n(GL_POINTS); and \c glVertex3fv() \attention If your selected objects are points, do not use \c glBegi n(GL_POINTS); and \c glVertex3fv()
in the above \c draw() method (not compatible with raster mode): use \c glRasterPos3fv() instead. */ in the above \c draw() method (not compatible with raster mode): use \c glRasterPos3fv() instead. */
virtual void drawWithNames() {}; virtual void drawWithNames() {}
virtual void endSelection(const QPoint& point); virtual void endSelection(const QPoint& point);
/*! This method is called at the end of the select() procedure. It s hould finalize the selection /*! This method is called at the end of the select() procedure. It s hould finalize the selection
process and update the data structure/interface/computation/display. .. according to the newly process and update the data structure/interface/computation/display. .. according to the newly
selected entity. selected entity.
The default implementation is empty. Overload this method if needed, and use selectedName() to The default implementation is empty. Overload this method if needed, and use selectedName() to
retrieve the selected entity name (returns -1 if no object was selec ted). See the <a retrieve the selected entity name (returns -1 if no object was selec ted). See the <a
href="../examples/select.html">select example</a> for an illustratio n. */ href="../examples/select.html">select example</a> for an illustratio n. */
virtual void postSelection(const QPoint& point) { Q_UNUSED(point); } ; virtual void postSelection(const QPoint& point) { Q_UNUSED(point); }
//@} //@}
/*! @name Keyboard customization */ /*! @name Keyboard customization */
//@{ //@{
protected: protected:
/*! Defines the different actions that can be associated with a keyb oard shortcut using /*! Defines the different actions that can be associated with a keyb oard shortcut using
setShortcut(). setShortcut().
See the <a href="../keyboard.html">keyboard page</a> for details. */ See the <a href="../keyboard.html">keyboard page</a> for details. */
enum KeyboardAction { DRAW_AXIS, DRAW_GRID, DISPLAY_FPS, ENABLE_TEXT , EXIT_VIEWER, enum KeyboardAction { DRAW_AXIS, DRAW_GRID, DISPLAY_FPS, ENABLE_TEXT , EXIT_VIEWER,
SAVE_SCREENSHOT, CAMERA_MODE, FULL_SCREEN, STEREO, ANIMATION SAVE_SCREENSHOT, CAMERA_MO
, HELP, EDIT_CAMERA, DE, FULL_SCREEN, STEREO, ANIMATION, HELP, EDIT_CAMERA,
MOVE_CAMERA_LEFT, MOVE_CAMERA_RIGHT, MOVE_CAMERA_UP, MOVE_CA MOVE_CAMERA_LEFT, MOVE_CAM
MERA_DOWN, ERA_RIGHT, MOVE_CAMERA_UP, MOVE_CAMERA_DOWN,
INCREASE_FLYSPEED, DECREASE_FLYSPEED, SNAPSHOT_TO_CLIPBOARD INCREASE_FLYSPEED, DECREAS
}; E_FLYSPEED, SNAPSHOT_TO_CLIPBOARD };
public: public:
unsigned int shortcut(KeyboardAction action) const; unsigned int shortcut(KeyboardAction action) const;
#ifndef DOXYGEN #ifndef DOXYGEN
// QGLViewer 1.x // QGLViewer 1.x
int keyboardAccelerator(KeyboardAction action) const; int keyboardAccelerator(KeyboardAction action) const;
Qt::Key keyFrameKey(int index) const; Qt::Key keyFrameKey(int index) const;
Qt::KeyboardModifiers playKeyFramePathStateKey() const; Qt::KeyboardModifiers playKeyFramePathStateKey() const;
// QGLViewer 2.0 without Qt4 support // QGLViewer 2.0 without Qt4 support
Qt::KeyboardModifiers addKeyFrameStateKey() const; Qt::KeyboardModifiers addKeyFrameStateKey() const;
Qt::KeyboardModifiers playPathStateKey() const; Qt::KeyboardModifiers playPathStateKey() const;
#endif #endif
Qt::Key pathKey(int index) const; Qt::Key pathKey(int index) const;
Qt::KeyboardModifiers addKeyFrameKeyboardModifiers() const; Qt::KeyboardModifiers addKeyFrameKeyboardModifiers() const;
Qt::KeyboardModifiers playPathKeyboardModifiers() const; Qt::KeyboardModifiers playPathKeyboardModifiers() const;
public Q_SLOTS: public Q_SLOTS:
void setShortcut(KeyboardAction action, unsigned int key); void setShortcut(KeyboardAction action, unsigned int key);
#ifndef DOXYGEN #ifndef DOXYGEN
void setKeyboardAccelerator(KeyboardAction action, int key); void setKeyboardAccelerator(KeyboardAction action, int key);
#endif #endif
void setKeyDescription(int key, QString description); void setKeyDescription(int key, QString description);
void clearShortcuts();
// Key Frames shortcut keys // Key Frames shortcut keys
#ifndef DOXYGEN #ifndef DOXYGEN
// QGLViewer 1.x compatibility methods // QGLViewer 1.x compatibility methods
virtual void setKeyFrameKey(int index, int key); virtual void setKeyFrameKey(int index, int key);
virtual void setPlayKeyFramePathStateKey(int buttonState); virtual void setPlayKeyFramePathStateKey(int buttonState);
// QGLViewer 2.0 without Qt4 support // QGLViewer 2.0 without Qt4 support
virtual void setPlayPathStateKey(int buttonState); virtual void setPlayPathStateKey(int buttonState);
virtual void setAddKeyFrameStateKey(int buttonState); virtual void setAddKeyFrameStateKey(int buttonState);
#endif #endif
virtual void setPathKey(int key, int index = 0); virtual void setPathKey(int key, int index = 0);
virtual void setPlayPathKeyboardModifiers(Qt::KeyboardModifiers mod virtual void setPlayPathKeyboardModifiers(Qt::KeyboardModifiers modi
ifiers); fiers);
virtual void setAddKeyFrameKeyboardModifiers(Qt::KeyboardModifiers virtual void setAddKeyFrameKeyboardModifiers(Qt::KeyboardModifiers m
modifiers); odifiers);
//@} //@}
/*! @name Mouse customization */ /*! @name Mouse customization */
//@{ //@{
protected: protected:
/*! Defines the different mouse handlers: camera() or manipulatedFra me(). /*! Defines the different mouse handlers: camera() or manipulatedFra me().
Used by setMouseBinding(), setMouseBinding(int, ClickAction, bool, i nt) and setWheelBinding() to Used by setMouseBinding(), setMouseBinding(int, ClickAction, bool, i nt) and setWheelBinding() to
define which handler receives the mouse events. */ define which handler receives the mouse events. */
enum MouseHandler { CAMERA, FRAME }; enum MouseHandler { CAMERA, FRAME };
/*! Defines the possible actions that can be binded to a mouse click using /*! Defines the possible actions that can be binded to a mouse click using
setMouseBinding(int,ClickAction,bool,int). setMouseBinding(int,ClickAction,bool,int).
See the <a href="../mouse.html">mouse page</a> for details. */ See the <a href="../mouse.html">mouse page</a> for details. */
enum ClickAction { NO_CLICK_ACTION, ZOOM_ON_PIXEL, ZOOM_TO_FIT, SELE CT, RAP_FROM_PIXEL, RAP_IS_CENTER, enum ClickAction { NO_CLICK_ACTION, ZOOM_ON_PIXEL, ZOOM_TO_FIT, SELE CT, RAP_FROM_PIXEL, RAP_IS_CENTER,
CENTER_FRAME, CENTER_SCENE, SHOW_ENTIRE_SCENE, ALIGN_FRAME, ALIGN_CAMERA }; CENTER_FRAME, CENTER_SCENE, SHOW_ ENTIRE_SCENE, ALIGN_FRAME, ALIGN_CAMERA };
#ifndef DOXYGEN #ifndef DOXYGEN
// So that it can be used in ManipulatedFrame and ManipulatedCameraF rame. // So that it can be used in ManipulatedFrame and ManipulatedCameraF rame.
public: public:
#endif #endif
/*! Defines the possible actions that can be binded to a mouse motio n (a click, followed by a /*! Defines the possible actions that can be binded to a mouse motio n (a click, followed by a
mouse displacement). mouse displacement).
These actions may be binded to the camera() or to the manipulatedFra me() (see QGLViewer::MouseHandler) using These actions may be binded to the camera() or to the manipulatedFra me() (see QGLViewer::MouseHandler) using
setMouseBinding(). */ setMouseBinding(). */
enum MouseAction { NO_MOUSE_ACTION, enum MouseAction { NO_MOUSE_ACTION,
ROTATE, ZOOM, TRANSLATE, ROTATE, ZOOM, TRANSLATE,
MOVE_FORWARD, LOOK_AROUND, MOVE_BACKWARD, MOVE_FORWARD, LOOK_AROUND, MOVE_B
SCREEN_ROTATE, ROLL, DRIVE, ACKWARD,
SCREEN_TRANSLATE, ZOOM_ON_REGION }; SCREEN_ROTATE, ROLL, DRIVE,
SCREEN_TRANSLATE, ZOOM_ON_REGION
};
#ifdef DOXYGEN #ifdef DOXYGEN
public: public:
#endif #endif
#ifndef DOXYGEN
MouseAction mouseAction(int state) const; MouseAction mouseAction(int state) const;
int mouseHandler(int state) const; int mouseHandler(int state) const;
int mouseButtonState(MouseHandler handler, MouseAction action, bool withConstraint=true) const; int mouseButtonState(MouseHandler handler, MouseAction action, bool withConstraint=true) const;
ClickAction clickAction(int state, bool doubleClick, Qt::MouseButtons b ClickAction clickAction(int state, bool doubleClick, Qt::MouseButton
uttonsBefore) const; s buttonsBefore) const;
void getClickButtonState(ClickAction action, int& state, bool& doubleCl void getClickButtonState(ClickAction action, int& state, bool& doubl
ick, Qt::MouseButtons& buttonsBefore) const; eClick, Qt::MouseButtons& buttonsBefore) const;
#endif
MouseAction mouseAction(Qt::KeyboardModifiers modifiers, Qt::MouseBu
ttons buttons) const;
int mouseHandler(Qt::KeyboardModifiers modifiers, Qt::MouseButtons b
uttons) const;
ClickAction clickAction(Qt::KeyboardModifiers modifiers, Qt::MouseBu
ttons buttons, bool doubleClick, Qt::MouseButtons buttonsBefore) const;
Qt::MouseButtons mouseButtons(MouseHandler handler, MouseAction acti
on, bool withConstraint=true) const;
Qt::KeyboardModifiers keyboardModifiers(MouseHandler handler, MouseA
ction action, bool withConstraint=true) const;
void getClickActionState(ClickAction action, Qt::KeyboardModifiers&
modifiers, Qt::MouseButtons& buttons, bool& doubleClick, Qt::MouseButtons&
buttonsBefore) const;
MouseAction wheelAction(Qt::KeyboardModifiers modifiers) const; MouseAction wheelAction(Qt::KeyboardModifiers modifiers) const;
int wheelHandler(Qt::KeyboardModifiers modifiers) const; int wheelHandler(Qt::KeyboardModifiers modifiers) const;
int wheelButtonState(MouseHandler handler, MouseAction action, bool withConstraint=true) const; int wheelButtonState(MouseHandler handler, MouseAction action, bool withConstraint=true) const;
public Q_SLOTS: public Q_SLOTS:
void setMouseBinding(int state, MouseHandler handler, MouseAction actio
n, bool withConstraint=true);
#if QT_VERSION < 0x030000
// Two slots cannot have the same name or two default parameters with Q
t 2.3.
public:
#endif
void setMouseBinding(int state, ClickAction action, bool doubleClick=fa
lse, Qt::MouseButtons buttonsBefore=Qt::NoButton);
#if QT_VERSION < 0x030000
public Q_SLOTS:
#endif
void setMouseBindingDescription(int state, QString description, bool do
ubleClick=false, Qt::MouseButtons buttonsBefore=Qt::NoButton);
void setWheelBinding(Qt::KeyboardModifiers modifiers, MouseHandler hand
ler, MouseAction action, bool withConstraint=true);
void setHandlerKeyboardModifiers(MouseHandler handler, Qt::KeyboardModi
fiers modifiers);
#ifndef DOXYGEN #ifndef DOXYGEN
void setHandlerStateKey(MouseHandler handler, int buttonState); void setMouseBinding(int state, MouseHandler handler, MouseAction ac
void setMouseStateKey(MouseHandler handler, int buttonState); tion, bool withConstraint=true);
void setMouseBinding(int state, ClickAction action, bool doubleClick
=false, Qt::MouseButtons buttonsBefore=Qt::NoButton);
void setMouseBindingDescription(int state, QString description, bool
doubleClick=false, Qt::MouseButtons buttonsBefore=Qt::NoButton);
#endif
void setMouseBinding(Qt::KeyboardModifiers modifiers, Qt::MouseButto
ns buttons, MouseHandler handler, MouseAction action, bool withConstraint=t
rue);
void setMouseBinding(Qt::KeyboardModifiers modifiers, Qt::MouseButto
ns buttons, ClickAction action, bool doubleClick=false, Qt::MouseButtons bu
ttonsBefore=Qt::NoButton);
void setMouseBindingDescription(Qt::KeyboardModifiers modifiers, Qt:
:MouseButtons buttons, QString description, bool doubleClick=false, Qt::Mou
seButtons buttonsBefore=Qt::NoButton);
void setWheelBinding(Qt::KeyboardModifiers modifiers, MouseHandler h
andler, MouseAction action, bool withConstraint=true);
void setHandlerKeyboardModifiers(MouseHandler handler, Qt::KeyboardM
odifiers modifiers);
void clearMouseBindings();
#ifndef DOXYGEN
void setHandlerStateKey(MouseHandler handler, int buttonState);
void setMouseStateKey(MouseHandler handler, int buttonState);
#endif #endif
private: private:
static QString mouseActionString(QGLViewer::MouseAction ma); static QString mouseActionString(QGLViewer::MouseAction ma);
static QString clickActionString(QGLViewer::ClickAction ca); static QString clickActionString(QGLViewer::ClickAction ca);
//@} //@}
/*! @name State persistence */ /*! @name State persistence */
//@{ //@{
public: public:
QString stateFileName() const; QString stateFileName() const;
virtual QDomElement domElement(const QString& name, QDomDocument& do cument) const; virtual QDomElement domElement(const QString& name, QDomDocument& do cument) const;
public Q_SLOTS: public Q_SLOTS:
virtual void initFromDOMElement(const QDomElement& element); virtual void initFromDOMElement(const QDomElement& element);
virtual void saveStateToFile(); // cannot be const because o virtual void saveStateToFile(); // cannot be const because of QMessa
f QMessageBox geBox
virtual bool restoreStateFromFile(); virtual bool restoreStateFromFile();
/*! Defines the stateFileName() used by saveStateToFile() an d restoreStateFromFile(). /*! Defines the stateFileName() used by saveStateToFile() and restor eStateFromFile().
The file name can have an optional prefix directory (no pref ix meaning current directory). If the The file name can have an optional prefix directory (no pref ix meaning current directory). If the
directory does not exist, it will be created by saveStateToF ile(). directory does not exist, it will be created by saveStateToF ile().
\code \code
// Name depends on the displayed 3D model. Saved in current directory. // Name depends on the displayed 3D model. Saved in current directory.
setStateFileName(3DModelName() + ".xml"); setStateFileName(3DModelName() + ".xml");
// Files are stored in a dedicated directory under user's ho me directory. // Files are stored in a dedicated directory under user's ho me directory.
setStateFileName(QDir::homeDirPath + "/.config/myApp.xml"); setStateFileName(QDir::homeDirPath + "/.config/myApp.xml");
\endcode */ \endcode */
void setStateFileName(const QString& name) { stateFileName_ = name; }; void setStateFileName(const QString& name) { stateFileName_ = name; }
#ifndef DOXYGEN #ifndef DOXYGEN
void saveToFile(const QString& fileName=QString::null); void saveToFile(const QString& fileName=QString::null);
bool restoreFromFile(const QString& fileName=QString::null); bool restoreFromFile(const QString& fileName=QString::null);
#endif #endif
private: private:
static void saveStateToFileForAllViewers(); static void saveStateToFileForAllViewers();
//@} //@}
/*! @name QGLViewer pool */ /*! @name QGLViewer pool */
//@{ //@{
public: public:
/*! Returns a \c QList that contains pointers to all the created QGL Viewers. /*! Returns a \c QList that contains pointers to all the created QGL Viewers.
Note that this list may contain \c NULL pointers if the associated viewer has been deleted. Note that this list may contain \c NULL pointers if the asso ciated viewer has been deleted.
Can be useful to apply a method or to connect a signal to all the vi ewers: Can be useful to apply a method or to connect a signal to all the vi ewers:
\code \code
foreach (QGLViewer* viewer, QGLViewer::QGLViewerPool()) foreach (QGLViewer* viewer, QGLViewer::QGLViewerPool())
connect(myObject, SIGNAL(IHaveChangedSignal()), viewer, SLOT(updat eGL())); connect(myObject, SIGNAL(IHaveChangedSignal()), viewer, SLOT(updat e()));
\endcode \endcode
\attention With Qt version 3, this method returns a \c QPtrList inst ead. Use a \c QPtrListIterator \attention With Qt version 3, this method returns a \c QPtrList inst ead. Use a \c QPtrListIterator
to iterate on the list instead.*/ to iterate on the list instead.*/
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
static const QList<QGLViewer*>& QGLViewerPool() { return QGLViewer:: QGLViewerPool_; }; static const QList<QGLViewer*>& QGLViewerPool() { return QGLViewer:: QGLViewerPool_; }
#else #else
static const QPtrList<QGLViewer>& QGLViewerPool() { return QGLViewer ::QGLViewerPool_; }; static const QPtrList<QGLViewer>& QGLViewerPool() { return QGLViewer ::QGLViewerPool_; }
#endif #endif
/*! Returns the index of the QGLViewer \p viewer in the QGLViewerPoo l(). This index in unique and /*! Returns the index of the QGLViewer \p viewer in the QGLViewerPoo l(). This index in unique and
can be used to identify the different created QGLViewers (see stateF ileName() for an application can be used to identify the different created QGLViewers (see stateF ileName() for an application
example). example).
When a QGLViewer is deleted, the QGLViewers' indexes are preserved a nd NULL is set for that index. When a QGLViewer is deleted, the QGLViewers' indexes are preserved a nd NULL is set for that index.
When a QGLViewer is created, it is placed in the first available po When a QGLViewer is created, it is placed in the first avail
sition in that list. able position in that list.
Returns -1 if the QGLViewer could not be found (which should not be Returns -1 if the QGLViewer could not be found (which should
possible). */ not be possible). */
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
static int QGLViewerIndex(const QGLViewer* const viewer) { return QG LViewer::QGLViewerPool_.indexOf(const_cast<QGLViewer*>(viewer)); }; static int QGLViewerIndex(const QGLViewer* const viewer) { return QG LViewer::QGLViewerPool_.indexOf(const_cast<QGLViewer*>(viewer)); }
#else #else
static int QGLViewerIndex(const QGLViewer* const viewer) { return QG LViewer::QGLViewerPool_.findRef(viewer); }; static int QGLViewerIndex(const QGLViewer* const viewer) { return QG LViewer::QGLViewerPool_.findRef(viewer); }
#endif #endif
//@} //@}
#ifndef DOXYGEN #ifndef DOXYGEN
/*! @name Visual hints */ /*! @name Visual hints */
//@{ //@{
public: public:
virtual void setVisualHintsMask(int mask, int delay = 2000); virtual void setVisualHintsMask(int mask, int delay = 2000);
virtual void drawVisualHints(); virtual void drawVisualHints();
public Q_SLOTS: public Q_SLOTS:
virtual void resetVisualHints(); virtual void resetVisualHints();
//@} //@}
#endif #endif
private Q_SLOTS: private Q_SLOTS:
// Patch for a Qt bug with fullScreen on startup // Patch for a Qt bug with fullScreen on startup
void delayedFullScreen() { move(prevPos_); setFullSc void delayedFullScreen() { move(prevPos_); setFullScreen(); }
reen(); }; void hideMessage();
void hideMessage();
private: private:
// Copy constructor and operator= are declared private and undefined // Copy constructor and operator= are declared private and undefined
// Prevents everyone from trying to use them // Prevents everyone from trying to use them
QGLViewer(const QGLViewer& v); QGLViewer(const QGLViewer& v);
QGLViewer& operator=(const QGLViewer& v); QGLViewer& operator=(const QGLViewer& v);
// Set parameters to their default values. Called by the constructor s. // Set parameters to their default values. Called by the constructor s.
void defaultConstructor(); void defaultConstructor();
skipping to change at line 1177 skipping to change at line 1187
GLuint* selectBuffer_; GLuint* selectBuffer_;
int selectedObjectId_; int selectedObjectId_;
// V i s u a l h i n t s // V i s u a l h i n t s
int visualHint_; int visualHint_;
// S h o r t c u t k e y s // S h o r t c u t k e y s
void setDefaultShortcuts(); void setDefaultShortcuts();
QString cameraPathKeysString() const; QString cameraPathKeysString() const;
QMap<KeyboardAction, QString> keyboardActionDescription_; QMap<KeyboardAction, QString> keyboardActionDescription_;
QMap<KeyboardAction, unsigned int> keyboardBinding_; QMap<KeyboardAction, unsigned int> keyboardBinding_;
QMap<int, QString> keyDescription_; QMap<int, QString> keyDescription_;
// K e y F r a m e s s h o r t c u t s // K e y F r a m e s s h o r t c u t s
QMap<Qt::Key, int> pathIndex_; QMap<Qt::Key, int> pathIndex_;
Qt::KeyboardModifiers addKeyFrameKeyboardModifiers_, playPathKeyboardMo difiers_; Qt::KeyboardModifiers addKeyFrameKeyboardModifiers_, playPathKeyboar dModifiers_;
// B u f f e r T e x t u r e // B u f f e r T e x t u r e
GLuint bufferTextureId_; GLuint bufferTextureId_;
float bufferTextureMaxU_, bufferTextureMaxV_; float bufferTextureMaxU_, bufferTextureMaxV_;
int bufferTextureWidth_, bufferTextureHeight_; int bufferTextureWidth_, bufferTextureHeight_;
unsigned int previousBufferTextureFormat_; unsigned int previousBufferTextureFormat_;
int previousBufferTextureInternalFormat_; int previousBufferTextureInternalFormat_;
#ifndef DOXYGEN #ifndef DOXYGEN
// M o u s e a c t i o n s // M o u s e a c t i o n s
struct MouseActionPrivate { struct MouseActionPrivate {
MouseHandler handler; MouseHandler handler;
MouseAction action; MouseAction action;
bool withConstraint; bool withConstraint;
}; };
// C l i c k a c t i o n s // M o u s e b i n d i n g s
struct ClickActionPrivate { struct MouseBindingPrivate {
Qt::KeyboardModifiers modifiers; const Qt::KeyboardModifiers modifiers;
Qt::MouseButtons button; const Qt::MouseButtons buttons;
bool doubleClick;
Qt::MouseButtons buttonsBefore; // only defined when doubleClick is MouseBindingPrivate(Qt::KeyboardModifiers m, Qt::MouseButton
true s b)
: modifiers(m), buttons(b) {}
// This sort order is used in mouseString() to display sorte
d mouse bindings
bool operator<(const MouseBindingPrivate& mbp) const
{
if (modifiers != mbp.modifiers)
return modifiers < mbp.modifiers;
else
return buttons < mbp.buttons;
}
};
// C l i c k b i n d i n g s
struct ClickBindingPrivate {
const Qt::KeyboardModifiers modifiers;
const Qt::MouseButtons buttons;
const bool doubleClick;
const Qt::MouseButtons buttonsBefore; // only defined when d
oubleClick is true
ClickBindingPrivate(Qt::KeyboardModifiers m, Qt::MouseButton
s b, bool dc, Qt::MouseButtons bb)
: modifiers(m), buttons(b), doubleClick(dc), buttons
Before(bb) {}
// This sort order in used in mouseString() to displays sort // This sort order is used in mouseString() to display sorte
ed mouse bindings d mouse bindings
bool operator<(const ClickActionPrivate& cap) const bool operator<(const ClickBindingPrivate& cbp) const
{ {
if (buttonsBefore != cap.buttonsBefore) if (buttonsBefore != cbp.buttonsBefore)
return buttonsBefore < cap.buttonsBefore; return buttonsBefore < cbp.buttonsBefore;
else else
if (modifiers != cap.modifiers) if (modifiers != cbp.modifiers)
return modifiers < cap.modifiers; return modifiers < cbp.modifiers;
else else
if (button != cap.button) if (buttons != cbp.buttons)
return button < cap.button; return buttons < cbp.buttons
;
else else
return !doubleClick && cap.d oubleClick; return !doubleClick && cbp.d oubleClick;
} }
}; };
#endif #endif
static QString formatClickActionPrivate(ClickActionPrivate cap); static QString formatClickActionPrivate(ClickBindingPrivate cbp);
QMap<ClickActionPrivate, QString> mouseDescription_; QMap<ClickBindingPrivate, QString> mouseDescription_;
void setDefaultMouseBindings(); void setDefaultMouseBindings();
void performClickAction(ClickAction ca, const QMouseEvent* const e); void performClickAction(ClickAction ca, const QMouseEvent* const e);
QMap<int, MouseActionPrivate> mouseBinding_; QMap<MouseBindingPrivate, MouseActionPrivate> mouseBinding_;
QMap<Qt::KeyboardModifiers, MouseActionPrivate> wheelBinding_; QMap<Qt::KeyboardModifiers, MouseActionPrivate> wheelBinding_;
QMap<ClickActionPrivate, ClickAction> clickBinding_; QMap<ClickBindingPrivate, ClickAction> clickBinding_;
// S n a p s h o t s // S n a p s h o t s
void initializeSnapshotFormats(); void initializeSnapshotFormats();
QImage frameBufferSnapshot(); QImage frameBufferSnapshot();
QString snapshotFileName_, snapshotFormat_; QString snapshotFileName_, snapshotFormat_;
int snapshotCounter_, snapshotQuality_; int snapshotCounter_, snapshotQuality_;
TileRegion* tileRegion_; TileRegion* tileRegion_;
// Q G L V i e w e r p o o l // Q G L V i e w e r p o o l
#if QT_VERSION >= 0x040000 #if QT_VERSION >= 0x040000
static QList<QGLViewer*> QGLViewerPool_; static QList<QGLViewer*> QGLViewerPool_;
#else #else
static QPtrList<QGLViewer> QGLViewerPool_; static QPtrList<QGLViewer> QGLViewerPool_;
#endif #endif
// S t a t e F i l e // S t a t e F i l e
QString stateFileName_; QString stateFileName_;
// H e l p w i n d o w // H e l p w i n d o w
QTabWidget* helpWidget_; QTabWidget* helpWidget_;
// I n t e r n a l d e b u g
bool updateGLOK_;
}; };
#endif // QGLVIEWER_QGLVIEWER_H #endif // QGLVIEWER_QGLVIEWER_H
 End of changes. 122 change blocks. 
328 lines changed or deleted 367 lines changed or added


 quaternion.h   quaternion.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 31 skipping to change at line 31
*************************************************************************** **/ *************************************************************************** **/
#ifndef QGLVIEWER_QUATERNION_H #ifndef QGLVIEWER_QUATERNION_H
#define QGLVIEWER_QUATERNION_H #define QGLVIEWER_QUATERNION_H
#include "vec.h" #include "vec.h"
#include <math.h> #include <math.h>
#include <iostream> #include <iostream>
namespace qglviewer { namespace qglviewer {
/*! \brief The Quaternion class represents 3D rotations and orientat ions. /*! \brief The Quaternion class represents 3D rotations and orientations.
\class Quaternion quaternion.h QGLViewer/quaternion.h \class Quaternion quaternion.h QGLViewer/quaternion.h
The Quaternion is an appropriate (although not very intuitive) repre sentation for 3D rotations and The Quaternion is an appropriate (although not very intuitive) repre sentation for 3D rotations and
orientations. Many tools are provided to ease the definition of a Qu aternion: see constructors, orientations. Many tools are provided to ease the definition of a Qu aternion: see constructors,
setAxisAngle(), setFromRotationMatrix(), setFromRotatedBasis(). setAxisAngle(), setFromRotationMatrix(), setFromRotatedBasis().
You can apply the rotation represented by the Quaternion to 3D point s using rotate() and You can apply the rotation represented by the Quaternion to 3D point s using rotate() and
inverseRotate(). See also the Frame class that represents a coordina te system and provides other inverseRotate(). See also the Frame class that represents a coordina te system and provides other
conversion functions like Frame::coordinatesOf() and Frame::transfor mOf(). conversion functions like Frame::coordinatesOf() and Frame::transfor mOf().
skipping to change at line 66 skipping to change at line 66
{q[0],q[1],q[2]} = sin(alpha/2) * {axis[0],axis[1],axis[2]} {q[0],q[1],q[2]} = sin(alpha/2) * {axis[0],axis[1],axis[2]}
q[3] = cos(alpha/2) q[3] = cos(alpha/2)
\endcode \endcode
Note that certain implementations place the cosine term in first pos ition (instead of last here). Note that certain implementations place the cosine term in first pos ition (instead of last here).
The Quaternion is always normalized, so that its inverse() is actual ly its conjugate. The Quaternion is always normalized, so that its inverse() is actual ly its conjugate.
See also the Vec and Frame classes' documentations. See also the Vec and Frame classes' documentations.
\nosubgrouping */ \nosubgrouping */
class QGLVIEWER_EXPORT Quaternion class QGLVIEWER_EXPORT Quaternion
{ {
public: public:
/*! @name Defining a Quaternion */ /*! @name Defining a Quaternion */
//@{ //@{
/*! Default constructor, builds an identity rotation. */ /*! Default constructor, builds an identity rotation. */
Quaternion() Quaternion()
{ q[0]=q[1]=q[2]=0.0; q[3]=1.0; } { q[0]=q[1]=q[2]=0.0; q[3]=1.0; }
/*! Constructor from rotation axis (non null) and angle (in /*! Constructor from rotation axis (non null) and angle (in radians)
radians). See also setAxisAngle(). */ . See also setAxisAngle(). */
Quaternion(const Vec& axis, double angle) Quaternion(const Vec& axis, double angle)
{ {
setAxisAngle(axis, angle); setAxisAngle(axis, angle);
} }
Quaternion(const Vec& from, const Vec& to); Quaternion(const Vec& from, const Vec& to);
/*! Constructor from the four values of a Quaternion. First three values are axis*sin(angle/2) and /*! Constructor from the four values of a Quaternion. First three va lues are axis*sin(angle/2) and
last one is cos(angle/2). last one is cos(angle/2).
\attention The identity Quaternion is Quaternion(0,0,0,1) an d \e not Quaternion(0,0,0,0) (which is \attention The identity Quaternion is Quaternion(0,0,0,1) an d \e not Quaternion(0,0,0,0) (which is
not unitary). The default Quaternion() creates such identity Quaternion. */ not unitary). The default Quaternion() creates such identity Quaternion. */
Quaternion(double q0, double q1, double q2, double q3) Quaternion(double q0, double q1, double q2, double q3)
{ q[0]=q0; q[1]=q1; q[2]=q2; q[3]=q3; } { q[0]=q0; q[1]=q1; q[2]=q2; q[3]=q3; }
/*! Copy constructor. */ /*! Copy constructor. */
Quaternion(const Quaternion& Q) Quaternion(const Quaternion& Q)
{ for (int i=0; i<4; ++i) q[i] = Q.q[i]; } { for (int i=0; i<4; ++i) q[i] = Q.q[i]; }
/*! Equal operator. */ /*! Equal operator. */
Quaternion& operator=(const Quaternion& Q) Quaternion& operator=(const Quaternion& Q)
{ {
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
q[i] = Q.q[i]; q[i] = Q.q[i];
return (*this); return (*this);
} }
/*! Sets the Quaternion as a rotation of axis \p axis and an gle \p angle (in radians). /*! Sets the Quaternion as a rotation of axis \p axis and angle \p a ngle (in radians).
\p axis does not need to be normalized. A null \p axis will result in an identity Quaternion. */ \p axis does not need to be normalized. A null \p axis will result in an identity Quaternion. */
void setAxisAngle(const Vec& axis, double angle) void setAxisAngle(const Vec& axis, double angle)
{
const double norm = axis.norm();
if (norm < 1E-8)
{
// Null rotation
q[0] = 0.0; q[1] = 0.0; q[2] = 0.0; q
[3] = 1.0;
}
else
{ {
const double norm = axis.norm(); const double sin_half_angle = sin(angle / 2.0);
if (norm < 1E-8) q[0] = sin_half_angle*axis[0]/norm;
{ q[1] = sin_half_angle*axis[1]/norm;
// Null rotation q[2] = sin_half_angle*axis[2]/norm;
q[0] = 0.0; q[1] = 0.0; q[2] = 0.0 q[3] = cos(angle / 2.0);
; q[3] = 1.0;
}
else
{
const double sin_half_angle = sin(angle / 2.
0);
q[0] = sin_half_angle*axis[0]/norm;
q[1] = sin_half_angle*axis[1]/norm;
q[2] = sin_half_angle*axis[2]/norm;
q[3] = cos(angle / 2.0);
}
} }
}
/*! Sets the Quaternion value. See the Quaternion(double, do /*! Sets the Quaternion value. See the Quaternion(double, double, do
uble, double, double) constructor documentation. */ uble, double) constructor documentation. */
void setValue(double q0, double q1, double q2, double q3) void setValue(double q0, double q1, double q2, double q3)
{ q[0]=q0; q[1]=q1; q[2]=q2; q[3]=q3; } { q[0]=q0; q[1]=q1; q[2]=q2; q[3]=q3; }
#ifndef DOXYGEN #ifndef DOXYGEN
void setFromRotationMatrix(const float m[3][3]); void setFromRotationMatrix(const float m[3][3]);
void setFromRotatedBase(const Vec& X, const Vec& Y, const Ve void setFromRotatedBase(const Vec& X, const Vec& Y, const Vec& Z);
c& Z);
#endif #endif
void setFromRotationMatrix(const double m[3][3]); void setFromRotationMatrix(const double m[3][3]);
void setFromRotatedBasis(const Vec& X, const Vec& Y, const V void setFromRotatedBasis(const Vec& X, const Vec& Y, const Vec& Z);
ec& Z); //@}
//@}
/*! @name Accessing values */
/*! @name Accessing values */ //@{
//@{ Vec axis() const;
Vec axis() const; double angle() const;
double angle() const; void getAxisAngle(Vec& axis, float& angle) const;
void getAxisAngle(Vec& axis, float& angle) const;
/*! Bracket operator, with a constant return value. \p i must range
/*! Bracket operator, with a constant return value. \p i mus in [0..3]. See the Quaternion(double, double, double, double) documentation
t range in [0..3]. See the Quaternion(double, double, double, double) docum . */
entation. */ double operator[](int i) const { return q[i]; }
double operator[](int i) const { return q[i]; }
/*! Bracket operator returning an l-value. \p i must range in [0..3]
/*! Bracket operator returning an l-value. \p i must range i . See the Quaternion(double, double, double, double) documentation. */
n [0..3]. See the Quaternion(double, double, double, double) documentation. double& operator[](int i) { return q[i]; }
*/ //@}
double& operator[](int i) { return q[i]; }
//@} /*! @name Rotation computations */
//@{
/*! @name Rotation computations */ /*! Returns the composition of the \p a and \p b rotations.
//@{
/*! Returns the composition of the \p a and \p b rotations.
The order is important. When applied to a Vec \c v (see oper ator*(const Quaternion&, const Vec&) The order is important. When applied to a Vec \c v (see oper ator*(const Quaternion&, const Vec&)
and rotate()) the resulting Quaternion acts as if \p b was a pplied first and then \p a was and rotate()) the resulting Quaternion acts as if \p b was a pplied first and then \p a was
applied. This is obvious since the image \c v' of \p v by th e composited rotation satisfies: \code applied. This is obvious since the image \c v' of \p v by th e composited rotation satisfies: \code
v'= (a*b) * v = a * (b*v) \endcode v'= (a*b) * v = a * (b*v) \endcode
Note that a*b usually differs from b*a. Note that a*b usually differs from b*a.
\attention For efficiency reasons, the resulting Quaternion is not normalized. Use normalize() in \attention For efficiency reasons, the resulting Quaternion is not normalized. Use normalize() in
case of numerical drift with small rotation composition. */ case of numerical drift with small rotation composition. */
friend Quaternion operator*(const Quaternion& a, const Quate friend Quaternion operator*(const Quaternion& a, const Quaternion& b
rnion& b) )
{ {
return Quaternion(a.q[3]*b.q[0] + b.q[3]*a.q[0] + a. return Quaternion(a.q[3]*b.q[0] + b.q[3]*a.q[0] + a.q[1]*b.q
q[1]*b.q[2] - a.q[2]*b.q[1], [2] - a.q[2]*b.q[1],
a.q[3]*b.q[1] + b.q[3]*a.q[1] + a.q[2]*b.q[0 ] - a.q[0]*b.q[2], a.q[3]*b.q[1] + b.q[3]*a.q[1] + a.q[2]*b.q[0 ] - a.q[0]*b.q[2],
a.q[3]*b.q[2] + b.q[3]*a.q[2] + a.q[0]*b.q[1 ] - a.q[1]*b.q[0], a.q[3]*b.q[2] + b.q[3]*a.q[2] + a.q[0]*b.q[1 ] - a.q[1]*b.q[0],
a.q[3]*b.q[3] - b.q[0]*a.q[0] - a.q[1]*b.q[1 ] - a.q[2]*b.q[2]); a.q[3]*b.q[3] - b.q[0]*a.q[0] - a.q[1]*b.q[1 ] - a.q[2]*b.q[2]);
} }
/*! Quaternion rotation is composed with \p q. /*! Quaternion rotation is composed with \p q.
See operator*(), since this is equivalent to \c this = \c th is * \p q. See operator*(), since this is equivalent to \c this = \c th is * \p q.
\note For efficiency reasons, the resulting Quaternion is no t normalized. \note For efficiency reasons, the resulting Quaternion is no t normalized.
You may normalize() it after each application in case of num erical drift. */ You may normalize() it after each application in case of num erical drift. */
Quaternion& operator*=(const Quaternion &q) Quaternion& operator*=(const Quaternion &q)
{ {
*this = (*this)*q; *this = (*this)*q;
return *this; return *this;
} }
/*! Returns the image of \p v by the rotation \p q. /*! Returns the image of \p v by the rotation \p q.
Same as q.rotate(v). See rotate() and inverseRotate(). */ Same as q.rotate(v). See rotate() and inverseRotate(). */
friend Vec operator*(const Quaternion& q, const Vec& v) friend Vec operator*(const Quaternion& q, const Vec& v)
{ {
return q.rotate(v); return q.rotate(v);
} }
Vec rotate(const Vec& v) const; Vec rotate(const Vec& v) const;
Vec inverseRotate(const Vec& v) const; Vec inverseRotate(const Vec& v) const;
//@} //@}
/*! @name Inversion */ /*! @name Inversion */
//@{ //@{
/*! Returns the inverse Quaternion (inverse rotation). /*! Returns the inverse Quaternion (inverse rotation).
Result has a negated axis() direction and the same angle(). A composition (see operator*()) of a Result has a negated axis() direction and the same angle(). A composition (see operator*()) of a
Quaternion and its inverse() results in an identity function . Quaternion and its inverse() results in an identity function .
Use invert() to actually modify the Quaternion. */ Use invert() to actually modify the Quaternion. */
Quaternion inverse() const { return Quaternion(-q[0], -q[1], -q[2], q[3]); } Quaternion inverse() const { return Quaternion(-q[0], -q[1], -q[2], q[3]); }
/*! Inverses the Quaternion (same rotation angle(), but nega ted axis()). /*! Inverses the Quaternion (same rotation angle(), but negated axis ()).
See also inverse(). */ See also inverse(). */
void invert() { q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; } void invert() { q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; }
/*! Negates all the coefficients of the Quaternion. /*! Negates all the coefficients of the Quaternion.
This results in an other representation of the \e same rotat ion (opposite rotation angle, but with This results in an other representation of the \e same rotat ion (opposite rotation angle, but with
a negated axis direction: the two cancel out). However, note that the results of axis() and a negated axis direction: the two cancel out). However, note that the results of axis() and
angle() are unchanged after a call to this method since angl e() always returns a value in [0,pi]. angle() are unchanged after a call to this method since angl e() always returns a value in [0,pi].
This method is mainly useful for Quaternion interpolation, s o that the spherical This method is mainly useful for Quaternion interpolation, s o that the spherical
interpolation takes the shortest path on the unit sphere. Se e slerp() for details. */ interpolation takes the shortest path on the unit sphere. Se e slerp() for details. */
void negate() { invert(); q[3] = -q[3]; } void negate() { invert(); q[3] = -q[3]; }
/*! Normalizes the Quaternion coefficients. /*! Normalizes the Quaternion coefficients.
This method should not need to be called since we only deal with unit Quaternions. This is however This method should not need to be called since we only deal with unit Quaternions. This is however
useful to prevent numerical drifts, especially with small ro tational increments. See also useful to prevent numerical drifts, especially with small ro tational increments. See also
normalized(). */ normalized(). */
double normalize() double normalize()
{ {
const double norm = sqrt(q[0]*q[0] + q[1]*q[1] + q[2 const double norm = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] +
]*q[2] + q[3]*q[3]); q[3]*q[3]);
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
q[i] /= norm; q[i] /= norm;
return norm; return norm;
} }
/*! Returns a normalized version of the Quaternion. /*! Returns a normalized version of the Quaternion.
See also normalize(). */ See also normalize(). */
Quaternion normalized() const Quaternion normalized() const
{ {
double Q[4]; double Q[4];
const double norm = sqrt(q[0]*q[0] + q[1]*q[1] + q[2 const double norm = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] +
]*q[2] + q[3]*q[3]); q[3]*q[3]);
for (int i=0; i<4; ++i) for (int i=0; i<4; ++i)
Q[i] = q[i] / norm; Q[i] = q[i] / norm;
return Quaternion(Q[0], Q[1], Q[2], Q[3]); return Quaternion(Q[0], Q[1], Q[2], Q[3]);
} }
//@} //@}
/*! @name Associated matrix */ /*! @name Associated matrix */
//@{ //@{
const GLdouble* matrix() const; const GLdouble* matrix() const;
void getMatrix(GLdouble m[4][4]) const; void getMatrix(GLdouble m[4][4]) const;
void getMatrix(GLdouble m[16]) const; void getMatrix(GLdouble m[16]) const;
void getRotationMatrix(float m[3][3]) const; void getRotationMatrix(float m[3][3]) const;
const GLdouble* inverseMatrix() const; const GLdouble* inverseMatrix() const;
void getInverseMatrix(GLdouble m[4][4]) const; void getInverseMatrix(GLdouble m[4][4]) const;
void getInverseMatrix(GLdouble m[16]) const; void getInverseMatrix(GLdouble m[16]) const;
void getInverseRotationMatrix(float m[3][3]) const; void getInverseRotationMatrix(float m[3][3]) const;
//@} //@}
/*! @name Slerp interpolation */ /*! @name Slerp interpolation */
//@{ //@{
static Quaternion slerp(const Quaternion& a, const Quaternio static Quaternion slerp(const Quaternion& a, const Quaternion& b, fl
n& b, float t, bool allowFlip=true); oat t, bool allowFlip=true);
static Quaternion squad(const Quaternion& a, const Quaternio static Quaternion squad(const Quaternion& a, const Quaternion& tgA,
n& tgA, const Quaternion& tgB, const Quaternion& b, float t); const Quaternion& tgB, const Quaternion& b, float t);
/*! Returns the "dot" product of \p a and \p b: a[0]*b[0] + /*! Returns the "dot" product of \p a and \p b: a[0]*b[0] + a[1]*b[1
a[1]*b[1] + a[2]*b[2] + a[3]*b[3]. */ ] + a[2]*b[2] + a[3]*b[3]. */
static double dot(const Quaternion& a, const Quaternion& b) static double dot(const Quaternion& a, const Quaternion& b) { return
{ return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]; } a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]; }
Quaternion log(); Quaternion log();
Quaternion exp(); Quaternion exp();
static Quaternion lnDif(const Quaternion& a, const Quaternio static Quaternion lnDif(const Quaternion& a, const Quaternion& b);
n& b); static Quaternion squadTangent(const Quaternion& before, const Quate
static Quaternion squadTangent(const Quaternion& before, con rnion& center, const Quaternion& after);
st Quaternion& center, const Quaternion& after); //@}
//@}
/*! @name Random Quaternion */
/*! @name Random Quaternion */ //@{
//@{ static Quaternion randomQuaternion();
static Quaternion randomQuaternion(); //@}
//@}
/*! @name XML representation */
/*! @name XML representation */ //@{
//@{ explicit Quaternion(const QDomElement& element);
explicit Quaternion(const QDomElement& element); QDomElement domElement(const QString& name, QDomDocument& document)
QDomElement domElement(const QString& name, QDomDocument& do const;
cument) const; void initFromDOMElement(const QDomElement& element);
void initFromDOMElement(const QDomElement& element); //@}
//@}
#ifdef DOXYGEN #ifdef DOXYGEN
/*! @name Output stream */ /*! @name Output stream */
//@{ //@{
/*! Output stream operator. Enables debugging code like: /*! Output stream operator. Enables debugging code like:
\code \code
Quaternion rot(...); Quaternion rot(...);
cout << "Rotation=" << rot << endl; cout << "Rotation=" << rot << endl;
\endcode */ \endcode */
std::ostream& operator<<(std::ostream& o, const qglviewer::V std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
ec&); //@}
//@}
#endif #endif
private: private:
/*! The internal data representation is private, use operato /*! The internal data representation is private, use operator[] to a
r[] to access values. */ ccess values. */
double q[4]; double q[4];
}; };
} // namespace } // namespace
std::ostream& operator<<(std::ostream& o, const qglviewer::Quaternion&); std::ostream& operator<<(std::ostream& o, const qglviewer::Quaternion&);
#endif // QGLVIEWER_QUATERNION_H #endif // QGLVIEWER_QUATERNION_H
 End of changes. 35 change blocks. 
187 lines changed or deleted 181 lines changed or added


 vec.h   vec.h 
/************************************************************************** ** /************************************************************************** **
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved. Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.4.0. This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com http://www.libqglviewer.com - contact@libqglviewer.com
This file may be used under the terms of the GNU General Public License This file may be used under the terms of the GNU General Public License
versions 2.0 or 3.0 as published by the Free Software Foundation and versions 2.0 or 3.0 as published by the Free Software Foundation and
appearing in the LICENSE file included in the packaging of this file. appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package. additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must libQGLViewer uses dual licensing. Commercial/proprietary software must
skipping to change at line 72 skipping to change at line 72
Vec implements a universal explicit converter, based on the \c [] \c oper ator. Vec implements a universal explicit converter, based on the \c [] \c oper ator.
Everywhere a \c const \c Vec& argument is expected, you can use your own vector type Everywhere a \c const \c Vec& argument is expected, you can use your own vector type
instead, as long as it implements this operator (see the Vec(const C& c) documentation). instead, as long as it implements this operator (see the Vec(const C& c) documentation).
See also the Quaternion and the Frame documentations. See also the Quaternion and the Frame documentations.
\nosubgrouping */ \nosubgrouping */
class QGLVIEWER_EXPORT Vec class QGLVIEWER_EXPORT Vec
{ {
// If your compiler complains the "The class "qglviewer::Vec" has no memb // If your compiler complains the "The class "qglviewer::Vec" has no
er "x"." member "x"."
// Add your architecture Q_OS_XXXX flag (see qglobal.h) in this list. // Add your architecture Q_OS_XXXX flag (see qglobal.h) in this list
.
#if defined (Q_OS_IRIX) || defined (Q_OS_AIX) || defined (Q_OS_HPUX) #if defined (Q_OS_IRIX) || defined (Q_OS_AIX) || defined (Q_OS_HPUX)
# define QGLVIEWER_UNION_NOT_SUPPORTED # define QGLVIEWER_UNION_NOT_SUPPORTED
#endif #endif
public: public:
/*! The internal data representation is public. One can use v.x, v.y, v.z . See also operator[](). */ /*! The internal data representation is public. One can use v.x, v.y , v.z. See also operator[](). */
#if defined (DOXYGEN) || defined (QGLVIEWER_UNION_NOT_SUPPORTED) #if defined (DOXYGEN) || defined (QGLVIEWER_UNION_NOT_SUPPORTED)
double x, y, z; double x, y, z;
#else #else
union union
{ {
struct { double x, y, z; }; struct { double x, y, z; };
double v_[3]; double v_[3];
}; };
#endif #endif
/*! @name Setting the value */
//@{
/*! Default constructor. Value is set to (0,0,0). */
Vec() : x(0.0), y(0.0), z(0.0) {}
/*! @name Setting the value */ /*! Standard constructor with the x, y and z values. */
//@{ Vec(double X, double Y, double Z) : x(X), y(Y), z(Z) {}
/*! Default constructor. Value is set to (0,0,0). */
Vec() : x(0.0), y(0.0), z(0.0) {}
/*! Standard constructor with the x, y and z values. */ /*! Universal explicit converter from any class to Vec. You can use
Vec(double X, double Y, double Z) : x(X), y(Y), z(Z) {} your own vector class everywhere
/*! Universal explicit converter from any class to Vec. You can use your
own vector class everywhere
a \c const \c Vec& parameter is required, as long as it implements the \c operator[ ]: a \c const \c Vec& parameter is required, as long as it implements the \c operator[ ]:
\code \code
class MyVec class MyVec
{ {
// ... // ...
double operator[](int i) const { returns x, y or z when i=0, 1 or 2; } double operator[](int i) const { returns x, y or z when i=0, 1 or 2;
}
} }
MyVec v(...); MyVec v(...);
camera()->setPosition(v); camera()->setPosition(v);
\endcode \endcode
Note that standard vector types (STL, \c double[3], ...) implement this o perator and can hence Note that standard vector types (STL, \c double[3], ...) implement this o perator and can hence
be used in place of Vec. See also operator const double*() .*/ be used in place of Vec. See also operator const double*() .*/
template <class C> template <class C>
explicit Vec(const C& c) : x(c[0]), y(c[1]), z(c[2]) {} explicit Vec(const C& c) : x(c[0]), y(c[1]), z(c[2]) {}
// Should NOT be explicit to prevent conflicts with operator<<. // Should NOT be explicit to prevent conflicts with operator<<.
// ! Copy constructor // ! Copy constructor
// Vec(const Vec& v) : x(v.x), y(v.y), z(v.z) {} // Vec(const Vec& v) : x(v.x), y(v.y), z(v.z) {}
/*! Equal operator. */ /*! Equal operator. */
Vec& operator=(const Vec& v) Vec& operator=(const Vec& v)
{ {
x = v.x; y = v.y; z = v.z; x = v.x; y = v.y; z = v.z;
return *this; return *this;
} }
/*! Set the current value. May be faster than using operator=() with a te /*! Set the current value. May be faster than using operator=() with
mporary Vec(x,y,z). */ a temporary Vec(x,y,z). */
void setValue(double X, double Y, double Z) void setValue(double X, double Y, double Z)
{ x=X; y=Y; z=Z; } { x=X; y=Y; z=Z; }
// Universal equal operator which allows the use of any type in place of // Universal equal operator which allows the use of any type in plac
Vec, e of Vec,
// as long as the [] operator is implemented (v[0]=v.x, v[1]=v.y, v[2]=v. // as long as the [] operator is implemented (v[0]=v.x, v[1]=v.y, v[
z). 2]=v.z).
// template <class C> // template <class C>
// Vec& operator=(const C& c) // Vec& operator=(const C& c)
// { // {
// x=c[0]; y=c[1]; z=c[2]; // x=c[0]; y=c[1]; z=c[2];
// return *this; // return *this;
// } // }
//@} //@}
/*! @name Accessing the value */ /*! @name Accessing the value */
//@{ //@{
/*! Bracket operator, with a constant return value. \p i must range in [0 /*! Bracket operator, with a constant return value. \p i must range
..2]. */ in [0..2]. */
double operator[](int i) const { double operator[](int i) const {
#ifdef QGLVIEWER_UNION_NOT_SUPPORTED #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
return (&x)[i]; return (&x)[i];
#else #else
return v_[i]; return v_[i];
#endif #endif
} }
/*! Bracket operator returning an l-value. \p i must range in [0..2]. */ /*! Bracket operator returning an l-value. \p i must range in [0..2]
double& operator[](int i) { . */
double& operator[](int i) {
#ifdef QGLVIEWER_UNION_NOT_SUPPORTED #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
return (&x)[i]; return (&x)[i];
#else #else
return v_[i]; return v_[i];
#endif #endif
} }
#ifndef DOXYGEN #ifndef DOXYGEN
/*! This method is deprecated since version 2.0. Use operator const doubl /*! This method is deprecated since version 2.0. Use operator const
e* instead. */ double* instead. */
const double* address() const { qWarning("Vec::address() is deprecated, u const double* address() const { qWarning("Vec::address() is deprecat
se operator const double* instead."); return operator const double*(); }; ed, use operator const double* instead."); return operator const double*();
}
#endif #endif
/*! Conversion operator returning the memory address of the vector. /*! Conversion operator returning the memory address of the vector.
Very convenient to pass a Vec pointer as a parameter to OpenGL functions: Very convenient to pass a Vec pointer as a parameter to OpenGL functions:
\code \code
Vec pos, normal; Vec pos, normal;
glNormal3dv(normal); glNormal3dv(normal);
glVertex3dv(pos); glVertex3dv(pos);
\endcode */ \endcode */
operator const double*() const { operator const double*() const {
#ifdef QGLVIEWER_UNION_NOT_SUPPORTED #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
return &x; return &x;
#else #else
return v_; return v_;
#endif #endif
} }
/*! Non const conversion operator returning the memory address of the vec tor. /*! Non const conversion operator returning the memory address of th e vector.
Useful to pass a Vec to a method that requires and fills a \c double*, as provided by certain libraries. */ Useful to pass a Vec to a method that requires and fills a \c double*, as provided by certain libraries. */
operator double*() { operator double*() {
#ifdef QGLVIEWER_UNION_NOT_SUPPORTED #ifdef QGLVIEWER_UNION_NOT_SUPPORTED
return &x; return &x;
#else #else
return v_; return v_;
#endif #endif
} }
/*! Conversion operator returning the memory address of the vector. /*! Conversion operator returning the memory address of the vector.
Very convenient to pass a Vec pointer as a parameter to OpenGL functions: Very convenient to pass a Vec pointer as a parameter to OpenGL functions:
\code \code
Vec pos, normal; Vec pos, normal;
glNormal3fv(normal); glNormal3fv(normal);
glVertex3fv(pos); glVertex3fv(pos);
\endcode \endcode
\note The returned float array is a static shared by all \c Vec instances . */ \note The returned float array is a static shared by all \c Vec instances . */
operator const float*() const { operator const float*() const {
static float* const result = new float[3]; static float* const result = new float[3];
result[0] = (float)x; result[0] = (float)x;
result[1] = (float)y; result[1] = (float)y;
result[2] = (float)z; result[2] = (float)z;
return result; return result;
} }
//@} //@}
/*! @name Algebraic computations */
//@{
/*! Returns the sum of the two vectors. */
friend Vec operator+(const Vec &a, const Vec &b)
{
return Vec(a.x+b.x, a.y+b.y, a.z+b.z);
}
/*! Returns the difference of the two vectors. */
friend Vec operator-(const Vec &a, const Vec &b)
{
return Vec(a.x-b.x, a.y-b.y, a.z-b.z);
}
/*! Unary minus operator. */
friend Vec operator-(const Vec &a)
{
return Vec(-a.x, -a.y, -a.z);
}
/*! Returns the product of the vector with a scalar. */
friend Vec operator*(const Vec &a, double k)
{
return Vec(a.x*k, a.y*k, a.z*k);
}
/*! Returns the product of a scalar with the vector. */
friend Vec operator*(double k, const Vec &a)
{
return a*k;
}
/*! @name Algebraic computations */ /*! Returns the division of the vector with a scalar.
//@{
/*! Returns the sum of the two vectors. */
friend Vec operator+(const Vec &a, const Vec &b)
{
return Vec(a.x+b.x, a.y+b.y, a.z+b.z);
}
/*! Returns the difference of the two vectors. */
friend Vec operator-(const Vec &a, const Vec &b)
{
return Vec(a.x-b.x, a.y-b.y, a.z-b.z);
}
/*! Unary minus operator. */
friend Vec operator-(const Vec &a)
{
return Vec(-a.x, -a.y, -a.z);
}
/*! Returns the product of the vector with a scalar. */
friend Vec operator*(const Vec &a, double k)
{
return Vec(a.x*k, a.y*k, a.z*k);
}
/*! Returns the product of a scalar with the vector. */
friend Vec operator*(double k, const Vec &a)
{
return a*k;
}
/*! Returns the division of the vector with a scalar.
Too small \p k values are \e not tested (unless the library was compiled with the "debug" Qt \c Too small \p k values are \e not tested (unless the library was compiled with the "debug" Qt \c
CONFIG flag) and may result in \c NaN values. */ CONFIG flag) and may result in \c NaN values. */
friend Vec operator/(const Vec &a, double k) friend Vec operator/(const Vec &a, double k)
{ {
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
if (fabs(k) < 1.0E-10) if (fabs(k) < 1.0E-10)
qWarning("Vec::operator / : dividing by a null value (%f)", k); qWarning("Vec::operator / : dividing by a null value
(%f)", k);
#endif #endif
return Vec(a.x/k, a.y/k, a.z/k); return Vec(a.x/k, a.y/k, a.z/k);
} }
/*! Returns \c true only when the two vector are not equal (see operator= /*! Returns \c true only when the two vector are not equal (see oper
=()). */ ator==()). */
friend bool operator!=(const Vec &a, const Vec &b) friend bool operator!=(const Vec &a, const Vec &b)
{ {
return !(a==b); return !(a==b);
} }
/*! Returns \c true when the squaredNorm() of the difference vector is lo /*! Returns \c true when the squaredNorm() of the difference vector
wer than 1E-10. */ is lower than 1E-10. */
friend bool operator==(const Vec &a, const Vec &b) friend bool operator==(const Vec &a, const Vec &b)
{ {
const double epsilon = 1.0E-10f; const double epsilon = 1.0E-10f;
return (a-b).squaredNorm() < epsilon; return (a-b).squaredNorm() < epsilon;
} }
/*! Adds \p a to the vector. */
Vec& operator+=(const Vec &a)
{
x += a.x; y += a.y; z += a.z;
return *this;
}
/*! Subtracts \p a to the vector. */
Vec& operator-=(const Vec &a)
{
x -= a.x; y -= a.y; z -= a.z;
return *this;
}
/*! Multiply the vector by a scalar \p k. */
Vec& operator*=(double k)
{
x *= k; y *= k; z *= k;
return *this;
}
/*! Adds \p a to the vector. */ /*! Divides the vector by a scalar \p k.
Vec& operator+=(const Vec &a)
{
x += a.x; y += a.y; z += a.z;
return *this;
}
/*! Subtracts \p a to the vector. */
Vec& operator-=(const Vec &a)
{
x -= a.x; y -= a.y; z -= a.z;
return *this;
}
/*! Multiply the vector by a scalar \p k. */
Vec& operator*=(double k)
{
x *= k; y *= k; z *= k;
return *this;
}
/*! Divides the vector by a scalar \p k.
An absolute \p k value lower than 1E-10 will print a warning if the libra ry was compiled with the An absolute \p k value lower than 1E-10 will print a warning if the libra ry was compiled with the
"debug" Qt \c CONFIG flag. Otherwise, no test is performed for efficiency reasons. */ "debug" Qt \c CONFIG flag. Otherwise, no test is performed for efficiency reasons. */
Vec& operator/=(double k) Vec& operator/=(double k)
{ {
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
if (fabs(k)<1.0E-10) if (fabs(k)<1.0E-10)
qWarning("Vec::operator /= : dividing by a null value (%f)", k); qWarning("Vec::operator /= : dividing by a null valu
e (%f)", k);
#endif #endif
x /= k; y /= k; z /= k; x /= k; y /= k; z /= k;
return *this; return *this;
} }
/*! Dot product of the two Vec. */
friend double operator*(const Vec &a, const Vec &b)
{
return a.x*b.x + a.y*b.y + a.z*b.z;
}
/*! Cross product of the two vectors. Same as cross(). */
friend Vec operator^(const Vec &a, const Vec &b)
{
return cross(a,b);
}
/*! Cross product of the two Vec. Mind the order ! */
friend Vec cross(const Vec &a, const Vec &b)
{
return Vec(a.y*b.z - a.z*b.y,
a.z*b.x - a.x*b.z,
a.x*b.y - a.y*b.x);
}
/*! Dot product of the two Vec. */ Vec orthogonalVec() const;
friend double operator*(const Vec &a, const Vec &b) //@}
{
return a.x*b.x + a.y*b.y + a.z*b.z;
}
/*! Cross product of the two vectors. Same as cross(). */
friend Vec operator^(const Vec &a, const Vec &b)
{
return cross(a,b);
}
/*! Cross product of the two Vec. Mind the order ! */
friend Vec cross(const Vec &a, const Vec &b)
{
return Vec(a.y*b.z - a.z*b.y,
a.z*b.x - a.x*b.z,
a.x*b.y - a.y*b.x);
}
Vec orthogonalVec() const; /*! @name Norm of the vector */
//@} //@{
/*! @name Norm of the vector */
//@{
#ifndef DOXYGEN #ifndef DOXYGEN
/*! This method is deprecated since version 2.0. Use squaredNorm() instea /*! This method is deprecated since version 2.0. Use squaredNorm() i
d. */ nstead. */
double sqNorm() const { return x*x + y*y + z*z; } double sqNorm() const { return x*x + y*y + z*z; }
#endif #endif
/*! Returns the \e squared norm of the Vec. */ /*! Returns the \e squared norm of the Vec. */
double squaredNorm() const { return x*x + y*y + z*z; } double squaredNorm() const { return x*x + y*y + z*z; }
/*! Returns the norm of the vector. */ /*! Returns the norm of the vector. */
double norm() const { return sqrt(x*x + y*y + z*z); } double norm() const { return sqrt(x*x + y*y + z*z); }
/*! Normalizes the Vec and returns its original norm. /*! Normalizes the Vec and returns its original norm.
Normalizing a null vector will result in \c NaN values. */ Normalizing a null vector will result in \c NaN values. */
double normalize() double normalize()
{ {
const double n = norm(); const double n = norm();
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
if (n < 1.0E-10) if (n < 1.0E-10)
qWarning("Vec::normalize: normalizing a null vector (norm=%f)", n); qWarning("Vec::normalize: normalizing a null vector
(norm=%f)", n);
#endif #endif
*this /= n; *this /= n;
return n; return n;
} }
/*! Returns a unitary (normalized) \e representation of the vector. The o /*! Returns a unitary (normalized) \e representation of the vector.
riginal Vec is not modified. */ The original Vec is not modified. */
Vec unit() const Vec unit() const
{ {
Vec v = *this; Vec v = *this;
v.normalize(); v.normalize();
return v; return v;
} }
//@} //@}
/*! @name Projection */ /*! @name Projection */
//@{ //@{
void projectOnAxis(const Vec& direction); void projectOnAxis(const Vec& direction);
void projectOnPlane(const Vec& normal); void projectOnPlane(const Vec& normal);
//@} //@}
/*! @name XML representation */ /*! @name XML representation */
//@{ //@{
explicit Vec(const QDomElement& element); explicit Vec(const QDomElement& element);
QDomElement domElement(const QString& name, QDomDocument& document) const QDomElement domElement(const QString& name, QDomDocument& document)
; const;
void initFromDOMElement(const QDomElement& element); void initFromDOMElement(const QDomElement& element);
//@} //@}
#ifdef DOXYGEN #ifdef DOXYGEN
/*! @name Output stream */ /*! @name Output stream */
//@{ //@{
/*! Output stream operator. Enables debugging code like: /*! Output stream operator. Enables debugging code like:
\code \code
Vec pos(...); Vec pos(...);
cout << "Position=" << pos << endl; cout << "Position=" << pos << endl;
\endcode */ \endcode */
std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&); std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
//@} //@}
#endif #endif
}; };
} // namespace } // namespace
std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&); std::ostream& operator<<(std::ostream& o, const qglviewer::Vec&);
#endif // QGLVIEWER_VEC_H #endif // QGLVIEWER_VEC_H
 End of changes. 49 change blocks. 
241 lines changed or deleted 248 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/