Git commit 2b61b6f7b21fa206fcc9fac30a25609f9abb34c6 by Torsten Rahn. Committed on 31/03/2016 at 20:47. Pushed by rahn into branch 'master'. - Turn the Quaternion inside a GeoDataCoordinate into a pointer - Instantiate the Quaternion and initialize it lazily only once quaternion() is called As a result the quaternion is only instantiated for spherical projections. And it only gets instantiated once the GeoDataCoordinate object is evaluated for drawing. This reduces initialization time and reduces the memory footprint by about 4 MB on average. M +16 -14 src/lib/marble/geodata/data/GeoDataCoordinates.cpp M +8 -7 src/lib/marble/geodata/data/GeoDataCoordinates_p.h http://commits.kde.org/marble/2b61b6f7b21fa206fcc9fac30a25609f9abb34c6 diff --git a/src/lib/marble/geodata/data/GeoDataCoordinates.cpp b/src/lib/m= arble/geodata/data/GeoDataCoordinates.cpp index e27519c..2553bfa 100644 --- a/src/lib/marble/geodata/data/GeoDataCoordinates.cpp +++ b/src/lib/marble/geodata/data/GeoDataCoordinates.cpp @@ -620,6 +620,9 @@ GeoDataCoordinates::GeoDataCoordinates() */ GeoDataCoordinates::~GeoDataCoordinates() { + delete d->m_q; + d->m_q =3D 0; + if (!d->ref.deref()) delete d; #ifdef DEBUG_GEODATA @@ -640,8 +643,11 @@ bool GeoDataCoordinates::isValid() const * this state shouldn't happen, but if it does, we have to clean up behind= us. */ void GeoDataCoordinates::detach() -{ +{ = if(d->ref.load() =3D=3D 1) { + delete d->m_q; + d->m_q =3D 0; + return; } = @@ -664,12 +670,10 @@ void GeoDataCoordinates::set( qreal _lon, qreal _lat,= qreal _alt, GeoDataCoordin switch( unit ){ default: case Radian: - d->m_q =3D Quaternion::fromSpherical( _lon, _lat ); d->m_lon =3D _lon; d->m_lat =3D _lat; break; case Degree: - d->m_q =3D Quaternion::fromSpherical( _lon * DEG2RAD , _lat * DEG2= RAD ); d->m_lon =3D _lon * DEG2RAD; d->m_lat =3D _lat * DEG2RAD; break; @@ -685,11 +689,9 @@ void GeoDataCoordinates::setLongitude( qreal _lon, Geo= DataCoordinates::Unit unit switch( unit ){ default: case Radian: - d->m_q =3D Quaternion::fromSpherical( _lon, d->m_lat ); d->m_lon =3D _lon; break; case Degree: - d->m_q =3D Quaternion::fromSpherical( _lon * DEG2RAD , d->m_lat ); d->m_lon =3D _lon * DEG2RAD; break; } @@ -704,11 +706,9 @@ void GeoDataCoordinates::setLatitude( qreal _lat, GeoD= ataCoordinates::Unit unit detach(); switch( unit ){ case Radian: - d->m_q =3D Quaternion::fromSpherical( d->m_lon, _lat ); d->m_lat =3D _lat; break; case Degree: - d->m_q =3D Quaternion::fromSpherical( d->m_lon, _lat * DEG2RAD ); d->m_lat =3D _lat * DEG2RAD; break; } @@ -1318,13 +1318,17 @@ GeoDataCoordinates GeoDataCoordinates::moveByBearin= g( qreal bearing, qreal dista = const Quaternion& GeoDataCoordinates::quaternion() const { - return d->m_q; + if (d->m_q =3D=3D 0) { + d->m_q =3D new Quaternion(); + *d->m_q =3D Quaternion::fromSpherical( d->m_lon , d->m_lat ); + } + return *d->m_q; } = GeoDataCoordinates GeoDataCoordinates::interpolate( const GeoDataCoordinat= es &target, double t_ ) const { double const t =3D qBound( 0.0, t_, 1.0 ); - Quaternion const quat =3D Quaternion::slerp( d->m_q, target.d->m_q, t = ); + Quaternion const quat =3D Quaternion::slerp( quaternion(), target.quat= ernion(), t ); qreal lon, lat; quat.getSpherical( lon, lat ); double const alt =3D (1.0-t) * d->m_altitude + t * target.d->m_altitud= e; @@ -1334,9 +1338,9 @@ GeoDataCoordinates GeoDataCoordinates::interpolate( c= onst GeoDataCoordinates &ta GeoDataCoordinates GeoDataCoordinates::interpolate( const GeoDataCoordinat= es &before, const GeoDataCoordinates &target, const GeoDataCoordinates &aft= er, double t_ ) const { double const t =3D qBound( 0.0, t_, 1.0 ); - Quaternion const b1 =3D GeoDataCoordinatesPrivate::basePoint( before.d= ->m_q, d->m_q, target.d->m_q ); - Quaternion const a2 =3D GeoDataCoordinatesPrivate::basePoint( d->m_q, = target.d->m_q, after.d->m_q ); - Quaternion const a =3D Quaternion::slerp( d->m_q, target.d->m_q, t ); + Quaternion const b1 =3D GeoDataCoordinatesPrivate::basePoint( before.q= uaternion(), quaternion(), target.quaternion() ); + Quaternion const a2 =3D GeoDataCoordinatesPrivate::basePoint( quaterni= on(), target.quaternion(), after.quaternion() ); + Quaternion const a =3D Quaternion::slerp( quaternion(), target.quatern= ion(), t ); Quaternion const b =3D Quaternion::slerp( b1, a2, t ); Quaternion c =3D Quaternion::slerp( a, b, 2 * t * (1.0-t) ); qreal lon, lat; @@ -1422,8 +1426,6 @@ void GeoDataCoordinates::unpack( QDataStream& stream ) stream >> d->m_lon; stream >> d->m_lat; stream >> d->m_altitude; - - d->m_q =3D Quaternion::fromSpherical( d->m_lon, d->m_lat ); } = Quaternion GeoDataCoordinatesPrivate::basePoint( const Quaternion &q1, con= st Quaternion &q2, const Quaternion &q3 ) diff --git a/src/lib/marble/geodata/data/GeoDataCoordinates_p.h b/src/lib/m= arble/geodata/data/GeoDataCoordinates_p.h index 787b19f..b246e1a 100644 --- a/src/lib/marble/geodata/data/GeoDataCoordinates_p.h +++ b/src/lib/marble/geodata/data/GeoDataCoordinates_p.h @@ -28,7 +28,8 @@ class GeoDataCoordinatesPrivate * needs this name. Maybe we can rename it to our scheme later on. */ GeoDataCoordinatesPrivate() - : m_lon( 0 ), + : m_q( 0 ), + m_lon( 0 ), m_lat( 0 ), m_altitude( 0 ), m_detail( 0 ), @@ -46,19 +47,18 @@ class GeoDataCoordinatesPrivate GeoDataCoordinatesPrivate( qreal _lon, qreal _lat, qreal _alt, GeoDataCoordinates::Unit unit, int _detail ) - : m_altitude( _alt ), + : m_q( 0 ), + m_altitude( _alt ), m_detail( _detail ), ref( 0 ) { switch( unit ){ default: case GeoDataCoordinates::Radian: - m_q =3D Quaternion::fromSpherical( _lon, _lat ); m_lon =3D _lon; m_lat =3D _lat; break; case GeoDataCoordinates::Degree: - m_q =3D Quaternion::fromSpherical( _lon * DEG2RAD , _lat * DEG= 2RAD ); m_lon =3D _lon * DEG2RAD; m_lat =3D _lat * DEG2RAD; break; @@ -70,7 +70,7 @@ class GeoDataCoordinatesPrivate * initialize the reference with the value of the other */ GeoDataCoordinatesPrivate( const GeoDataCoordinatesPrivate &other ) - : m_q( Quaternion::fromSpherical( other.m_lon, other.m_lat ) ), + : m_q( 0 ), m_lon( other.m_lon ), m_lat( other.m_lat ), m_altitude( other.m_altitude ), @@ -88,8 +88,9 @@ class GeoDataCoordinatesPrivate m_lat =3D other.m_lat; m_altitude =3D other.m_altitude; m_detail =3D other.m_detail; - m_q =3D other.m_q; ref =3D 0; + delete m_q; + m_q =3D 0; return *this; } = @@ -201,7 +202,7 @@ class GeoDataCoordinatesPrivate */ static qreal lonLatToEasting( qreal lon, qreal lat ); = - Quaternion m_q; + Quaternion * m_q; qreal m_lon; qreal m_lat; qreal m_altitude; // in meters above sea level