calculation of the cube animtor matrix aligned ( still some questions

left concerning non symmetric calculations )
This commit is contained in:
Uwe Rathmann 2022-09-16 18:06:16 +02:00
parent cb67a057d7
commit 3a0796e085
2 changed files with 108 additions and 141 deletions

View File

@ -67,14 +67,9 @@ namespace
Q_OBJECT
public:
RotationTransform( Qt::Axis axis, qreal dx1, qreal dy1, qreal dx2,
qreal dy2, qreal radians, QQuickItem* item )
RotationTransform( Qt::Axis axis, qreal radians, QQuickItem* item )
: QQuickTransform( item )
, m_axis( axis )
, m_dx1( dx1 )
, m_dy1( dy1 )
, m_dx2( dx2 )
, m_dy2( dy2 )
, m_radians( radians )
{
prependToItem( item );
@ -89,34 +84,17 @@ namespace
}
}
void setPreTransform( qreal dx1, qreal dy1 )
{
if( !qskFuzzyCompare( dx1, m_dx1 ) || !qskFuzzyCompare( dy1, m_dy1 ) )
{
m_dx1 = dx1;
m_dy1 = dy1;
update();
}
}
void setPostTransform( qreal dx2, qreal dy2 )
{
if( !qskFuzzyCompare( dx2, m_dx2 ) || !qskFuzzyCompare( dy2, m_dy2 ) )
{
m_dx2 = dx2;
m_dy2 = dy2;
update();
}
}
void applyTo( QMatrix4x4* matrix ) const override
void applyTo( QMatrix4x4* matrix) const override
{
if ( const auto item = qobject_cast< QQuickItem* >( parent() ) )
{
const auto dx = 0.5 * item->width();
const auto dy = 0.5 * item->height();
QTransform transform;
transform.translate( m_dx1, m_dy1 );
transform.translate( dx, dy );
transform.rotateRadians( m_radians, m_axis );
transform.translate( m_dx2, m_dy2 );
transform.translate( -dx, -dy );
*matrix *= transform;
}
@ -124,19 +102,46 @@ namespace
private:
const Qt::Axis m_axis;
qreal m_dx1;
qreal m_dy1;
qreal m_dx2;
qreal m_dy2;
qreal m_radians;
};
static RotationTransform* qskFindRotationTransform( const QQuickItem* item )
class QuickTransform final : public QQuickTransform
{
Q_OBJECT
public:
QuickTransform( QQuickItem* item )
: QQuickTransform( item )
{
prependToItem( item );
}
void setTransform( const QTransform& transform )
{
if ( transform != m_transform )
{
m_transform = transform;
update();
}
}
void applyTo( QMatrix4x4* matrix ) const override
{
if ( const auto item = qobject_cast< QQuickItem* >( parent() ) )
*matrix *= m_transform;
}
private:
QTransform m_transform;
};
template< typename Transform >
Transform* qskFindTransform( const QQuickItem* item )
{
const auto& transforms = QQuickItemPrivate::get( item )->transforms;
for ( const auto& t : transforms )
{
if ( auto transform = qobject_cast< RotationTransform* >( t ) )
if ( auto transform = qobject_cast< Transform* >( t ) )
return transform;
}
@ -402,19 +407,12 @@ void QskStackBoxAnimator2::setup()
{
const auto axis = ( m_orientation == Qt::Horizontal )
? Qt::YAxis : Qt::XAxis;
if ( auto item = itemAt( 0 ) )
{
const auto dx = 0.5 * item->width();
const auto dy = 0.5 * item->height();
( void ) new RotationTransform( axis, dx, dy, -dx, -dy, 0.0, item );
}
( void ) new RotationTransform( axis, 0.0, item );
if ( auto item = itemAt( 1 ) )
{
const auto dx = 0.5 * item->width();
const auto dy = 0.5 * item->height();
( void ) new RotationTransform( axis, dx, dy, -dx, -dy, M_PI_2, item );
}
( void ) new RotationTransform( axis, M_PI_2, item );
}
void QskStackBoxAnimator2::advanceIndex( qreal value )
@ -428,7 +426,7 @@ void QskStackBoxAnimator2::advanceIndex( qreal value )
if ( !m_inverted )
radians = 2 * M_PI - radians;
auto rotation = qskFindRotationTransform( item );
auto rotation = qskFindTransform< RotationTransform >( item );
rotation->setRadians( radians );
item->setVisible( true );
@ -452,7 +450,7 @@ void QskStackBoxAnimator2::advanceIndex( qreal value )
if ( !m_inverted )
radians = 2 * M_PI - radians;
auto rotation = qskFindRotationTransform( item );
auto rotation = qskFindTransform< RotationTransform >( item );
rotation->setRadians( radians );
item->setVisible( true );
@ -466,7 +464,7 @@ void QskStackBoxAnimator2::done()
{
if ( auto item = itemAt( i ) )
{
delete qskFindRotationTransform( item );
delete qskFindTransform< RotationTransform >( item );
item->setVisible( i == 1 );
}
}
@ -552,18 +550,15 @@ bool QskStackBoxAnimator4::isInverted() const
void QskStackBoxAnimator4::setup()
{
const auto axis = ( m_orientation == Qt::Horizontal )
? Qt::YAxis : Qt::XAxis;
if ( auto item = itemAt( 0 ) )
{
( void ) new RotationTransform( axis, 0.0, 0.0, 0.0, 0.0, 0.0, item );
( void ) new QuickTransform( item );
item->setVisible( true );
}
if ( auto item = itemAt( 1 ) )
{
( void ) new RotationTransform( axis, 0.0, 0.0, 0.0, 0.0, -M_PI_2, item );
( void ) new QuickTransform( item );
item->setVisible( true );
}
}
@ -572,107 +567,76 @@ void QskStackBoxAnimator4::advanceIndex( qreal value )
{
if ( auto item = itemAt( 0 ) )
{
auto rotation = qskFindRotationTransform( item );
const auto transform = transformation( item, false, value );
qreal dx1, dy1, radians, dx2, dy2;
if( orientation() == Qt::Horizontal )
{
const auto w = item->parentItem() ? item->parentItem()->width() : item->width();
if( isInverted() )
{
dx1 = ( w - item->x() ) * value;
radians = -M_PI_2 * value;
dx2 = 0.0;
}
else
{
dx1 = w * ( 1 - value ) - item->x() * value;
radians = M_PI_2 * value;
dx2 = -w;
}
dy1 = 0.5 * item->height();
dy2 = -dy1;
}
else
{
const auto h = item->parentItem() ? item->parentItem()->height() : item->height();
dx1 = 0.5 * item->width();
dx2 = -dx1;
if( isInverted() )
{
dy1 = ( h - item->y() ) * value;
radians = -M_PI_2 * value;
dy2 = 0.0;
}
else
{
dy1 = h * ( 1 - value ) - item->y() * value;
radians = M_PI_2 * value;
dy2 = -h;
}
}
rotation->setPreTransform( dx1, dy1 );
rotation->setRadians( radians );
rotation->setPostTransform( dx2, dy2 );
auto rotation = qskFindTransform< QuickTransform >( item );
rotation->setTransform( transform );
}
if ( auto item = itemAt( 1 ) )
{
auto rotation = qskFindRotationTransform( item );
const auto transform = transformation( item, true, value );
qreal dx1, dy1, radians, dx2, dy2;
auto rotation = qskFindTransform< QuickTransform >( item );
rotation->setTransform( transform );
}
}
if( orientation() == Qt::Horizontal )
QTransform QskStackBoxAnimator4::transformation(
const QQuickItem* item, bool increasing, qreal value ) const
{
const qreal v = increasing ? value : 1.0 - value;
qreal radians = M_PI_2 * ( 1.0 - v );
if ( increasing != isInverted() )
radians = -radians;
QTransform transform;
if( orientation() == Qt::Horizontal )
{
qreal dx1, dx2;
if ( increasing == isInverted() )
{
const auto w = item->parentItem() ? item->parentItem()->width() : item->width();
if( isInverted() )
{
dx1 = w * value - item->x() * ( 1 - value );
radians = -M_PI_2 * ( value - 1 );
dx2 = -w;
}
else
{
dx1 = ( item->width() + item->x() ) * ( 1 - value );
radians = M_PI_2 * ( value - 1 );
dx2 = 0.0;
}
dy1 = 0.5 * item->height();
dy2 = -dy1;
dx1 = item->width() * v - item->x() * ( 1.0 - v );
dx2 = -item->width();
}
else
{
const auto h = item->parentItem() ? item->parentItem()->height() : item->height();
dx1 = 0.5 * item->width();
dx2 = -dx1;
if( isInverted() )
{
dy1 = h * value - item->y() * ( 1 - value );
radians = -M_PI_2 * ( value - 1 );
dy2 = -h;
}
else
{
dy1 = ( item->height() + item->y() ) * ( 1 - value );
radians = M_PI_2 * ( value - 1 );
dy2 = 0.0;
}
dx1 = ( item->x() + item->width() ) * ( 1.0 - v );
dx2 = 0.0;
}
rotation->setPreTransform( dx1, dy1 );
rotation->setRadians( radians );
rotation->setPostTransform( dx2, dy2 );
const qreal h2 = 0.5 * item->height();
transform.translate( dx1, h2 );
transform.rotateRadians( radians, Qt::YAxis );
transform.translate( dx2, -h2 );
}
else
{
qreal dy1, dy2;
if ( increasing == isInverted() )
{
dy1 = item->height() * v - item->y() * ( 1.0 - v );
dy2 = -item->height();
}
else
{
dy1 = ( item->y() + item->height() ) * ( 1.0 - v );
dy2 = 0.0;
}
const qreal w2 = 0.5 * item->width();
transform.translate( w2, dy1 );
transform.rotateRadians( radians, Qt::XAxis );
transform.translate( -w2, dy2 );
}
return transform;
}
void QskStackBoxAnimator4::done()
@ -681,7 +645,7 @@ void QskStackBoxAnimator4::done()
{
if ( auto item = itemAt( i ) )
{
delete qskFindRotationTransform( item );
delete qskFindTransform< QuickTransform >( item );
item->setVisible( i == 1 );
}
}

View File

@ -13,6 +13,7 @@
class QskStackBox;
class QQuickItem;
class QTransform;
class QSK_EXPORT QskStackBoxAnimator : public QObject, public QskAnimator
{
@ -137,6 +138,8 @@ class QSK_EXPORT QskStackBoxAnimator4 : public QskStackBoxAnimator
void done() override;
private:
QTransform transformation( const QQuickItem*, bool increasing, qreal value ) const;
Qt::Orientation m_orientation : 2;
bool m_inverted : 1;
};