Key Frames | |
void | setFrame (Frame *fr) |
Frame * | frame () const |
void | addKeyFrame (const Frame &fr) |
void | addKeyFrame (const Frame &fr, const float time) |
void | addKeyFrame (const Frame *fr) |
void | addKeyFrame (const Frame *fr, const float time) |
void | deletePath () |
int | numberOfKeyFrames () const |
Frame | keyFrame (const int i) const |
Vec | keyFramePosition (const int i) const |
Quaternion | keyFrameOrientation (const int i) const |
float | keyFrameTime (const int i) const |
Interpolation parameters | |
float | interpolationTime () const |
void | setInterpolationTime (const float time) |
float | interpolationSpeed () const |
void | setInterpolationSpeed (const float speed) |
int | interpolationPeriod () const |
void | setInterpolationPeriod (const int msecs) |
bool | loopInterpolation () const |
void | setLoopInterpolation (const bool loop=true) |
bool | closedPath () const |
void | setClosedPath (const bool closed=true) |
Interpolation | |
virtual void | interpolateAtTime (const float time) |
void | startInterpolation (const int msecs=-1) |
void | stopInterpolation () |
void | resetInterpolation () |
bool | interpolationIsStarted () const |
void | toggleInterpolation () |
Path drawing | |
virtual void | drawPath (const int mask=1, int nbFrames=6, const float scale=1.0f) |
virtual void | drawPathModifyGLState (const int mask, int nbFrames, const float scale) |
XML representation | |
virtual QDomElement | domElement (const QString &name, QDomDocument &doc) const |
virtual void | initFromDOMElement (const QDomElement &de) |
Public Slots | |
virtual void | update () |
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.
Use addKeyFrame() to define the keyframes and then call startInterpolation(). The frame() associated with the interpolator (using the constructor or with setFrame()) will then be updated over time. frame() should be a pointer to one of the Frame of your application, the one that you want the KeyFrameInterpolator to drive:
// The KeyFrameInterpolator must be 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(); glPushMatrix(); // Recover 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 interpolation can loop (setLoopInterpolation()) and the keyFrame path can be closed (setClosedPath()) (not yet implemented). The current interpolation time (interpolationTime()) and speed (interpolationSpeed()) can also be tuned.
The keyFrames are defined by a Frame and a time, expressed in seconds. If the keyFrame is defined using a pointer to a Frame, the keyFrame path will automatically be updated if the Frame is modified (see the Frame::modified() signal).
The time has to be monotonously increasing over keyFrames. When interpolationSpeed() equals 1.0, these times correspond to actual user' seconds during the interpolation (provided that your QGLViewer::draw() function is fast enough).
Note that a Camera has 12 attached KeyFrameInterpolator binded to the F1-F12 keys. Press Alt+Fx to define a new keyFrame for path x. Pressing Fx plays/pause path interpolation. See the shortcuts page for details.
When interpolated, the KeyFrameInterpolator emits an interpolated() signal, which should be connected to the viewer's updateGL() slot. See the interpolated() documentation for details.
|
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. Releases allocated memory. |
|
Same as the reference version of addKeyFrame(), but with a pointer to a frame. |
|
Same as the reference version of addKeyFrame(), but with a pointer to a frame. See the keyFrames example for an illustration. |
|
Defines a new keyFrame, and the associated time (in seconds) that will be used to rhythm the interpolation. The keyFrameTime() have to be monotonously increasing over keyFrames. |
|
Defines a new keyFrame. Same as addKeyFrame() with a keyFrameTime() specification, except that the time is automatically set as previous keyFrameTime() + 1 second. See the keyFrames example for an illustration. |
|
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. Use initFromDOMElement() to restore the KeyFrameInterpolator state from the resulting domElement. See also Camera::domElement(), Frame::domElement()...
If you want to save the KeyFrameInterpolator QDomDocument doc( "myKFI" ); doc.appendChild( kfi.domElement("KFI", doc) ); ofstream file( "myKFI.xml" ); file << doc.toString();
Use the following code to retrieve the KeyFrameInterpolator // Load DOM from file QDomDocument doc; QFile f("myKFI.xml"); f.open(IO_ReadOnly); doc.setContent(&f); f.close(); // Parse the DOM tree QDomElement main=doc.documentElement(); kfi.initFromDOMElement(main);
|
|
Draws the path that will be used to interpolate the frame().
drawPath(); // Simply draws the interpolation path drawPath(3); // Draws path and cameras drawPath(7); // Draws path, cameras and axis drawPath(5); // Draws path and axis
When camera or axis is drawn,
The color of the path is the one of 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. |
|
This signal is emitted when the interpolation reaches the last keyFrameTime(). Use startInterpolation() to start the interpolation and you will be warned with this signal when the interpolation is finished.
|
|
The frame that is associated and modified by the KeyFrameInterpolator. Set using setFrame() or with the KeyFrameInterpolator() constructor. |
|
Restore the KeyFrameInterpolator state from a QDomElement created by domElement(). See also Camera::initFromDOMElement(), Frame::initFromDOMElement().
|
|
Interpolate frame() for time If you simply want to change interpolationTime() but not the frame(), use setInterpolationTime() instead. Emits the interpolated() signal. |
|
This signal is emitted whenever the frame() state is interpolated. Connect this signal to any object that should be notified. This signal should especially be connected to your viewer updateGL() slot, so that the display is updated after every update of the KeyFrameInterpolator frame(). Use code like this : connect(myKeyFrameInterpolator, SIGNAL(interpolated()), SLOT(updateGL())); Note that every QGLViewer::camera() holds several KeyFrameInterpolator and that their interpolated() signals are automatically connected to the viewer's updateGL() slot. 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: QGLViewer::connectSignalToAllViewers(myKeyFrameInterpolator, SIGNAL(interpolated())); See also the ManipulatedFrame::manipulated() and spinningFrame::spinned() signals documentations. |
|
Returns |
|
Returns the current interpolation period, expressed in milliseconds. This period will be added to the interpolationTime() at each update(), when interpolationIsStarted() is |
|
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 respected during the interpolation (see startInterpolation()), provided that your display is fast enough. A negative value will result in a reverse interpolation of the keyFrames. |
|
Current interpolation time, updated when interpolationIsStarted() is true. Can be set directly with setInterpolationTime() or interpolateAtTime(). |
|
|
|
Returns the keyFrame orientation of keyFrame number |
|
Returns the keyFrame position of keyFrame number |
|
Returns the time associated with the keyframe number |
|
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 (not much more than stopInterpolation() and setInterpolationTime()). |
|
Set the closedPath() value.
|
|
Set the frame that will be associated with the KeyFrameInterpolator. Current frame is in frame(). The Frame you associate with a KeyFrameInterpolator is usually one of your application Frame, that you would like to interpolate. You will then setFrame() to a pointer to your Frame. |
|
Set the interpolationPeriod(). |
|
Set the interpolation speed. Negative values are possible. See interpolationSpeed(). |
|
Set the current interpolation time. See also interpolationTime().
|
|
Set the loopInterpolation() value. |
|
Starts the interpolation process. A timer will be started with a period defined by If interpolationTime() is greater than the last keyFrameTime(), it is reset to the first keyFrameTime() and interpolation starts from there (natural behavior).
If You may also be interested in QGLViewer::animate() and QGLViewer::startAnimation(). See the keyFrames example for an illustration.
|
|
Stops an interpolation started with startInterpolation(). |
|
Calls startInterpolation() or stopInterpolation(), depending on interpolationIsStarted(). |
|
Interpolates frame() for the next interpolationTime() (defined by interpolationPeriod()). This internal function is called by a timer when startInterpolation() is called. It is publicly provided for your debugging purpose only. stopInterpolation() is called when interpolationTime() reaches the first or last keyFrameTime(), unless loopInterpolation() is |