#include <keyFrameInterpolator.h>
Associated Frame | |
Frame * | frame () const |
void | setFrame (Frame *fr) |
Path parameters | |
int | numberOfKeyFrames () const |
Frame | keyFrame (int i) const |
Vec | keyFramePosition (int i) const |
Quaternion | keyFrameOrientation (int i) const |
float | keyFrameTime (int i) const |
float | duration () const |
float | firstTime () const |
float | lastTime () const |
Interpolation parameters | |
float | interpolationTime () const |
float | interpolationSpeed () const |
int | interpolationPeriod () const |
bool | loopInterpolation () const |
bool | closedPath () const |
void | setInterpolationTime (float time) |
void | setInterpolationSpeed (float speed) |
void | setInterpolationPeriod (int msecs) |
void | setLoopInterpolation (bool loop=true) |
void | setClosedPath (bool closed=true) |
Interpolation | |
bool | interpolationIsStarted () const |
virtual void | interpolateAtTime (float time) |
void | startInterpolation (int msecs=-1) |
void | stopInterpolation () |
void | resetInterpolation () |
void | toggleInterpolation () |
Path drawing | |
virtual void | drawPath (int mask=1, int nbFrames=6, float scale=1.0f) |
virtual void | drawPathModifyGLState (int mask, int nbFrames, float scale) |
XML representation | |
virtual QDomElement | domElement (const QString &name, QDomDocument &doc) const |
virtual void | initFromDOMElement (const QDomElement &e) |
Adding Key Frames | |
void | addKeyFrame (const Frame &fr) |
void | addKeyFrame (const Frame &fr, float time) |
void | addKeyFrame (const Frame *fr) |
void | addKeyFrame (const Frame *fr, float time) |
void | deletePath () |
Signals | |
void | interpolated () |
void | finished () |
Public Member Functions | |
KeyFrameInterpolator (Frame *fr=NULL) | |
virtual | ~KeyFrameInterpolator () |
KeyFrameInterpolator implements a classical interpolation of key Frames, using a smooth Catmull-Rom interpolation. See the keyFrames example for an illustration of the class.
A KeyFrameInterpolator holds some key frames, that define a path, and is given a pointer to a Frame of your application. When the user startInterpolation(), the KeyFrameInterpolator will make this frame() follow the path, updating its position and orientation over time. Here is a typical utilization example:
// The KeyFrameInterpolator kfi is given the Frame that it will drive over time. KeyFrameInterpolator kfi( new Frame() ); init() { kfi.addKeyFrame( Frame( Vec(1,0,2), Quaternion() ) ); kfi.addKeyFrame( new Frame( Vec(2,1,0), Quaternion() ) ); // ...and so on for all the Key Frames. // Ask for a display update after each update of the KeyFrameInterpolator connect(&kfi, SIGNAL(interpolated()), SLOT(updateGL())); kfi.startInterpolation(); } draw() { kfi.drawPath(); // optional glPushMatrix(); // Retrieve kfi associated frame with kfi.frame(), and use its matrix(). glMultMatrixd( kfi.frame()->matrix() ); // Draw your object here. Its position and orientation will be 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 (see 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' seconds during the interpolation (provided that your QGLViewer::draw() function is fast enough).
During the interpolation, the KeyFrameInterpolator emits an interpolated() signal, which will usually be connected to the viewer's updateGL()
slot. The finished() signal is emitted at the end of an interpolation().
Note that a Camera has 12 potential KeyFrameInterpolator binded to the F1-F12 keys, that can be used to drive the Camera along a path, or to restore a saved position (path made of a single key frame). Press Alt+Fx to define a new keyFrame for path x. Pressing Fx plays/pause path interpolation. See the keyboard page for details.
The interpolation can loop (setLoopInterpolation()) and the keyFrame path can be closed (setClosedPath()) (not yet implemented). The current interpolationTime() and the interpolationSpeed() can also be tuned.
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.
If the application main loop is fast enough, and interpolationSpeed() equals 1.0 (default), the interpolation will be real-time : the key frames will be reached at their precise keyFrameTime().
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. The number of frame() updates is hence constant, even when real-time interpolation is not possible (for instance because drawing is too slow) and the timer frequency cannot be satisfied.
The interpolation is stopped when interpolationTime() is greater than the lastTime() (unless loopInterpolation() is true
) and the finished() signal is then emitted.
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. 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; }
You may want to temporally disconnect the kfi
interpolated() signal from the viewers' updateGL() slot before calling this code.
|
Creates a KeyFrameInterpolator, which will drive the Use addKeyFrame() to define the key frames. Default interpolationTime() is 0.0, and interpolationSpeed() is 1.0. See the keyFrames example for an illustration. |
|
Virtual destructor. Clears the key frame path. |
|
Appends a new key frame to the path. The key Frame is given as a pointer to a Frame, which will be connected to the KeyFrameInterpolator: when Use the const reference version of this function if you want to provide a fixed key frame.
|
|
Same as the pointer version of addKeyFrame(), except the keyFrameTime() is set to the previous keyFrameTime() plus one second (or 0.0 if there is no previous key frame). |
|
Appends a new key frame to the path, with its associated time (in seconds). The path will use the current |
|
Appends a new key frame to path. Same as addKeyFrame(), except that the keyFrameTime() is automatically set to previous keyFrameTime() plus one second (or 0.0 if there is no previous key frame). |
|
Whether or not (default) the path defined by the keyFrames is a closed loop. When Use setLoopInterpolation() to create a continuous animation over the entire path.
|
|
Remove all keyFrames from the path. The numberOfKeyFrames() is set to 0. |
|
Creates an XML QDomElement that represents the KeyFrameInterpolator.
If you want to save the KeyFrameInterpolator
Use initFromDOMElement() to restore the KeyFrameInterpolator state from the resulting domElement. Note that the Camera::keyFrameInterpolator() are automatically saved by QGLViewer::saveToFile() when a QGLViewer is closed (default keyboard accelerator is 'Escape'). See also Camera::domElement() or Frame::domElement().
|
|
Draws the path that will be used to interpolate the frame().
When camera or axis is drawn,
The color of the path is the current See the keyFrames example for an illustration. This function actually call drawPathModifyGLState(), but saves and restores the GL state before and after. |
|
Same as drawPath(), but the GL state is modified : GL_LIGHTING is disabled and line width set to 2. This function should only be used for efficiency reasons (as is done by QGLViewer::postDraw()). Prefer calling drawPath(), which preserves the GL state, for debugging purpose. |
|
Returns the duration of the KeyFrameInterpolator path, expressed in seconds. Returns 0.0 if path is empty or made of a single KeyFrame. See also firstTime(), lastTime() and keyFrameTime(). |
|
This signal is emitted when the interpolation reaches the last key frame. Use startInterpolation() to start the interpolation and you will be warned with this signal when the interpolation is finished.
|
|
First key frame time, in seconds. Returns 0.0 is no key frame is defined. See also lastTime() and duration(). |
|
The frame that is associated and modified by the KeyFrameInterpolator. When the interpolationIsStarted(), this Frame 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. |
|
Restore the KeyFrameInterpolator state from a QDomElement created by domElement().
Use the following code to retrieve the KeyFrameInterpolator
See also Camera::initFromDOMElement() and Frame::initFromDOMElement().
|
|
Interpolate frame() for time If you simply want to change interpolationTime() but not the frame(), 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. Connect this signal to any object that should be notified. The emission of this signal triggers the synchonous emission of the frame() Frame::interpolated() signal, which may also be useful.
This signal should especially be connected to your viewer
Note that every QGLViewer::camera() holds Camera::nbPaths() KeyFrameInterpolator and that their interpolated() signals are automatically connected to the viewer's When several viewers display the same scene, it may be interesting to update all the viewers when a KeyFrameInterpolator (and probably hence an object) is interpolated. Simply use this code to achieve this behavior:
See also the ManipulatedFrame::manipulated() and SpinningFrame::spinned() signals documentations. |
|
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 also 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 that the times associated with the keyFrames (see keyFrameTime() and addKeyFrame()), expressed in seconds, will be matched during the interpolation, provided that your display is fast enough. A negative value will result in a reverse interpolation of the keyFrames. See also interpolationPeriod(). |
|
Current interpolation time (in seconds) along the KeyFrameInterpolator path, updated when interpolationIsStarted(). Can be set directly with setInterpolationTime() or interpolateAtTime(). |
|
Returns the Frame associated with the keyframe number
|
|
Returns the keyFrame orientation of keyFrame number |
|
Returns the keyFrame position of keyFrame number |
|
Returns the time associated with the keyframe number |
|
Last key frame time, in seconds. Returns 0.0 is no key frame is defined. See also firstTime() and duration(). |
|
Whether or not (default) the interpolation will be played in (infinite) loop when startInterpolation() is called (until stopInterpolation() is called). When Use setClosedPath() to create a closed path with the keyFrames. |
|
Number of keyFrames used in the interpolation. Use addKeyFrame() to add new keyFrames. |
|
interpolationTime() is reset to the keyFrameTime() associated with the first keyFrame and interpolation is stopped. |
|
Sets the closedPath() value.
|
|
Set the frame that will be associated with the KeyFrameInterpolator. Current value is frame().
The Frame |
|
Sets the interpolationPeriod(). |
|
Sets the interpolation speed. Negative values are possible. See interpolationSpeed(). |
|
Sets the current interpolation time. See also interpolationTime().
|
|
Sets the loopInterpolation() value. |
|
Starts the interpolation process. A timer is started with a period defined by If interpolationTime() is larger than lastTime(), interpolationTime() is reset to firstTime() before interpolation starts.
If Use setInterpolationTime() before calling this method to change the starting interpolationTime(). You may also be interested in QGLViewer::animate() and QGLViewer::startAnimation(). See the keyFrames example for an illustration.
|
|
Stops an interpolation started with startInterpolation(). See also toggleInterpolation(). |
|
Calls startInterpolation() or stopInterpolation(), depending on interpolationIsStarted(). |