关于qt:如何获取QQuickItem的变换矩阵?

How can I get transform matrix for QQuickItem?

我在QGraphicsItem上工作了很长时间,它具有transform()功能。 现在,我不会对QQuickItem做同样的事情,但是不幸的是它错过了transform()。 所以我的问题-如何获得QQuickItem的变换矩阵?


实际上,QQuickItem提供了transform()方法,但是它返回分配给给定项目的所有转换的列表。这是因为可以将多个转换分配给单个ItemQQuickItem::transform的返回类型是QQmlListPropeamp;lt;QQuickTransfamp;gt;-它是QML lamp;lt;Transfamp;gt;类型的包装(请参阅Item的文档)。可以对其进行迭代,生成QQuickTransform *元素。 QQuickTransform是转换的基类,它提供了带有QMatrix4x4 *自变量并将其应用转换的虚拟方法applyTo

QML允许实例化几个QQuickTransform子类(用于平移,旋转和缩放),并且允许用户定义自定义转换(例如,用于偏斜)。

要获得所需的单个转换矩阵,必须从单位矩阵开始,并顺序应用给定QQuickItem的所有转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
QMatrix4x4 transformOfItem(QQuickItem *item)
{
    QQmlListProperty transformations = item->transform();

    const int count = transformations.couamp;transformations);

    // Prepare result structure, it will be default-initialized to be an identity matrix
    QMatrix4x4 transformMatrix;

    // Apply sequentially all transformation from the item
    for(int i = 0; i applyamp;transformMatrix);
    }

    return transformMatrix;
}

请注意,该函数返回的转换矩阵为QMatrix4x4-它比基于3x3转换矩阵的旧QTransform还要多,因此无法进行转换而不会造成损失。如果需要,可以使用QMatrix4x4::toAffine获取QMatrix(3x3)并使用它创建QTransform对象。但是,如果您的QQuickItem转换包含非亲和元素,则它们将丢失。

编辑

还有一点需要注意:我发布的方法仅适用于通过分配给transform属性定义的转换。它不检查scalerotation属性。如果使用它们,则应使用适当的QQuickItem方法检查它们的值,并调整返回的矩阵以包括这两个附加转换。


这是一个正确的解决方案,基于Michael先前提供的代码,但实际上已经过固定,因此您不必花20分钟的时间就可以知道如何使用QQmlListProperty

1
2
3
4
5
6
7
8
9
10
11
12
13
QMatrix4x4 YourQQuickItem::get_model_matrix() {
    QMatrix4x4 result;

    // Compose model matrix from our transform properties in the QML
    QQmlListPropeamp;lt;QQuickTransfamp;gt; transformations = transform();
    const int count = transformations.couamp;transformations);
    for (int i=0amp;lt;count; i++) {
        QQuickTransform *transform = transformations.amp;transformations, i);
        transfoamp;gt;applyamp;result);
    }

    return result;
}

在我的用例中,我使用它来获取对象的模型矩阵,然后将其与视图和投影矩阵相乘以计算出模型-视图-投影矩阵。


QSGTransformNode类在场景图中实现转换。在updatePaintNode函数中,参数updatePaintNodeData提供指向与此QQuickItem关联的QSGTransformNode的指针。

1
2
3
4
QSGNode *MyQuickItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data)
{
     QSGTransformNode *transformNode = data->transformNode;
     qDebug() << transformNode->matrix();