Inherited by AxisPlaneConstraint.
Public Member Functions | |
virtual | ~Constraint () |
virtual void | constrainTranslation (Vec &translation, Frame *const frame) |
virtual void | constrainRotation (Quaternion &rotation, Frame *const frame) |
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 NULL
Frame::constraint()).
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:
Frame::translate(Vec& T) { if (constraint()) constraint()->constrainTranslation(T, this); t += T; } Frame::rotate(Quaternion& Q) { if (constraint()) constraint()->constrainRotation(Q, this); q *= Q; }
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 const
for versatility reasons, but directly modifying it should be avoided.
Classical axial and plane Constraints are provided for convenience: see the LocalConstraint, WorldConstraint and CameraConstraint classes' documentations.
Try the constrainedFrame and constrainedCamera examples for an illustration.
The implementation of a new Constraint class simply consists in overloading the filtering methods:
// 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 } };
Note that the translation (resp. rotation) parameter passed to constrainTranslation() (resp. constrainRotation()) is expressed in the 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:
myConstraint::constrainTranslation(Vec& v, Frame* const fr) { constraint1->constrainTranslation(v, fr); constraint2->constrainTranslation(v, fr); // and so on, with possible branches, tests, loops... }
|
Virtual destructor. Empty. |
|
Filters the rotation applied to the Overload this method in your own Constraint class to define a new rotation constraint. See constrainTranslation() for details.
Use Frame::inverseTransformOf() on the Reimplemented in AxisPlaneConstraint, LocalConstraint, WorldConstraint, and CameraConstraint. |
|
Filters the translation applied to the
Overload this method in your own Constraint class to define a new translation constraint.
Reimplemented in AxisPlaneConstraint, LocalConstraint, WorldConstraint, and CameraConstraint. |