/usr/include/QGLViewer/constraint.h is in libqglviewer-dev 2.5.0+dfsg-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | /****************************************************************************
Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
This file is part of the QGLViewer library version 2.5.0.
http://www.libqglviewer.com - contact@libqglviewer.com
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
appearing in the LICENSE file included in the packaging of this file.
In addition, as a special exception, Gilles Debunne gives you certain
additional rights, described in the file GPL_EXCEPTION in this package.
libQGLViewer uses dual licensing. Commercial/proprietary software must
purchase a libQGLViewer Commercial License.
This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*****************************************************************************/
#ifndef QGLVIEWER_CONSTRAINT_H
#define QGLVIEWER_CONSTRAINT_H
#include "vec.h"
#include "quaternion.h"
namespace qglviewer {
class Frame;
class Camera;
/*! \brief An interface class for Frame constraints.
\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
motion. Use Frame::setConstraint() to associate a Constraint to a Frame (default is a \c NULL
Frame::constraint()).
<h3>How does it work ?</h3>
The Constraint acts as a filter on the translation and rotation Frame increments.
constrainTranslation() and constrainRotation() should be overloaded to specify the constraint
behavior: the desired displacement is given as a parameter that can optionally be modified.
Here is how the Frame::translate() and Frame::rotate() methods use the Constraint:
\code
Frame::translate(Vec& T)
{
if (constraint())
constraint()->constrainTranslation(T, this);
t += T;
}
Frame::rotate(Quaternion& Q)
{
if (constraint())
constraint()->constrainRotation(Q, this);
q *= Q;
}
\endcode
The default behavior of constrainTranslation() and constrainRotation() is empty (meaning no
filtering).
The Frame which uses the Constraint is passed as a parameter to the constrainTranslation() and
constrainRotation() methods, so that they can have access to its current state (mainly
Frame::position() and Frame::orientation()). It is not \c const for versatility reasons, but
directly modifying it should be avoided.
\attention Frame::setTranslation(), Frame::setRotation() and similar methods will actually indeed
set the frame position and orientation, without taking the constraint into account. Use the \e
WithConstraint versions of these methods to enforce the Constraint.
<h3>Implemented Constraints</h3>
Classical axial and plane Constraints are provided for convenience: see the LocalConstraint,
WorldConstraint and CameraConstraint classes' documentations.
Try the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a
href="../examples/constrainedCamera.html">constrainedCamera</a> examples for an illustration.
<h3>Creating new Constraints</h3>
The implementation of a new Constraint class simply consists in overloading the filtering methods:
\code
// This Constraint enforces that the Frame cannot have a negative z world coordinate.
class myConstraint : public Constraint
{
public:
virtual void constrainTranslation(Vec& t, Frame * const fr)
{
// Express t in the world coordinate system.
const Vec tWorld = fr->inverseTransformOf(t);
if (fr->position().z + tWorld.z < 0.0) // check the new fr z coordinate
t.z = fr->transformOf(-fr->position().z); // t.z is clamped so that next z position is 0.0
}
};
\endcode
Note that the translation (resp. rotation) parameter passed to constrainTranslation() (resp.
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
coordinate system.
Combined constraints can easily be achieved by creating a new class that applies the different
constraint filters:
\code
myConstraint::constrainTranslation(Vec& v, Frame* const fr)
{
constraint1->constrainTranslation(v, fr);
constraint2->constrainTranslation(v, fr);
// and so on, with possible branches, tests, loops...
}
\endcode
*/
class QGLVIEWER_EXPORT Constraint
{
public:
/*! Virtual destructor. Empty. */
virtual ~Constraint() {}
/*! Filters the translation applied to the \p frame. This default implementation is empty (no
filtering).
Overload this method in your own Constraint class to define a new translation constraint. \p
frame is the Frame to which is applied the translation. It is not defined \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 implementation is empty (no
filtering).
Overload this method in your own Constraint class to define a new rotation 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 frame) { Q_UNUSED(rotation); Q_UNUSED(frame); }
};
/*!
\brief An abstract class for Frame Constraints defined by an axis or a plane.
\class AxisPlaneConstraint constraint.h QGLViewer/constraint.h
AxisPlaneConstraint is an interface for (translation and/or rotation) Constraint that are defined
by a direction. translationConstraintType() and rotationConstraintType() define how this
direction should be interpreted: as an axis (AxisPlaneConstraint::AXIS) or as a plane normal
(AxisPlaneConstraint::PLANE). See the Type() documentation for details.
The three implementations of this class: LocalConstraint, WorldConstraint and CameraConstraint
differ by the coordinate system in which this direction is expressed.
Different implementations of this class are illustrated in the
<a href="../examples/constrainedCamera.html">contrainedCamera</a> and
<a href="../examples/constrainedFrame.html">constrainedFrame</a> examples.
\attention When applied, the rotational Constraint may not intuitively follow the mouse
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 compute the projected
coordinates of the rotation center (as is done with the QGLViewer::SCREEN_ROTATE binding).
However, adding an extra pointer to the QGLViewer::camera() in all the AxisPlaneConstraint
derived classes (which the user would have to update in a multi-viewer application) was judged as
an overkill. */
class QGLVIEWER_EXPORT AxisPlaneConstraint : public Constraint
{
public:
AxisPlaneConstraint();
/*! Virtual destructor. Empty. */
virtual ~AxisPlaneConstraint() {}
/*! Type lists the different types of translation and rotation constraints that are available.
It specifies the meaning of the constraint direction (see translationConstraintDirection() and
rotationConstraintDirection()): as an axis direction (AxisPlaneConstraint::AXIS) or a plane
normal (AxisPlaneConstraint::PLANE). AxisPlaneConstraint::FREE means no constraint while
AxisPlaneConstraint::FORBIDDEN completely forbids the translation and/or the rotation.
See translationConstraintType() and rotationConstraintType().
\attention The AxisPlaneConstraint::PLANE Type is not valid for rotational constraint.
New derived classes can use their own extended enum for specific constraints:
\code
class MyAxisPlaneConstraint : public AxisPlaneConstraint
{
public:
enum MyType { FREE, AXIS, PLANE, FORBIDDEN, CUSTOM };
virtual void constrainTranslation(Vec &translation, Frame *const frame)
{
// translationConstraintType() is simply an int. CUSTOM Type is handled seamlessly.
switch (translationConstraintType())
{
case MyAxisPlaneConstraint::FREE: ... break;
case MyAxisPlaneConstraint::CUSTOM: ... break;
}
};
MyAxisPlaneConstraint* c = new MyAxisPlaneConstraint();
// Note the Type conversion
c->setTranslationConstraintType(AxisPlaneConstraint::Type(MyAxisPlaneConstraint::CUSTOM));
};
\endcode */
enum Type { FREE, AXIS, PLANE, FORBIDDEN };
/*! @name Translation constraint */
//@{
/*! Overloading of Constraint::constrainTranslation(). Empty */
virtual void constrainTranslation(Vec& translation, Frame* const frame) { Q_UNUSED(translation); Q_UNUSED(frame); };
void setTranslationConstraint(Type type, const Vec& direction);
/*! Sets the Type() of the translationConstraintType(). Default is AxisPlaneConstraint::FREE. */
void setTranslationConstraintType(Type type) { translationConstraintType_ = type; };
void setTranslationConstraintDirection(const Vec& direction);
/*! Returns the translation constraint Type().
Depending on this value, the Frame will freely translate (AxisPlaneConstraint::FREE), will only
be able to translate along an axis direction (AxisPlaneConstraint::AXIS), will be forced to stay
into a plane (AxisPlaneConstraint::PLANE) or will not able to translate at all
(AxisPlaneConstraint::FORBIDDEN).
Use Frame::setPosition() to define the position of the constrained Frame before it gets
constrained. */
Type translationConstraintType() const { return translationConstraintType_; };
/*! Returns the direction used by the translation constraint.
It represents the axis direction (AxisPlaneConstraint::AXIS) or the plane normal
(AxisPlaneConstraint::PLANE) depending on the translationConstraintType(). It is undefined for
AxisPlaneConstraint::FREE or AxisPlaneConstraint::FORBIDDEN.
The AxisPlaneConstraint derived classes express this direction in different coordinate system
(camera for CameraConstraint, local for LocalConstraint, and world for WorldConstraint). This
value can be modified with setTranslationConstraintDirection(). */
Vec translationConstraintDirection() const { return translationConstraintDir_; };
//@}
/*! @name Rotation constraint */
//@{
/*! Overloading of Constraint::constrainRotation(). Empty. */
virtual void constrainRotation(Quaternion& rotation, Frame* const frame) { Q_UNUSED(rotation); Q_UNUSED(frame); };
void setRotationConstraint(Type type, const Vec& direction);
void setRotationConstraintType(Type type);
void setRotationConstraintDirection(const Vec& direction);
/*! Returns the rotation constraint Type(). */
Type rotationConstraintType() const { return rotationConstraintType_; };
/*! Returns the axis direction used by the rotation constraint.
This direction is defined only when rotationConstraintType() is AxisPlaneConstraint::AXIS.
The AxisPlaneConstraint derived classes express this direction in different coordinate system
(camera for CameraConstraint, local for LocalConstraint, and world for WorldConstraint). This
value can be modified with setRotationConstraintDirection(). */
Vec rotationConstraintDirection() const { return rotationConstraintDir_; };
//@}
private:
// int and not Type to allow for overloading and new types definition.
Type translationConstraintType_;
Type rotationConstraintType_;
Vec translationConstraintDir_;
Vec rotationConstraintDir_;
};
/*! \brief An AxisPlaneConstraint defined in the Frame local coordinate system.
\class LocalConstraint constraint.h QGLViewer/constraint.h
The translationConstraintDirection() and rotationConstraintDirection() are expressed in the Frame
local coordinate system (see Frame::referenceFrame()).
See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> example for an illustration. */
class QGLVIEWER_EXPORT LocalConstraint : public AxisPlaneConstraint
{
public:
/*! Virtual destructor. Empty. */
virtual ~LocalConstraint() {};
virtual void constrainTranslation(Vec& translation, Frame* const frame);
virtual void constrainRotation (Quaternion& rotation, Frame* const frame);
};
/*! \brief An AxisPlaneConstraint defined in the world coordinate system.
\class WorldConstraint constraint.h QGLViewer/constraint.h
The translationConstraintDirection() and rotationConstraintDirection() are expressed in world
coordinate system.
See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a
href="../examples/multiView.html">multiView</a> examples for an illustration. */
class QGLVIEWER_EXPORT WorldConstraint : public AxisPlaneConstraint
{
public:
/*! Virtual destructor. Empty. */
virtual ~WorldConstraint() {};
virtual void constrainTranslation(Vec& translation, Frame* const frame);
virtual void constrainRotation (Quaternion& rotation, Frame* const frame);
};
/*! \brief An AxisPlaneConstraint defined in the camera coordinate system.
\class CameraConstraint constraint.h QGLViewer/constraint.h
The translationConstraintDirection() and rotationConstraintDirection() are expressed in the
associated camera() coordinate system.
See the <a href="../examples/constrainedFrame.html">constrainedFrame</a> and <a
href="../examples/constrainedCamera.html">constrainedCamera</a> examples for an illustration. */
class QGLVIEWER_EXPORT CameraConstraint : public AxisPlaneConstraint
{
public:
explicit CameraConstraint(const Camera* const camera);
/*! Virtual destructor. Empty. */
virtual ~CameraConstraint() {};
virtual void constrainTranslation(Vec& translation, Frame* const frame);
virtual void constrainRotation (Quaternion& rotation, Frame* const frame);
/*! Returns the associated Camera. Set using the CameraConstraint constructor. */
const Camera* camera() const { return camera_; };
private:
const Camera* const camera_;
};
} // namespace qglviewer
#endif // QGLVIEWER_CONSTRAINT_H
|