diff options
author | Pasi Keränen <pasi.keranen@qt.io> | 2019-06-06 16:22:02 +0300 |
---|---|---|
committer | Pasi Keränen <pasi.keranen@qt.io> | 2019-06-07 13:52:44 +0300 |
commit | b4954701093739e7a4e54a0669f306922d0d4605 (patch) | |
tree | 73d71319a921234f6b507c9098fdc842f7fe06dc /src/engine/Qt3DSRuntimeView.cpp | |
parent | 8548a5f5579e3eee7e5ae6b1f6901dcc8bfee19e (diff) |
Long live the slayer!
Initial commit of OpenGL Runtime to repository.
Based on SHA1 61823aaccc6510699a54b34a2fe3f7523dab3b4e
of qt3dstudio repository.
Task-number: QT3DS-3600
Change-Id: Iaeb80237399f0e5656a19ebec9d1ab3a681d8832
Reviewed-by: Pasi Keränen <pasi.keranen@qt.io>
Diffstat (limited to 'src/engine/Qt3DSRuntimeView.cpp')
-rw-r--r-- | src/engine/Qt3DSRuntimeView.cpp | 862 |
1 files changed, 862 insertions, 0 deletions
diff --git a/src/engine/Qt3DSRuntimeView.cpp b/src/engine/Qt3DSRuntimeView.cpp new file mode 100644 index 0000000..c1f3b3d --- /dev/null +++ b/src/engine/Qt3DSRuntimeView.cpp @@ -0,0 +1,862 @@ +/**************************************************************************** +** +** Copyright (C) 1993-2009 NVIDIA Corporation. +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//============================================================================== +// Includes +//============================================================================== +#include "Qt3DSRuntimeView.h" +#include "Qt3DSTegraInputEngine.h" +#include "Qt3DSDataLogger.h" +#include "Qt3DSFileStream.h" +#include "Qt3DSArray.h" +#include "Qt3DSApplication.h" +#include "foundation/FileTools.h" +#include "Qt3DSIPresentation.h" +#include "Qt3DSPresentation.h" +#include "EASTL/string.h" +#include "Qt3DSMemory.h" +#include "Qt3DSKernelTypes.h" +#include "Qt3DSRenderContextCore.h" +#include "Qt3DSRenderer.h" +#include "Qt3DSRenderBufferManager.h" +#include "Qt3DSRenderRuntimeBindingImpl.h" +#include "Qt3DSImportMesh.h" + +#include "Qt3DSDLLManager.h" +#include "foundation/Qt3DSSimpleTypes.h" +#include "foundation/TrackingAllocator.h" +// For perf log timestamp +#include <time.h> +#include "Qt3DSArray.h" +// For perf log timestamp +#include <time.h> + +#ifdef _LINUXPLATFORM +#include <sys/types.h> +#include <unistd.h> +#endif + +#ifdef ANDROID +#include <android/log.h> +#endif + +#include <QCoreApplication> +#include <QSurfaceFormat> + +//============================================================================== +// Namespace +//============================================================================== +namespace qt3ds { +namespace render { +extern qt3ds::foundation::MallocAllocator g_BaseAllocator; +} +} + +namespace Q3DStudio { + +namespace { + +bool CaselessEqual(const char *lhs, const char *rhs) +{ + if (lhs == nullptr) + lhs = ""; + if (rhs == nullptr) + rhs = ""; + return Q3DStudio_stricmp(lhs, rhs) == 0; +} + +CInputEngine *CreateInputEngine() +{ + return Q3DStudio_virtual_new(CTegraInputEngine) CTegraInputEngine(); +} + +static eastl::string *theAppDir = nullptr; +const eastl::string &GetAppDir(const eastl::string &inAppExe) +{ + if (!theAppDir) + theAppDir = new eastl::string; +#ifndef __ANDROID__ + theAppDir->assign(inAppExe.empty() == false ? inAppExe : ""); +#ifdef Qt3DS_OS_LINUX + char theBuf[1024] = { 0 }; + int rc = readlink("/proc/self/exe", theBuf, sizeof(theBuf)); + if (rc > 0) + theAppDir->assign(theBuf); +#endif +#ifdef Qt3DS_OS_QNX + char theBuf[1024] = { 0 }; + FILE *exefile = fopen("/proc/self/exefile", "r"); + if (exefile != nullptr) { + fgets(theBuf, sizeof(theBuf), exefile); + fclose(exefile); + theAppDir->assign(theBuf); + } +#endif + eastl::string::size_type pos = theAppDir->find_last_of("\\/"); + if (pos != eastl::string::npos) + *theAppDir = theAppDir->substr(0, pos); + theAppDir->append("\\"); +#endif + return *theAppDir; +} +} + +using namespace qt3ds; +using namespace qt3ds::foundation; + +class CRuntimeView : public IRuntimeView +{ + //============================================================================== + // Fields + //============================================================================== +private: + ITegraApplicationRenderEngine *m_RenderEngine; ///< Handles all rendering functions + CTegraInputEngine *m_InputEngine; ///< Handles all user input events + // Pre graphics init objects + NVScopedRefCounted<qt3ds::render::IQt3DSRenderFactoryCore> m_RuntimeFactoryCore; + ///< Base application before graphics + NVScopedRefCounted<qt3ds::runtime::IApplication> m_ApplicationCore; + + // Post graphics init objects + NVScopedRefCounted<qt3ds::render::IQt3DSRenderFactory> m_RuntimeFactory; + NVScopedRefCounted<qt3ds::runtime::IApplication> m_Application; ///< Application after graphics + ///< Currently loaded presentation, this should be removed in the future + CPresentation *m_Presentation; + + CPausingTimeProvider m_TimeProvider; + IWindowSystem &m_WindowSystem; + IAudioPlayer *m_AudioPlayer; + + volatile QT3DSI32 mRefCount; + + qt3ds::Qt3DSAssetVisitor *m_visitor; + bool m_showOnScreenStats; + QElapsedTimer *m_startupTimer; + qint64 m_startupTime; + +public: + CRuntimeView(ITimeProvider &inTimeProvider, IWindowSystem &inWindowSystem, + IAudioPlayer *inAudioPlayer, QElapsedTimer *startupTimer); + ~CRuntimeView() override; + + QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(qt3ds::render::g_BaseAllocator) + + bool BeginLoad(const QString &sourcePath, const QStringList &variantList) override; + bool HasOfflineLoadingCompleted() override; + bool InitializeGraphics(const QSurfaceFormat &format, bool delayedLoading) override; + + void Cleanup() override; + + bool CanRender() override; + void Render() override; + bool WasLastFrameDirty() override; + + bool HandleMessage(const QEvent *inEvent) override; + + void Pause() override; + void UnPause() override; + bool IsPaused() override; + void setAssetVisitor(qt3ds::Qt3DSAssetVisitor *) override; + + INT32 GetFrameCount() override; + void showOnScreenStats(bool) override; + + CInputEngine *GetInputEngine() override; + // Only valid after InitializeGraphics + ITegraApplicationRenderEngine *GetTegraRenderEngine() override { return m_RenderEngine; } + + void GoToSlideByName(const char *elementPath, const char *slideName) override; + void GoToSlideByIndex(const char *elementPath, const int slideIndex) override; + void GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) override; + bool GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) override; + void SetPresentationAttribute(const char *presId, const char *, const char *value) override; + void GoToTime(const char *elementPath, const float time) override; + void SetGlobalAnimationTime(qint64 inMilliSecs) override; + void SetDataInputValue(const QString &name, const QVariant &value, + int property) override; + + void setPresentationId(const QString &id) override + { + m_Application->setPresentationId(id); + } + + QList<QString> dataInputs() const override; + QList<QString> dataOutputs() const override; + float dataInputMax(const QString &name) const override; + float dataInputMin(const QString &name) const override; + QHash<QString, QString> dataInputMetadata(const QString &name) const override; + + void createElements(const QString &parentElementPath, const QString &slideName, + const QVector<QHash<QString, QVariant>> &properties) override; + void deleteElements(const QStringList &elementPaths) override; + void createMaterials(const QString &subPresId, + const QStringList &materialDefinitions) override; + void deleteMaterials(const QStringList &materialNames) override; + void createMesh(const QString &name, qt3dsimp::Mesh *mesh) override; + void deleteMeshes(const QStringList &meshNames) override; + void SetAttribute(const char *elementPath, const char *attributeName, + const char *value) override; + bool GetAttribute(const char *elementPath, const char *attributeName, void *value) override; + void FireEvent(const char *element, const char *evtName) override; + bool PeekCustomAction(char *&outElementPath, char *&outActionName) override; + bool RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) override; + void FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) override; + qt3ds::foundation::Option<SPresentationSize> GetPresentationSize() override; + void preloadSlide(const QString &slide) override; + void unloadSlide(const QString &slide) override; + void setDelayedLoading(bool enable) override; + void BootupPreGraphicsInitObjects(); +}; + +CRuntimeView::CRuntimeView(ITimeProvider &inTimeProvider, IWindowSystem &inWindowSystem, + IAudioPlayer *inAudioPlayer, QElapsedTimer *startupTimer) + : m_RenderEngine(nullptr) + , m_InputEngine(nullptr) + , m_Application(nullptr) + , m_Presentation(nullptr) + , m_TimeProvider(inTimeProvider) + , m_WindowSystem(inWindowSystem) + , m_AudioPlayer(inAudioPlayer) + , mRefCount(0) + , m_visitor(nullptr) + , m_showOnScreenStats(false) + , m_startupTimer(startupTimer) + , m_startupTime(-1) +{ +} + +CRuntimeView::~CRuntimeView() +{ +} + +bool CRuntimeView::BeginLoad(const QString &sourcePath, const QStringList &variantList) +{ + bool theResult = false; + + // boot up the application + BootupPreGraphicsInitObjects(); + + // If there was a presentation file then we have to load it or something failed. + if (m_ApplicationCore->BeginLoad(sourcePath.toUtf8(), variantList)) + theResult = true; + else + theResult = false; + + // If Initialize wasn't successful - this means the CShaderFactory failed to initialize + // or, the presentation failed to load. + // + // NOTE: if no presentation was passed, this is 'ok' + if (!theResult) + Cleanup(); + + return theResult; +} + +bool CRuntimeView::HasOfflineLoadingCompleted() +{ + if (m_Application.mPtr == nullptr) { + if (m_ApplicationCore) + return m_ApplicationCore->HasCompletedLoading(); + else + return false; + } + return true; +} + +bool CRuntimeView::InitializeGraphics(const QSurfaceFormat &format, bool delayedLoading) +{ + m_ApplicationCore->EndLoad(); + // Next call will initialize the render portion of the scenes. This *must* have a loaded + // application to go further as it will bind scene graph data to application data. + m_RuntimeFactory = m_RuntimeFactoryCore->CreateRenderFactory(format, delayedLoading); + m_Application + = m_ApplicationCore->CreateApplication(*m_InputEngine, m_AudioPlayer, + *m_RuntimeFactory); + if (!m_Application->createSuccessful()) + return false; + + m_Application->ResetTime(); + m_RenderEngine = &m_RuntimeFactory->CreateRenderEngine(); + m_Presentation = m_Application->GetPrimaryPresentation(); + + QObject::connect(m_Presentation->signalProxy(), &QPresentationSignalProxy::SigSlideEntered, + signalProxy(), &QRuntimeViewSignalProxy::SigSlideEntered); + QObject::connect(m_Presentation->signalProxy(), &QPresentationSignalProxy::SigSlideExited, + signalProxy(), &QRuntimeViewSignalProxy::SigSlideExited); + QObject::connect(m_Presentation->signalProxy(), &QPresentationSignalProxy::SigCustomSignal, + signalProxy(), &QRuntimeViewSignalProxy::SigCustomSignal); + QObject::connect(m_Presentation->signalProxy(), + &QPresentationSignalProxy::SigPresentationReady, + signalProxy(), &QRuntimeViewSignalProxy::SigPresentationReady); + QObject::connect(m_Presentation->signalProxy(), &QPresentationSignalProxy::SigElementsCreated, + signalProxy(), &QRuntimeViewSignalProxy::SigElementsCreated); + QObject::connect(m_Presentation->signalProxy(), &QPresentationSignalProxy::SigMaterialsCreated, + signalProxy(), &QRuntimeViewSignalProxy::SigMaterialsCreated); + QObject::connect(m_Presentation->signalProxy(), + &QPresentationSignalProxy::SigDataOutputValueUpdated, + signalProxy(), + &QRuntimeViewSignalProxy::SigDataOutputValueUpdated); + + m_TimeProvider.Reset(); + return true; +} + +void CRuntimeView::Cleanup() +{ + // Q3DStudio_virtual_delete( m_Timer, CTimer ); + // Q3DStudio_virtual_delete( m_PerfFileStream, CFileStream ); + m_Application = nullptr; + Q3DStudio_virtual_delete(m_InputEngine, CTegraInputEngine); + if (m_RenderEngine) { + m_RenderEngine->Release(); + m_RenderEngine = nullptr; + } + + CDLLManager &theDLLManager = CDLLManager::GetDLLManager(); + theDLLManager.Cleanup(); + if (m_Presentation) + QObject::disconnect(m_Presentation->signalProxy(), 0, signalProxy(), 0); + + m_InputEngine = nullptr; + m_RenderEngine = nullptr; + m_Presentation = nullptr; +} + +bool CRuntimeView::CanRender() +{ + return m_Application.mPtr != nullptr; +} + +//============================================================================== +/** + * nv_main APP-SPECIFIC rendering call + * returns KD_TRUE to call egl_render and swap properly, KD_FALSE if there has been no scene update + *or redraw. + */ +void CRuntimeView::Render() +{ + if (m_Application.mPtr == nullptr) { + // InitializeGraphics has not been called + QT3DS_ASSERT(false); + } + + PerfLogGeneralEvent1(DATALOGGER_FRAME); + + m_Application->UpdateAndRender(); + + if (m_startupTime < 0 && m_startupTimer) { + m_startupTime = m_startupTimer->elapsed(); + m_startupTimer->invalidate(); + } + + if (m_showOnScreenStats) { + ITegraRenderStateManager &manager + = GetTegraRenderEngine()->GetTegraRenderStateManager(); + manager.PushState(); + + QSize dim = m_WindowSystem.GetWindowDimensions(); + manager.SetScissorTestEnabled(false); + manager.SetViewport(0, 0, dim.width(), dim.height()); + + QPair<QT3DSF32, QT3DSF32> fps + = m_RuntimeFactory->GetQt3DSRenderContext().GetFPS(); + const QVector<QT3DSF32> times = m_RuntimeFactory->GetQt3DSRenderContext().GetFrameTimes(); + + QString text; + QTextStream stream(&text); + stream << QStringLiteral("Render Statistics: "); + stream << QString::number(fps.first, 'f', 2); + stream << " fps, frame count "; + stream << QString::number(fps.second); + stream << ", frame time "; + stream << QString::number(times[0], 'f', 2); + stream << " ms"; + if (m_startupTime) { + stream << ", Init time: "; + stream << QString::number(m_startupTime); + stream << " ms"; + } + + // bottom left coordinates + GetTegraRenderEngine()->RenderText2D( + dim.width() / 4, dim.height() - 25, qt3ds::QT3DSVec3(0.0, 1.0, 0.0), + text.toLatin1().constData()); + GetTegraRenderEngine()->RenderGpuProfilerStats( + 20.0, dim.height() - 80, qt3ds::QT3DSVec3(0.0, 1.0, 0.0)); + + manager.PopState(); + } +} + +bool CRuntimeView::WasLastFrameDirty() +{ + if (m_Application) + return m_Application->IsApplicationDirty(); + return false; +} + +//============================================================================== +/** + * nv_main APP-SPECIFIC message call + * HandleMessage + */ +bool CRuntimeView::HandleMessage(const QEvent *inEvent) +{ + if (m_Application.mPtr == nullptr || m_RenderEngine == nullptr) + return 0; + + bool ret = false; + switch (inEvent->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + { + const QMouseEvent *event = static_cast<const QMouseEvent *>(inEvent); + m_InputEngine->SetPickInput(static_cast<FLOAT>(event->x()), + static_cast<FLOAT>(event->y()), true); + m_InputEngine->SetPickFlags(inEvent->type() == QEvent::MouseButtonPress + ? LMOUSE_DOWN : LMOUSE_UP); + ret = true; + } + break; + case QEvent::Resize: + { + if (m_Application->GetPrimaryPresentation()) + m_RenderEngine->CheckResize(true, *m_Application->GetPrimaryPresentation()); + ret = true; + } + break; + default: + break; + } + + m_InputEngine->HandleMessage(inEvent, *m_RenderEngine, m_Application->GetPrimaryPresentation()); + return ret ? 1 : 0; +} + +void CRuntimeView::Pause() +{ + m_TimeProvider.Pause(); +} + +void CRuntimeView::UnPause() +{ + m_TimeProvider.UnPause(); +} + +bool CRuntimeView::IsPaused() +{ + return m_TimeProvider.IsPaused(); +} + +INT32 CRuntimeView::GetFrameCount() +{ + return m_Application->GetFrameCount(); +} + +void CRuntimeView::showOnScreenStats(bool show) +{ + m_showOnScreenStats = show; + m_RuntimeFactory->GetQt3DSRenderContext().GetRenderer().EnableLayerGpuProfiling(show); +} + +CInputEngine *CRuntimeView::GetInputEngine() +{ + return m_InputEngine; +} + +//============================================================================== +/** + * Generates an event in the presentation. + */ +void CRuntimeView::GoToSlideByName(const char *elementPath, const char *slideName) +{ + if (m_Application) { + if (!elementPath || !slideName) + return; + + CPresentation *thePresentation = m_Application->GetPrimaryPresentation(); + IScriptBridge *theBridge = thePresentation->GetScriptBridgeQml(); + + if (!theBridge) + return; + + theBridge->GotoSlide(elementPath, slideName, SScriptEngineGotoSlideArgs()); + } +} + +void CRuntimeView::GoToSlideByIndex(const char *elementPath, const int slideIndex) +{ + if (m_Application) { + if (!elementPath || slideIndex < 0) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.GotoSlideIndex(elementPath, slideIndex, SScriptEngineGotoSlideArgs()); + } +} + +void CRuntimeView::GoToSlideRelative(const char *elementPath, const bool next, const bool wrap) +{ + if (m_Application) { + if (!elementPath) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.GotoSlideRelative(elementPath, next, wrap, SScriptEngineGotoSlideArgs()); + } +} + +bool CRuntimeView::GetSlideInfo(const char *elementPath, int ¤tIndex, int &previousIndex, + QString ¤tName, QString &previousName) +{ + if (m_Application && elementPath) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + return theBridgeEngine.GetSlideInfo(elementPath, currentIndex, previousIndex, + currentName, previousName); + } + return false; +} + +void CRuntimeView::SetPresentationAttribute(const char *presId, const char *, const char *value) +{ + if (m_Application) { + if (!presId || !value) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.SetPresentationAttribute(presId, nullptr, value); + } +} + +bool CRuntimeView::RegisterScriptCallback(int callbackType, qml_Function func, void *inUserData) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + return theBridgeEngine.RegisterCallback(callbackType, func, inUserData); + } + + return false; +} + +void CRuntimeView::GoToTime(const char *elementPath, const float time) +{ + if (m_Application) { + if (!elementPath || time < 0.0) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.GotoTime(elementPath, time); + } +} + +void CRuntimeView::SetGlobalAnimationTime(qint64 inMilliSecs) +{ + if (m_Application) + m_Application->SetTimeMilliSecs(inMilliSecs); +} + +void CRuntimeView::SetDataInputValue( + const QString &name, const QVariant &value, + int property = 0) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + theBridgeEngine.SetDataInputValue(name, value, (qt3ds::runtime::DataInputValueRole)property); + } +} + +QList<QString> CRuntimeView::dataInputs() const +{ + if (m_Application) + return m_Application->dataInputs(); + + return {}; +} + +QList<QString> CRuntimeView::dataOutputs() const +{ + if (m_Application) + return m_Application->dataOutputs(); + + return {}; +} + +float CRuntimeView::dataInputMax(const QString &name) const +{ + if (m_Application) + return m_Application->dataInputMax(name); + + return 0; +} + +float CRuntimeView::dataInputMin(const QString &name) const +{ + if (m_Application) + return m_Application->dataInputMin(name); + + return 0; +} + +QHash<QString, QString> CRuntimeView::dataInputMetadata(const QString &name) const +{ + if (m_Application) + return m_Application->dataInputMetadata(name); + + return {}; +} + +void CRuntimeView::createElements(const QString &parentElementPath, const QString &slideName, + const QVector<QHash<QString, QVariant>> &properties) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + theBridgeEngine.createElements(parentElementPath, slideName, properties, + &m_RuntimeFactory->GetQt3DSRenderContext().GetRenderer()); + } +} + +void CRuntimeView::deleteElements(const QStringList &elementPaths) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + theBridgeEngine.deleteElements(elementPaths, + &m_RuntimeFactory->GetQt3DSRenderContext().GetRenderer()); + } +} + +void CRuntimeView::createMaterials(const QString &subPresId, + const QStringList &materialDefinitions) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + theBridgeEngine.createMaterials( + subPresId, materialDefinitions, + &m_RuntimeFactory->GetQt3DSRenderContext().GetCustomMaterialSystem(), + &m_RuntimeFactory->GetQt3DSRenderContext().GetDynamicObjectSystem(), + &m_RuntimeFactory->GetQt3DSRenderContext().GetRenderer()); + } +} + +void CRuntimeView::deleteMaterials(const QStringList &materialNames) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + theBridgeEngine.deleteMaterials(materialNames, + &m_RuntimeFactory->GetQt3DSRenderContext().GetRenderer()); + } +} + +void CRuntimeView::createMesh(const QString &name, qt3dsimp::Mesh *mesh) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + theBridgeEngine.createMesh( + name, mesh, &m_RuntimeFactory->GetQt3DSRenderContext().GetBufferManager()); + } +} + +void CRuntimeView::deleteMeshes(const QStringList &meshNames) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + theBridgeEngine.deleteMeshes( + meshNames, &m_RuntimeFactory->GetQt3DSRenderContext().GetBufferManager()); + } +} + +void CRuntimeView::SetAttribute(const char *elementPath, const char *attributeName, + const char *value) +{ + if (m_Application) { + if (!elementPath || !attributeName || !value) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.SetAttribute(elementPath, attributeName, value); + } +} + +bool CRuntimeView::GetAttribute(const char *elementPath, const char *attributeName, void *value) +{ + if (m_Application) { + if (!elementPath || !attributeName || !value) + return false; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + return theBridgeEngine.GetAttribute(elementPath, attributeName, (char *)value); + } + + return false; +} + +void CRuntimeView::FireEvent(const char *element, const char *evtName) +{ + if (m_Application) { + if (!element || !evtName) + return; + + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + theBridgeEngine.FireEvent(element, evtName); + } +} + +bool CRuntimeView::PeekCustomAction(char *&outElementPath, char *&outActionName) +{ + bool actionAvailable = true; + + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + + Q3DStudio::TElement *theElement = nullptr; + actionAvailable = theBridgeEngine.PeekSignal(theElement, outActionName); + if (actionAvailable && theElement) + outElementPath = (char *)theElement->m_Path.c_str(); + } + + return actionAvailable; +} + +void CRuntimeView::FireEvent(const TEventCommandHash inEventType, eastl::string inArgument) +{ + if (m_Application) { + CPresentation *thePresentation = m_Application->GetPrimaryPresentation(); + TElement *theScene = thePresentation->GetRoot(); + if (inArgument.empty()) { + thePresentation->FireEvent(inEventType, theScene, nullptr, nullptr, ATTRIBUTETYPE_NONE, + ATTRIBUTETYPE_NONE); + } else { + UVariant inArg; + inArg.m_StringHandle = thePresentation->GetStringTable().GetHandle(inArgument.c_str()); + thePresentation->FireEvent(inEventType, theScene, &inArg, nullptr, ATTRIBUTETYPE_STRING, + ATTRIBUTETYPE_NONE); + } + } +} + +void CRuntimeView::preloadSlide(const QString &slide) +{ + if (m_Application) + m_Application->preloadSlide(slide); +} + +void CRuntimeView::unloadSlide(const QString &slide) +{ + if (m_Application) + m_Application->unloadSlide(slide); +} + +void CRuntimeView::setDelayedLoading(bool enable) +{ + if (m_Application) + m_Application->setDelayedLoading(enable); +} + +qt3ds::foundation::Option<SPresentationSize> CRuntimeView::GetPresentationSize() +{ + if (m_Application) { + CPresentation *thePresentation = m_Application->GetPrimaryPresentation(); + if (thePresentation) + return thePresentation->GetSize(); + } + return qt3ds::foundation::Empty(); +} + +//============================================================================== +/** + * Perform the initialization steps prior to loading any presentation. + */ +void CRuntimeView::BootupPreGraphicsInitObjects() +{ + qCInfo(TRACE_INFO) << "CNDDView::BootupPreGraphicsInitObjects: DoInitialize"; + // Create engines and runtime + const eastl::string &theAppDir = QCoreApplication::applicationDirPath().toLatin1().constData(); + + m_RuntimeFactoryCore = qt3ds::render::IQt3DSRenderFactoryCore::CreateRenderFactoryCore( + theAppDir.c_str(), m_WindowSystem, m_TimeProvider); + m_ApplicationCore = qt3ds::runtime::IApplication::CreateApplicationCore(*m_RuntimeFactoryCore, + theAppDir.c_str()); + + if (m_ApplicationCore && m_visitor) + m_ApplicationCore->setAssetVisitor(m_visitor); + + m_InputEngine = static_cast<CTegraInputEngine *>(CreateInputEngine()); + Q3DStudio_ASSERT(m_InputEngine != nullptr); + + qCInfo(TRACE_INFO) << "CNDDView::DoInitialize: Successfully initialized!"; +} + +void CRuntimeView::setAssetVisitor(qt3ds::Qt3DSAssetVisitor *v) +{ + m_visitor = v; + if (m_ApplicationCore) + m_ApplicationCore->setAssetVisitor(v); +} + +IRuntimeView &IRuntimeView::Create(ITimeProvider &inProvider, IWindowSystem &inWindowSystem, + IAudioPlayer *inAudioPlayer, QElapsedTimer *startupTimer) +{ + return *QT3DS_NEW(qt3ds::render::g_BaseAllocator, CRuntimeView)(inProvider, inWindowSystem, + inAudioPlayer, startupTimer); +} + +QRuntimeViewSignalProxy *IRuntimeView::signalProxy() +{ + return &m_SignalProxy; +} + +} // namespace Q3DStudio + |