如何获得QQuickItem的变换矩阵?

时间:2015-02-16 06:15:43

标签: qt qml qtquick2

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

3 个答案:

答案 0 :(得分:5)

实际上QQuickItem提供了transform()方法,但它返回分配给给定项目的所有转换的列表。这是因为可以将多个转换分配给单个ItemQQuickItem::transform的返回类型为QQmlListProperty<QQuickTransform> - 它是QML list<Transform>类型的包装器(请参阅documentation for Item)。它可以迭代,产生QQuickTransform *个元素。 QQuickTransform是转换的基类,它提供了一个虚拟方法applyTo获取QMatrix4x4 *参数并在其上应用转换。

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

要获得所需的单个变换矩阵,必须从单位矩阵开始,然后依次应用给定QQuickItem的所有变换。

QMatrix4x4 transformOfItem(QQuickItem *item)
{
    QQmlListProperty transformations = item->transform();

    const int count = transformations.count(&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 applyTo(&transformMatrix);
    }

    return transformMatrix;
}

请注意,该函数将转换矩阵返回为QMatrix4x4 - 它不仅仅是基于3x3转换矩阵的旧QTransform,因此无法在没有丢失的情况下进行转换。如果需要,您可以使用QMatrix4x4::toAffine获取QMatrix(3x3)并使用它来创建QTransform对象。但是,如果您的QQuickItem转换包含非关联元素,则它们将丢失。

修改

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

这是一个正确的解决方案,基于迈克尔之前提供的代码,但实际上已经修复了,所以你不必花费20分钟来弄清楚如何使用QQmlListProperty

QMatrix4x4 YourQQuickItem::get_model_matrix() {
    QMatrix4x4 result;

    // Compose model matrix from our transform properties in the QML
    QQmlListProperty<QQuickTransform> transformations = transform();
    const int count = transformations.count(&transformations);
    for (int i=0; i<count; i++) {
        QQuickTransform *transform = transformations.at(&transformations, i);
        transform->applyTo(&result);
    }

    return result;
}

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