QmlDesigner: Fix orthographic camera hdpi issues in edit 3D view

There is no need to double the viewport anymore when calculating
orthographic camera frustum visualization, Qt6 correctly accounts
for device pixel ratio in ortho projection. Even in Qt5, the old
hack only made frustum visualization correct for hdpi screens while
breaking it for regular screens.

Also fixed zoom factor handling for orthographic edit camera mode.

Task-number: QDS-5469
Change-Id: Ie53b5dfa2fbcc00f098ea64e5a6673e4b7af0963
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Miikka Heikkinen
2021-11-15 17:24:23 +02:00
parent e018a8649c
commit cb00a8d30f
5 changed files with 27 additions and 23 deletions

View File

@@ -57,7 +57,7 @@ Item {
_zoomFactor = cameraState[1]; _zoomFactor = cameraState[1];
camera.position = cameraState[2]; camera.position = cameraState[2];
camera.rotation = cameraState[3]; camera.rotation = cameraState[3];
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, _generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
_zoomFactor, false); _zoomFactor, false);
} }
@@ -70,7 +70,7 @@ Item {
_zoomFactor = 1; _zoomFactor = 1;
camera.position = _defaultCameraPosition; camera.position = _defaultCameraPosition;
camera.eulerRotation = _defaultCameraRotation; camera.eulerRotation = _defaultCameraRotation;
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, _generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
_zoomFactor, false); _zoomFactor, false);
} }
@@ -114,21 +114,21 @@ Item {
if (!camera) if (!camera)
return; return;
_zoomFactor = _generalHelper.zoomCamera(camera, distance, _defaultCameraLookAtDistance, _zoomFactor = _generalHelper.zoomCamera(view3d, camera, distance, _defaultCameraLookAtDistance,
_lookAtPoint, _zoomFactor, true); _lookAtPoint, _zoomFactor, true);
} }
onCameraChanged: { onCameraChanged: {
if (camera && _prevCamera) { if (camera && _prevCamera) {
// Reset zoom on previous camera to ensure it's properties are good to copy to new cam // Reset zoom on previous camera to ensure it's properties are good to copy to new cam
_generalHelper.zoomCamera(_prevCamera, 0, _defaultCameraLookAtDistance, _lookAtPoint, _generalHelper.zoomCamera(view3d, _prevCamera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
1, false); 1, false);
camera.position = _prevCamera.position; camera.position = _prevCamera.position;
camera.rotation = _prevCamera.rotation; camera.rotation = _prevCamera.rotation;
// Apply correct zoom to new camera // Apply correct zoom to new camera
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, _generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
_zoomFactor, false); _zoomFactor, false);
} }
_prevCamera = camera; _prevCamera = camera;

View File

@@ -57,7 +57,7 @@ Item {
_zoomFactor = cameraState[1]; _zoomFactor = cameraState[1];
camera.position = cameraState[2]; camera.position = cameraState[2];
camera.rotation = cameraState[3]; camera.rotation = cameraState[3];
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, _generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
_zoomFactor, false); _zoomFactor, false);
} }
@@ -70,7 +70,7 @@ Item {
_zoomFactor = 1; _zoomFactor = 1;
camera.position = _defaultCameraPosition; camera.position = _defaultCameraPosition;
camera.eulerRotation = _defaultCameraRotation; camera.eulerRotation = _defaultCameraRotation;
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, _generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
_zoomFactor, false); _zoomFactor, false);
} }
@@ -114,21 +114,21 @@ Item {
if (!camera) if (!camera)
return; return;
_zoomFactor = _generalHelper.zoomCamera(camera, distance, _defaultCameraLookAtDistance, _zoomFactor = _generalHelper.zoomCamera(view3d, camera, distance, _defaultCameraLookAtDistance,
_lookAtPoint, _zoomFactor, true); _lookAtPoint, _zoomFactor, true);
} }
onCameraChanged: { onCameraChanged: {
if (camera && _prevCamera) { if (camera && _prevCamera) {
// Reset zoom on previous camera to ensure it's properties are good to copy to new cam // Reset zoom on previous camera to ensure it's properties are good to copy to new cam
_generalHelper.zoomCamera(_prevCamera, 0, _defaultCameraLookAtDistance, _lookAtPoint, _generalHelper.zoomCamera(view3d, _prevCamera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
1, false); 1, false);
camera.position = _prevCamera.position; camera.position = _prevCamera.position;
camera.rotation = _prevCamera.rotation; camera.rotation = _prevCamera.rotation;
// Apply correct zoom to new camera // Apply correct zoom to new camera
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, _generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
_zoomFactor, false); _zoomFactor, false);
} }
_prevCamera = camera; _prevCamera = camera;

