24 #include "qglviewer.h"
26 using namespace qglviewer;
29 #if QT_VERSION < 0x040000
31 # define peekNext current
41 : frame_(NULL), period_(40), interpolationTime_(0.0), interpolationSpeed_(1.0), interpolationStarted_(false),
42 closedPath_(false), loopInterpolation_(false), pathIsValid_(false), valuesAreValid_(true), currentFrameValid_(false)
46 #if QT_VERSION < 0x040000
47 keyFrame_.setAutoDelete(
true);
49 for (
int i=0; i<4; ++i)
50 #
if QT_VERSION >= 0x040000
51 currentFrame_[i] =
new QMutableListIterator<KeyFrame*>(keyFrame_);
53 currentFrame_[i] =
new QPtrListIterator<KeyFrame>(keyFrame_);
55 connect(&timer_, SIGNAL(timeout()), SLOT(update()));
62 for (
int i=0; i<4; ++i)
63 delete currentFrame_[i];
84 void KeyFrameInterpolator::update()
106 setInterpolationTime(keyFrame_.last()->time() - keyFrame_.first()->time() + interpolationTime_);
143 if (!keyFrame_.isEmpty())
150 interpolationStarted_ =
true;
160 interpolationStarted_ =
false;
191 if (keyFrame_.isEmpty())
192 interpolationTime_ = time;
194 if ( (!keyFrame_.isEmpty()) && (keyFrame_.last()->time() > time) )
195 qWarning(
"Error in KeyFrameInterpolator::addKeyFrame: time is not monotone");
197 keyFrame_.append(
new KeyFrame(frame, time));
198 connect(frame, SIGNAL(modified()), SLOT(invalidateValues()));
199 valuesAreValid_ =
false;
200 pathIsValid_ =
false;
201 currentFrameValid_ =
false;
214 if (keyFrame_.isEmpty())
215 interpolationTime_ = time;
217 if ( (!keyFrame_.isEmpty()) && (keyFrame_.last()->time() > time) )
218 qWarning(
"Error in KeyFrameInterpolator::addKeyFrame: time is not monotone");
220 keyFrame_.append(
new KeyFrame(frame, time));
222 valuesAreValid_ =
false;
223 pathIsValid_ =
false;
224 currentFrameValid_ =
false;
236 if (keyFrame_.isEmpty())
251 if (keyFrame_.isEmpty())
254 time = keyFrame_.last()->time() + 1.0;
263 #if QT_VERSION >= 0x040000
264 qDeleteAll(keyFrame_);
267 pathIsValid_ =
false;
268 valuesAreValid_ =
false;
269 currentFrameValid_ =
false;
272 static void drawCamera(
float scale)
274 glDisable(GL_LIGHTING);
276 const float halfHeight = scale * 0.07;
277 const float halfWidth = halfHeight * 1.3;
278 const float dist = halfHeight / tan(M_PI/8.0);
280 const float arrowHeight = 1.5f * halfHeight;
281 const float baseHeight = 1.2f * halfHeight;
282 const float arrowHalfWidth = 0.5f * halfWidth;
283 const float baseHalfWidth = 0.3f * halfWidth;
286 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
287 glBegin(GL_LINE_STRIP);
288 glVertex3f(-halfWidth, halfHeight,-dist);
289 glVertex3f(-halfWidth,-halfHeight,-dist);
290 glVertex3f( 0.0f, 0.0f, 0.0f);
291 glVertex3f( halfWidth,-halfHeight,-dist);
292 glVertex3f(-halfWidth,-halfHeight,-dist);
294 glBegin(GL_LINE_STRIP);
295 glVertex3f( halfWidth,-halfHeight,-dist);
296 glVertex3f( halfWidth, halfHeight,-dist);
297 glVertex3f( 0.0f, 0.0f, 0.0f);
298 glVertex3f(-halfWidth, halfHeight,-dist);
299 glVertex3f( halfWidth, halfHeight,-dist);
303 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
306 glVertex3f(-baseHalfWidth, halfHeight,-dist);
307 glVertex3f( baseHalfWidth, halfHeight,-dist);
308 glVertex3f( baseHalfWidth, baseHeight,-dist);
309 glVertex3f(-baseHalfWidth, baseHeight,-dist);
313 glBegin(GL_TRIANGLES);
314 glVertex3f( 0.0f, arrowHeight,-dist);
315 glVertex3f(-arrowHalfWidth, baseHeight, -dist);
316 glVertex3f( arrowHalfWidth, baseHeight, -dist);
353 const int nbSteps = 30;
357 #if QT_VERSION < 0x040000
358 path_.reserve(nbSteps*keyFrame_.count());
361 if (keyFrame_.isEmpty())
364 if (!valuesAreValid_)
365 updateModifiedFrameValues();
367 if (keyFrame_.first() == keyFrame_.last())
368 path_.push_back(
Frame(keyFrame_.first()->position(), keyFrame_.first()->orientation()));
373 kf_[0] = keyFrame_.first();
375 #if QT_VERSION >= 0x040000
377 kf_[2] = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
379 kf_[3] = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
381 kf_[2] = keyFrame_.next();
382 kf_[3] = keyFrame_.next();
387 Vec diff = kf_[2]->position() - kf_[1]->position();
388 Vec v1 = 3.0 * diff - 2.0 * kf_[1]->tgP() - kf_[2]->tgP();
389 Vec v2 = -2.0 * diff + kf_[1]->tgP() + kf_[2]->tgP();
392 for (
int step=0; step<nbSteps; ++step)
394 float alpha = step /
static_cast<float>(nbSteps);
395 fr.
setPosition(kf_[1]->position() + alpha * (kf_[1]->tgP() + alpha * (v1+alpha*v2)));
404 #if QT_VERSION >= 0x040000
406 kf_[3] = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
408 kf_[3] = keyFrame_.next();
412 path_.push_back(
Frame(kf_[1]->position(), kf_[1]->orientation()));
419 glDisable(GL_LIGHTING);
424 glBegin(GL_LINE_STRIP);
425 #if QT_VERSION >= 0x040000
426 Q_FOREACH (
Frame fr, path_)
429 # if QT_VERSION < 0x030000
430 for (
int i=0; i < path_.size(); ++i)
431 glVertex3fv((path_.at(i)).position());
433 for (QValueVector<Frame>::const_iterator pnt=path_.begin(), end=path_.end(); pnt!=end; ++pnt)
434 glVertex3fv((*pnt).position());
442 if (nbFrames > nbSteps)
445 #if QT_VERSION >= 0x040000
446 Q_FOREACH (
Frame fr, path_)
448 # if QT_VERSION < 0x030000
449 for (
int i=0; i < path_.size(); ++i)
451 for (QValueVector<Frame>::const_iterator pnt=path_.begin(), end=path_.end(); pnt!=end; ++pnt)
454 if ((count++) >= goal)
456 goal += nbSteps /
static_cast<float>(nbFrames);
458 #if QT_VERSION >= 0x040000
459 glMultMatrixd(fr.
matrix());
461 # if QT_VERSION < 0x030000
462 glMultMatrixd((path_.at(i)).matrix());
464 glMultMatrixd((*pnt).matrix());
467 if (mask & 2) drawCamera(scale);
475 void KeyFrameInterpolator::updateModifiedFrameValues()
477 Quaternion prevQ = keyFrame_.first()->orientation();
479 #if QT_VERSION >= 0x040000
480 for (
int i=0; i<keyFrame_.size(); ++i)
482 kf = keyFrame_.at(i);
484 for (kf = keyFrame_.first(); kf; kf=keyFrame_.next())
488 kf->updateValuesFromPointer();
489 kf->flipOrientationIfNeeded(prevQ);
490 prevQ = kf->orientation();
493 KeyFrame* prev = keyFrame_.first();
494 kf = keyFrame_.first();
495 #if QT_VERSION >= 0x040000
500 #if QT_VERSION >= 0x040000
501 KeyFrame* next = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
504 KeyFrame* next = keyFrame_.next();
507 kf->computeTangent(prev, next);
509 kf->computeTangent(prev, kf);
513 valuesAreValid_ =
true;
524 const KeyFrame*
const kf = keyFrame_.at(index);
525 return Frame(kf->position(), kf->orientation());
533 return keyFrame_.at(index)->time();
550 if (keyFrame_.isEmpty())
553 return keyFrame_.first()->time();
561 if (keyFrame_.isEmpty())
564 return keyFrame_.last()->time();
567 void KeyFrameInterpolator::updateCurrentKeyFrameForTime(
float time)
573 if (!currentFrameValid_)
575 #if QT_VERSION >= 0x040000
576 currentFrame_[1]->toFront();
578 currentFrame_[1]->toFirst();
581 while (currentFrame_[1]->peekNext()->time() > time)
583 currentFrameValid_ =
false;
584 #if QT_VERSION >= 0x040000
585 if (!currentFrame_[1]->hasPrevious())
587 if (currentFrame_[1]->atFirst())
590 #if QT_VERSION >= 0x040000
591 currentFrame_[1]->previous();
593 --(*currentFrame_[1]);
597 if (!currentFrameValid_)
598 *currentFrame_[2] = *currentFrame_[1];
600 while (currentFrame_[2]->peekNext()->time() < time)
602 currentFrameValid_ =
false;
603 #if QT_VERSION >= 0x040000
604 if (!currentFrame_[2]->hasNext())
606 if (currentFrame_[2]->atLast())
609 #if QT_VERSION >= 0x040000
610 currentFrame_[2]->next();
612 ++(*currentFrame_[2]);
616 if (!currentFrameValid_)
618 *currentFrame_[1] = *currentFrame_[2];
619 #if QT_VERSION >= 0x040000
620 if ((currentFrame_[1]->hasPrevious()) && (time < currentFrame_[2]->peekNext()->time()))
621 currentFrame_[1]->previous();
623 if ((!currentFrame_[1]->atFirst()) && (time < currentFrame_[2]->current()->time()))
624 --(*currentFrame_[1]);
627 *currentFrame_[0] = *currentFrame_[1];
628 #if QT_VERSION >= 0x040000
629 if (currentFrame_[0]->hasPrevious())
630 currentFrame_[0]->previous();
632 if (!currentFrame_[0]->atFirst())
633 --(*currentFrame_[0]);
636 *currentFrame_[3] = *currentFrame_[2];
637 #if QT_VERSION >= 0x040000
638 if (currentFrame_[3]->hasNext())
639 currentFrame_[3]->next();
641 if (!currentFrame_[3]->atLast())
642 ++(*currentFrame_[3]);
645 currentFrameValid_ =
true;
646 splineCacheIsValid_ =
false;
653 void KeyFrameInterpolator::updateSplineCache()
655 Vec delta = currentFrame_[2]->peekNext()->position() - currentFrame_[1]->peekNext()->position();
656 v1 = 3.0 * delta - 2.0 * currentFrame_[1]->peekNext()->tgP() - currentFrame_[2]->peekNext()->tgP();
657 v2 = -2.0 * delta + currentFrame_[1]->peekNext()->tgP() + currentFrame_[2]->peekNext()->tgP();
658 splineCacheIsValid_ =
true;
672 if ((keyFrame_.isEmpty()) || (!
frame()))
675 if (!valuesAreValid_)
676 updateModifiedFrameValues();
678 updateCurrentKeyFrameForTime(time);
680 if (!splineCacheIsValid_)
684 float dt = currentFrame_[2]->peekNext()->time() - currentFrame_[1]->peekNext()->time();
688 alpha = (time - currentFrame_[1]->peekNext()->time()) / dt;
692 Vec pos = currentFrame_[1]->peekNext()->position() + alpha * (currentFrame_[1]->peekNext()->tgP() + alpha * (v1+alpha*v2));
694 currentFrame_[2]->peekNext()->tgQ(), currentFrame_[2]->peekNext()->orientation(), alpha);
717 QDomElement de = document.createElement(name);
719 #if QT_VERSION >= 0x040000
720 Q_FOREACH (KeyFrame* kf, keyFrame_)
722 for (KeyFrame* kf = keyFrame_.first(); kf; kf = keyFrame_.next() )
725 Frame fr(kf->position(), kf->orientation());
726 QDomElement kfNode = fr.
domElement(
"KeyFrame", document);
727 kfNode.setAttribute(
"index", QString::number(count));
728 kfNode.setAttribute(
"time", QString::number(kf->time()));
729 de.appendChild(kfNode);
732 de.setAttribute(
"nbKF", QString::number(keyFrame_.count()));
736 de.setAttribute(
"closedPath", (
closedPath()?
"true":
"false"));
751 #if QT_VERSION >= 0x040000
752 qDeleteAll(keyFrame_);
755 QDomElement child=element.firstChild().toElement();
756 while (!child.isNull())
758 if (child.tagName() ==
"KeyFrame")
762 float time = DomUtils::floatFromDom(child,
"time", 0.0);
766 child = child.nextSibling().toElement();
773 setClosedPath(DomUtils::boolFromDom(element,
"closedPath",
false));
777 pathIsValid_ =
false;
778 valuesAreValid_ =
false;
779 currentFrameValid_ =
false;
787 KeyFrameInterpolator::KeyFrame::KeyFrame(
const Frame& fr,
float t)
788 : time_(t), frame_(NULL)
794 KeyFrameInterpolator::KeyFrame::KeyFrame(
const Frame* fr,
float t)
795 : time_(t), frame_(fr)
797 updateValuesFromPointer();
800 void KeyFrameInterpolator::KeyFrame::updateValuesFromPointer()
802 p_ = frame()->position();
803 q_ = frame()->orientation();
806 void KeyFrameInterpolator::KeyFrame::computeTangent(
const KeyFrame*
const prev,
const KeyFrame*
const next)
808 tgP_ = 0.5 * (next->position() - prev->position());
812 void KeyFrameInterpolator::KeyFrame::flipOrientationIfNeeded(
const Quaternion& prev)