24 #include "qglviewer.h"
26 using namespace qglviewer;
36 : frame_(NULL), period_(40), interpolationTime_(0.0), interpolationSpeed_(1.0), interpolationStarted_(false),
37 closedPath_(false), loopInterpolation_(false), pathIsValid_(false), valuesAreValid_(true), currentFrameValid_(false)
41 for (
int i=0; i<4; ++i)
42 currentFrame_[i] =
new QMutableListIterator<KeyFrame*>(keyFrame_);
43 connect(&timer_, SIGNAL(timeout()), SLOT(update()));
50 for (
int i=0; i<4; ++i)
51 delete currentFrame_[i];
72 void KeyFrameInterpolator::update()
131 if (!keyFrame_.isEmpty())
138 interpolationStarted_ =
true;
148 interpolationStarted_ =
false;
179 if (keyFrame_.isEmpty())
180 interpolationTime_ = time;
182 if ( (!keyFrame_.isEmpty()) && (keyFrame_.last()->time() > time) )
183 qWarning(
"Error in KeyFrameInterpolator::addKeyFrame: time is not monotone");
185 keyFrame_.append(
new KeyFrame(frame, time));
186 connect(frame, SIGNAL(modified()), SLOT(invalidateValues()));
187 valuesAreValid_ =
false;
188 pathIsValid_ =
false;
189 currentFrameValid_ =
false;
202 if (keyFrame_.isEmpty())
203 interpolationTime_ = time;
205 if ( (!keyFrame_.isEmpty()) && (keyFrame_.last()->time() > time) )
206 qWarning(
"Error in KeyFrameInterpolator::addKeyFrame: time is not monotone");
208 keyFrame_.append(
new KeyFrame(frame, time));
210 valuesAreValid_ =
false;
211 pathIsValid_ =
false;
212 currentFrameValid_ =
false;
224 if (keyFrame_.isEmpty())
239 if (keyFrame_.isEmpty())
242 time = keyFrame_.last()->time() + 1.0;
251 qDeleteAll(keyFrame_);
253 pathIsValid_ =
false;
254 valuesAreValid_ =
false;
255 currentFrameValid_ =
false;
258 static void drawCamera(
float scale)
260 glDisable(GL_LIGHTING);
262 const float halfHeight = scale * 0.07;
263 const float halfWidth = halfHeight * 1.3;
264 const float dist = halfHeight / tan(M_PI/8.0);
266 const float arrowHeight = 1.5f * halfHeight;
267 const float baseHeight = 1.2f * halfHeight;
268 const float arrowHalfWidth = 0.5f * halfWidth;
269 const float baseHalfWidth = 0.3f * halfWidth;
272 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
273 glBegin(GL_LINE_STRIP);
274 glVertex3f(-halfWidth, halfHeight,-dist);
275 glVertex3f(-halfWidth,-halfHeight,-dist);
276 glVertex3f( 0.0f, 0.0f, 0.0f);
277 glVertex3f( halfWidth,-halfHeight,-dist);
278 glVertex3f(-halfWidth,-halfHeight,-dist);
280 glBegin(GL_LINE_STRIP);
281 glVertex3f( halfWidth,-halfHeight,-dist);
282 glVertex3f( halfWidth, halfHeight,-dist);
283 glVertex3f( 0.0f, 0.0f, 0.0f);
284 glVertex3f(-halfWidth, halfHeight,-dist);
285 glVertex3f( halfWidth, halfHeight,-dist);
289 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
292 glVertex3f(-baseHalfWidth, halfHeight,-dist);
293 glVertex3f( baseHalfWidth, halfHeight,-dist);
294 glVertex3f( baseHalfWidth, baseHeight,-dist);
295 glVertex3f(-baseHalfWidth, baseHeight,-dist);
299 glBegin(GL_TRIANGLES);
300 glVertex3f( 0.0f, arrowHeight,-dist);
301 glVertex3f(-arrowHalfWidth, baseHeight, -dist);
302 glVertex3f( arrowHalfWidth, baseHeight, -dist);
339 const int nbSteps = 30;
344 if (keyFrame_.isEmpty())
347 if (!valuesAreValid_)
348 updateModifiedFrameValues();
350 if (keyFrame_.first() == keyFrame_.last())
351 path_.push_back(
Frame(keyFrame_.first()->position(), keyFrame_.first()->orientation()));
356 kf_[0] = keyFrame_.first();
359 kf_[2] = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
361 kf_[3] = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
365 Vec diff = kf_[2]->position() - kf_[1]->position();
366 Vec v1 = 3.0 * diff - 2.0 * kf_[1]->tgP() - kf_[2]->tgP();
367 Vec v2 = -2.0 * diff + kf_[1]->tgP() + kf_[2]->tgP();
370 for (
int step=0; step<nbSteps; ++step)
372 float alpha = step /
static_cast<float>(nbSteps);
373 fr.
setPosition(kf_[1]->position() + alpha * (kf_[1]->tgP() + alpha * (v1+alpha*v2)));
383 kf_[3] = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
386 path_.push_back(
Frame(kf_[1]->position(), kf_[1]->orientation()));
393 glDisable(GL_LIGHTING);
398 glBegin(GL_LINE_STRIP);
399 Q_FOREACH (
Frame fr, path_)
406 if (nbFrames > nbSteps)
409 Q_FOREACH (
Frame fr, path_)
410 if ((count++) >= goal)
412 goal += nbSteps /
static_cast<float>(nbFrames);
414 glMultMatrixd(fr.
matrix());
415 if (mask & 2) drawCamera(scale);
423 void KeyFrameInterpolator::updateModifiedFrameValues()
425 Quaternion prevQ = keyFrame_.first()->orientation();
427 for (
int i=0; i<keyFrame_.size(); ++i)
429 kf = keyFrame_.at(i);
431 kf->updateValuesFromPointer();
432 kf->flipOrientationIfNeeded(prevQ);
433 prevQ = kf->orientation();
436 KeyFrame* prev = keyFrame_.first();
437 kf = keyFrame_.first();
441 KeyFrame* next = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
444 kf->computeTangent(prev, next);
446 kf->computeTangent(prev, kf);
450 valuesAreValid_ =
true;
461 const KeyFrame*
const kf = keyFrame_.at(index);
462 return Frame(kf->position(), kf->orientation());
470 return keyFrame_.at(index)->time();
487 if (keyFrame_.isEmpty())
490 return keyFrame_.first()->time();
498 if (keyFrame_.isEmpty())
501 return keyFrame_.last()->time();
504 void KeyFrameInterpolator::updateCurrentKeyFrameForTime(
float time)
510 if (!currentFrameValid_)
512 currentFrame_[1]->toFront();
514 while (currentFrame_[1]->peekNext()->time() > time)
516 currentFrameValid_ =
false;
517 if (!currentFrame_[1]->hasPrevious())
519 currentFrame_[1]->previous();
522 if (!currentFrameValid_)
523 *currentFrame_[2] = *currentFrame_[1];
525 while (currentFrame_[2]->peekNext()->time() < time)
527 currentFrameValid_ =
false;
528 if (!currentFrame_[2]->hasNext())
530 currentFrame_[2]->next();
533 if (!currentFrameValid_)
535 *currentFrame_[1] = *currentFrame_[2];
536 if ((currentFrame_[1]->hasPrevious()) && (time < currentFrame_[2]->peekNext()->time()))
537 currentFrame_[1]->previous();
539 *currentFrame_[0] = *currentFrame_[1];
540 if (currentFrame_[0]->hasPrevious())
541 currentFrame_[0]->previous();
543 *currentFrame_[3] = *currentFrame_[2];
544 if (currentFrame_[3]->hasNext())
545 currentFrame_[3]->next();
547 currentFrameValid_ =
true;
548 splineCacheIsValid_ =
false;
555 void KeyFrameInterpolator::updateSplineCache()
557 Vec delta = currentFrame_[2]->peekNext()->position() - currentFrame_[1]->peekNext()->position();
558 v1 = 3.0 * delta - 2.0 * currentFrame_[1]->peekNext()->tgP() - currentFrame_[2]->peekNext()->tgP();
559 v2 = -2.0 * delta + currentFrame_[1]->peekNext()->tgP() + currentFrame_[2]->peekNext()->tgP();
560 splineCacheIsValid_ =
true;
574 if ((keyFrame_.isEmpty()) || (!
frame()))
577 if (!valuesAreValid_)
578 updateModifiedFrameValues();
580 updateCurrentKeyFrameForTime(time);
582 if (!splineCacheIsValid_)
586 float dt = currentFrame_[2]->peekNext()->time() - currentFrame_[1]->peekNext()->time();
590 alpha = (time - currentFrame_[1]->peekNext()->time()) / dt;
594 Vec pos = currentFrame_[1]->peekNext()->position() + alpha * (currentFrame_[1]->peekNext()->tgP() + alpha * (v1+alpha*v2));
596 currentFrame_[2]->peekNext()->tgQ(), currentFrame_[2]->peekNext()->orientation(), alpha);
619 QDomElement de = document.createElement(name);
621 Q_FOREACH (KeyFrame* kf, keyFrame_)
623 Frame fr(kf->position(), kf->orientation());
624 QDomElement kfNode = fr.
domElement(
"KeyFrame", document);
625 kfNode.setAttribute(
"index", QString::number(count));
626 kfNode.setAttribute(
"time", QString::number(kf->time()));
627 de.appendChild(kfNode);
630 de.setAttribute(
"nbKF", QString::number(keyFrame_.count()));
634 DomUtils::setBoolAttribute(de,
"closedPath",
closedPath());
649 qDeleteAll(keyFrame_);
651 QDomElement child=element.firstChild().toElement();
652 while (!child.isNull())
654 if (child.tagName() ==
"KeyFrame")
658 float time = DomUtils::floatFromDom(child,
"time", 0.0);
662 child = child.nextSibling().toElement();
669 setClosedPath(DomUtils::boolFromDom(element,
"closedPath",
false));
673 pathIsValid_ =
false;
674 valuesAreValid_ =
false;
675 currentFrameValid_ =
false;
683 KeyFrameInterpolator::KeyFrame::KeyFrame(
const Frame& fr,
float t)
684 : time_(t), frame_(NULL)
690 KeyFrameInterpolator::KeyFrame::KeyFrame(
const Frame* fr,
float t)
691 : time_(t), frame_(fr)
693 updateValuesFromPointer();
696 void KeyFrameInterpolator::KeyFrame::updateValuesFromPointer()
698 p_ = frame()->position();
699 q_ = frame()->orientation();
702 void KeyFrameInterpolator::KeyFrame::computeTangent(
const KeyFrame*
const prev,
const KeyFrame*
const next)
704 tgP_ = 0.5 * (next->position() - prev->position());
708 void KeyFrameInterpolator::KeyFrame::flipOrientationIfNeeded(
const Quaternion& prev)