KeyFrameInterpolator Class Reference

A key frame interpolator. More...

#include <keyFrameInterpolator.h>

List of all members.

Associated Frame

Frameframe () 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 ()


Detailed Description

A key frame interpolator.

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.

Interpolation details

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.

Attention:
If a Constraint is attached to the frame() (see Frame::setConstraint()), it should be desactived before interpolationIsStarted(), otherwise the interpolated motion (computed as if there was no constraint) will probably be erroneous.

Retrieving interpolated values

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.


Constructor & Destructor Documentation

KeyFrameInterpolator Frame fr = NULL  ) 
 

Creates a KeyFrameInterpolator, which will drive the fr frame (see setFrame() for details on the associated frame).

Use addKeyFrame() to define the key frames. Default interpolationTime() is 0.0, and interpolationSpeed() is 1.0.

See the keyFrames example for an illustration.

~KeyFrameInterpolator  )  [virtual]
 

Virtual destructor. Clears the key frame path.


Member Function Documentation

void addKeyFrame const Frame fr,
float  time
[slot]
 

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 fr is modified, the KeyFrameInterpolator path is updated in consequence. This allows for dynamic paths, where key Frame can be edited, even during the interpolation. See the keyFrames example for an illustration.

Use the const reference version of this function if you want to provide a fixed key frame.

NULL fr pointers are silently ignored. time is given in seconds, and has to be monotonously increasing over key frames.

void addKeyFrame const Frame fr  )  [slot]
 

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).

void addKeyFrame const Frame fr,
float  time
[slot]
 

Appends a new key frame to the path, with its associated time (in seconds). The path will use the current fr state. If you want the path to change when fr is modified, you need to pass a pointer to the Frame instead (see the pointer version of addKeyFrame()). The keyFrameTime() have to be monotonously increasing over keyFrames.

void addKeyFrame const Frame fr  )  [slot]
 

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).

bool closedPath  )  const [inline]
 

Whether or not (default) the path defined by the keyFrames is a closed loop. When true, the last and the first KeyFrame are linked by a new spline segment.

Use setLoopInterpolation() to create a continuous animation over the entire path.

Attention:
The closed path feature is not yet implemented.

void deletePath  )  [slot]
 

Remove all keyFrames from the path. The numberOfKeyFrames() is set to 0.

QDomElement domElement const QString &  name,
QDomDocument &  doc
const [virtual]
 

Creates an XML QDomElement that represents the KeyFrameInterpolator. name is the name of the QDomElement tag. You need to provide the QDomDocument doc that will hold the resulting element.

If you want to save the KeyFrameInterpolator kfi in a file, use

QDomDocument doc( "myKFI" ); doc.appendChild( kfi.domElement("KFI", doc) ); QFile f("myKFI.xml"); if (f.open(IO_WriteOnly)) { QTextStream out(&f); doc.save(out, 2); }

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().

Attention:
For KeyFrames defined by pointers, only the values of the pointed Frame are saved. See Frame::domElement().

void drawPath int  mask = 1,
int  nbFrames = 6,
float  scale = 1.0f
[virtual]
 

Draws the path that will be used to interpolate the frame().

mask controls what is drawn on the path : if (mask & 1) (default), the position path is drawn. If (mask & 2), a camera representation is regularly drawn and if (mask & 4), an oriented axis is regularly drawn. Examples:

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, nbFrames controls the number of objects (axis or camera) drawn between two successive keyFrames. When nbFrames=1, only the path Key Frames are drawn. nbFrames=2 also draws the intermediate orientation, etc. The maximum value is 30. nbFrames should divide 30 so that an object is drawn for each Key Frame. Default value is 6.

scale (default=1.0) controls the scaling of the camera and axis drawing. A value of QGLViewer::sceneRadius() should give good results.

The color of the path is the current glColor().

See the keyFrames example for an illustration.

This function actually call drawPathModifyGLState(), but saves and restores the GL state before and after.

void drawPathModifyGLState int  mask,
int  nbFrames,
float  scale
[virtual]
 

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.

float duration  )  const
 

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().

void finished  )  [signal]
 

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.

Note:
A call to stopInterpolation() will not emit this signal. If loopInterpolation() is activated, the signal is emitted each time the interpolation loops back to first keyFrame.

If the interpolationSpeed() is negative, finished() is emitted when interpolationTime() reaches firstTime() instead of lastTime().

float firstTime  )  const
 

First key frame time, in seconds. Returns 0.0 is no key frame is defined. See also lastTime() and duration().

Frame* frame  )  const [inline]
 

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.

void initFromDOMElement const QDomElement &  e  )  [virtual]
 

Restore the KeyFrameInterpolator state from a QDomElement created by domElement().

Use the following code to retrieve the KeyFrameInterpolator kfi from the saved file:

// Load DOM from file QDomDocument doc; QFile f("myKFI.xml"); if (f.open(IO_ReadOnly)) { doc.setContent(&f); f.close(); } // Parse the DOM tree and initialize kfi QDomElement main=doc.documentElement(); kfi.initFromDOMElement(main);

