Associated Frame | |
Frame * | frame () const |
void | setFrame (Frame *const frame) |
Path parameters | |
Frame | keyFrame (int index) const |
float | keyFrameTime (int index) const |
int | numberOfKeyFrames () const |
float | duration () const |
float | firstTime () const |
float | lastTime () const |
Interpolation parameters | |
float | interpolationTime () const |
float | interpolationSpeed () const |
int | interpolationPeriod () const |
bool | loopInterpolation () const |
void | setInterpolationTime (float time) |
void | setInterpolationSpeed (float speed) |
void | setInterpolationPeriod (int period) |
void | setLoopInterpolation (bool loop=true) |
Interpolation | |
bool | interpolationIsStarted () const |
void | startInterpolation (int period=-1) |
void | stopInterpolation () |
void | resetInterpolation () |
void | toggleInterpolation () |
virtual void | interpolateAtTime (float time) |
Path drawing | |
virtual void | drawPath (int mask=1, int nbFrames=6, float scale=1.0f) |
XML representation | |
virtual QDomElement | domElement (const QString &name, QDomDocument &document) const |
virtual void | initFromDOMElement (const QDomElement &element) |
Path creation | |
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 | deletePath () |
Signals | |
void | interpolated () |
void | endReached () |
Public Member Functions | |
KeyFrameInterpolator (Frame *fr=NULL) | |
virtual | ~KeyFrameInterpolator () |
A KeyFrameInterpolator holds keyFrames (that define a path) and a pointer to a Frame of your application (which will be interpolated). When the user startInterpolation(), the KeyFrameInterpolator regularly updates the frame() position and orientation along the path.
Here is a typical utilization example (see also the keyFrames example):
init() { // The KeyFrameInterpolator kfi is given the Frame that it will drive over time. kfi = new KeyFrameInterpolator( new Frame() ); kfi->addKeyFrame( Frame( Vec(1,0,0), Quaternion() ) ); kfi->addKeyFrame( new Frame( Vec(2,1,0), Quaternion() ) ); // ...and so on for all the keyFrames. // Ask for a display update after each update of the KeyFrameInterpolator connect(kfi, SIGNAL(interpolated()), SLOT(updateGL())); kfi->startInterpolation(); } draw() { glPushMatrix(); glMultMatrixd( kfi->frame()->matrix() ); // Draw your object here. Its position and orientation are interpolated. glPopMatrix(); }
The keyFrames are defined by a Frame and a time, expressed in seconds. The Frame can be provided as a const reference or as a pointer to a Frame (see the addKeyFrame() methods). In the latter case, the path will automatically be updated when the Frame is modified (using the Frame::modified() signal).
The time has to be monotonously increasing over keyFrames. When interpolationSpeed() equals 1.0 (default value), these times correspond to actual user's seconds during interpolation (provided that your main loop is fast enough). The interpolation is then real-time: the keyFrames will be reached at their keyFrameTime().
When the user startInterpolation(), a timer is started which will update the frame()'s position and orientation every interpolationPeriod() milliseconds. This update increases the interpolationTime() by interpolationPeriod() * interpolationSpeed() milliseconds.
Note that this mechanism ensures that the number of interpolation steps is constant and equal to the total path duration() divided by the interpolationPeriod() * interpolationSpeed(). This is especially useful for benchmarking or movie creation (constant number of snapshots).
During the interpolation, the KeyFrameInterpolator emits an interpolated() signal, which will usually be connected to the QGLViewer::updateGL() slot. The interpolation is stopped when interpolationTime() is greater than the lastTime() (unless loopInterpolation() is true
) and the endReached() signal is then emitted.
Note that a Camera has Camera::keyFrameInterpolator(), that can be used to 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 new keyFrame for path x. Pressing Fx plays/pauses path interpolation. See QGLViewer::pathKey() and the keyboard page for details.
This code defines a KeyFrameInterpolator, and displays the positions that will be followed by the frame() along the path:
KeyFrameInterpolator kfi( new Frame() ); // calls to kfi.addKeyFrame() to define the path. const float deltaTime = 0.04; // output a position every deltaTime seconds for (float time=kfi.firstTime(); time<=kfi.lastTime(); time += deltaTime) { kfi.interpolateAtTime(time); cout << "t=" << time << "\tpos=" << kfi.frame()->position() << endl; }
kfi
interpolated() signal from the QGLViewer::updateGL() slot before calling this code.
|
Creates a KeyFrameInterpolator, with The frame() can be set or changed using setFrame(). interpolationTime(), interpolationSpeed() and interpolationPeriod() are set to their default values. |
|
Virtual destructor. Clears the keyFrame path. |
|
Appends a new keyFrame to the path, with its associated
The keyFrame is given as a pointer to a Frame, which will be connected to the KeyFrameInterpolator: when
Use addKeyFrame(const Frame&, float) to add keyFrame by values. |
|
Appends a new keyFrame to the path. Same as addKeyFrame(const Frame* frame, float), except that the keyFrameTime() is set to the previous keyFrameTime() plus one second (or 0.0 if there is no previous keyFrame). |
|
Appends a new keyFrame to the path, with its associated
The path will use the current The keyFrameTime() have to be monotonously increasing over keyFrames. |
|
Appends a new keyFrame to the path. Same as addKeyFrame(const Frame& frame, float), except that the keyFrameTime() is automatically set to previous keyFrameTime() plus one second (or 0.0 if there is no previous keyFrame). |
|
Removes all keyFrames from the path. The numberOfKeyFrames() is set to 0. |
|
Returns an XML The resulting QDomElement holds the KeyFrameInterpolator parameters as well as the path keyFrames (if the keyFrame is defined by a pointer to a Frame, use its current value).
Use initFromDOMElement() to restore the ManipulatedFrame state from the resulting QDomElement. See Vec::domElement() for a complete example. See also Quaternion::domElement(), Camera::domElement()... Note that the Camera::keyFrameInterpolator() are automatically saved by QGLViewer::saveStateToFile() when a QGLViewer is closed. |
|
Draws the path used to interpolate the frame().
drawPath(); // Simply draws the interpolation path drawPath(3); // Draws path and cameras drawPath(5); // Draws path and axis
In the case where camera or axis is drawn,
See the keyFrames example for an illustration.
The color of the path is the current
|
|
Returns the duration of the KeyFrameInterpolator path, expressed in seconds. Simply corresponds to lastTime() - firstTime(). Returns 0.0 if the path has less than 2 keyFrames. See also keyFrameTime(). |
|
This signal is emitted when the interpolation reaches the first (when interpolationSpeed() is negative) or the last keyFrame.
When loopInterpolation() is |
|
Returns the time corresponding to the first keyFrame, expressed in seconds. Returns 0.0 if the path is empty. See also lastTime(), duration() and keyFrameTime(). |
|
Returns the associated Frame and that is interpolated by the KeyFrameInterpolator. When interpolationIsStarted(), this Frame's position and orientation will regularly be updated by a timer, so that they follow the KeyFrameInterpolator path. Set using setFrame() or with the KeyFrameInterpolator constructor. |
|
Restores the KeyFrameInterpolator state from a Note that the frame() pointer is not included in the domElement(): you need to setFrame() after this method to attach a Frame to the KeyFrameInterpolator. See Vec::initFromDOMElement() for a complete code example. See also Camera::initFromDOMElement() and Frame::initFromDOMElement(). |
|
Interpolate frame() at time If you simply want to change interpolationTime() but not the frame() state, use setInterpolationTime() instead. Emits the interpolated() signal and makes the frame() emit the Frame::interpolated() signal. |
|
This signal is emitted whenever the frame() state is interpolated. The emission of this signal triggers the synchronous emission of the frame() Frame::interpolated() signal, which may also be useful. This signal should especially be connected to your QGLViewer::updateGL() slot, so that the display is updated after every update of the KeyFrameInterpolator frame(): connect(myKeyFrameInterpolator, SIGNAL(interpolated()), SLOT(updateGL())); Note that the QGLViewer::camera() Camera::keyFrameInterpolator() created using QGLViewer::pathKey() have their interpolated() signals automatically connected to the QGLViewer::updateGL() slot. |
|
Returns |
|
Returns the current interpolation period, expressed in milliseconds. The update of the frame() state will be done by a timer at this period when interpolationIsStarted(). This period (multiplied by interpolationSpeed()) is added to the interpolationTime() at each update, and the frame() state is modified accordingly (see interpolateAtTime()). Default value is 40 milliseconds. |
|
Returns the current interpolation speed. Default value is 1.0, which means keyFrameTime() will be matched during the interpolation (provided that your main loop is fast enough). A negative value will result in a reverse interpolation of the keyFrames. See also interpolationPeriod(). |
|
Returns the current interpolation time (in seconds) along the KeyFrameInterpolator path. This time is regularly updated when interpolationIsStarted(). Can be set directly with setInterpolationTime() or interpolateAtTime(). |
|
Returns the Frame associated with the keyFrame at index
See also keyFrameTime().
|
|
Returns the time corresponding to the
See also keyFrame(). |
|
Returns the time corresponding to the last keyFrame, expressed in seconds. Returns 0.0 if the path is empty. See also firstTime(), duration() and keyFrameTime(). |
|
Returns
When interpolationTime() is otherwise reset to firstTime() (+ interpolationTime() - lastTime()) (and inversely for negative interpolationSpeed()) and interpolation continues. In both cases, the endReached() signal is emitted. |
|
Returns the number of keyFrames used by the interpolation. Use addKeyFrame() to add new keyFrames. |
|
Stops the interpolation and resets interpolationTime() to the firstTime(). If desired, call interpolateAtTime() after this method to actually move the frame() to firstTime(). |
|
Sets the frame() associated to the KeyFrameInterpolator. |
|
Sets the interpolationPeriod(). |
|
Sets the interpolationSpeed(). Negative or null values are allowed. |
|
Sets the interpolationTime().
|
|
Sets the loopInterpolation() value. |
|
Starts the interpolation process.
A timer is started with an interpolationPeriod() period that updates the frame()'s position and orientation. interpolationIsStarted() will return
If If interpolationTime() is larger than lastTime(), interpolationTime() is reset to firstTime() before interpolation starts (and inversely for negative interpolationSpeed()). Use setInterpolationTime() before calling this method to change the starting interpolationTime(). See the keyFrames example for an illustration. You may also be interested in QGLViewer::animate() and QGLViewer::startAnimation().
|
|
Stops an interpolation started with startInterpolation(). See interpolationIsStarted() and toggleInterpolation(). |
|
Calls startInterpolation() or stopInterpolation(), depending on interpolationIsStarted(). |