File indexing completed on 2024-04-14 03:48:00

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
0004 //
0005 
0006 #include "PlaybackFlyToItem.h"
0007 
0008 #include "GeoDataLookAt.h"
0009 #include "GeoDataCamera.h"
0010 #include "GeoDataFlyTo.h"
0011 #include "Quaternion.h"
0012 
0013 #include <QTimer>
0014 
0015 namespace Marble
0016 {
0017 PlaybackFlyToItem::PlaybackFlyToItem( const GeoDataFlyTo* flyTo ):
0018         m_flyTo( flyTo ),
0019         m_before( nullptr ),
0020         m_next( nullptr ),
0021         m_isPlaying( false ),
0022         m_isFirst( false )
0023 {
0024     //do nothing
0025 }
0026 
0027 const GeoDataFlyTo* PlaybackFlyToItem::flyTo() const
0028 {
0029     return m_flyTo;
0030 }
0031 
0032 double PlaybackFlyToItem::duration() const
0033 {
0034     // We use duration 0 for first FlyTo for instantly flight to it.
0035     return m_isFirst ? 0 : m_flyTo->duration();
0036 }
0037 
0038 void PlaybackFlyToItem::play()
0039 {
0040     if( m_isPlaying ){
0041         return;
0042     } else {
0043         m_isPlaying = true;
0044         if ( !( m_start.isValid() ) ){
0045             m_start = QDateTime::currentDateTime();
0046             Q_ASSERT( m_start.isValid() );
0047         } else {
0048             m_start = m_start.addMSecs( m_pause.msecsTo( QDateTime::currentDateTime() ) );
0049         }
0050         playNext();
0051     }
0052 }
0053 
0054 void PlaybackFlyToItem::playNext()
0055 {
0056     if( !m_start.isValid() ){
0057         return;
0058     }
0059     double const progress = m_start.msecsTo( QDateTime::currentDateTime() ) / 1000.0;
0060     Q_ASSERT( progress >= 0.0 );
0061     double const t = progress / duration();
0062     if( t <= 1 ){
0063         if( m_isPlaying ){
0064             center( t );
0065             emit progressChanged( progress );
0066             QTimer::singleShot( 5, this, SLOT(playNext()) );
0067         }
0068     } else {
0069         center( 1.0 );
0070         emit finished();
0071         stop();
0072     }
0073 }
0074 
0075 void PlaybackFlyToItem::pause()
0076 {
0077     m_isPlaying = false;
0078     m_pause = QDateTime::currentDateTime();
0079 }
0080 
0081 void PlaybackFlyToItem::seek( double t )
0082 {
0083     m_start = QDateTime::currentDateTime().addMSecs( -t * duration() * 1000 );
0084     m_pause = QDateTime::currentDateTime();
0085     center( t );
0086 }
0087 
0088 void PlaybackFlyToItem::stop()
0089 {
0090     m_isPlaying = false;
0091     m_start = QDateTime();
0092     m_pause = QDateTime();
0093 }
0094 
0095 void PlaybackFlyToItem::center( double t )
0096 {
0097     Q_ASSERT( t >= 0.0 && t <= 1.0 );
0098     Q_ASSERT( m_before );
0099     if ( m_flyTo->flyToMode() == GeoDataFlyTo::Bounce || !m_before->m_before || !m_next ) {
0100         GeoDataCoordinates const a = m_before->m_flyTo->view()->coordinates();
0101         GeoDataCoordinates const b = m_flyTo->view()->coordinates();
0102         emit centerOn( a.interpolate( b, t ) );
0103     } else {
0104         Q_ASSERT( m_flyTo->flyToMode() == GeoDataFlyTo::Smooth );
0105         GeoDataCoordinates const a = m_before->m_before->m_flyTo->view()->coordinates();
0106         GeoDataCoordinates const b = m_before->m_flyTo->view()->coordinates();
0107         GeoDataCoordinates const c = m_flyTo->view()->coordinates();
0108         GeoDataCoordinates const d = m_next->m_flyTo->view()->coordinates();
0109         emit centerOn( b.interpolate( a, c, d, t ) );
0110     }
0111 }
0112 
0113 void PlaybackFlyToItem::setBefore( PlaybackFlyToItem *before )
0114 {
0115     m_before = before;
0116 }
0117 
0118 void PlaybackFlyToItem::setNext( PlaybackFlyToItem *next )
0119 {
0120     m_next = next;
0121 }
0122 
0123 void PlaybackFlyToItem::setFirst(bool isFirst)
0124 {
0125     m_isFirst = isFirst;
0126 }
0127 
0128 }
0129 
0130 #include "moc_PlaybackFlyToItem.cpp"