【问题标题】:How can I get transform matrix for QQuickItem?如何获得 QQuickItem 的变换矩阵?
【发布时间】:2015-02-16 06:15:43
【问题描述】:

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

【问题讨论】:

    标签: qt qml qtquick2


    【解决方案1】:

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

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

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

    QMatrix4x4 transformOfItem(QQuickItem *item) { QQmlListProperty 转换 = item->transform(); const int count = transformations.count(&transformations); // 准备结果结构,默认初始化为单位矩阵 QMatrix4x4 变换矩阵; // 按顺序应用项目的所有转换 for(int i = 0; i applyTo(&transformMatrix); } 返回变换矩阵; }

    请注意,该函数返回一个转换矩阵为QMatrix4x4——它比旧的基于 3x3 转换矩阵的QTransform 更多,因此它不能在没有损失的情况下进行转换。如果需要,您可以使用 QMatrix4x4::toAffine 获取 QMatrix (3x3) 并使用它来创建 QTransform 对象。但是,如果您的 QQuickItem 转换包含非亲和元素,它们将会丢失。

    编辑

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

    【讨论】:

    • 谢谢,@Michał W. Urbańczyk。我会试试你的建议。
    【解决方案2】:

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

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

    【讨论】:

    【解决方案3】:

    这是一个正确的解决方案,基于 Michael 之前提供的代码,但实际上可以正常工作,因此您不必花 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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多