【发布时间】:2015-02-16 06:15:43
【问题描述】:
我与QGraphicsItem 合作了很长时间,它具有transform() 功能。现在我不会对QQuickItem 做同样的事情,但不幸的是它错过了transform()。所以我的问题 - 我怎样才能得到QQuickItem 的变换矩阵?
【问题讨论】:
我与QGraphicsItem 合作了很长时间,它具有transform() 功能。现在我不会对QQuickItem 做同样的事情,但不幸的是它错过了transform()。所以我的问题 - 我怎样才能得到QQuickItem 的变换矩阵?
【问题讨论】:
实际上QQuickItem 提供了transform() 方法,但是它返回分配给给定项目的所有转换的列表。这是因为可以将多个转换分配给单个Item。 QQuickItem::transform 的返回类型是 QQmlListProperty<QQuickTransform> — 它是 QML list<Transform> 类型的包装器(参见 documentation for Item)。它可以被迭代,产生QQuickTransform * 元素。 QQuickTransform 是转换的基类,它提供了一个虚拟方法 applyTo 接受 QMatrix4x4 * 参数并将转换应用于它。
QML 允许实例化多个QQuickTransform 子类(用于平移、旋转和缩放),并且允许用户定义自定义转换(例如,用于倾斜)。
要获得您需要的单个变换矩阵,您必须从单位矩阵开始,并依次应用给定QQuickItem 的所有变换。
请注意,该函数返回一个转换矩阵为QMatrix4x4——它比旧的基于 3x3 转换矩阵的QTransform 更多,因此它不能在没有损失的情况下进行转换。如果需要,您可以使用 QMatrix4x4::toAffine 获取 QMatrix (3x3) 并使用它来创建 QTransform 对象。但是,如果您的 QQuickItem 转换包含非亲和元素,它们将会丢失。
还有一点需要注意:我发布的方法仅适用于通过分配给transform 属性定义的转换。它不检查 scale 和 rotation 属性。如果您使用它们,您应该使用适当的QQuickItem 方法检查它们的值,并调整返回的矩阵以包含这两个额外的转换。
【讨论】:
QSGTransformNode 类在场景图中实现转换。在updatePaintNode 函数中,参数updatePaintNodeData 提供指向与此QQuickItem 关联的QSGTransformNode 的指针。
QSGNode *MyQuickItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data)
{
QSGTransformNode *transformNode = data->transformNode;
qDebug() << transformNode->matrix();
【讨论】:
这是一个正确的解决方案,基于 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;
}
在我的用例中,我使用它来获取对象的模型矩阵,然后与视图和投影矩阵相乘以计算模型-视图-投影矩阵。
【讨论】: