diff options
author | Kaj Grönholm <kaj.gronholm@qt.io> | 2023-01-17 15:05:08 +0200 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2023-06-01 12:45:29 +0200 |
commit | 334c93b4a26f71f937026d5ce2d6c990e1bf290e (patch) | |
tree | 6adb3d3df458e914c643adef50fffeced2faafc2 | |
parent | 4e1cc1b01aec7528e9789dffb84a260d129e9d14 (diff) |
Add support for controlling the stereoscopic eye convergence
Add API for controlling rotation of left & right eye cameras. By adding
some rotation, the eyes convergence distance can be adjusted to other
than the default infinity. Add support for this into viewer application.
Task-number: QT3DS-4238
Change-Id: I3a54893cd6295615016b3d00347c51eca581015b
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r-- | src/api/studio3d/q3dscommandqueue.cpp | 5 | ||||
-rw-r--r-- | src/api/studio3d/q3dscommandqueue_p.h | 2 | ||||
-rw-r--r-- | src/api/studio3d/q3dsviewersettings.cpp | 59 | ||||
-rw-r--r-- | src/api/studio3d/q3dsviewersettings.h | 4 | ||||
-rw-r--r-- | src/api/studio3d/q3dsviewersettings_p.h | 2 | ||||
-rw-r--r-- | src/api/studio3dqml/q3dsplugin.cpp | 3 | ||||
-rw-r--r-- | src/api/studio3dqml/q3dsrenderer.cpp | 2 | ||||
-rw-r--r-- | src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp | 15 | ||||
-rw-r--r-- | src/engine/Qt3DSRuntimeView.h | 2 | ||||
-rw-r--r-- | src/runtimerender/Qt3DSRenderContextCore.cpp | 9 | ||||
-rw-r--r-- | src/runtimerender/Qt3DSRenderContextCore.h | 2 | ||||
-rw-r--r-- | src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp | 41 | ||||
-rw-r--r-- | src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h | 7 | ||||
-rw-r--r-- | src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp | 1 | ||||
-rw-r--r-- | src/viewer/Qt3DSViewerApp.cpp | 14 | ||||
-rw-r--r-- | src/viewer/Qt3DSViewerApp.h | 3 | ||||
-rw-r--r-- | tools/viewer/qml/main.qml | 30 |
17 files changed, 180 insertions, 21 deletions
diff --git a/src/api/studio3d/q3dscommandqueue.cpp b/src/api/studio3d/q3dscommandqueue.cpp index a839e69..18aeb78 100644 --- a/src/api/studio3d/q3dscommandqueue.cpp +++ b/src/api/studio3d/q3dscommandqueue.cpp @@ -217,6 +217,8 @@ void CommandQueue::copyCommands(CommandQueue &fromQueue) m_stereoModeChanged = m_stereoModeChanged || fromQueue.m_stereoModeChanged; m_stereoEyeSeparationChanged = m_stereoEyeSeparationChanged || fromQueue.m_stereoEyeSeparationChanged; + m_stereoEyeRotationChanged + = m_stereoEyeRotationChanged || fromQueue.m_stereoEyeRotationChanged; m_stereoProgressiveEnabledChanged = m_stereoProgressiveEnabledChanged || fromQueue.m_stereoProgressiveEnabledChanged; m_skipFramesIntervalChanged @@ -240,6 +242,8 @@ void CommandQueue::copyCommands(CommandQueue &fromQueue) m_stereoMode = fromQueue.m_stereoMode; if (fromQueue.m_stereoEyeSeparationChanged) m_stereoEyeSeparation = fromQueue.m_stereoEyeSeparation; + if (fromQueue.m_stereoEyeRotationChanged) + m_stereoEyeRotation = fromQueue.m_stereoEyeRotation; if (fromQueue.m_stereoProgressiveEnabledChanged) m_stereoProgressiveEnabled = fromQueue.m_stereoProgressiveEnabled; if (fromQueue.m_skipFramesIntervalChanged) @@ -346,6 +350,7 @@ void CommandQueue::clear(bool deleteCommandData) m_scaleModeChanged = false; m_stereoModeChanged = false; m_stereoEyeSeparationChanged = false; + m_stereoEyeRotationChanged = false; m_stereoProgressiveEnabledChanged = false; m_skipFramesIntervalChanged = false; m_shadeModeChanged = false; diff --git a/src/api/studio3d/q3dscommandqueue_p.h b/src/api/studio3d/q3dscommandqueue_p.h index 9939cb0..15d9397 100644 --- a/src/api/studio3d/q3dscommandqueue_p.h +++ b/src/api/studio3d/q3dscommandqueue_p.h @@ -143,6 +143,7 @@ public: bool m_scaleModeChanged = false; bool m_stereoModeChanged = false; bool m_stereoEyeSeparationChanged = false; + bool m_stereoEyeRotationChanged = false; bool m_stereoProgressiveEnabledChanged = false; bool m_skipFramesIntervalChanged = false; bool m_shadeModeChanged = false; @@ -159,6 +160,7 @@ public: Q3DSViewerSettings::ScaleMode m_scaleMode = Q3DSViewerSettings::ScaleModeCenter; Q3DSViewerSettings::StereoMode m_stereoMode = Q3DSViewerSettings::StereoModeMono; double m_stereoEyeSeparation = 0.4; + double m_stereoEyeRotation = 0.0; bool m_stereoProgressiveEnabled = false; int m_skipFramesInterval = 0; Q3DSViewerSettings::ShadeMode m_shadeMode = Q3DSViewerSettings::ShadeModeShaded; diff --git a/src/api/studio3d/q3dsviewersettings.cpp b/src/api/studio3d/q3dsviewersettings.cpp index cbb273a..2c3e8db 100644 --- a/src/api/studio3d/q3dsviewersettings.cpp +++ b/src/api/studio3d/q3dsviewersettings.cpp @@ -332,6 +332,48 @@ void Q3DSViewerSettings::setStereoEyeSeparation(double separation) } /*! + \qmlproperty real ViewerSettings::stereoEyeRotation + + \since QtStudio3D.OpenGL 2.8 + + Specifies the eye (camera) rotation of stereo rendering. + Value is the amount left and right eye cameras rotate in y-coordinate + (horizontally) away from center as radians. Adding rotation moves + the eyes convergence distance closer. The default value is 0, + meaning convergence point is at infinity. + + This has only effect when stereo mode is set to something else than + default \c{StereoModeMono}. + */ +/*! + \property Q3DSViewerSettings::stereoEyeRotation + + \since Qt 3D Studio 2.8 + + Specifies the eye (camera) rotation of stereo rendering. + Value is the amount left and right eye cameras rotate in y-coordinate + (horizontally) away from center as radians. Adding rotation moves + the eyes convergence distance closer. The default value is 0, + meaning convergence point is at infinity. + + This has only effect when stereo mode is set to something else than + default \c{StereoModeMono}. + */ +double Q3DSViewerSettings::stereoEyeRotation() const +{ + return d_ptr->m_stereoEyeRotation; +} + +void Q3DSViewerSettings::setStereoEyeRotation(double rotation) +{ + if (rotation >= 0 + && !qFuzzyCompare(d_ptr->m_stereoEyeRotation, rotation)) { + d_ptr->setStereoEyeRotation(rotation); + Q_EMIT stereoEyeRotationChanged(rotation); + } +} + +/*! \qmlproperty bool ViewerSettings::stereoProgressiveEnabled \since QtStudio3D.OpenGL 2.7 @@ -487,6 +529,7 @@ Q3DSViewerSettingsPrivate::Q3DSViewerSettingsPrivate(Q3DSViewerSettings *q) , m_scaleMode(Q3DSViewerSettings::ScaleModeCenter) , m_stereoMode(Q3DSViewerSettings::StereoModeMono) , m_stereoEyeSeparation(0.4) + , m_stereoEyeRotation(0.0) , m_stereoProgressiveEnabled(false) , m_skipFramesInterval(0) , m_savedSettings(nullptr) @@ -508,6 +551,7 @@ void Q3DSViewerSettingsPrivate::setViewerApp(Q3DSViewer::Q3DSViewerApp *app) setScaleMode(m_scaleMode); setStereoMode(m_stereoMode); setStereoEyeSeparation(m_stereoEyeSeparation); + setStereoEyeRotation(m_stereoEyeRotation); setStereoProgressiveEnabled(m_stereoProgressiveEnabled); setSkipFramesInterval(m_skipFramesInterval); } @@ -524,6 +568,7 @@ void Q3DSViewerSettingsPrivate::setCommandQueue(CommandQueue *queue) setScaleMode(m_scaleMode); setStereoMode(m_stereoMode); setStereoEyeSeparation(m_stereoEyeSeparation); + setStereoEyeRotation(m_stereoEyeRotation); setStereoProgressiveEnabled(m_stereoProgressiveEnabled); setSkipFramesInterval(m_skipFramesInterval); } @@ -540,6 +585,7 @@ void Q3DSViewerSettingsPrivate::save(const QString &group, const QString &organi m_savedSettings->setValue(QStringLiteral("scaleMode"), m_scaleMode); m_savedSettings->setValue(QStringLiteral("stereoMode"), m_stereoMode); m_savedSettings->setValue(QStringLiteral("stereoEyeSeparation"), m_stereoEyeSeparation); + m_savedSettings->setValue(QStringLiteral("stereoEyeRotation"), m_stereoEyeRotation); m_savedSettings->setValue(QStringLiteral("matteEnabled"), m_matteEnabled); } @@ -558,6 +604,8 @@ void Q3DSViewerSettingsPrivate::load(const QString &group, const QString &organi m_savedSettings->value(QStringLiteral("stereoMode")).toInt())); q_ptr->setStereoEyeSeparation( m_savedSettings->value(QStringLiteral("stereoEyeSeparation")).toDouble()); + q_ptr->setStereoEyeRotation( + m_savedSettings->value(QStringLiteral("stereoEyeRotation")).toDouble()); q_ptr->setStereoProgressiveEnabled( m_savedSettings->value(QStringLiteral("stereoProgressiveEnabled")).toBool()); q_ptr->setSkipFramesInterval( @@ -659,6 +707,17 @@ void Q3DSViewerSettingsPrivate::setStereoEyeSeparation(double separation) } } +void Q3DSViewerSettingsPrivate::setStereoEyeRotation(double rotation) +{ + m_stereoEyeRotation = rotation; + if (m_viewerApp) { + m_viewerApp->SetStereoEyeRotation(rotation); + } else if (m_commandQueue) { + m_commandQueue->m_stereoEyeRotation = rotation; + m_commandQueue->m_stereoEyeRotationChanged = true; + } +} + void Q3DSViewerSettingsPrivate::setStereoProgressiveEnabled(bool enabled) { m_stereoProgressiveEnabled = enabled; diff --git a/src/api/studio3d/q3dsviewersettings.h b/src/api/studio3d/q3dsviewersettings.h index 80b36df..a0e29d6 100644 --- a/src/api/studio3d/q3dsviewersettings.h +++ b/src/api/studio3d/q3dsviewersettings.h @@ -54,6 +54,7 @@ class Q_STUDIO3D_EXPORT Q3DSViewerSettings : public QObject Q_PROPERTY(double stereoEyeSeparation READ stereoEyeSeparation WRITE setStereoEyeSeparation NOTIFY stereoEyeSeparationChanged REVISION 1) Q_PROPERTY(bool stereoProgressiveEnabled READ stereoProgressiveEnabled WRITE setStereoProgressiveEnabled NOTIFY stereoProgressiveEnabledChanged REVISION 2) Q_PROPERTY(int skipFramesInterval READ skipFramesInterval WRITE setSkipFramesInterval NOTIFY skipFramesIntervalChanged REVISION 2) + Q_PROPERTY(double stereoEyeRotation READ stereoEyeRotation WRITE setStereoEyeRotation NOTIFY stereoEyeRotationChanged REVISION 3) public: enum ShadeMode { @@ -86,6 +87,7 @@ public: double stereoEyeSeparation() const; Q_REVISION(2) bool stereoProgressiveEnabled() const; Q_REVISION(2) int skipFramesInterval() const; + Q_REVISION(3) double stereoEyeRotation() const; Q_INVOKABLE void save(const QString &group, const QString &organization = QString(), const QString &application = QString()); @@ -101,6 +103,7 @@ public Q_SLOTS: void setStereoEyeSeparation(double separation); Q_REVISION(2) void setStereoProgressiveEnabled(bool enabled); Q_REVISION(2) void setSkipFramesInterval(int interval); + Q_REVISION(3) void setStereoEyeRotation(double rotation); Q_SIGNALS: void matteEnabledChanged(bool enabled); @@ -112,6 +115,7 @@ Q_SIGNALS: void stereoEyeSeparationChanged(double separation); Q_REVISION(2) void stereoProgressiveEnabledChanged(bool enabled); Q_REVISION(2) void skipFramesIntervalChanged(int interval); + Q_REVISION(3) void stereoEyeRotationChanged(double rotation); private: Q_DISABLE_COPY(Q3DSViewerSettings) diff --git a/src/api/studio3d/q3dsviewersettings_p.h b/src/api/studio3d/q3dsviewersettings_p.h index 6a2dc75..a9f8c5b 100644 --- a/src/api/studio3d/q3dsviewersettings_p.h +++ b/src/api/studio3d/q3dsviewersettings_p.h @@ -69,6 +69,7 @@ public: void setScaleMode(Q3DSViewerSettings::ScaleMode mode); void setStereoMode(Q3DSViewerSettings::StereoMode mode); void setStereoEyeSeparation(double separation); + void setStereoEyeRotation(double rotation); void setStereoProgressiveEnabled(bool enabled); void setSkipFramesInterval(int interval); @@ -88,6 +89,7 @@ private: Q3DSViewerSettings::ScaleMode m_scaleMode; Q3DSViewerSettings::StereoMode m_stereoMode; double m_stereoEyeSeparation; + double m_stereoEyeRotation; bool m_stereoProgressiveEnabled; int m_skipFramesInterval; QSettings *m_savedSettings; diff --git a/src/api/studio3dqml/q3dsplugin.cpp b/src/api/studio3dqml/q3dsplugin.cpp index 6ce3628..5ab3dfa 100644 --- a/src/api/studio3dqml/q3dsplugin.cpp +++ b/src/api/studio3dqml/q3dsplugin.cpp @@ -70,6 +70,9 @@ void Q3DSPlugin::registerTypes(const char *uri) qmlRegisterType<Q3DSViewerSettings, 2>(uri, 2, 7, "ViewerSettings"); qmlRegisterRevision<Q3DSPresentation, 2>(uri, 2, 7); + // 2.8 + qmlRegisterType<Q3DSViewerSettings, 3>(uri, 2, 8, "ViewerSettings"); + // Automatically register the latest version qmlRegisterModule(uri, ((QTSTUDIO3D_VERSION >> 16) & 0xff), ((QTSTUDIO3D_VERSION >> 8) & 0xff)); } diff --git a/src/api/studio3dqml/q3dsrenderer.cpp b/src/api/studio3dqml/q3dsrenderer.cpp index 8aa2c21..52f20f7 100644 --- a/src/api/studio3dqml/q3dsrenderer.cpp +++ b/src/api/studio3dqml/q3dsrenderer.cpp @@ -355,6 +355,8 @@ void Q3DSRenderer::processCommands() m_settings->setStereoMode(m_commands.m_stereoMode); if (m_commands.m_stereoEyeSeparationChanged) m_settings->setStereoEyeSeparation(m_commands.m_stereoEyeSeparation); + if (m_commands.m_stereoEyeRotationChanged) + m_settings->setStereoEyeRotation(m_commands.m_stereoEyeRotation); if (m_commands.m_stereoProgressiveEnabledChanged) m_settings->setStereoProgressiveEnabled(m_commands.m_stereoProgressiveEnabled); if (m_commands.m_skipFramesIntervalChanged) diff --git a/src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp b/src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp index e0176c7..82b42b1 100644 --- a/src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp +++ b/src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp @@ -157,6 +157,21 @@ struct SRenderer : public Q3DStudio::ITegraApplicationRenderEngine return 0; } + void SetStereoEyeRotation(double rotation) override + { + if (m_BindingCore && m_BindingCore->m_Context) + m_BindingCore->m_Context->SetStereoEyeRotation(rotation); + } + double GetStereoEyeRotation() const override + { + if (m_BindingCore && m_BindingCore->m_Context) { + return const_cast<SRenderer &>(*this).m_BindingCore-> + m_Context->GetStereoEyeRotation(); + } + QT3DS_ASSERT(false); + return 0; + } + void SetStereoProgressiveEnabled(bool enabled) override { if (m_BindingCore && m_BindingCore->m_Context) diff --git a/src/engine/Qt3DSRuntimeView.h b/src/engine/Qt3DSRuntimeView.h index 4cef00a..ea0f7e3 100644 --- a/src/engine/Qt3DSRuntimeView.h +++ b/src/engine/Qt3DSRuntimeView.h @@ -147,6 +147,8 @@ public: virtual TegraRenderStereoModes::Enum GetStereoMode() const = 0; virtual void SetStereoEyeSeparation(double separation) = 0; virtual double GetStereoEyeSeparation() const = 0; + virtual void SetStereoEyeRotation(double rotation) = 0; + virtual double GetStereoEyeRotation() const = 0; virtual void SetStereoProgressiveEnabled(bool enabled) = 0; virtual bool GetStereoProgressiveEnabled() const = 0; virtual void SetSkipFramesInterval(int interval) = 0; diff --git a/src/runtimerender/Qt3DSRenderContextCore.cpp b/src/runtimerender/Qt3DSRenderContextCore.cpp index 8280c39..4d925a8 100644 --- a/src/runtimerender/Qt3DSRenderContextCore.cpp +++ b/src/runtimerender/Qt3DSRenderContextCore.cpp @@ -248,6 +248,7 @@ struct SRenderContext : public IQt3DSRenderContext StereoModes::Enum m_StereoMode; StereoViews::Enum m_StereoView; double m_StereoEyeSeparation; + double m_StereoEyeRotation; bool m_StereoProgressiveEnabled; int m_SkipFramesInterval; bool m_WireframeMode; @@ -293,6 +294,7 @@ struct SRenderContext : public IQt3DSRenderContext , m_StereoMode(StereoModes::Mono) , m_StereoView(StereoViews::Mono) , m_StereoEyeSeparation(0.4) + , m_StereoEyeRotation(0.0) , m_StereoProgressiveEnabled(false) , m_SkipFramesInterval(0) , m_WireframeMode(false) @@ -483,6 +485,13 @@ struct SRenderContext : public IQt3DSRenderContext double GetStereoEyeSeparation() const override { return m_StereoEyeSeparation; } + void SetStereoEyeRotation(double rotation) override + { + m_StereoEyeRotation = rotation; + } + + double GetStereoEyeRotation() const override { return m_StereoEyeRotation; } + void SetStereoProgressiveEnabled(bool enabled) override { m_StereoProgressiveEnabled = enabled; diff --git a/src/runtimerender/Qt3DSRenderContextCore.h b/src/runtimerender/Qt3DSRenderContextCore.h index 337b58f..bb5943e 100644 --- a/src/runtimerender/Qt3DSRenderContextCore.h +++ b/src/runtimerender/Qt3DSRenderContextCore.h @@ -200,6 +200,8 @@ namespace render { virtual StereoViews::Enum GetStereoView() const = 0; virtual void SetStereoEyeSeparation(double separation) = 0; virtual double GetStereoEyeSeparation() const = 0; + virtual void SetStereoEyeRotation(double rotation) = 0; + virtual double GetStereoEyeRotation() const = 0; virtual void SetStereoProgressiveEnabled(bool enabled) = 0; virtual bool GetStereoProgressiveEnabled() const = 0; virtual void SetSkipFramesInterval(int interval) = 0; diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp index 5f290fa..4650e83 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp @@ -84,6 +84,7 @@ SLayerRenderHelper::SLayerRenderHelper(const NVRenderRectF &inPresentationViewpo qt3ds::render::StereoModes::Enum inStereoMode, qt3ds::render::StereoViews::Enum inStereoView, double inStereoEyeSeparation, + double inStereoEyeRotation, qt3ds::QT3DSVec2 inScaleFactor) : m_PresentationViewport(inPresentationViewport) , m_PresentationScissor(inPresentationScissor) @@ -97,6 +98,7 @@ SLayerRenderHelper::SLayerRenderHelper(const NVRenderRectF &inPresentationViewpo , m_StereoMode(inStereoMode) , m_StereoView(inStereoView) , m_StereoEyeSeparation(QT3DSF32(inStereoEyeSeparation)) + , m_StereoEyeRotation(QT3DSF32(inStereoEyeRotation)) , m_ScaleFactor(inScaleFactor) { { @@ -282,8 +284,10 @@ SCameraGlobalCalculationResult SLayerRenderHelper::SetupCameraForRender(SCamera { m_Camera = &inCamera; - if (isStereoscopic()) + if (isStereoscopic()) { + m_Camera->AddChild(*GetCamera()); adjustCameraStereoSeparation(); + } NVRenderRectF rect = GetLayerRenderViewport(); if (m_ScaleMode == ScaleModes::FitSelected) { @@ -296,7 +300,12 @@ SCameraGlobalCalculationResult SLayerRenderHelper::SetupCameraForRender(SCamera if (isStereoscopic()) m_Camera->CalculateGlobalVariables(rect, m_PresentationDesignDimensions); // Return current camera variables - return GetCamera()->CalculateGlobalVariables(rect, m_PresentationDesignDimensions); + auto ret = GetCamera()->CalculateGlobalVariables(rect, m_PresentationDesignDimensions); + + if (isStereoscopic()) + m_Camera->RemoveChild(*GetCamera()); + + return ret; } Option<QT3DSVec2> SLayerRenderHelper::GetLayerMouseCoords(const QT3DSVec2 &inMouseCoords, @@ -381,8 +390,8 @@ NVRenderRectF SLayerRenderHelper::getOriginalLayerToPresentationViewport() const return m_originalViewport; } -void SLayerRenderHelper::copyCameraProperties(SCamera *sourceCamera, - SCamera *destinationCamera) +void SLayerRenderHelper::copyCameraStereoProperties(SCamera *sourceCamera, + SCamera *destinationCamera) { if (!sourceCamera || !destinationCamera) return; @@ -400,33 +409,27 @@ void SLayerRenderHelper::copyCameraProperties(SCamera *sourceCamera, destinationCamera->m_Pivot = sourceCamera->m_Pivot; destinationCamera->m_Scale = sourceCamera->m_Scale; destinationCamera->m_DFSIndex = sourceCamera->m_DFSIndex; - destinationCamera->m_Position = sourceCamera->m_Position; - destinationCamera->m_Rotation = sourceCamera->m_Rotation; - destinationCamera->m_UserData = sourceCamera->m_UserData; - destinationCamera->m_LocalOpacity = sourceCamera->m_LocalOpacity; - destinationCamera->m_GlobalOpacity = sourceCamera->m_GlobalOpacity; destinationCamera->m_RotationOrder = sourceCamera->m_RotationOrder; - destinationCamera->m_LocalTransform = sourceCamera->m_LocalTransform; - destinationCamera->m_GlobalTransform = sourceCamera->m_GlobalTransform; - destinationCamera->m_Parent = sourceCamera->m_Parent; } void SLayerRenderHelper::adjustCameraStereoSeparation() { // Copy m_Camera properties into left & right cameras - copyCameraProperties(m_Camera, &m_CameraLeftEye); - copyCameraProperties(m_Camera, &m_CameraRightEye); + copyCameraStereoProperties(m_Camera, &m_CameraLeftEye); + copyCameraStereoProperties(m_Camera, &m_CameraRightEye); // Adjust left & right camera positions by eye separation QT3DSVec3 eyeMove(m_StereoEyeSeparation, 0, 0); - QT3DSVec3 camMove = m_Camera->m_GlobalTransform.transform(eyeMove) - - m_Camera->m_GlobalTransform.getPosition(); - camMove.z *= -1; // Inverse z - m_CameraLeftEye.m_Position -= camMove; + m_CameraLeftEye.m_Position = -eyeMove; m_CameraLeftEye.m_Flags.SetTransformDirty(true); - m_CameraRightEye.m_Position += camMove; + m_CameraRightEye.m_Position = eyeMove; m_CameraRightEye.m_Flags.SetTransformDirty(true); + // Adjust left & right camera rotations + QT3DSVec3 eyeRotation(0, m_StereoEyeRotation, 0); + m_CameraLeftEye.m_Rotation = eyeRotation; + m_CameraRightEye.m_Rotation = -eyeRotation; + m_CameraLeftEye.MarkDirty(); m_CameraRightEye.MarkDirty(); } diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h index 078c2ec..2c64569 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h @@ -73,6 +73,7 @@ namespace render { StereoModes::Enum m_StereoMode = StereoModes::Mono; StereoViews::Enum m_StereoView = StereoViews::Mono; QT3DSF32 m_StereoEyeSeparation = 0.4f; + QT3DSF32 m_StereoEyeRotation = 0.0f; QT3DSVec2 m_ScaleFactor; @@ -86,6 +87,7 @@ namespace render { qt3ds::render::StereoModes::Enum inStereoMode, qt3ds::render::StereoViews::Enum inStereoView, double inStereoEyeSeparation, + double inStereoEyeRotation, qt3ds::QT3DSVec2 inScaleFactor); NVRenderRectF GetPresentationViewport() const { return m_PresentationViewport; } @@ -103,6 +105,9 @@ namespace render { // Get/set eye (camera) separation. QT3DSF32 getEyeSeparation() const { return m_StereoEyeSeparation; } void setEyeSeparation(QT3DSF32 separation) { m_StereoEyeSeparation = separation; } + // Get/set eye (camera) rotation. + QT3DSF32 getEyeRotation() const { return m_StereoEyeRotation; } + void setEyeRotation(QT3DSF32 rotation) { m_StereoEyeRotation = rotation; } void setViewport(const NVRenderRectF &viewport); // Does not differ whether offscreen or not, simply states how this layer maps to the @@ -133,7 +138,7 @@ namespace render { // different than the layer to presentation viewport. NVRenderRectF GetLayerRenderViewport() const; - void copyCameraProperties(SCamera *sourceCamera, SCamera *destinationCamera); + void copyCameraStereoProperties(SCamera *sourceCamera, SCamera *destinationCamera); void adjustCameraStereoSeparation(); }; } diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp index 0ee8aae..c8c287c 100644 --- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp +++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp @@ -1511,6 +1511,7 @@ namespace render { m_Renderer.GetQt3DSContext().GetStereoMode(), m_Renderer.GetQt3DSContext().GetStereoView(), m_Renderer.GetQt3DSContext().GetStereoEyeSeparation(), + m_Renderer.GetQt3DSContext().GetStereoEyeRotation(), m_Renderer.GetQt3DSContext().GetPresentationScaleFactor())); m_LayerPrepResult->m_LastEffect = theLastEffect; m_LayerPrepResult->m_MaxAAPassIndex = maxNumAAPasses; diff --git a/src/viewer/Qt3DSViewerApp.cpp b/src/viewer/Qt3DSViewerApp.cpp index 523f681..9b5eb8b 100644 --- a/src/viewer/Qt3DSViewerApp.cpp +++ b/src/viewer/Qt3DSViewerApp.cpp @@ -874,6 +874,20 @@ double Q3DSViewerApp::GetStereoEyeSeparation() const return 0; } +void Q3DSViewerApp::SetStereoEyeRotation(double rotation) +{ + if (m_Impl.m_view && m_Impl.m_view->GetTegraRenderEngine()) + m_Impl.m_view->GetTegraRenderEngine()->SetStereoEyeRotation(rotation); +} + +double Q3DSViewerApp::GetStereoEyeRotation() const +{ + if (m_Impl.m_view && m_Impl.m_view->GetTegraRenderEngine()) + return m_Impl.m_view->GetTegraRenderEngine()->GetStereoEyeRotation(); + + return 0; +} + void Q3DSViewerApp::SetStereoProgressiveEnabled(bool enabled) { if (m_Impl.m_view && m_Impl.m_view->GetTegraRenderEngine()) diff --git a/src/viewer/Qt3DSViewerApp.h b/src/viewer/Qt3DSViewerApp.h index 39ebb63..8b53e85 100644 --- a/src/viewer/Qt3DSViewerApp.h +++ b/src/viewer/Qt3DSViewerApp.h @@ -325,6 +325,9 @@ public: void SetStereoEyeSeparation(double separation); double GetStereoEyeSeparation() const; + void SetStereoEyeRotation(double rotation); + double GetStereoEyeRotation() const; + void SetStereoProgressiveEnabled(bool enabled); bool GetStereoProgressiveEnabled() const; diff --git a/tools/viewer/qml/main.qml b/tools/viewer/qml/main.qml index baaf6d3..93d52a8 100644 --- a/tools/viewer/qml/main.qml +++ b/tools/viewer/qml/main.qml @@ -31,7 +31,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Dialogs 1.2 import Qt3DStudioViewer 1.0 -import QtStudio3D.OpenGL 2.7 +import QtStudio3D.OpenGL 2.8 import QtQuick.Window 2.2 ApplicationWindow { @@ -52,6 +52,7 @@ ApplicationWindow { property int scaleMode: ViewerSettings.ScaleModeCenter property int stereoMode: ViewerSettings.StereoModeMono property double stereoEyeSeparation: 0.4 + property double stereoEyeRotation: 0.0 property bool stereoProgressiveEnabled: false function closeMenus() { @@ -220,6 +221,7 @@ ApplicationWindow { scaleMode: window.scaleMode stereoMode: window.stereoMode stereoEyeSeparation: window.stereoEyeSeparation + stereoEyeRotation: window.stereoEyeRotation stereoProgressiveEnabled: window.stereoProgressiveEnabled } @@ -668,6 +670,32 @@ ApplicationWindow { } } } + StyledMenuItem { + id: stereoEyeRotationUp + text: qsTr("Increase Rotation") + shortcut: "Ctrl+Shift+9" + enabled: _viewerHelper.contentView === ViewerHelper.StudioView + onTriggered: { + // Rotate in 0.1-degree steps + let step = Math.PI / 1800; + if (enabled) + window.stereoEyeRotation += step; + } + } + StyledMenuItem { + id: stereoEyeRotationDown + text: qsTr("Decrease Rotation") + shortcut: "Ctrl+Shift+8" + enabled: _viewerHelper.contentView === ViewerHelper.StudioView + onTriggered: { + if (enabled) { + // Rotate in 0.1-degree steps + let step = Math.PI / 1800; + window.stereoEyeRotation + = Math.max(0, window.stereoEyeRotation - step); + } + } + } } } StyledMenuItem { |