00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #include "domUtils.h"
00024 #include "qglviewer.h" 
00025 
00026 using namespace qglviewer;
00027 using namespace std;
00028 
00029 #if QT_VERSION < 0x040000
00030 
00031 # define peekNext current
00032 #endif
00033 
00040 KeyFrameInterpolator::KeyFrameInterpolator(Frame* frame)
00041   : frame_(NULL), period_(40), interpolationTime_(0.0), interpolationSpeed_(1.0), interpolationStarted_(false),
00042     closedPath_(false), loopInterpolation_(false), pathIsValid_(false), valuesAreValid_(true), currentFrameValid_(false)
00043   
00044 {
00045   setFrame(frame);
00046 #if QT_VERSION < 0x040000
00047   keyFrame_.setAutoDelete(true);
00048 #endif
00049   for (int i=0; i<4; ++i)
00050 #if QT_VERSION >= 0x040000
00051     currentFrame_[i] = new QMutableListIterator<KeyFrame*>(keyFrame_);
00052 #else
00053     currentFrame_[i] = new QPtrListIterator<KeyFrame>(keyFrame_);
00054 #endif
00055   connect(&timer_, SIGNAL(timeout()), SLOT(update()));
00056 }
00057 
00059 KeyFrameInterpolator::~KeyFrameInterpolator()
00060 {
00061   deletePath();
00062   for (int i=0; i<4; ++i)
00063     delete currentFrame_[i];
00064 }
00065 
00067 void KeyFrameInterpolator::setFrame(Frame* const frame)
00068 {
00069   if (this->frame())
00070     disconnect(this, SIGNAL( interpolated() ), this->frame(), SIGNAL( interpolated() ));
00071 
00072   frame_ = frame;
00073 
00074   if (this->frame())
00075     connect(this, SIGNAL( interpolated() ), this->frame(), SIGNAL( interpolated() ));
00076 }
00077 
00084 void KeyFrameInterpolator::update()
00085 {
00086   interpolateAtTime(interpolationTime());
00087 
00088   interpolationTime_ += interpolationSpeed() * interpolationPeriod() / 1000.0;
00089 
00090   if (interpolationTime() > keyFrame_.last()->time())
00091     {
00092       if (loopInterpolation())
00093         setInterpolationTime(keyFrame_.first()->time() + interpolationTime_ - keyFrame_.last()->time());
00094       else
00095         {
00096           
00097           interpolateAtTime(keyFrame_.last()->time());
00098           stopInterpolation();
00099         }
00100       Q_EMIT endReached();
00101     }
00102   else
00103     if (interpolationTime() < keyFrame_.first()->time())
00104       {
00105         if (loopInterpolation())
00106           setInterpolationTime(keyFrame_.last()->time() - keyFrame_.first()->time() + interpolationTime_);
00107         else
00108           {
00109             
00110             interpolateAtTime(keyFrame_.first()->time());
00111             stopInterpolation();
00112           }
00113         Q_EMIT endReached();
00114       }
00115 }
00116 
00117 
00138 void KeyFrameInterpolator::startInterpolation(int period)
00139 {
00140   if (period >= 0)
00141     setInterpolationPeriod(period);
00142 
00143   if (!keyFrame_.isEmpty())
00144     {
00145       if ((interpolationSpeed() > 0.0) && (interpolationTime() >= keyFrame_.last()->time()))
00146         setInterpolationTime(keyFrame_.first()->time());
00147       if ((interpolationSpeed() < 0.0) && (interpolationTime() <= keyFrame_.first()->time()))
00148         setInterpolationTime(keyFrame_.last()->time());
00149       timer_.start(interpolationPeriod());
00150       interpolationStarted_ = true;
00151       update();
00152     }
00153 }
00154 
00155 
00157 void KeyFrameInterpolator::stopInterpolation()
00158 {
00159   timer_.stop();
00160   interpolationStarted_ = false;
00161 }
00162 
00163 
00168 void KeyFrameInterpolator::resetInterpolation()
00169 {
00170   stopInterpolation();
00171   setInterpolationTime(firstTime());
00172 }
00173 
00186 void KeyFrameInterpolator::addKeyFrame(const Frame* const frame, float time)
00187 {
00188   if (!frame)
00189     return;
00190 
00191   if (keyFrame_.isEmpty())
00192     interpolationTime_ = time;
00193 
00194   if ( (!keyFrame_.isEmpty()) && (keyFrame_.last()->time() > time) )
00195     qWarning("Error in KeyFrameInterpolator::addKeyFrame: time is not monotone");
00196   else
00197     keyFrame_.append(new KeyFrame(frame, time));
00198   connect(frame, SIGNAL(modified()), SLOT(invalidateValues()));
00199   valuesAreValid_ = false;
00200   pathIsValid_ = false;
00201   currentFrameValid_ = false;
00202   resetInterpolation();
00203 }
00204 
00212 void KeyFrameInterpolator::addKeyFrame(const Frame& frame, float time)
00213 {
00214   if (keyFrame_.isEmpty())
00215     interpolationTime_ = time;
00216 
00217   if ( (!keyFrame_.isEmpty()) && (keyFrame_.last()->time() > time) )
00218     qWarning("Error in KeyFrameInterpolator::addKeyFrame: time is not monotone");
00219   else
00220     keyFrame_.append(new KeyFrame(frame, time));
00221 
00222   valuesAreValid_ = false;
00223   pathIsValid_ = false;
00224   currentFrameValid_ = false;
00225   resetInterpolation();
00226 }
00227 
00228 
00233 void KeyFrameInterpolator::addKeyFrame(const Frame* const frame)
00234 {
00235   float time;
00236   if (keyFrame_.isEmpty())
00237     time = 0.0;
00238   else
00239     time = lastTime() + 1.0;
00240 
00241   addKeyFrame(frame, time);
00242 }
00243 
00248 void KeyFrameInterpolator::addKeyFrame(const Frame& frame)
00249 {
00250   float time;
00251   if (keyFrame_.isEmpty())
00252     time = 0.0;
00253   else
00254     time = keyFrame_.last()->time() + 1.0;
00255 
00256   addKeyFrame(frame, time);
00257 }
00258 
00260 void KeyFrameInterpolator::deletePath()
00261 {
00262   stopInterpolation();
00263 #if QT_VERSION >= 0x040000
00264   qDeleteAll(keyFrame_);
00265 #endif
00266   keyFrame_.clear();
00267   pathIsValid_ = false;
00268   valuesAreValid_ = false;
00269   currentFrameValid_ = false;
00270 }
00271 
00272 static void drawCamera(float scale)
00273 {
00274   glDisable(GL_LIGHTING);
00275 
00276   const float halfHeight = scale * 0.07;
00277   const float halfWidth  = halfHeight * 1.3;
00278   const float dist = halfHeight / tan(M_PI/8.0);
00279 
00280   const float arrowHeight    = 1.5f * halfHeight;
00281   const float baseHeight     = 1.2f * halfHeight;
00282   const float arrowHalfWidth = 0.5f * halfWidth;
00283   const float baseHalfWidth  = 0.3f * halfWidth;
00284 
00285   
00286   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00287   glBegin(GL_LINE_STRIP);
00288   glVertex3f(-halfWidth, halfHeight,-dist);
00289   glVertex3f(-halfWidth,-halfHeight,-dist);
00290   glVertex3f( 0.0f, 0.0f, 0.0f);
00291   glVertex3f( halfWidth,-halfHeight,-dist);
00292   glVertex3f(-halfWidth,-halfHeight,-dist);
00293   glEnd();
00294   glBegin(GL_LINE_STRIP);
00295   glVertex3f( halfWidth,-halfHeight,-dist);
00296   glVertex3f( halfWidth, halfHeight,-dist);
00297   glVertex3f( 0.0f, 0.0f, 0.0f);
00298   glVertex3f(-halfWidth, halfHeight,-dist);
00299   glVertex3f( halfWidth, halfHeight,-dist);
00300   glEnd();
00301 
00302   
00303   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00304   
00305   glBegin(GL_QUADS);
00306   glVertex3f(-baseHalfWidth, halfHeight,-dist);
00307   glVertex3f( baseHalfWidth, halfHeight,-dist);
00308   glVertex3f( baseHalfWidth, baseHeight,-dist);
00309   glVertex3f(-baseHalfWidth, baseHeight,-dist);
00310   glEnd();
00311 
00312   
00313   glBegin(GL_TRIANGLES);
00314   glVertex3f( 0.0f,           arrowHeight,-dist);
00315   glVertex3f(-arrowHalfWidth, baseHeight, -dist);
00316   glVertex3f( arrowHalfWidth, baseHeight, -dist);
00317   glEnd();
00318 }
00319 
00351 void KeyFrameInterpolator::drawPath(int mask, int nbFrames, float scale)
00352 {
00353   const int nbSteps = 30;
00354   if (!pathIsValid_)
00355     {
00356       path_.clear();
00357 #if QT_VERSION < 0x040000
00358       path_.reserve(nbSteps*keyFrame_.count());
00359 #endif
00360 
00361       if (keyFrame_.isEmpty())
00362         return;
00363 
00364       if (!valuesAreValid_)
00365         updateModifiedFrameValues();
00366 
00367       if (keyFrame_.first() == keyFrame_.last())
00368         path_.push_back(Frame(keyFrame_.first()->position(), keyFrame_.first()->orientation()));
00369       else
00370         {
00371           static Frame fr;
00372           KeyFrame* kf_[4];
00373           kf_[0] = keyFrame_.first();
00374           kf_[1] = kf_[0];
00375 #if QT_VERSION >= 0x040000
00376           int index = 1;
00377           kf_[2] = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
00378           index++;
00379           kf_[3] = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
00380 #else
00381           kf_[2] = keyFrame_.next();
00382           kf_[3] = keyFrame_.next();
00383 #endif
00384 
00385           while (kf_[2])
00386             {
00387               Vec diff = kf_[2]->position() - kf_[1]->position();
00388               Vec v1 = 3.0 * diff - 2.0 * kf_[1]->tgP() - kf_[2]->tgP();
00389               Vec v2 = -2.0 * diff + kf_[1]->tgP() + kf_[2]->tgP();
00390 
00391               
00392               for (int step=0; step<nbSteps; ++step)
00393                 {
00394                   float alpha = step / static_cast<float>(nbSteps);
00395                   fr.setPosition(kf_[1]->position() + alpha * (kf_[1]->tgP() + alpha * (v1+alpha*v2)));
00396                   fr.setOrientation(Quaternion::squad(kf_[1]->orientation(), kf_[1]->tgQ(), kf_[2]->tgQ(), kf_[2]->orientation(), alpha));
00397                   path_.push_back(fr);
00398                 }
00399 
00400               
00401               kf_[0] = kf_[1];
00402               kf_[1] = kf_[2];
00403               kf_[2] = kf_[3];
00404 #if QT_VERSION >= 0x040000
00405               index++;
00406               kf_[3] = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
00407 #else
00408               kf_[3] = keyFrame_.next();
00409 #endif
00410             }
00411           
00412           path_.push_back(Frame(kf_[1]->position(), kf_[1]->orientation()));
00413         }
00414       pathIsValid_ = true;
00415     }
00416 
00417   if (mask)
00418     {
00419       glDisable(GL_LIGHTING);
00420       glLineWidth(2);
00421 
00422       if (mask & 1)
00423         {
00424           glBegin(GL_LINE_STRIP);
00425 #if QT_VERSION >= 0x040000
00426           Q_FOREACH (Frame fr, path_)
00427             glVertex3fv(fr.position());
00428 #else
00429 # if QT_VERSION < 0x030000
00430           for (int i=0; i < path_.size(); ++i)
00431             glVertex3fv((path_.at(i)).position());
00432 # else
00433           for (QValueVector<Frame>::const_iterator pnt=path_.begin(), end=path_.end(); pnt!=end; ++pnt)
00434             glVertex3fv((*pnt).position());
00435 # endif
00436 #endif
00437           glEnd();
00438         }
00439       if (mask & 6)
00440         {
00441           int count = 0;
00442           if (nbFrames > nbSteps)
00443             nbFrames = nbSteps;
00444           float goal = 0.0f;
00445 #if QT_VERSION >= 0x040000
00446           Q_FOREACH (Frame fr, path_)
00447 #else
00448 # if QT_VERSION < 0x030000
00449           for (int i=0; i < path_.size(); ++i)
00450 # else
00451           for (QValueVector<Frame>::const_iterator pnt=path_.begin(), end=path_.end(); pnt!=end; ++pnt)
00452 # endif
00453 #endif
00454               if ((count++) >= goal)
00455                 {
00456                   goal += nbSteps / static_cast<float>(nbFrames);
00457                   glPushMatrix();
00458 #if QT_VERSION >= 0x040000
00459                   glMultMatrixd(fr.matrix());
00460 #else
00461 # if QT_VERSION < 0x030000
00462                   glMultMatrixd((path_.at(i)).matrix());
00463 # else
00464                   glMultMatrixd((*pnt).matrix());
00465 # endif
00466 #endif
00467                   if (mask & 2) drawCamera(scale);
00468                   if (mask & 4) QGLViewer::drawAxis(scale/10.0);
00469                   glPopMatrix();
00470                 }
00471         }
00472     }
00473 }
00474 
00475 void KeyFrameInterpolator::updateModifiedFrameValues()
00476 {
00477   Quaternion prevQ = keyFrame_.first()->orientation();
00478   KeyFrame* kf;
00479 #if QT_VERSION >= 0x040000
00480   for (int i=0; i<keyFrame_.size(); ++i)
00481     {
00482       kf = keyFrame_.at(i);
00483 #else
00484   for (kf = keyFrame_.first(); kf; kf=keyFrame_.next())
00485     {
00486 #endif
00487       if (kf->frame())
00488         kf->updateValuesFromPointer();
00489       kf->flipOrientationIfNeeded(prevQ);
00490       prevQ = kf->orientation();
00491     }
00492 
00493   KeyFrame* prev = keyFrame_.first();
00494   kf = keyFrame_.first();
00495 #if QT_VERSION >= 0x040000
00496   int index = 1;
00497 #endif
00498   while (kf)
00499     {
00500 #if QT_VERSION >= 0x040000
00501       KeyFrame* next = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL;
00502       index++;
00503 #else
00504       KeyFrame* next = keyFrame_.next();
00505 #endif
00506       if (next)
00507         kf->computeTangent(prev, next);
00508       else
00509         kf->computeTangent(prev, kf);
00510       prev = kf;
00511       kf = next;
00512     }
00513   valuesAreValid_ = true;
00514 }
00515 
00522 Frame KeyFrameInterpolator::keyFrame(int index) const
00523 {
00524   const KeyFrame* const kf = keyFrame_.at(index);
00525   return Frame(kf->position(), kf->orientation());
00526 }
00527 
00531 float KeyFrameInterpolator::keyFrameTime(int index) const
00532 {
00533   return keyFrame_.at(index)->time();
00534 }
00535 
00540 float KeyFrameInterpolator::duration() const
00541 {
00542   return lastTime() - firstTime();
00543 }
00544 
00548 float KeyFrameInterpolator::firstTime() const
00549 {
00550   if (keyFrame_.isEmpty())
00551     return 0.0;
00552   else
00553     return keyFrame_.first()->time();
00554 }
00555 
00559 float KeyFrameInterpolator::lastTime() const
00560 {
00561   if (keyFrame_.isEmpty())
00562     return 0.0;
00563   else
00564     return keyFrame_.last()->time();
00565 }
00566 
00567 void KeyFrameInterpolator::updateCurrentKeyFrameForTime(float time)
00568 {
00569   
00570   
00571 
00572   
00573   if (!currentFrameValid_)
00574     
00575 #if QT_VERSION >= 0x040000
00576     currentFrame_[1]->toFront();
00577 #else
00578     currentFrame_[1]->toFirst();
00579 #endif
00580 
00581   while (currentFrame_[1]->peekNext()->time() > time)
00582     {
00583       currentFrameValid_ = false;
00584 #if QT_VERSION >= 0x040000
00585       if (!currentFrame_[1]->hasPrevious())
00586 #else
00587       if (currentFrame_[1]->atFirst())
00588 #endif
00589         break;
00590 #if QT_VERSION >= 0x040000
00591       currentFrame_[1]->previous();
00592 #else
00593       --(*currentFrame_[1]);
00594 #endif
00595     }
00596 
00597   if (!currentFrameValid_)
00598     *currentFrame_[2] = *currentFrame_[1];
00599 
00600   while (currentFrame_[2]->peekNext()->time() < time)
00601     {
00602       currentFrameValid_ = false;
00603 #if QT_VERSION >= 0x040000
00604       if (!currentFrame_[2]->hasNext())
00605 #else
00606       if (currentFrame_[2]->atLast())
00607 #endif
00608         break;
00609 #if QT_VERSION >= 0x040000
00610       currentFrame_[2]->next();
00611 #else
00612       ++(*currentFrame_[2]);
00613 #endif
00614     }
00615 
00616   if (!currentFrameValid_)
00617     {
00618       *currentFrame_[1] = *currentFrame_[2];
00619 #if QT_VERSION >= 0x040000
00620       if ((currentFrame_[1]->hasPrevious()) && (time < currentFrame_[2]->peekNext()->time()))
00621         currentFrame_[1]->previous();
00622 #else
00623       if ((!currentFrame_[1]->atFirst()) && (time < currentFrame_[2]->current()->time()))
00624         --(*currentFrame_[1]);
00625 #endif
00626 
00627       *currentFrame_[0] = *currentFrame_[1];
00628 #if QT_VERSION >= 0x040000
00629       if (currentFrame_[0]->hasPrevious())
00630         currentFrame_[0]->previous();
00631 #else
00632       if (!currentFrame_[0]->atFirst())
00633         --(*currentFrame_[0]);
00634 #endif
00635 
00636       *currentFrame_[3] = *currentFrame_[2];
00637 #if QT_VERSION >= 0x040000
00638       if (currentFrame_[3]->hasNext())
00639         currentFrame_[3]->next();
00640 #else
00641       if (!currentFrame_[3]->atLast())
00642         ++(*currentFrame_[3]);
00643 #endif
00644 
00645       currentFrameValid_ = true;
00646       splineCacheIsValid_ = false;
00647     }
00648 
00649   
00650   
00651 }
00652 
00653 void KeyFrameInterpolator::updateSplineCache()
00654 {
00655   Vec delta = currentFrame_[2]->peekNext()->position() - currentFrame_[1]->peekNext()->position();
00656   v1 = 3.0 * delta - 2.0 * currentFrame_[1]->peekNext()->tgP() - currentFrame_[2]->peekNext()->tgP();
00657   v2 = -2.0 * delta + currentFrame_[1]->peekNext()->tgP() + currentFrame_[2]->peekNext()->tgP();
00658   splineCacheIsValid_ = true;
00659 }
00660 
00668 void KeyFrameInterpolator::interpolateAtTime(float time)
00669 {
00670   setInterpolationTime(time);
00671 
00672   if ((keyFrame_.isEmpty()) || (!frame()))
00673     return;
00674 
00675   if (!valuesAreValid_)
00676     updateModifiedFrameValues();
00677 
00678   updateCurrentKeyFrameForTime(time);
00679 
00680   if (!splineCacheIsValid_)
00681     updateSplineCache();
00682 
00683   float alpha;
00684   float dt = currentFrame_[2]->peekNext()->time() - currentFrame_[1]->peekNext()->time();
00685   if (dt == 0.0)
00686     alpha = 0.0;
00687   else
00688     alpha = (time - currentFrame_[1]->peekNext()->time()) / dt;
00689 
00690   
00691   
00692   Vec pos = currentFrame_[1]->peekNext()->position() + alpha * (currentFrame_[1]->peekNext()->tgP() + alpha * (v1+alpha*v2));
00693   Quaternion q = Quaternion::squad(currentFrame_[1]->peekNext()->orientation(), currentFrame_[1]->peekNext()->tgQ(),
00694                                    currentFrame_[2]->peekNext()->tgQ(), currentFrame_[2]->peekNext()->orientation(), alpha);
00695   frame()->setPositionAndOrientationWithConstraint(pos, q);
00696 
00697   Q_EMIT interpolated();
00698 }
00699 
00715 QDomElement KeyFrameInterpolator::domElement(const QString& name, QDomDocument& document) const
00716 {
00717   QDomElement de = document.createElement(name);
00718   int count = 0;
00719 #if QT_VERSION >= 0x040000
00720   Q_FOREACH (KeyFrame* kf, keyFrame_)
00721 #else
00722   for (KeyFrame* kf = keyFrame_.first(); kf; kf = keyFrame_.next() )
00723 #endif
00724     {
00725       Frame fr(kf->position(), kf->orientation());
00726       QDomElement kfNode = fr.domElement("KeyFrame", document);
00727       kfNode.setAttribute("index", QString::number(count));
00728       kfNode.setAttribute("time",  QString::number(kf->time()));
00729       de.appendChild(kfNode);
00730       ++count;
00731     }
00732   de.setAttribute("nbKF", QString::number(keyFrame_.count()));
00733   de.setAttribute("time", QString::number(interpolationTime()));
00734   de.setAttribute("speed", QString::number(interpolationSpeed()));
00735   de.setAttribute("period", QString::number(interpolationPeriod()));
00736   de.setAttribute("closedPath", (closedPath()?"true":"false"));
00737   de.setAttribute("loop", (loopInterpolation()?"true":"false"));
00738   return de;
00739 }
00740 
00749 void KeyFrameInterpolator::initFromDOMElement(const QDomElement& element)
00750 {
00751 #if QT_VERSION >= 0x040000
00752   qDeleteAll(keyFrame_);
00753 #endif
00754   keyFrame_.clear();
00755   QDomElement child=element.firstChild().toElement();
00756   while (!child.isNull())
00757     {
00758       if (child.tagName() == "KeyFrame")
00759         {
00760           Frame fr;
00761           fr.initFromDOMElement(child);
00762           float time = DomUtils::floatFromDom(child, "time", 0.0);
00763           addKeyFrame(fr, time);
00764         }
00765 
00766       child = child.nextSibling().toElement();
00767     }
00768 
00769   
00770   setInterpolationTime(DomUtils::floatFromDom(element, "time", 0.0));
00771   setInterpolationSpeed(DomUtils::floatFromDom(element, "speed", 1.0));
00772   setInterpolationPeriod(DomUtils::intFromDom(element, "period", 40));
00773   setClosedPath(DomUtils::boolFromDom(element, "closedPath", false));
00774   setLoopInterpolation(DomUtils::boolFromDom(element, "loop", false));
00775 
00776   
00777   pathIsValid_ = false;
00778   valuesAreValid_ = false;
00779   currentFrameValid_ = false;
00780 
00781   stopInterpolation();
00782 }
00783 
00784 #ifndef DOXYGEN
00785 
00787 KeyFrameInterpolator::KeyFrame::KeyFrame(const Frame& fr, float t)
00788   : time_(t), frame_(NULL)
00789 {
00790   p_ = fr.position();
00791   q_ = fr.orientation();
00792 }
00793 
00794 KeyFrameInterpolator::KeyFrame::KeyFrame(const Frame* fr, float t)
00795   : time_(t), frame_(fr)
00796 {
00797   updateValuesFromPointer();
00798 }
00799 
00800 void KeyFrameInterpolator::KeyFrame::updateValuesFromPointer()
00801 {
00802   p_ = frame()->position();
00803   q_ = frame()->orientation();
00804 }
00805 
00806 void KeyFrameInterpolator::KeyFrame::computeTangent(const KeyFrame* const prev, const KeyFrame* const next)
00807 {
00808   tgP_ = 0.5 * (next->position() - prev->position());
00809   tgQ_ = Quaternion::squadTangent(prev->orientation(), q_, next->orientation());
00810 }
00811 
00812 void KeyFrameInterpolator::KeyFrame::flipOrientationIfNeeded(const Quaternion& prev)
00813 {
00814   if (Quaternion::dot(prev, q_) < 0.0)
00815     q_.negate();
00816 }
00817 
00818 #endif //DOXYGEN