See also Camera::initFromDOMElement() and Frame::initFromDOMElement().

Attention:
For KeyFrames defined by pointers, only the values of the pointed Frame are saved, and hence retrieved.

The attached frame() is not set by this method. Use setFrame() for that.

void interpolateAtTime float  time  )  [virtual, slot]
 

Interpolate frame() for time time. interpolationTime() is set to time and frame() is set accordingly.

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.

void 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 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 Camera::nbPaths() 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.

bool interpolationIsStarted  )  const [inline]
 

Returns true when the interpolation is being performed. Calls to startInterpolation(), stopInterpolation() or toggleInterpolation() migth modify this state.

int interpolationPeriod  )  const [inline]
 

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.

float interpolationSpeed  )  const [inline]
 

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().

float interpolationTime  )  const [inline]
 

Current interpolation time (in seconds) along the KeyFrameInterpolator path, updated when interpolationIsStarted(). Can be set directly with setInterpolationTime() or interpolateAtTime().

Frame keyFrame int  i  )  const
 

Returns the Frame associated with the keyframe number i. See also keyFramePosition(), keyFrameOrientation() and keyFrameTime(). i has to be in the range 0..numberOfKeyFrames()-1.

Note:
If this keyFrame was defined using a pointer to a Frame (see addKeyFrame()), the current pointed Frame state is returned.

Quaternion keyFrameOrientation int  i  )  const
 

Returns the keyFrame orientation of keyFrame number i (located in the 0..numberOfKeyFrames()-1 interval). See also keyFramePosition(), keyFrameTime() and numberOfKeyFrames().

Vec keyFramePosition int  i  )  const
 

Returns the keyFrame position of keyFrame number i (located in the 0..numberOfKeyFrames()-1 interval). See also keyFrameOrientation(), keyFrameTime() and numberOfKeyFrames().

float keyFrameTime int  i  )  const
 

Returns the time associated with the keyframe number i (located in the 0..numberOfKeyFrames()-1 interval). See also keyFramePosition(), keyFrameOrientation() and addKeyFrame().

float lastTime  )  const
 

Last key frame time, in seconds. Returns 0.0 is no key frame is defined. See also firstTime() and duration().

bool loopInterpolation  )  const [inline]
 

Whether or not (default) the interpolation will be played in (infinite) loop when startInterpolation() is called (until stopInterpolation() is called). When false, the interpolation will stop when interpolationTime() reaches lastTime().

Use setClosedPath() to create a closed path with the keyFrames.

int numberOfKeyFrames  )  const [inline]
 

Number of keyFrames used in the interpolation. Use addKeyFrame() to add new keyFrames.

void resetInterpolation  )  [slot]
 

interpolationTime() is reset to the keyFrameTime() associated with the first keyFrame and interpolation is stopped.

void setClosedPath bool  closed = true  )  [inline, slot]
 

Sets the closedPath() value.

Attention:
The closed path feature is not yet implemented.

void setFrame Frame fr  )  [slot]
 

Set the frame that will be associated with the KeyFrameInterpolator. Current value is frame().

The Frame fr you associate with a KeyFrameInterpolator is one of your application's Frame, that you would like to interpolate using the KeyFrameInterpolator.

void setInterpolationPeriod int  msecs  )  [inline, slot]
 

Sets the interpolationPeriod().

void setInterpolationSpeed float  speed  )  [inline, slot]
 

Sets the interpolation speed. Negative values are possible. See interpolationSpeed().

void setInterpolationTime float  time  )  [inline, slot]
 

Sets the current interpolation time. See also interpolationTime().

Attention:
The frame() state is not affected by this method. Use this function to define the starting time of a future interpolation (see startInterpolation()). Use interpolateAtTime() to actually interpolate at a given time.

void setLoopInterpolation bool  loop = true  )  [inline, slot]
 

Sets the loopInterpolation() value.

void startInterpolation int  msecs = -1  )  [slot]
 

Starts the interpolation process. A timer is started with a period defined by msecs (which becomes the new interpolationPeriod()) and updates the frame() position and orientation. interpolationIsStarted() will be true until stopInterpolation() or toggleInterpolation() is called.

If interpolationTime() is larger than lastTime(), interpolationTime() is reset to firstTime() before interpolation starts.

If msecs is negative (default), the current interpolationPeriod() is used (default is 40 milliseconds, see setInterpolationPeriod()), otherwise interpolationPeriod() is set to msecs.

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.

Attention:
The keyFrames must be defined before you startInterpolation(), or else the interpolation will naturally immediately stop.

void stopInterpolation  )  [slot]
 

Stops an interpolation started with startInterpolation(). See also toggleInterpolation().

void toggleInterpolation  )  [inline, slot]
 

Calls startInterpolation() or stopInterpolation(), depending on interpolationIsStarted().


Generated on Wed Dec 1 12:41:26 2004 for libQGLViewer by doxygen 1.3.7