From ae044e6ee37b228e109b19c7c13be5c260c0bb64 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 1 Mar 2019 11:26:51 +0200 Subject: Implement scene camera preview MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scene camera preview tab will use a completely separate renderer from the main scene renderer. This essentially duplicates the rendering overhead, but it is required as Qt3D underlying the runtime will not respond to any scene changes without some delay, making it impossible to render both preview and regular scene with the same renderer in a timely manner. Task-number: QT3DS-2070 Change-Id: I5e2c9f280990bf295ef84d83244c18a37f94aca3 Reviewed-by: Mahmoud Badri Reviewed-by: Antti Määttä Reviewed-by: Tomi Korpipää --- src/Authoring/Studio/MainFrm.cpp | 1 - .../Palettes/scenecamera/scenecameraglwidget.cpp | 66 ++++++- .../Palettes/scenecamera/scenecameraglwidget.h | 13 +- .../Palettes/scenecamera/scenecamerascrollarea.cpp | 7 + .../Palettes/scenecamera/scenecamerascrollarea.h | 1 + .../Palettes/scenecamera/scenecameraview.cpp | 18 +- .../Studio/Palettes/scenecamera/scenecameraview.h | 9 +- src/Authoring/Studio/Render/IStudioRenderer.h | 6 +- .../Studio/Render/Q3DSManipulationWidget.cpp | 5 + .../Studio/Render/Q3DSManipulationWidget.h | 3 + src/Authoring/Studio/Render/Q3DSTranslation.cpp | 220 ++++++++++++--------- src/Authoring/Studio/Render/Q3DSTranslation.h | 11 +- .../Studio/Render/Q3DSVisualAidWidget.cpp | 5 + src/Authoring/Studio/Render/Q3DSVisualAidWidget.h | 1 + src/Authoring/Studio/Render/Q3DStudioRenderer.cpp | 99 ++++------ src/Authoring/Studio/Render/Q3DStudioRenderer.h | 9 +- src/Authoring/Studio/UI/Q3DSPlayerWidget.cpp | 2 +- src/Authoring/Studio/UI/Q3DSPlayerWnd.h | 1 - 18 files changed, 302 insertions(+), 175 deletions(-) diff --git a/src/Authoring/Studio/MainFrm.cpp b/src/Authoring/Studio/MainFrm.cpp index 9bf14265..334e0936 100644 --- a/src/Authoring/Studio/MainFrm.cpp +++ b/src/Authoring/Studio/MainFrm.cpp @@ -1628,7 +1628,6 @@ void CMainFrame::onUpdateViewSceneCamera() const bool cameraVisible = m_paletteManager->IsControlVisible( CPaletteManager::CONTROLTYPE_SCENECAMERA); m_ui->actionSceneCamera->setChecked(cameraVisible); - g_StudioApp.getRenderer().setFullSizePreview(cameraVisible); } //============================================================================== diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.cpp b/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.cpp index a82f7158..fc3b59bd 100644 --- a/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.cpp +++ b/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.cpp @@ -29,14 +29,19 @@ #include "Qt3DSCommonPrecompile.h" #include "scenecameraglwidget.h" #include "StudioApp.h" -#include "IStudioRenderer.h" #include "WGLRenderContext.h" #include "StudioPreferences.h" +#include "Q3DStudioRenderer.h" +#include "StudioProjectSettings.h" +#include "StudioUtils.h" #include #include #include #include +#include +#include +#include const QVector4D defaultTextureOffset = QVector4D(0.0f, 0.0f, 1.0f, 1.0f); const QVector2D defaultGeometryOffset = QVector2D(1.0f, 1.0f); @@ -55,6 +60,13 @@ SceneCameraGlWidget::SceneCameraGlWidget(QWidget *parent) SceneCameraGlWidget::~SceneCameraGlWidget() { cleanup(); + m_renderer = std::shared_ptr(); +} + +void SceneCameraGlWidget::requestRender() +{ + if (m_renderer && m_renderer->IsInitialized()) + m_renderer->RequestRender(); } void SceneCameraGlWidget::initializeGL() @@ -63,6 +75,11 @@ void SceneCameraGlWidget::initializeGL() QObject::connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &SceneCameraGlWidget::cleanup); + if (!m_renderer) + m_renderer = Q3DStudio::IStudioRenderer::CreateStudioRenderer(true); + if (!m_renderer->IsInitialized()) + m_renderer->initialize(this, m_hasPresentation); + m_program = new QOpenGLShaderProgram(); if (!m_program->addShaderFromSourceCode( QOpenGLShader::Vertex, @@ -154,23 +171,36 @@ void SceneCameraGlWidget::initializeGL() void SceneCameraGlWidget::paintGL() { - Q3DStudio::IStudioRenderer &renderer(g_StudioApp.getRenderer()); - if (renderer.IsInitialized()) { - m_vao->bind(); + if (m_renderer && m_renderer->IsInitialized()) { + m_fboSize = g_StudioApp.GetCore()->GetStudioProjectSettings()->getPresentationSize(); + if (!m_fbo || m_fboSize != m_fbo->size()) { + delete m_fbo; + m_fbo = new QOpenGLFramebufferObject(m_fboSize, + QOpenGLFramebufferObject::CombinedDepthStencil); + m_renderer->SetViewRect(QRect(0, 0, m_fboSize.width(), m_fboSize.height()), m_fboSize); + } + m_fbo->bind(); + m_renderer->renderNow(); + m_fbo->bindDefault(); + // Clean the OpenGL state glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glViewport(0, 0, width() * m_pixelRatio, height() * m_pixelRatio); + + m_program->bind(); + m_vao->bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - QSize fboSize; - qt3ds::QT3DSU32 textureId; - renderer.getPreviewFbo(fboSize, textureId); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, GLuint(textureId)); + glBindTexture(GL_TEXTURE_2D, m_fbo->texture()); m_program->setUniformValueArray(m_uniformTextureOffset, &m_textureOffset, 1); m_program->setUniformValueArray(m_uniformGeometryOffset, &m_geometryOffset, 1); @@ -178,23 +208,36 @@ void SceneCameraGlWidget::paintGL() glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); m_vao->release(); + m_program->release(); } } -void SceneCameraGlWidget::resizeGL(int, int) +void SceneCameraGlWidget::resizeGL(int w, int h) { // We need to update immediately to avoid flicker - update(); + update(); + + const qreal pixelRatio = StudioUtils::devicePixelRatio(window()->windowHandle()); + if (pixelRatio != m_pixelRatio) { + m_pixelRatio = pixelRatio; + delete m_fbo; + m_fbo = nullptr; + } + + if (m_renderer && m_renderer->IsInitialized()) + m_renderer->RequestRender(); } void SceneCameraGlWidget::cleanup() { makeCurrent(); + delete m_fbo; delete m_program; delete m_vertexBuffer; delete m_uvBuffer; delete m_vao; + m_fbo = nullptr; m_program = nullptr; m_vertexBuffer = nullptr; m_uvBuffer = nullptr; @@ -204,5 +247,8 @@ void SceneCameraGlWidget::cleanup() m_textureOffset = defaultTextureOffset; m_geometryOffset = defaultGeometryOffset; + if (m_renderer) + m_renderer->Close(); + doneCurrent(); } diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.h b/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.h index 93becf19..e985c378 100644 --- a/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.h +++ b/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.h @@ -29,6 +29,8 @@ #ifndef SCENE_CAMERA_GLWIDGET_H #define SCENE_CAMERA_GLWIDGET_H +#include "IStudioRenderer.h" + #include #include #include @@ -37,6 +39,7 @@ QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram) QT_FORWARD_DECLARE_CLASS(QOpenGLBuffer) QT_FORWARD_DECLARE_CLASS(QOpenGLVertexArrayObject) +QT_FORWARD_DECLARE_CLASS(QOpenGLFramebufferObject) class SceneCameraGlWidget : public QOpenGLWidget, QOpenGLFunctions { @@ -48,10 +51,13 @@ public: void setTextureOffset(const QVector4D &offset) { m_textureOffset = offset; } void setGeometryOffset(const QVector4D &offset) { m_geometryOffset = offset; } + void requestRender(); + void setPresentationAvailable(bool available) { m_hasPresentation = available; } + protected: void initializeGL() override; void paintGL() override; - void resizeGL(int, int) override; + void resizeGL(int w, int h) override; private: void cleanup(); @@ -60,10 +66,15 @@ private: QOpenGLBuffer *m_vertexBuffer = nullptr; QOpenGLBuffer *m_uvBuffer = nullptr; QOpenGLVertexArrayObject *m_vao = nullptr; + QOpenGLFramebufferObject *m_fbo = nullptr; + QSize m_fboSize; GLint m_uniformTextureOffset = 0; GLint m_uniformGeometryOffset = 0; QVector4D m_textureOffset; QVector4D m_geometryOffset; + std::shared_ptr m_renderer; + qreal m_pixelRatio = 1.; + bool m_hasPresentation = false; }; #endif diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.cpp b/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.cpp index 035e242c..fbec11a7 100644 --- a/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.cpp +++ b/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.cpp @@ -122,6 +122,13 @@ void SceneCameraScrollArea::recalculateOffsets() m_glWidget->setGeometryOffset(geometryOffset); } +void SceneCameraScrollArea::setPresentationAvailable(bool available) +{ + if (available) + setZoom(m_zoom, viewport()->geometry().center()); + m_glWidget->setPresentationAvailable(available); +} + void SceneCameraScrollArea::scrollContentsBy(int, int) { recalculateOffsets(); diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.h b/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.h index 682dc430..8ba7936c 100644 --- a/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.h +++ b/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.h @@ -47,6 +47,7 @@ public: void setPresentationSize(const QSize &size); void recalculateScrollRanges(); void recalculateOffsets(); + void setPresentationAvailable(bool available); Q_SIGNALS: void needUpdate(); diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.cpp b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.cpp index b4470cd6..63da8ef2 100644 --- a/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.cpp +++ b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.cpp @@ -36,6 +36,7 @@ #include "Q3DSPlayerWnd.h" #include "MouseCursor.h" #include "ResourceCache.h" +#include "Dispatch.h" #include #include @@ -50,6 +51,8 @@ SceneCameraView::SceneCameraView(CMainFrame *mainFrame, QWidget *parent) : { m_ui->setupUi(this); + g_StudioApp.GetCore()->GetDispatch()->AddPresentationChangeListener(this); + m_cursorPan = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_EDIT_CAMERA_PAN); m_cursorZoom = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_EDIT_CAMERA_ZOOM); @@ -59,8 +62,6 @@ SceneCameraView::SceneCameraView(CMainFrame *mainFrame, QWidget *parent) : connect(m_ui->zoomSlider, &QSlider::valueChanged, this, &SceneCameraView::handleSliderValueChange); - connect(mainFrame->GetPlayerWnd(), &Q3DStudio::Q3DSPlayerWnd::newFrame, - this, &SceneCameraView::requestUpdate); connect(m_ui->scrollArea, &SceneCameraScrollArea::needUpdate, this, &SceneCameraView::requestUpdate); connect(&m_updateTimer, &QTimer::timeout, this, &SceneCameraView::doUpdate); @@ -68,9 +69,20 @@ SceneCameraView::SceneCameraView(CMainFrame *mainFrame, QWidget *parent) : SceneCameraView::~SceneCameraView() { + g_StudioApp.GetCore()->GetDispatch()->RemovePresentationChangeListener(this); delete m_ui; } +void SceneCameraView::OnNewPresentation() +{ + m_ui->scrollArea->setPresentationAvailable(true); +} + +void SceneCameraView::OnClosingPresentation() +{ + m_ui->scrollArea->setPresentationAvailable(false); +} + void SceneCameraView::wheelEvent(QWheelEvent *e) { m_zoomPoint = m_ui->scrollArea->viewport()->mapFrom(this, e->pos()); @@ -151,7 +163,7 @@ void SceneCameraView::doUpdate() // There is no event for presentation size change, so update every frame to catch the change m_ui->scrollArea->setPresentationSize( g_StudioApp.GetCore()->GetStudioProjectSettings()->getPresentationSize()); - m_ui->scrollArea->glWidget()->update(); + m_ui->scrollArea->glWidget()->requestRender(); } void SceneCameraView::requestUpdate() diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.h b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.h index e2bfb05b..299115d0 100644 --- a/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.h +++ b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.h @@ -29,6 +29,8 @@ #ifndef SCENECAMERAVIEW_H #define SCENECAMERAVIEW_H +#include "DispatchListeners.h" + #include #include @@ -44,7 +46,8 @@ QT_END_NAMESPACE class CMainFrame; -class SceneCameraView : public QWidget +class SceneCameraView : public QWidget, + public CPresentationChangeListener { Q_OBJECT @@ -52,6 +55,10 @@ public: explicit SceneCameraView(CMainFrame *mainFrame, QWidget *parent = 0); ~SceneCameraView(); + // CPresentationChangeListener + void OnNewPresentation() override; + void OnClosingPresentation() override; + protected: void wheelEvent(QWheelEvent *e) override; void resizeEvent(QResizeEvent *e) override; diff --git a/src/Authoring/Studio/Render/IStudioRenderer.h b/src/Authoring/Studio/Render/IStudioRenderer.h index afea2f48..bfd8615d 100644 --- a/src/Authoring/Studio/Render/IStudioRenderer.h +++ b/src/Authoring/Studio/Render/IStudioRenderer.h @@ -55,10 +55,9 @@ public: virtual bool IsInitialized() = 0; - virtual void initialize(QOpenGLWidget *widget) = 0; + virtual void initialize(QOpenGLWidget *widget, bool hasPresentation) = 0; virtual void SetViewRect(const QRect &inRect, const QSize &size) = 0; - virtual void setFullSizePreview(bool enabled) = 0; virtual void GetEditCameraList(QStringList &outCameras) = 0; virtual void SetPolygonFillModeEnabled(bool inEnableFillMode) = 0; @@ -83,12 +82,11 @@ public: // synchronously render the content virtual void renderNow() = 0; - virtual void getPreviewFbo(QSize &outFboDim, qt3ds::QT3DSU32 &outFboTexture) = 0; virtual void RegisterSubpresentations( const QVector &subpresentations) = 0; // Uses the global studio app to get the doc and dispatch. - static std::shared_ptr CreateStudioRenderer(); + static std::shared_ptr CreateStudioRenderer(bool sceneCameraMode = false); }; }; diff --git a/src/Authoring/Studio/Render/Q3DSManipulationWidget.cpp b/src/Authoring/Studio/Render/Q3DSManipulationWidget.cpp index 87232aa7..925d61c3 100644 --- a/src/Authoring/Studio/Render/Q3DSManipulationWidget.cpp +++ b/src/Authoring/Studio/Render/Q3DSManipulationWidget.cpp @@ -34,6 +34,11 @@ namespace Q3DStudio { +Q3DSManipulationWidget::~Q3DSManipulationWidget() +{ + destroyManipulators(); +} + bool Q3DSManipulationWidget::hasManipulators() const { return m_manipulators.size() > 0; diff --git a/src/Authoring/Studio/Render/Q3DSManipulationWidget.h b/src/Authoring/Studio/Render/Q3DSManipulationWidget.h index daa8c65b..f4cce682 100644 --- a/src/Authoring/Studio/Render/Q3DSManipulationWidget.h +++ b/src/Authoring/Studio/Render/Q3DSManipulationWidget.h @@ -43,6 +43,9 @@ enum class ManipulationWidgetType class Q3DSManipulationWidget { public: + Q3DSManipulationWidget() {} + ~Q3DSManipulationWidget(); + bool hasManipulators() const; bool isXAxis(Q3DSGraphObject *obj) const; bool isYAxis(Q3DSGraphObject *obj) const; diff --git a/src/Authoring/Studio/Render/Q3DSTranslation.cpp b/src/Authoring/Studio/Render/Q3DSTranslation.cpp index 14436ead..311fac57 100644 --- a/src/Authoring/Studio/Render/Q3DSTranslation.cpp +++ b/src/Authoring/Studio/Render/Q3DSTranslation.cpp @@ -247,7 +247,8 @@ static inline float makeNiceRotation(float inAngle) } Q3DSTranslation::Q3DSTranslation(Q3DStudioRenderer &inRenderer, - const QSharedPointer &presentation) + const QSharedPointer &presentation, + bool sceneCameraMode) : m_studioRenderer(inRenderer) , m_doc(*g_StudioApp.GetCore()->GetDoc()) , m_reader(m_doc.GetDocumentReader()) @@ -258,7 +259,13 @@ Q3DSTranslation::Q3DSTranslation(Q3DStudioRenderer &inRenderer, , m_assetGraph(*m_doc.GetAssetGraph()) , m_engine(inRenderer.engine()) , m_presentation(presentation) + , m_sceneCameraMode(sceneCameraMode) { + if (!m_sceneCameraMode) { + m_selectionWidget = new Q3DSSelectionWidget(); + m_manipulationWidget = new Q3DSManipulationWidget(); + } + qt3dsdm::Qt3DSDMInstanceHandle sceneRoot = m_assetGraph.GetRoot(0); m_graphIterator.ClearResults(); m_assetGraph.GetDepthFirst(m_graphIterator, sceneRoot); @@ -354,6 +361,13 @@ Q3DSTranslation::Q3DSTranslation(Q3DStudioRenderer &inRenderer, enableForegroundLayer(); } +Q3DSTranslation::~Q3DSTranslation() +{ + delete m_manipulationWidget; + delete m_selectionWidget; + disableVisualAids(); +} + Q3DSTranslation::THandleTranslatorPairList &Q3DSTranslation::getTranslatorsForInstance( qt3dsdm::Qt3DSDMInstanceHandle instance) { @@ -481,17 +495,17 @@ QVector4D Q3DSTranslation::calculateWidgetArrowDrag(const QPoint &mousePos, // Find the direction of the drag and the best plane to map against that is parallel // to the direction vector - if (m_manipulationWidget.isXAxis(m_pickedWidget)) { + if (m_manipulationWidget->isXAxis(m_pickedWidget)) { direction = getXAxis(m_dragNodeGlobalTransform); plane1 = getYAxis(m_dragNodeGlobalTransform); plane2 = getZAxis(m_dragNodeGlobalTransform); distanceMultiplier = -1.f; - } else if (m_manipulationWidget.isYAxis(m_pickedWidget)) { + } else if (m_manipulationWidget->isYAxis(m_pickedWidget)) { plane1 = getXAxis(m_dragNodeGlobalTransform); direction = getYAxis(m_dragNodeGlobalTransform); plane2 = getZAxis(m_dragNodeGlobalTransform); distanceMultiplier = -1.f; - } else if (m_manipulationWidget.isZAxis(m_pickedWidget)) { + } else if (m_manipulationWidget->isZAxis(m_pickedWidget)) { plane1 = getXAxis(m_dragNodeGlobalTransform); plane2 = getYAxis(m_dragNodeGlobalTransform); direction = getZAxis(m_dragNodeGlobalTransform); @@ -865,7 +879,8 @@ Q3DSGraphObjectTranslator *Q3DSTranslation::createTranslator( case qt3dsdm::ComposerObjectTypes::Layer: { Q3DSLayerTranslator *t = new Q3DSLayerTranslator(instance, *m_presentation->newObject(id)); - m_layerTranslators.push_back(t); + if (!m_sceneCameraMode) + m_layerTranslators.push_back(t); translator = t; break; } @@ -876,14 +891,16 @@ Q3DSGraphObjectTranslator *Q3DSTranslation::createTranslator( case qt3dsdm::ComposerObjectTypes::Camera: { Q3DSCameraTranslator *t = new Q3DSCameraTranslator(instance, *m_presentation->newObject(id)); - m_cameraTranslators.push_back(t); + if (!m_sceneCameraMode) + m_cameraTranslators.push_back(t); translator = t; break; } case qt3dsdm::ComposerObjectTypes::Light: { Q3DSLightTranslator *t = new Q3DSLightTranslator( instance, *m_presentation->newObject(id)); - m_lightTranslators.push_back(t); + if (!m_sceneCameraMode) + m_lightTranslators.push_back(t); translator = t; break; } @@ -986,6 +1003,10 @@ void Q3DSTranslation::releaseTranslator(Q3DSGraphObjectTranslator *translator) if (static_cast(translator)) m_cameraTranslators.removeAll(static_cast(translator)); + if (static_cast(translator)) + m_lightTranslators.removeAll(static_cast(translator)); + if (static_cast(translator)) + m_layerTranslators.removeAll(static_cast(translator)); if (static_cast(translator)) m_refMatTranslators.removeAll(static_cast(translator)); @@ -1067,8 +1088,10 @@ void Q3DSTranslation::prepareRender(const QRect &rect, const QSize &size, qreal m_rect = rect; m_size = size; m_pixelRatio = pixelRatio; - m_manipulationWidget.setDefaultScale( - QVector3D(float(m_pixelRatio), float(m_pixelRatio), float(m_pixelRatio))); + if (m_manipulationWidget) { + m_manipulationWidget->setDefaultScale( + QVector3D(float(m_pixelRatio), float(m_pixelRatio), float(m_pixelRatio))); + } } } @@ -1199,7 +1222,7 @@ void Q3DSTranslation::wheelZoom(qreal factor) void Q3DSTranslation::enableBackgroundLayer() { - if (!m_backgroundLayer) { + if (!m_backgroundLayer && !m_sceneCameraMode) { m_backgroundLayer = m_presentation->newObject("StudioBackgroundLayer_"); m_scene->appendChildNode(m_backgroundLayer); m_presentation->masterSlide()->addObject(m_backgroundLayer); @@ -1211,7 +1234,7 @@ void Q3DSTranslation::enableBackgroundLayer() void Q3DSTranslation::enableForegroundLayer() { - if (!m_foregroundLayer && !m_foregroundPickingLayer) { + if (!m_foregroundLayer && !m_foregroundPickingLayer && !m_sceneCameraMode) { m_foregroundLayer = m_presentation->newObject("StudioForegroundLayer_"); m_scene->prependChildNode(m_foregroundLayer); m_presentation->masterSlide()->addObject(m_foregroundLayer); @@ -1245,7 +1268,7 @@ void Q3DSTranslation::disableGradient() void Q3DSTranslation::enableGradient() { - if (m_cameraType != m_editCameraInfo.m_cameraType) { + if (m_cameraType != m_editCameraInfo.m_cameraType && !m_sceneCameraMode) { disableGradient(); if (m_backgroundLayer) { m_gradient = m_presentation->newObject("StudioGradient_"); @@ -1333,6 +1356,9 @@ void Q3DSTranslation::enableGradient() void Q3DSTranslation::selectObject(Qt3DSDMInstanceHandle instance) { + if (m_sceneCameraMode) + return; + Q3DSGraphObjectTranslator *translator = getOrCreateTranslator(instance); if (!translator) return; @@ -1342,21 +1368,29 @@ void Q3DSTranslation::selectObject(Qt3DSDMInstanceHandle instance) enableManipulationWidget(); const auto layer = layerForNode(m_selectedObject); - if (layer) - m_selectionWidget.select(m_presentation.data(), static_cast(m_selectedObject)); - else - m_selectionWidget.deselect(); + if (layer) { + m_selectionWidget->select(m_presentation.data(), + static_cast(m_selectedObject)); + } else { + m_selectionWidget->deselect(); + } } void Q3DSTranslation::unselectObject() { + if (m_sceneCameraMode) + return; + m_selectedObject = nullptr; - m_manipulationWidget.destroyManipulators(); - m_selectionWidget.deselect(); + m_manipulationWidget->destroyManipulators(); + m_selectionWidget->deselect(); } void Q3DSTranslation::enableManipulationWidget() { + if (m_sceneCameraMode) + return; + if (!m_selectedObject || (m_selectedObject->type() != Q3DSGraphObject::Model && m_selectedObject->type() != Q3DSGraphObject::Alias && m_selectedObject->type() != Q3DSGraphObject::Group @@ -1364,7 +1398,7 @@ void Q3DSTranslation::enableManipulationWidget() && m_selectedObject->type() != Q3DSGraphObject::Camera && m_selectedObject->type() != Q3DSGraphObject::Text && m_selectedObject->type() != Q3DSGraphObject::Component)) { - m_manipulationWidget.setEyeballEnabled(false); + m_manipulationWidget->setEyeballEnabled(false); } updateForegroundLayerProperties(); @@ -1373,22 +1407,22 @@ void Q3DSTranslation::enableManipulationWidget() void Q3DSTranslation::disableVisualAids() { - if (!m_visualAids.empty()) { - for (int i = 0; i < m_visualAids.size(); ++i) - m_visualAids[i].destroy(); - m_visualAids.clear(); - } + qDeleteAll(m_visualAids); + m_visualAids.clear(); } void Q3DSTranslation::enableVisualAids() { + if (m_sceneCameraMode) + return; + m_visualAids.reserve(m_cameraTranslators.size() + m_lightTranslators.size()); for (auto &camera : qAsConst(m_cameraTranslators)) { if (m_selectedLayer != nullptr && layerForNode(&camera->graphObject()) == m_selectedLayer) { bool alreadyCreated = false; for (auto &visualAid : qAsConst(m_visualAids)) { - if (visualAid.hasGraphObject(&camera->graphObject())) { + if (visualAid->hasGraphObject(&camera->graphObject())) { alreadyCreated = true; break; } @@ -1396,14 +1430,15 @@ void Q3DSTranslation::enableVisualAids() if (alreadyCreated) continue; - m_visualAids.append(Q3DSVisualAidWidget(m_presentation.data(), m_foregroundLayer, - m_foregroundPickingLayer, - VisualAidType::Camera, &camera->graphObject(), - m_visualAidIndex++)); + m_visualAids.append(new Q3DSVisualAidWidget( + m_presentation.data(), m_foregroundLayer, + m_foregroundPickingLayer, + VisualAidType::Camera, &camera->graphObject(), + m_visualAidIndex++)); } else { for (int i = m_visualAids.size() - 1; i >= 0; --i) { - if (m_visualAids[i].hasGraphObject(&camera->graphObject())) { - m_visualAids[i].destroy(); + if (m_visualAids[i]->hasGraphObject(&camera->graphObject())) { + delete m_visualAids[i]; m_visualAids.remove(i); } } @@ -1424,11 +1459,11 @@ void Q3DSTranslation::enableVisualAids() bool alreadyCreated = false; for (int i = m_visualAids.size() - 1; i >= 0; --i) { - if (m_visualAids[i].hasGraphObject(&light->graphObject())) { - if (m_visualAids[i].type() == newVisualAidType) { + if (m_visualAids[i]->hasGraphObject(&light->graphObject())) { + if (m_visualAids[i]->type() == newVisualAidType) { alreadyCreated = true; } else { - m_visualAids[i].destroy(); + delete m_visualAids[i]; m_visualAids.remove(i); } break; @@ -1438,13 +1473,14 @@ void Q3DSTranslation::enableVisualAids() if (alreadyCreated) continue; - m_visualAids.append(Q3DSVisualAidWidget(m_presentation.data(), m_foregroundLayer, - m_foregroundPickingLayer, newVisualAidType, - &light->graphObject(), m_visualAidIndex++)); + m_visualAids.append(new Q3DSVisualAidWidget( + m_presentation.data(), m_foregroundLayer, + m_foregroundPickingLayer, newVisualAidType, + &light->graphObject(), m_visualAidIndex++)); } else { for (int i = m_visualAids.size() - 1; i >= 0; --i) { - if (m_visualAids[i].hasGraphObject(&light->graphObject())) { - m_visualAids[i].destroy(); + if (m_visualAids[i]->hasGraphObject(&light->graphObject())) { + delete m_visualAids[i]; m_visualAids.remove(i); } } @@ -1485,9 +1521,13 @@ Q3DSCameraNode *Q3DSTranslation::cameraForNode(Q3DSGraphObject *node, bool ignor void Q3DSTranslation::updateForegroundLayerProperties() { + if (m_sceneCameraMode) + return; + if (m_foregroundLayer && m_foregroundPickingLayer && !m_foregroundCamera && !m_foregroundPickingCamera) { - m_foregroundCamera = m_presentation->newObject("StudioForegroundCamera_"); + m_foregroundCamera + = m_presentation->newObject("StudioForegroundCamera_"); m_foregroundLayer->appendChildNode(m_foregroundCamera); m_presentation->masterSlide()->addObject(m_foregroundCamera); @@ -1580,8 +1620,7 @@ void Q3DSTranslation::updateForegroundLayerProperties() list.clear(); list.append(m_foregroundPickingLayer->setHorizontalFields( m_selectedLayer->horizontalFields())); - list.append(m_foregroundPickingLayer->setVerticalFields( - m_selectedLayer->verticalFields())); + list.append(m_foregroundPickingLayer->setVerticalFields(m_selectedLayer->verticalFields())); list.append(m_foregroundPickingLayer->setTopUnits(m_selectedLayer->topUnits())); list.append(m_foregroundPickingLayer->setLeftUnits(m_selectedLayer->leftUnits())); list.append(m_foregroundPickingLayer->setRightUnits(m_selectedLayer->rightUnits())); @@ -1600,34 +1639,39 @@ void Q3DSTranslation::updateForegroundLayerProperties() void Q3DSTranslation::updateWidgetProperties() { + if (m_sceneCameraMode) + return; + if (m_selectedObject) { - if (!m_manipulationWidget.hasManipulators()) { + if (!m_manipulationWidget->hasManipulators()) { createManipulationWidget(); } else if (g_StudioApp.GetToolMode() != m_toolMode) { - m_manipulationWidget.destroyManipulators(); + m_manipulationWidget->destroyManipulators(); createManipulationWidget(); } - m_manipulationWidget.setEyeballEnabled(false); + m_manipulationWidget->setEyeballEnabled(false); if (m_foregroundPickingCamera) { const auto camera = cameraForNode(m_selectedObject, true); const auto layer = layerForNode(m_selectedObject); if (camera && layer) { - m_manipulationWidget.applyProperties(m_selectedObject, camera, layer, - g_StudioApp.GetManipulationMode() == StudioManipulationModes::Global); + m_manipulationWidget->applyProperties( + m_selectedObject, camera, layer, + g_StudioApp.GetManipulationMode() + == StudioManipulationModes::Global); } } - } - m_selectionWidget.update(); + m_selectionWidget->update(); - if (m_cameraType == EditCameraTypes::SceneCamera) { - disableVisualAids(); - } else { - enableVisualAids(); - if (m_foregroundCamera) { - for (int i = 0; i < m_visualAids.size(); ++i) - m_visualAids[i].update(m_foregroundCamera, m_selectedObject); + if (m_cameraType == EditCameraTypes::SceneCamera) { + disableVisualAids(); + } else { + enableVisualAids(); + if (m_foregroundCamera) { + for (int i = 0; i < m_visualAids.size(); ++i) + m_visualAids[i]->update(m_foregroundCamera, m_selectedObject); + } } } } @@ -1636,13 +1680,13 @@ void Q3DSTranslation::createManipulationWidget() { m_toolMode = g_StudioApp.GetToolMode(); if (m_toolMode == STUDIO_TOOLMODE_MOVE) { - m_manipulationWidget.createManipulators(m_presentation.data(), m_foregroundPickingLayer, + m_manipulationWidget->createManipulators(m_presentation.data(), m_foregroundPickingLayer, ManipulationWidgetType::Translation); } else if (m_toolMode == STUDIO_TOOLMODE_ROTATE) { - m_manipulationWidget.createManipulators(m_presentation.data(), m_foregroundPickingLayer, + m_manipulationWidget->createManipulators(m_presentation.data(), m_foregroundPickingLayer, ManipulationWidgetType::Rotation); } else if (m_toolMode == STUDIO_TOOLMODE_SCALE) { - m_manipulationWidget.createManipulators(m_presentation.data(), m_foregroundPickingLayer, + m_manipulationWidget->createManipulators(m_presentation.data(), m_foregroundPickingLayer, ManipulationWidgetType::Scale); } } @@ -1680,10 +1724,10 @@ void Q3DSTranslation::prepareDrag(const QPoint &mousePos, Q3DSGraphObjectTransla void Q3DSTranslation::prepareWidgetDrag(const QPoint &mousePos, Q3DSGraphObject *obj) { - for (auto &visualAid : qAsConst(m_visualAids)) { - if (visualAid.hasCollisionBox(obj)) { + for (auto visualAid : qAsConst(m_visualAids)) { + if (visualAid->hasCollisionBox(obj)) { auto visualAidTranslator = Q3DSGraphObjectTranslator::translatorForObject( - visualAid.graphObject()); + visualAid->graphObject()); m_doc.SelectDataModelObject(visualAidTranslator->instanceHandle()); prepareDrag(mousePos, visualAidTranslator); return; @@ -1691,7 +1735,7 @@ void Q3DSTranslation::prepareWidgetDrag(const QPoint &mousePos, Q3DSGraphObject } m_pickedWidget = obj; - m_manipulationWidget.setColor(m_pickedWidget, Qt::yellow); + m_manipulationWidget->setColor(m_pickedWidget, Qt::yellow); prepareDrag(mousePos); } @@ -1734,8 +1778,8 @@ void Q3DSTranslation::endDrag(bool dragReset, CUpdateableDocumentEditor &inEdito void Q3DSTranslation::endPickWidget() { if (m_pickedWidget) { - m_manipulationWidget.resetColor(m_pickedWidget); - m_manipulationWidget.resetScale(m_pickedWidget); + m_manipulationWidget->resetColor(m_pickedWidget); + m_manipulationWidget->resetScale(m_pickedWidget); } m_pickedWidget = nullptr; } @@ -1812,17 +1856,17 @@ void Q3DSTranslation::translateAlongWidget(const QPoint &inMouseCoords, Q3DSNode *node = m_dragTranslator->graphObject(); - if (m_manipulationWidget.isXAxis(m_pickedWidget) - || m_manipulationWidget.isYAxis(m_pickedWidget) - || m_manipulationWidget.isZAxis(m_pickedWidget)) { + if (m_manipulationWidget->isXAxis(m_pickedWidget) + || m_manipulationWidget->isYAxis(m_pickedWidget) + || m_manipulationWidget->isZAxis(m_pickedWidget)) { m_currentDragState.t = calculateWidgetArrowDrag(mousePos).toVector3D(); } else { QVector3D planeNormal; - if (m_manipulationWidget.isXYPlane(m_pickedWidget)) + if (m_manipulationWidget->isXYPlane(m_pickedWidget)) planeNormal = getZAxis(m_dragNodeGlobalTransform); - else if (m_manipulationWidget.isYZPlane(m_pickedWidget)) + else if (m_manipulationWidget->isYZPlane(m_pickedWidget)) planeNormal = getXAxis(m_dragNodeGlobalTransform); - else if (m_manipulationWidget.isZXPlane(m_pickedWidget)) + else if (m_manipulationWidget->isZXPlane(m_pickedWidget)) planeNormal = getYAxis(m_dragNodeGlobalTransform); m_currentDragState.t = mousePointToPlaneIntersection( mousePos, m_dragCamera, node, m_beginDragState.t, planeNormal, false); @@ -1903,18 +1947,18 @@ void Q3DSTranslation::scaleAlongWidget(const QPoint &inOriginalCoords, const QPo Q3DSNode *node = m_dragTranslator->graphObject(); QVector3D scaleVec(1.f, 1.f, 1.f); - if (m_manipulationWidget.isXAxis(m_pickedWidget) - || m_manipulationWidget.isYAxis(m_pickedWidget) - || m_manipulationWidget.isZAxis(m_pickedWidget)) { + if (m_manipulationWidget->isXAxis(m_pickedWidget) + || m_manipulationWidget->isYAxis(m_pickedWidget) + || m_manipulationWidget->isZAxis(m_pickedWidget)) { float distance = calculateWidgetArrowDrag(mousePos).w(); float scaleAmount = distance / scaleRatio; float magnitude = 1.f + scaleAmount; if (g_StudioApp.GetManipulationMode() == StudioManipulationModes::Local) { - if (m_manipulationWidget.isXAxis(m_pickedWidget)) + if (m_manipulationWidget->isXAxis(m_pickedWidget)) scaleVec = QVector3D(magnitude, 1.f, 1.f); - else if (m_manipulationWidget.isYAxis(m_pickedWidget)) + else if (m_manipulationWidget->isYAxis(m_pickedWidget)) scaleVec = QVector3D(1.f, magnitude, 1.f); - else if (m_manipulationWidget.isZAxis(m_pickedWidget)) + else if (m_manipulationWidget->isZAxis(m_pickedWidget)) scaleVec = QVector3D(1.f, 1.f, magnitude); } else { scaleVec = QVector3D(1, 1, 1) + calculateWidgetDragScale(mousePos, node, scaleRatio); @@ -1926,7 +1970,7 @@ void Q3DSTranslation::scaleAlongWidget(const QPoint &inOriginalCoords, const QPo QVector3D planeNormal; if (g_StudioApp.GetManipulationMode() == StudioManipulationModes::Local) { - if (m_manipulationWidget.isXYPlane(m_pickedWidget)) { + if (m_manipulationWidget->isXYPlane(m_pickedWidget)) { planeNormal = getZAxis(m_dragNodeGlobalTransform); xScale = 1.f + calculateWidgetArrowDrag( mousePos, planeNormal, getXAxis(m_dragNodeGlobalTransform)).w() @@ -1935,7 +1979,7 @@ void Q3DSTranslation::scaleAlongWidget(const QPoint &inOriginalCoords, const QPo mousePos, planeNormal, getYAxis(m_dragNodeGlobalTransform)).w() / -scaleRatio; scaleVec = QVector3D(xScale, yScale, 1.f); - } else if (m_manipulationWidget.isYZPlane(m_pickedWidget)) { + } else if (m_manipulationWidget->isYZPlane(m_pickedWidget)) { planeNormal = getXAxis(m_dragNodeGlobalTransform); yScale = 1.f + calculateWidgetArrowDrag( mousePos, planeNormal, getYAxis(m_dragNodeGlobalTransform)).w() @@ -1944,7 +1988,7 @@ void Q3DSTranslation::scaleAlongWidget(const QPoint &inOriginalCoords, const QPo mousePos, planeNormal, getZAxis(m_dragNodeGlobalTransform)).w() / scaleRatio; scaleVec = QVector3D(1.f, yScale, zScale); - } else if (m_manipulationWidget.isZXPlane(m_pickedWidget)) { + } else if (m_manipulationWidget->isZXPlane(m_pickedWidget)) { planeNormal = getYAxis(m_dragNodeGlobalTransform); xScale = 1.f + calculateWidgetArrowDrag( mousePos, planeNormal, getXAxis(m_dragNodeGlobalTransform)).w() @@ -1955,21 +1999,21 @@ void Q3DSTranslation::scaleAlongWidget(const QPoint &inOriginalCoords, const QPo scaleVec = QVector3D(xScale, 1.f, zScale); } } else { - if (m_manipulationWidget.isXYPlane(m_pickedWidget)) { + if (m_manipulationWidget->isXYPlane(m_pickedWidget)) { planeNormal = getZAxis(m_dragNodeGlobalTransform); scaleVec = QVector3D(1, 1, 1) + calculateWidgetDragScale(mousePos, node, scaleRatio, planeNormal, -getXAxis(m_dragNodeGlobalTransform)) + calculateWidgetDragScale(mousePos, node, scaleRatio, planeNormal, -getYAxis(m_dragNodeGlobalTransform)); - } else if (m_manipulationWidget.isYZPlane(m_pickedWidget)) { + } else if (m_manipulationWidget->isYZPlane(m_pickedWidget)) { planeNormal = getXAxis(m_dragNodeGlobalTransform); scaleVec = QVector3D(1, 1, 1) + calculateWidgetDragScale(mousePos, node, scaleRatio, planeNormal, -getYAxis(m_dragNodeGlobalTransform)) + calculateWidgetDragScale(mousePos, node, scaleRatio, planeNormal, getZAxis(m_dragNodeGlobalTransform)); - } else if (m_manipulationWidget.isZXPlane(m_pickedWidget)) { + } else if (m_manipulationWidget->isZXPlane(m_pickedWidget)) { planeNormal = getYAxis(m_dragNodeGlobalTransform); scaleVec = QVector3D(1, 1, 1) + calculateWidgetDragScale(mousePos, node, scaleRatio, planeNormal, @@ -1986,7 +2030,7 @@ void Q3DSTranslation::scaleAlongWidget(const QPoint &inOriginalCoords, const QPo // TODO: Fix widget scaling. Only the length of the arrow should scale, not the head. // TODO: Also the beginning of the arrow should not move while scaling. // TODO: Also widget shouldn't flip around if scaling goes negative in some direction - //m_selectionWidget.setScale(m_pickedWidget, scaleVec); + //m_selectionWidget->setScale(m_pickedWidget, scaleVec); Q3DSPropertyChangeList list; list.append(node->setScale(m_currentDragState.s)); @@ -2136,13 +2180,13 @@ void Q3DSTranslation::rotateAlongWidget(const QPoint &inOriginalCoords, flipZTranslation(origRay); QVector3D planeNormal; - if (m_manipulationWidget.isXYCircle(m_pickedWidget)) + if (m_manipulationWidget->isXYCircle(m_pickedWidget)) planeNormal = getZAxis(m_dragNodeGlobalTransform); - else if (m_manipulationWidget.isYZCircle(m_pickedWidget)) + else if (m_manipulationWidget->isYZCircle(m_pickedWidget)) planeNormal = getXAxis(m_dragNodeGlobalTransform); - else if (m_manipulationWidget.isZXCircle(m_pickedWidget)) + else if (m_manipulationWidget->isZXCircle(m_pickedWidget)) planeNormal = getYAxis(m_dragNodeGlobalTransform); - else if (m_manipulationWidget.isCameraCircle(m_pickedWidget)) + else if (m_manipulationWidget->isCameraCircle(m_pickedWidget)) planeNormal = getZAxis(cameraMatrix); flipZTranslation(planeNormal); diff --git a/src/Authoring/Studio/Render/Q3DSTranslation.h b/src/Authoring/Studio/Render/Q3DSTranslation.h index 1c7ea328..a15c7036 100644 --- a/src/Authoring/Studio/Render/Q3DSTranslation.h +++ b/src/Authoring/Studio/Render/Q3DSTranslation.h @@ -72,7 +72,9 @@ class Q3DSTranslation { public: Q3DSTranslation(Q3DStudioRenderer &inRenderer, - const QSharedPointer &presentation); + const QSharedPointer &presentation, + bool sceneCameraMode); + ~Q3DSTranslation(); protected: void markPropertyDirty(qt3dsdm::Qt3DSDMInstanceHandle instance, @@ -175,6 +177,7 @@ private: Q3DStudio::CGraph &m_assetGraph; QSharedPointer m_engine; QSharedPointer m_presentation; + bool m_sceneCameraMode = false; // All translator related containers must come after the allocator TInstanceToTranslatorMap m_translatorMap; @@ -221,10 +224,10 @@ private: Q3DSGraphObject *m_pickedWidget = nullptr; QColor m_pickedWidgetColor; EditCameraTypes m_cameraType = EditCameraTypes::SceneCamera; - Q3DSManipulationWidget m_manipulationWidget; - Q3DSSelectionWidget m_selectionWidget; + Q3DSManipulationWidget *m_manipulationWidget = nullptr; + Q3DSSelectionWidget *m_selectionWidget = nullptr; - QVector m_visualAids; + QVector m_visualAids; quint64 m_visualAidIndex = 0; struct DragState diff --git a/src/Authoring/Studio/Render/Q3DSVisualAidWidget.cpp b/src/Authoring/Studio/Render/Q3DSVisualAidWidget.cpp index 6e2d79ba..3dda9f7a 100644 --- a/src/Authoring/Studio/Render/Q3DSVisualAidWidget.cpp +++ b/src/Authoring/Studio/Render/Q3DSVisualAidWidget.cpp @@ -204,6 +204,11 @@ Q3DSVisualAidWidget::Q3DSVisualAidWidget(Q3DSUipPresentation *presentation, Q3DS } } +Q3DSVisualAidWidget::~Q3DSVisualAidWidget() +{ + destroy(); +} + bool Q3DSVisualAidWidget::isCreated() const { return m_wireframe && m_icon && m_collisionBox; diff --git a/src/Authoring/Studio/Render/Q3DSVisualAidWidget.h b/src/Authoring/Studio/Render/Q3DSVisualAidWidget.h index 8b8155fe..85837a6d 100644 --- a/src/Authoring/Studio/Render/Q3DSVisualAidWidget.h +++ b/src/Authoring/Studio/Render/Q3DSVisualAidWidget.h @@ -49,6 +49,7 @@ public: Q3DSVisualAidWidget(Q3DSUipPresentation *presentation, Q3DSLayerNode *layer, Q3DSLayerNode *pickingLayer, VisualAidType type, Q3DSGraphObject *graphObject, quint64 id); + ~Q3DSVisualAidWidget(); bool isCreated() const; Q3DSGraphObject *graphObject() const; diff --git a/src/Authoring/Studio/Render/Q3DStudioRenderer.cpp b/src/Authoring/Studio/Render/Q3DStudioRenderer.cpp index a67e4246..48705909 100644 --- a/src/Authoring/Studio/Render/Q3DStudioRenderer.cpp +++ b/src/Authoring/Studio/Render/Q3DStudioRenderer.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -85,28 +86,32 @@ static SEditCameraDefinition g_editCameraDefinitions[] = { static int g_numEditCameras = sizeof(g_editCameraDefinitions) / sizeof(*g_editCameraDefinitions); -Q3DStudioRenderer::Q3DStudioRenderer() +Q3DStudioRenderer::Q3DStudioRenderer(bool sceneCameraMode) : m_dispatch(*g_StudioApp.GetCore()->GetDispatch()) , m_doc(*g_StudioApp.GetCore()->GetDoc()) + , m_guidesEnabled(!sceneCameraMode) , m_updatableEditor(m_doc) + , m_sceneCameraMode(sceneCameraMode) { m_dispatch.AddReloadListener(this); m_dispatch.AddDataModelListener(this); m_dispatch.AddPresentationChangeListener(this); - m_selectionSignal - = m_dispatch.ConnectSelectionChange(std::bind(&Q3DStudioRenderer::onSelectionChange, - this, std::placeholders::_1)); - m_dispatch.AddSceneDragListener(this); - m_dispatch.AddToolbarChangeListener(this); - - m_rulerColor = CStudioPreferences::GetRulerBackgroundColor(); - m_rulerTickColor = CStudioPreferences::GetRulerTickColor(); - m_guideColor = CStudioPreferences::GetGuideColor(); - m_guideSelectedColor = CStudioPreferences::GetGuideSelectedColor(); - m_guideFillColor = CStudioPreferences::GetGuideFillColor(); - m_guideSelectedFillColor = CStudioPreferences::GetGuideFillSelectedColor(); - - m_editCameraInformation.resize(g_numEditCameras); + if (!m_sceneCameraMode) { + m_selectionSignal + = m_dispatch.ConnectSelectionChange(std::bind(&Q3DStudioRenderer::onSelectionChange, + this, std::placeholders::_1)); + m_dispatch.AddSceneDragListener(this); + m_dispatch.AddToolbarChangeListener(this); + + m_rulerColor = CStudioPreferences::GetRulerBackgroundColor(); + m_rulerTickColor = CStudioPreferences::GetRulerTickColor(); + m_guideColor = CStudioPreferences::GetGuideColor(); + m_guideSelectedColor = CStudioPreferences::GetGuideSelectedColor(); + m_guideFillColor = CStudioPreferences::GetGuideFillColor(); + m_guideSelectedFillColor = CStudioPreferences::GetGuideFillSelectedColor(); + + m_editCameraInformation.resize(g_numEditCameras); + } // Create engine and presentation as RenderBufferManager needs them before presentation is set m_engine.reset(new Q3DSEngine); @@ -122,6 +127,12 @@ Q3DStudioRenderer::Q3DStudioRenderer() Q3DStudioRenderer::~Q3DStudioRenderer() { + m_dispatch.RemoveDataModelListener(this); + m_dispatch.RemovePresentationChangeListener(this); + if (!m_sceneCameraMode) { + m_dispatch.RemoveSceneDragListener(this); + m_dispatch.RemoveToolbarChangeListener(this); + } Close(); } @@ -198,9 +209,10 @@ bool Q3DStudioRenderer::IsInitialized() return m_widget != nullptr; } -void Q3DStudioRenderer::initialize(QOpenGLWidget *widget) +void Q3DStudioRenderer::initialize(QOpenGLWidget *widget, bool hasPresentation) { m_widget = widget; + m_hasPresentation = hasPresentation; if (m_widget && m_translation.isNull() && m_hasPresentation) initEngineAndTranslation(); @@ -223,11 +235,6 @@ void Q3DStudioRenderer::SetViewRect(const QRect &inRect, const QSize &size) sendResizeToQt3D(); } -void Q3DStudioRenderer::setFullSizePreview(bool enabled) -{ - // TODO -} - void Q3DStudioRenderer::SetPolygonFillModeEnabled(bool inEnableFillMode) { @@ -344,12 +351,6 @@ bool Q3DStudioRenderer::isMouseDown() const void Q3DStudioRenderer::Close() { OnClosingPresentation(); - m_engine.reset(); - m_presentation.reset(); - m_dispatch.RemoveDataModelListener(this); - m_dispatch.RemovePresentationChangeListener(this); - m_dispatch.RemoveSceneDragListener(this); - m_dispatch.RemoveToolbarChangeListener(this); m_widget = nullptr; } @@ -591,10 +592,12 @@ void Q3DStudioRenderer::drawRulersAndGuides(QPainter *painter) void Q3DStudioRenderer::renderNow() { - if (m_setSubpresentationsCalled == false) - return; + // TODO: Not needed until QT3DS-2072 is implemented. + // TODO: Subpresentations need to be registered for scene camera preview renderer, too. +// if (m_setSubpresentationsCalled == false) +// return; - initialize(m_widget); + initialize(m_widget, m_hasPresentation); QOpenGLContextPrivate *ctxD = QOpenGLContextPrivate::get(m_widget->context()); QScopedValueRollback defaultFboRedirectRollback(ctxD->defaultFboRedirect, 0); @@ -620,27 +623,6 @@ void Q3DStudioRenderer::renderNow() } } -void Q3DStudioRenderer::getPreviewFbo(QSize &outFboDim, qt3ds::QT3DSU32 &outFboTexture) -{ -#ifdef RUNTIME_SPLIT_TEMPORARILY_REMOVED - if (m_Translation) { - outFboDim = QSize(m_Translation->m_previewFboDimensions.x, - m_Translation->m_previewFboDimensions.y); - // The handle is a void * so first cast to size_t to avoid truncating pointer warning - if (m_Translation->m_previewTexture) { - outFboTexture = static_cast(reinterpret_cast( - m_Translation->m_previewTexture->GetTextureObjectHandle())); - } else { - outFboTexture = 0; - } - - } else { - outFboDim = QSize(0, 0); - outFboTexture = 0; - } -#endif -} - void Q3DStudioRenderer::RegisterSubpresentations( const QVector &subpresentations){ m_subpresentations = subpresentations; @@ -691,6 +673,11 @@ void Q3DStudioRenderer::OnClosingPresentation() if (!m_engine.isNull() && !m_translation.isNull()) { m_widget->makeCurrent(); + + // Exit the aspect engine loop before shutdown to avoid random crashes + if (m_engine->aspectEngine()) + Qt3DCore::QAspectEnginePrivate::get(m_engine->aspectEngine())->exitSimulationLoop(); + auto renderAspectD = static_cast( Qt3DRender::QRenderAspectPrivate::get(m_renderAspect)); renderAspectD->renderShutdown(); @@ -698,8 +685,8 @@ void Q3DStudioRenderer::OnClosingPresentation() m_renderAspect = nullptr; // This will destroy render aspect - m_engine->setPresentation(nullptr); m_translation.reset(); + m_engine->setPresentation(nullptr); m_engine.reset(new Q3DSEngine); m_presentation.reset(new Q3DSUipPresentation); m_viewportSettings.reset(new Q3DSViewportSettings); @@ -1401,7 +1388,7 @@ void Q3DStudioRenderer::initEngineAndTranslation() createTranslation(); setupTextRenderer(); - if (m_editCameraIndex != m_pendingEditCameraIndex) + if (m_editCameraIndex != m_pendingEditCameraIndex && !m_sceneCameraMode) SetEditCamera(m_pendingEditCameraIndex); qDeleteAll(m_discardedPickers); @@ -1410,7 +1397,7 @@ void Q3DStudioRenderer::initEngineAndTranslation() void Q3DStudioRenderer::createTranslation() { - m_translation.reset(new Q3DSTranslation(*this, m_presentation)); + m_translation.reset(new Q3DSTranslation(*this, m_presentation, m_sceneCameraMode)); } void Q3DStudioRenderer::reloadFonts() @@ -1453,9 +1440,9 @@ void Q3DStudioRenderer::scheduleDirtySetUpdate() } } -std::shared_ptr IStudioRenderer::CreateStudioRenderer() +std::shared_ptr IStudioRenderer::CreateStudioRenderer(bool sceneCameraMode) { - return std::shared_ptr(new Q3DStudioRenderer()); + return std::shared_ptr(new Q3DStudioRenderer(sceneCameraMode)); } } diff --git a/src/Authoring/Studio/Render/Q3DStudioRenderer.h b/src/Authoring/Studio/Render/Q3DStudioRenderer.h index 2de0a1ad..412f662e 100644 --- a/src/Authoring/Studio/Render/Q3DStudioRenderer.h +++ b/src/Authoring/Studio/Render/Q3DStudioRenderer.h @@ -77,7 +77,7 @@ class Q3DStudioRenderer : public QObject, Q_OBJECT public: - Q3DStudioRenderer(); + Q3DStudioRenderer(bool sceneCameraMode); ~Q3DStudioRenderer() override; ITextRenderer *GetTextRenderer() override; QT3DSVec3 GetIntendedPosition(qt3dsdm::Qt3DSDMInstanceHandle inHandle, CPt inPoint) override; @@ -88,9 +88,8 @@ public: void RequestRender() override; void renderNow() override; bool IsInitialized() override; - void initialize(QOpenGLWidget *widget) override; + void initialize(QOpenGLWidget *widget, bool hasPresentation) override; void SetViewRect(const QRect &inRect, const QSize &size) override; - void setFullSizePreview(bool enabled) override; void GetEditCameraList(QStringList &outCameras) override; void SetPolygonFillModeEnabled(bool inEnableFillMode) override; bool IsPolygonFillModeEnabled() const override; @@ -104,7 +103,6 @@ public: void EditCameraZoomToFit() override; bool isMouseDown() const override; void Close() override; - void getPreviewFbo(QSize &outFboDim, qt3ds::QT3DSU32 &outFboTexture) override; void RegisterSubpresentations( const QVector &subpresentations) override; void drawRulersAndGuides(QPainter *painter) override; @@ -190,7 +188,7 @@ private: QColor m_guideSelectedColor; QColor m_guideFillColor; QColor m_guideSelectedFillColor; - bool m_guidesEnabled = true; + bool m_guidesEnabled = false; bool m_hasPresentation = false; int m_renderRequested = 0; bool m_setSubpresentationsCalled = false; @@ -216,6 +214,7 @@ private: bool m_resizeToQt3DSent = false; qreal m_parentPixelRatio = 1.0; QTimer m_asyncRenderTimer; + bool m_sceneCameraMode = false; }; } diff --git a/src/Authoring/Studio/UI/Q3DSPlayerWidget.cpp b/src/Authoring/Studio/UI/Q3DSPlayerWidget.cpp index d3f5e875..8374d118 100644 --- a/src/Authoring/Studio/UI/Q3DSPlayerWidget.cpp +++ b/src/Authoring/Studio/UI/Q3DSPlayerWidget.cpp @@ -78,7 +78,7 @@ void Q3DSPlayerWidget::initializeGL() Q3DStudio::IStudioRenderer &renderer(g_StudioApp.getRenderer()); if (!renderer.IsInitialized()) { try { - renderer.initialize(this); + renderer.initialize(this, false); } catch (...) { QMessageBox::critical(this, tr("Fatal Error"), tr("Unable to initialize OpenGL.\nThis may be because your " diff --git a/src/Authoring/Studio/UI/Q3DSPlayerWnd.h b/src/Authoring/Studio/UI/Q3DSPlayerWnd.h index bf80d09a..bb17951d 100644 --- a/src/Authoring/Studio/UI/Q3DSPlayerWnd.h +++ b/src/Authoring/Studio/UI/Q3DSPlayerWnd.h @@ -92,7 +92,6 @@ public: Q_SIGNALS: void dropReceived(); - void newFrame(); void toolChanged(); private Q_SLOTS: -- cgit v1.2.3