View File

@@ -176,14 +176,7 @@ void CameraGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexDat
QRectF rect = m_viewPortRect; QRectF rect = m_viewPortRect;
if (rect.isNull()) if (rect.isNull())
rect = QRectF(0, 0, 1000, 1000); // Let's have some visualization for null viewports rect = QRectF(0, 0, 1000, 1000); // Let's have some visualization for null viewports
if (qobject_cast<QQuick3DOrthographicCamera *>(m_camera)) {
// For some reason ortho cameras show double what projection suggests,
// so give them doubled viewport to match visualization to actual camera view
camera->calculateGlobalVariables(QRectF(0, 0, rect.width() * 2.0,
rect.height() * 2.0));
} else {
camera->calculateGlobalVariables(rect); camera->calculateGlobalVariables(rect);
}
m = camera->projection.inverted(); m = camera->projection.inverted();
} }

View File

@@ -130,8 +130,9 @@ QVector3D GeneralHelper::panCamera(QQuick3DCamera *camera, const QMatrix4x4 star
return startLookAt + delta; return startLookAt + delta;
} }
float GeneralHelper::zoomCamera(QQuick3DCamera *camera, float distance, float defaultLookAtDistance, float GeneralHelper::zoomCamera(QQuick3DViewport *viewPort, QQuick3DCamera *camera, float distance,
const QVector3D &lookAt, float zoomFactor, bool relative) float defaultLookAtDistance, const QVector3D &lookAt,
float zoomFactor, bool relative)
{ {
// Emprically determined divisor for nice zoom // Emprically determined divisor for nice zoom
float multiplier = 1.f + (distance / 40.f); float multiplier = 1.f + (distance / 40.f);
@@ -140,7 +141,16 @@ float GeneralHelper::zoomCamera(QQuick3DCamera *camera, float distance, float de
if (qobject_cast<QQuick3DOrthographicCamera *>(camera)) { if (qobject_cast<QQuick3DOrthographicCamera *>(camera)) {
// Ortho camera we can simply scale // Ortho camera we can simply scale
camera->setScale(QVector3D(newZoomFactor, newZoomFactor, newZoomFactor)); float orthoFactor = newZoomFactor;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
if (viewPort) {
if (const QQuickWindow *w = viewPort->window())
orthoFactor *= w->devicePixelRatio();
}
#else
Q_UNUSED(viewPort)
#endif
camera->setScale(QVector3D(orthoFactor, orthoFactor, orthoFactor));
} else if (qobject_cast<QQuick3DPerspectiveCamera *>(camera)) { } else if (qobject_cast<QQuick3DPerspectiveCamera *>(camera)) {
// Perspective camera is zoomed by moving camera forward or backward while keeping the // Perspective camera is zoomed by moving camera forward or backward while keeping the
// look-at point the same // look-at point the same
@@ -249,7 +259,8 @@ QVector4D GeneralHelper::focusNodesToCamera(QQuick3DCamera *camera, float defaul
float divisor = closeUp ? 900.f : 725.f; float divisor = closeUp ? 900.f : 725.f;
float newZoomFactor = updateZoom ? qBound(.01f, maxExtent / divisor, 100.f) : oldZoom; float newZoomFactor = updateZoom ? qBound(.01f, maxExtent / divisor, 100.f) : oldZoom;
float cameraZoomFactor = zoomCamera(camera, 0, defaultLookAtDistance, lookAt, newZoomFactor, false); float cameraZoomFactor = zoomCamera(viewPort, camera, 0, defaultLookAtDistance, lookAt,
newZoomFactor, false);
return QVector4D(lookAt, cameraZoomFactor); return QVector4D(lookAt, cameraZoomFactor);
} }

View File

@@ -65,7 +65,7 @@ public:
const QVector3D &startPosition, const QVector3D &startLookAt, const QVector3D &startPosition, const QVector3D &startLookAt,
const QVector3D &pressPos, const QVector3D &currentPos, const QVector3D &pressPos, const QVector3D &currentPos,
float zoomFactor); float zoomFactor);
Q_INVOKABLE float zoomCamera(QQuick3DCamera *camera, float distance, Q_INVOKABLE float zoomCamera(QQuick3DViewport *viewPort, QQuick3DCamera *camera, float distance,
float defaultLookAtDistance, const QVector3D &lookAt, float defaultLookAtDistance, const QVector3D &lookAt,
float zoomFactor, bool relative); float zoomFactor, bool relative);
Q_INVOKABLE QVector4D focusNodesToCamera(QQuick3DCamera *camera, float defaultLookAtDistance, Q_INVOKABLE QVector4D focusNodesToCamera(QQuick3DCamera *camera, float defaultLookAtDistance,