6#include "MarblePhysics.h" 
    8#include "GeoDataLineString.h" 
    9#include "GeoDataLookAt.h" 
   10#include "MarbleAbstractPresenter.h" 
   11#include "MarbleDebug.h" 
   12#include "Quaternion.h" 
   20class MarblePhysicsPrivate
 
   23    MarbleAbstractPresenter *
const m_presenter;
 
   25    GeoDataLookAt m_source;
 
   27    GeoDataLookAt m_target;
 
   35    explicit MarblePhysicsPrivate(MarbleAbstractPresenter *presenter)
 
   36        : m_presenter(presenter)
 
   38        , m_planetRadius(EARTH_RADIUS)
 
   40        m_timeline.setDuration(2000);
 
   44    qreal suggestedRange(qreal t)
 const 
   47        Q_ASSERT(0 <= t && t <= 1.0);
 
   50            qreal in = m_source.range();
 
   51            qreal out = m_target.range();
 
   53            return in + t * (out - in);
 
   54        } 
else if (m_mode == 
Jump) {
 
   55            qreal jumpDuration = m_timeline.duration();
 
   58            const qreal totalDistance = m_planetRadius * m_source.coordinates().sphericalDistanceTo(m_target.coordinates());
 
   59            qreal g = qMin(m_source.range(), m_target.range()); 
 
   60            qreal k = qMax(m_source.range(), m_target.range()); 
 
   61            qreal d = t > 0.5 ? m_source.range() - g : m_target.range() - g; 
 
   62            qreal c = d * 2 * qAbs(t - 0.5); 
 
   63            qreal h = qMin(1000 * 3000.0, totalDistance / 2.0); 
 
   67            qreal a = -h / ((qreal)(0.25 * jumpDuration * jumpDuration));
 
   68            qreal b = 2.0 * h / (qreal)(0.5 * jumpDuration);
 
   70            qreal x = jumpDuration * t;
 
   71            qreal y = (a * x + b) * x + k - c; 
 
   75            qWarning(
"Unhandled FlyTo mode, no camera distance interpolation.");
 
   76            return m_target.range();
 
   81MarblePhysics::MarblePhysics(MarbleAbstractPresenter *presenter)
 
   83    , d(new MarblePhysicsPrivate(presenter))
 
   89MarblePhysics::~MarblePhysics()
 
   94void MarblePhysics::flyTo(
const GeoDataLookAt &target, FlyToMode mode)
 
   97    d->m_source = d->m_presenter->lookAt();
 
   99    const ViewportParams *viewport = d->m_presenter->viewport();
 
  101    FlyToMode effectiveMode = mode;
 
  103    bool globeHidesPoint(
false);
 
  104    bool onScreen = viewport->screenCoordinates(target.coordinates(), x, y, globeHidesPoint);
 
  105    bool invisible = globeHidesPoint || !onScreen;
 
  107    if (effectiveMode == Automatic) {
 
  108        bool zoom = qAbs(d->m_source.range() - target.range()) > 10;
 
  110        if ((invisible || zoom)) {
 
  111            effectiveMode = 
Jump;
 
  117    d->m_mode = effectiveMode;
 
  119    switch (effectiveMode) {
 
  121        d->m_presenter->flyTo(target, Instant);
 
  124        d->m_timeline.setDuration(300);
 
  128        qreal duration = invisible ? 2000 : 1000;
 
  129        d->m_timeline.setDuration(duration);
 
  137    d->m_timeline.start();
 
  140void MarblePhysics::updateProgress(qreal progress)
 
  142    Q_ASSERT(d->m_mode != Instant);
 
  143    Q_ASSERT(d->m_mode != Automatic);
 
  145    if (progress >= 1.0) {
 
  146        d->m_presenter->flyTo(d->m_target, Instant);
 
  151    Q_ASSERT(progress >= 0.0 && progress < 1.0);
 
  152    const GeoDataCoordinates interpolated = d->m_source.coordinates().interpolate(d->m_target.coordinates(), progress);
 
  153    qreal range = d->suggestedRange(progress);
 
  155    GeoDataLookAt intermediate;
 
  156    intermediate.setCoordinates(interpolated);
 
  157    intermediate.setRange(range);
 
  160    d->m_presenter->flyTo(intermediate, Instant);
 
  163void MarblePhysics::startStillMode()
 
  170#include "moc_MarblePhysics.cpp" 
This file contains the headers for ViewportParams.
 
A 3d point representation.
 
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
 
Binds a QML item to a specific geodetic location in screen coordinates.
 
FlyToMode
Describes possible flight mode (interpolation between source and target camera positions)
 
@ Automatic
A sane value is chosen automatically depending on animation settings and the action.
 
@ Instant
Change camera position immediately (no interpolation)
 
@ Linear
Linear interpolation of lon, lat and distance to ground.
 
@ Jump
Linear interpolation of lon and lat, distance increases towards the middle point, then decreases.
 
@ Animation
animated view (e.g. while rotating the globe)
 
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
 
void valueChanged(qreal value)