File indexing completed on 2024-04-28 07:38:07
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"