forked from qt-creator/qt-creator
QmlDesigner: Fix issues in 3D view when parent node has transform
1. Hiding the selection box resets the parent transform we calculate during selection box geometry generation. Worked around this issue by hiding the boxes by using null material instead of visible property. 2. Aligning cameras to views and vice versa didn't consider the possibility that the camera might be a child node with a parent node that has transform. Fixes: QDS-10502 Change-Id: Ibf4af71424b8b673a42042dbc1840754967799c5 Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -311,7 +311,7 @@ Item {
|
|||||||
"geometryName": geometryName});
|
"geometryName": geometryName});
|
||||||
selectionBoxes[selectionBoxes.length] = box;
|
selectionBoxes[selectionBoxes.length] = box;
|
||||||
box.view3D = Qt.binding(function() {return editView;});
|
box.view3D = Qt.binding(function() {return editView;});
|
||||||
box.visible = Qt.binding(function() {return showSelectionBox;});
|
box.showBox = Qt.binding(function() {return showSelectionBox;});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,7 @@ Node {
|
|||||||
property Node targetNode: null
|
property Node targetNode: null
|
||||||
property alias model: selectionBoxModel
|
property alias model: selectionBoxModel
|
||||||
property alias geometryName: selectionBoxGeometry.name
|
property alias geometryName: selectionBoxGeometry.name
|
||||||
|
property bool showBox: true
|
||||||
|
|
||||||
SelectionBoxGeometry {
|
SelectionBoxGeometry {
|
||||||
id: selectionBoxGeometry
|
id: selectionBoxGeometry
|
||||||
@@ -31,17 +32,21 @@ Node {
|
|||||||
position: selectionBox.targetNode ? selectionBox.targetNode.position : Qt.vector3d(0, 0, 0)
|
position: selectionBox.targetNode ? selectionBox.targetNode.position : Qt.vector3d(0, 0, 0)
|
||||||
pivot: selectionBox.targetNode ? selectionBox.targetNode.pivot : Qt.vector3d(0, 0, 0)
|
pivot: selectionBox.targetNode ? selectionBox.targetNode.pivot : Qt.vector3d(0, 0, 0)
|
||||||
|
|
||||||
visible: selectionBox.targetNode && !selectionBoxGeometry.isEmpty
|
visible: selectionBox.targetNode
|
||||||
|
|
||||||
castsShadows: false
|
castsShadows: false
|
||||||
receivesShadows: false
|
receivesShadows: false
|
||||||
|
|
||||||
materials: [
|
DefaultMaterial {
|
||||||
DefaultMaterial {
|
id: boxMaterial
|
||||||
diffuseColor: "#fff600"
|
diffuseColor: "#fff600"
|
||||||
lighting: DefaultMaterial.NoLighting
|
lighting: DefaultMaterial.NoLighting
|
||||||
cullMode: Material.NoCulling
|
cullMode: Material.NoCulling
|
||||||
}
|
}
|
||||||
]
|
// We custom set the render node transform for the selectionBox node to correspond
|
||||||
|
// targetNode's parent transform when we calculate the box geometry.
|
||||||
|
// This transform gets reset if visibility of the box changes, so instead we hide the box
|
||||||
|
// by setting null material to it.
|
||||||
|
materials: selectionBox.showBox && !selectionBoxGeometry.isEmpty ? boxMaterial : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -353,8 +353,32 @@ void GeneralHelper::alignCameras(QQuick3DCamera *camera, const QVariant &nodes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (QQuick3DCamera *node : std::as_const(nodeList)) {
|
for (QQuick3DCamera *node : std::as_const(nodeList)) {
|
||||||
node->setPosition(camera->position());
|
QMatrix4x4 parentTransform;
|
||||||
node->setRotation(camera->rotation());
|
QMatrix4x4 parentRotationTransform;
|
||||||
|
if (node->parentNode()) {
|
||||||
|
QMatrix4x4 rotMat;
|
||||||
|
rotMat.rotate(node->parentNode()->sceneRotation());
|
||||||
|
parentRotationTransform = rotMat.inverted();
|
||||||
|
parentTransform = node->parentNode()->sceneTransform().inverted();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMatrix4x4 localTransform;
|
||||||
|
localTransform.translate(camera->position());
|
||||||
|
localTransform.rotate(camera->rotation());
|
||||||
|
|
||||||
|
QMatrix4x4 finalTransform = parentTransform * localTransform;
|
||||||
|
QVector3D newPos = QVector3D(finalTransform.column(3).x(),
|
||||||
|
finalTransform.column(3).y(),
|
||||||
|
finalTransform.column(3).z());
|
||||||
|
|
||||||
|
// Rotation must be calculated with sanitized transform that only contains rotation so
|
||||||
|
// that the scaling of ancestor nodes won't distort it
|
||||||
|
QMatrix4x4 finalRotTransform = parentRotationTransform * localTransform;
|
||||||
|
QMatrix3x3 rotationMatrix = finalRotTransform.toGenericMatrix<3, 3>();
|
||||||
|
QQuaternion newRot = QQuaternion::fromRotationMatrix(rotationMatrix).normalized();
|
||||||
|
|
||||||
|
node->setPosition(newPos);
|
||||||
|
node->setRotation(newRot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,8 +400,8 @@ QVector3D GeneralHelper::alignView(QQuick3DCamera *camera, const QVariant &nodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cameraNode) {
|
if (cameraNode) {
|
||||||
camera->setPosition(cameraNode->position());
|
camera->setPosition(cameraNode->scenePosition());
|
||||||
QVector3D newRotation = cameraNode->eulerRotation();
|
QVector3D newRotation = cameraNode->sceneRotation().toEulerAngles();
|
||||||
newRotation.setZ(0.f);
|
newRotation.setZ(0.f);
|
||||||
camera->setEulerRotation(newRotation);
|
camera->setEulerRotation(newRotation);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user