diff options
author | Pasi Keränen <pasi.keranen@qt.io> | 2019-03-21 14:49:23 +0200 |
---|---|---|
committer | Pasi Keränen <pasi.keranen@qt.io> | 2019-04-11 09:38:40 +0000 |
commit | 00b40db9326f0b951b423a97b7302d87280f029b (patch) | |
tree | 54bf9df9aaabd98171dc2066b33a83adee4385e1 /src/Runtime | |
parent | 9992c70d914fba4348e236a525deb273db213de1 (diff) |
Add variant support to OpenGL runtime
Task-number: QT3DS-3193
Change-Id: I5606d452104659e60ecbc2e8e08ec3e6f5b15cbc
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src/Runtime')
14 files changed, 509 insertions, 254 deletions
diff --git a/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro b/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro index e004a44d..c1986ce0 100644 --- a/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro +++ b/src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro @@ -56,6 +56,7 @@ SOURCES += \ ../Source/Runtime/Source/Qt3DSQmlEngine.cpp \ ../Source/Runtime/Source/Qt3DSSlideSystem.cpp \ ../Source/Runtime/Source/Qt3DSTimePolicy.cpp \ + ../Source/Runtime/Source/q3dsvariantconfig.cpp \ ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.cpp \ ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.cpp \ ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDynamicObject.cpp \ @@ -263,6 +264,7 @@ HEADERS += \ ../Source/Runtime/Include/Qt3DSIStateful.h \ ../Source/Runtime/Include/Qt3DSIText.h \ ../Source/Runtime/Include/Qt3DSKernelTypes.h \ + ../Source/Runtime/Include/q3dsvariantconfig_p.h \ ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCamera.h \ ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderCustomMaterial.h \ ../Source/Qt3DSRuntimeRender/GraphObjects/Qt3DSRenderDefaultMaterial.h \ diff --git a/src/Runtime/Source/Engine/Include/Qt3DSTegraApplication.h b/src/Runtime/Source/Engine/Include/Qt3DSTegraApplication.h index 0d4c8d0a..91233355 100644 --- a/src/Runtime/Source/Engine/Include/Qt3DSTegraApplication.h +++ b/src/Runtime/Source/Engine/Include/Qt3DSTegraApplication.h @@ -153,7 +153,7 @@ public: virtual ~INDDView(){} public: // loading - virtual bool BeginLoad(const QString &sourcePath) = 0; + virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) = 0; virtual bool HasOfflineLoadingCompleted() = 0; virtual bool InitializeGraphics(const QSurfaceFormat &format) = 0; @@ -222,7 +222,7 @@ public: IAudioPlayer *inAudioPlayer = 0); virtual ~CTegraApplication(); // loading - bool BeginLoad(const QString &sourcePath); + bool BeginLoad(const QString &sourcePath, const QStringList &variantList); // asynchronous BeginLoad completed? That only valid for binary presentation, for text // presentation, always true bool HasOfflineLoadingCompleted() { return m_NDDView->HasOfflineLoadingCompleted(); } diff --git a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp b/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp index b70bd48e..8fa75792 100644 --- a/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp +++ b/src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp @@ -958,7 +958,8 @@ struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager, Q3DStudio::IScene *LoadScene(Q3DStudio::IPresentation *inPresentation, Q3DStudio::IUIPParser *inParser, - Q3DStudio::IScriptBridge &inBridge) override + Q3DStudio::IScriptBridge &inBridge, + const qt3ds::Q3DSVariantConfig &variantConfig) override { // We have to initialize the tags late so that we can load flow data before adding anything // to the string table. @@ -985,7 +986,8 @@ struct Qt3DSRenderSceneManager : public Q3DStudio::ISceneManager, m_Context->m_Context->GetRenderPluginManager(), m_Context->m_Context->GetCustomMaterialSystem(), m_Context->m_Context->GetDynamicObjectSystem(), - m_Context->m_Context->GetPathManager(), &theResolver, false); + m_Context->m_Context->GetPathManager(), &theResolver, + variantConfig, false); if (!theScene->m_Presentation) { QT3DS_ASSERT(false); return NULL; diff --git a/src/Runtime/Source/Engine/Source/Qt3DSTegraApplication.cpp b/src/Runtime/Source/Engine/Source/Qt3DSTegraApplication.cpp index a2dcca91..92c7f6cc 100644 --- a/src/Runtime/Source/Engine/Source/Qt3DSTegraApplication.cpp +++ b/src/Runtime/Source/Engine/Source/Qt3DSTegraApplication.cpp @@ -170,7 +170,7 @@ public: QT3DS_IMPLEMENT_REF_COUNT_ADDREF_RELEASE_OVERRIDE(qt3ds::render::g_BaseAllocator); - bool BeginLoad(const QString &sourcePath) override; + bool BeginLoad(const QString &sourcePath, const QStringList &variantList) override; bool HasOfflineLoadingCompleted() override; bool InitializeGraphics(const QSurfaceFormat &format) override; @@ -233,7 +233,7 @@ CNDDView::~CNDDView() { } -bool CNDDView::BeginLoad(const QString &sourcePath) +bool CNDDView::BeginLoad(const QString &sourcePath, const QStringList &variantList) { bool theResult = false; @@ -241,7 +241,7 @@ bool CNDDView::BeginLoad(const QString &sourcePath) BootupPreGraphicsInitObjects(); // If there was a presentation file then we have to load it or something failed. - if (m_ApplicationCore->BeginLoad(sourcePath.toUtf8())) + if (m_ApplicationCore->BeginLoad(sourcePath.toUtf8(), variantList)) theResult = true; else theResult = false; @@ -692,7 +692,7 @@ CTegraApplication::~CTegraApplication() { } -bool CTegraApplication::BeginLoad(const QString &sourcePath) +bool CTegraApplication::BeginLoad(const QString &sourcePath, const QStringList &variantList) { #ifndef QT3DS_NO_SEARCH_PATH // We need these later on in case we try to load any files @@ -708,7 +708,7 @@ bool CTegraApplication::BeginLoad(const QString &sourcePath) if (!sourcePath.isEmpty()) { // If there was a presentation file then we have to load it or something failed. - if (m_NDDView->BeginLoad(sourcePath)) { + if (m_NDDView->BeginLoad(sourcePath, variantList)) { qCInfo(TRACE_INFO) << "CTegraApplication::BeginLoad: Successfully begin loading presentation: " << sourcePath; diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h index 22f6ea2c..2b70c687 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h @@ -38,6 +38,7 @@ #include <EASTL/utility.h> #include "foundation/Qt3DSContainers.h" #include "Qt3DSRenderGraphObject.h" +#include <QtCore/qstring.h> namespace Q3DStudio { class IRuntimeMetaData; @@ -50,6 +51,8 @@ struct SMetaDataCustomMaterial; } namespace qt3ds { +class Q3DSVariantConfig; + namespace render { class IBufferManager; @@ -102,6 +105,10 @@ namespace render { // its normal mode of operation so we try to reuse that code. , IUIPReferenceResolver *inResolver + // Variant config defines variant groups and tags to be used to filter out + // unneeded parts of the presentation + , + const Q3DSVariantConfig &variantConfig // Set some initial values by going to the master slide then slide 1 // Useful for quick testing, sort of equivalent to showing the first frame // of a given presentation diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp index 63341c9e..f64efbcc 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp @@ -76,6 +76,7 @@ #include "Qt3DSRenderPath.h" #include "Qt3DSRenderPathSubPath.h" #include "Qt3DSRenderPathManager.h" +#include "q3dsvariantconfig_p.h" using qt3ds::foundation::Option; using qt3ds::foundation::Empty; @@ -471,6 +472,7 @@ struct SRenderUIPLoader : public IDOMReferenceResolver MemoryBuffer<RawAllocator> m_TempBuffer; MemoryBuffer<RawAllocator> m_ValueBuffer; TIdPathAnchorIndexMap m_AnchorIdToPathAndAnchorIndexMap; + const Q3DSVariantConfig &m_variantConfig; SRenderUIPLoader(qt3dsdm::IDOMReader &inReader, const char8_t *inFullPathToPresentationFile, Q3DStudio::IRuntimeMetaData &inMetaData, IStringTable &inStrTable @@ -487,7 +489,8 @@ struct SRenderUIPLoader : public IDOMReferenceResolver qt3ds::render::IRenderPluginManager &inRPM, qt3ds::render::ICustomMaterialSystem &inCMS, qt3ds::render::IDynamicObjectSystem &inDynamicSystem, - qt3ds::render::IPathManager &inPathManager, IUIPReferenceResolver *inResolver) + qt3ds::render::IPathManager &inPathManager, IUIPReferenceResolver *inResolver, + const Q3DSVariantConfig &variantConfig) : m_Reader(inReader) , m_MetaData(inMetaData) , m_StrTable(inStrTable) @@ -504,6 +507,7 @@ struct SRenderUIPLoader : public IDOMReferenceResolver , m_DynamicObjectSystem(inDynamicSystem) , m_PathManager(inPathManager) , m_ReferenceResolver(inResolver) + , m_variantConfig(variantConfig) { std::string presentationFile = inFullPathToPresentationFile; std::string::size_type pos = presentationFile.find_last_of("\\/"); @@ -668,6 +672,7 @@ struct SRenderUIPLoader : public IDOMReferenceResolver #define Node_LocalOpacity "opacity" #define Node_RotationOrder "rotationorder" #define Node_LeftHanded "orientation" +#define Layer_Variants "variants" #define Layer_TemporalAAEnabled "temporalaa" #define Layer_LayerEnableDepthTest "disabledepthtest" #define Layer_LayerEnableDepthPrePass "disabledepthprepass" @@ -1175,103 +1180,111 @@ struct SRenderUIPLoader : public IDOMReferenceResolver qt3dsdm::ComposerObjectTypes::Convert(m_Reader.GetElementName()); SGraphObject *theNewObject(NULL); const char8_t *theId; + const char8_t *theVariants; m_Reader.Att("id", theId); - - switch (theObjType) { - case qt3dsdm::ComposerObjectTypes::Scene: { - SScene *theScene = QT3DS_NEW(m_PresentationAllocator, SScene)(); - theNewObject = theScene; - m_Presentation->m_Scene = theScene; - theScene->m_Presentation = m_Presentation; - } break; - case qt3dsdm::ComposerObjectTypes::Layer: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SLayer)(); - break; - case qt3dsdm::ComposerObjectTypes::Group: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SNode)(); - break; - case qt3dsdm::ComposerObjectTypes::Component: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SNode)(); - break; - case qt3dsdm::ComposerObjectTypes::Camera: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SCamera)(); - break; - case qt3dsdm::ComposerObjectTypes::Light: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SLight)(); - break; - case qt3dsdm::ComposerObjectTypes::Model: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SModel)(); - break; - case qt3dsdm::ComposerObjectTypes::Material: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SDefaultMaterial)(); - break; - case qt3dsdm::ComposerObjectTypes::ReferencedMaterial: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SReferencedMaterial)(); - break; - case qt3dsdm::ComposerObjectTypes::Image: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SImage)(); - break; - case qt3dsdm::ComposerObjectTypes::Text: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SText)(); - break; - case qt3dsdm::ComposerObjectTypes::Path: - theNewObject = QT3DS_NEW(m_PresentationAllocator, SPath)(); - break; - case qt3dsdm::ComposerObjectTypes::SubPath: { - SPathSubPath *thePath = QT3DS_NEW(m_PresentationAllocator, SPathSubPath)(); - theNewObject = thePath; - QT3DSU32 anchorCount = 0; - TScope _childScope(m_Reader); - for (bool success = m_Reader.MoveToFirstChild("PathAnchorPoint"); success; - success = m_Reader.MoveToNextSibling("PathAnchorPoint")) { - const char8_t *theId; - m_Reader.Att("id", theId); - CRegisteredString theIdStr = m_StrTable.RegisterStr(theId); - m_AnchorIdToPathAndAnchorIndexMap.insert( - eastl::make_pair(theIdStr, SPathAndAnchorIndex(thePath, anchorCount))); - ++anchorCount; - } - m_PathManager.ResizePathSubPathBuffer(*thePath, anchorCount); - } break; - case qt3dsdm::ComposerObjectTypes::Effect: { - const char8_t *effectClassId; - m_Reader.Att("class", effectClassId); - CRegisteredString theStr = m_StrTable.RegisterStr(effectClassId + 1); - if (m_EffectSystem.IsEffectRegistered(theStr)) - theNewObject = m_EffectSystem.CreateEffectInstance(theStr, m_PresentationAllocator); - } break; - case qt3dsdm::ComposerObjectTypes::RenderPlugin: { - const char8_t *classId; - m_Reader.Att("class", classId); - if (!qt3ds::foundation::isTrivial(classId)) { - ++classId; - TIdStringMap::iterator iter = - m_RenderPluginSourcePaths.find(m_StrTable.RegisterStr(classId)); - if (iter != m_RenderPluginSourcePaths.end()) { - CRegisteredString thePluginPath = m_StrTable.RegisterStr(iter->second.c_str()); - qt3ds::render::IRenderPluginClass *theClass = - m_RenderPluginManager.GetRenderPlugin(thePluginPath); - if (theClass) { - qt3ds::render::SRenderPlugin *thePlugin = - QT3DS_NEW(m_PresentationAllocator, qt3ds::render::SRenderPlugin)(); - thePlugin->m_PluginPath = thePluginPath; - thePlugin->m_Flags.SetActive(true); - theNewObject = thePlugin; + m_Reader.Att("variants", theVariants); + + QString theString(theVariants); + QStringRef theStringRef(&theString); + bool isPartOfConfig = m_variantConfig.isPartOfConfig(theStringRef); + if (isPartOfConfig) { + switch (theObjType) { + case qt3dsdm::ComposerObjectTypes::Scene: { + SScene *theScene = QT3DS_NEW(m_PresentationAllocator, SScene)(); + theNewObject = theScene; + m_Presentation->m_Scene = theScene; + theScene->m_Presentation = m_Presentation; + } break; + case qt3dsdm::ComposerObjectTypes::Layer: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SLayer)(); + break; + case qt3dsdm::ComposerObjectTypes::Group: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SNode)(); + break; + case qt3dsdm::ComposerObjectTypes::Component: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SNode)(); + break; + case qt3dsdm::ComposerObjectTypes::Camera: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SCamera)(); + break; + case qt3dsdm::ComposerObjectTypes::Light: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SLight)(); + break; + case qt3dsdm::ComposerObjectTypes::Model: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SModel)(); + break; + case qt3dsdm::ComposerObjectTypes::Material: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SDefaultMaterial)(); + break; + case qt3dsdm::ComposerObjectTypes::ReferencedMaterial: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SReferencedMaterial)(); + break; + case qt3dsdm::ComposerObjectTypes::Image: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SImage)(); + break; + case qt3dsdm::ComposerObjectTypes::Text: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SText)(); + break; + case qt3dsdm::ComposerObjectTypes::Path: + theNewObject = QT3DS_NEW(m_PresentationAllocator, SPath)(); + break; + case qt3dsdm::ComposerObjectTypes::SubPath: { + SPathSubPath *thePath = QT3DS_NEW(m_PresentationAllocator, SPathSubPath)(); + theNewObject = thePath; + QT3DSU32 anchorCount = 0; + TScope _childScope(m_Reader); + for (bool success = m_Reader.MoveToFirstChild("PathAnchorPoint"); success; + success = m_Reader.MoveToNextSibling("PathAnchorPoint")) { + const char8_t *theId; + m_Reader.Att("id", theId); + CRegisteredString theIdStr = m_StrTable.RegisterStr(theId); + m_AnchorIdToPathAndAnchorIndexMap.insert( + eastl::make_pair(theIdStr, SPathAndAnchorIndex(thePath, anchorCount))); + ++anchorCount; + } + m_PathManager.ResizePathSubPathBuffer(*thePath, anchorCount); + } break; + case qt3dsdm::ComposerObjectTypes::Effect: { + const char8_t *effectClassId; + m_Reader.Att("class", effectClassId); + CRegisteredString theStr = m_StrTable.RegisterStr(effectClassId + 1); + if (m_EffectSystem.IsEffectRegistered(theStr)) + theNewObject = m_EffectSystem.CreateEffectInstance(theStr, m_PresentationAllocator); + } break; + case qt3dsdm::ComposerObjectTypes::RenderPlugin: { + const char8_t *classId; + m_Reader.Att("class", classId); + if (!qt3ds::foundation::isTrivial(classId)) { + ++classId; + TIdStringMap::iterator iter = + m_RenderPluginSourcePaths.find(m_StrTable.RegisterStr(classId)); + if (iter != m_RenderPluginSourcePaths.end()) { + CRegisteredString thePluginPath = m_StrTable.RegisterStr(iter->second.c_str()); + qt3ds::render::IRenderPluginClass *theClass = + m_RenderPluginManager.GetRenderPlugin(thePluginPath); + if (theClass) { + qt3ds::render::SRenderPlugin *thePlugin = + QT3DS_NEW(m_PresentationAllocator, qt3ds::render::SRenderPlugin)(); + thePlugin->m_PluginPath = thePluginPath; + thePlugin->m_Flags.SetActive(true); + theNewObject = thePlugin; + } } } + } break; + case qt3dsdm::ComposerObjectTypes::CustomMaterial: { + const char8_t *materialClassId; + m_Reader.Att("class", materialClassId); + CRegisteredString theStr = m_StrTable.RegisterStr(materialClassId + 1); + if (m_CustomMaterialSystem.IsMaterialRegistered(theStr)) { + theNewObject = + m_CustomMaterialSystem.CreateCustomMaterial(theStr, m_PresentationAllocator); + } + } break; + default: + // Ignoring unknown objects entirely at this point + break; } - } break; - case qt3dsdm::ComposerObjectTypes::CustomMaterial: { - const char8_t *materialClassId; - m_Reader.Att("class", materialClassId); - CRegisteredString theStr = m_StrTable.RegisterStr(materialClassId + 1); - if (m_CustomMaterialSystem.IsMaterialRegistered(theStr)) - theNewObject = - m_CustomMaterialSystem.CreateCustomMaterial(theStr, m_PresentationAllocator); - } break; - default: - // Ignoring unknown objects entirely at this point - break; } if (theNewObject) { CRegisteredString theObjectId(m_StrTable.RegisterStr(theId)); @@ -1385,9 +1398,15 @@ struct SRenderUIPLoader : public IDOMReferenceResolver valid = m_Reader.MoveToNextSibling()) ParseGraphPass1(theNewObject); } else { - for (bool valid = m_Reader.MoveToFirstChild(); valid; - valid = m_Reader.MoveToNextSibling()) - ParseGraphPass1(NULL); + if (isPartOfConfig) { + // Object was of unknown type -> parse children with NULL parent + for (bool valid = m_Reader.MoveToFirstChild(); valid; + valid = m_Reader.MoveToNextSibling()) { + ParseGraphPass1(NULL); + } + } + // If object wasn't part of variant config -> skip children. + // Continue parsing from next sibling with same parent. } } @@ -1411,64 +1430,76 @@ struct SRenderUIPLoader : public IDOMReferenceResolver const char8_t *theId; m_Reader.Att("id", theId); const char8_t *theClass = ""; + const char8_t *theVariants = ""; m_Reader.Att("class", theClass); - TIdObjectMap::iterator theObject = m_ObjectMap.find(m_StrTable.RegisterStr(theId)); - if (theObject != m_ObjectMap.end()) { - switch (theObject->second->m_Type) { - case GraphObjectTypes::Scene: - ParsePass2Properties(*static_cast<SScene *>(theObject->second), theClass); - break; - case GraphObjectTypes::Node: - ParsePass2Properties(*static_cast<SNode *>(theObject->second), theClass); - break; - case GraphObjectTypes::Layer: - ParsePass2Properties(*static_cast<SLayer *>(theObject->second), theClass); - break; - case GraphObjectTypes::Camera: - ParsePass2Properties(*static_cast<SCamera *>(theObject->second), theClass); - break; - case GraphObjectTypes::Light: - ParsePass2Properties(*static_cast<SLight *>(theObject->second), theClass); - break; - case GraphObjectTypes::Model: - ParsePass2Properties(*static_cast<SModel *>(theObject->second), theClass); - break; - case GraphObjectTypes::DefaultMaterial: - ParsePass2Properties(*static_cast<SDefaultMaterial *>(theObject->second), theClass); - break; - case GraphObjectTypes::ReferencedMaterial: - ParsePass2Properties(*static_cast<SReferencedMaterial *>(theObject->second), - theClass); - break; - case GraphObjectTypes::Image: - ParsePass2Properties(*static_cast<SImage *>(theObject->second), theClass); - break; - case GraphObjectTypes::Text: - ParsePass2Properties(*static_cast<SText *>(theObject->second), theClass); - break; - case GraphObjectTypes::Effect: - ParsePass2Properties(*static_cast<SEffect *>(theObject->second), theClass); - break; - case GraphObjectTypes::RenderPlugin: - ParsePass2Properties(*static_cast<qt3ds::render::SRenderPlugin *>(theObject->second), - theClass); - break; - case GraphObjectTypes::CustomMaterial: - ParsePass2Properties(*static_cast<SCustomMaterial *>(theObject->second), theClass); - break; - case GraphObjectTypes::Path: - ParsePass2Properties(*static_cast<SPath *>(theObject->second), theClass); - break; - case GraphObjectTypes::PathSubPath: - ParsePass2Properties(*static_cast<SPathSubPath *>(theObject->second), theClass); - break; - default: - QT3DS_ASSERT(false); - break; + m_Reader.Att("variants", theVariants); + + QString theString(theVariants); + QStringRef theStringRef(&theString); + bool isPartOfConfig = m_variantConfig.isPartOfConfig(theStringRef); + if (isPartOfConfig) { + TIdObjectMap::iterator theObject = m_ObjectMap.find(m_StrTable.RegisterStr(theId)); + if (theObject != m_ObjectMap.end()) { + switch (theObject->second->m_Type) { + case GraphObjectTypes::Scene: + ParsePass2Properties(*static_cast<SScene *>(theObject->second), theClass); + break; + case GraphObjectTypes::Node: + ParsePass2Properties(*static_cast<SNode *>(theObject->second), theClass); + break; + case GraphObjectTypes::Layer: + ParsePass2Properties(*static_cast<SLayer *>(theObject->second), theClass); + break; + case GraphObjectTypes::Camera: + ParsePass2Properties(*static_cast<SCamera *>(theObject->second), theClass); + break; + case GraphObjectTypes::Light: + ParsePass2Properties(*static_cast<SLight *>(theObject->second), theClass); + break; + case GraphObjectTypes::Model: + ParsePass2Properties(*static_cast<SModel *>(theObject->second), theClass); + break; + case GraphObjectTypes::DefaultMaterial: + ParsePass2Properties(*static_cast<SDefaultMaterial *>(theObject->second), theClass); + break; + case GraphObjectTypes::ReferencedMaterial: + ParsePass2Properties(*static_cast<SReferencedMaterial *>(theObject->second), + theClass); + break; + case GraphObjectTypes::Image: + ParsePass2Properties(*static_cast<SImage *>(theObject->second), theClass); + break; + case GraphObjectTypes::Text: + ParsePass2Properties(*static_cast<SText *>(theObject->second), theClass); + break; + case GraphObjectTypes::Effect: + ParsePass2Properties(*static_cast<SEffect *>(theObject->second), theClass); + break; + case GraphObjectTypes::RenderPlugin: + ParsePass2Properties(*static_cast<qt3ds::render::SRenderPlugin *>(theObject->second), + theClass); + break; + case GraphObjectTypes::CustomMaterial: + ParsePass2Properties(*static_cast<SCustomMaterial *>(theObject->second), theClass); + break; + case GraphObjectTypes::Path: + ParsePass2Properties(*static_cast<SPath *>(theObject->second), theClass); + break; + case GraphObjectTypes::PathSubPath: + ParsePass2Properties(*static_cast<SPathSubPath *>(theObject->second), theClass); + break; + default: + QT3DS_ASSERT(false); + break; + } } } - for (bool valid = m_Reader.MoveToFirstChild(); valid; valid = m_Reader.MoveToNextSibling()) - ParseGraphPass2(); + + // If not part of variant config -> ignore children + if (isPartOfConfig) { + for (bool valid = m_Reader.MoveToFirstChild(); valid; valid = m_Reader.MoveToNextSibling()) + ParseGraphPass2(); + } } static bool ParseVec2(SDomReaderPropertyParser &inParser, const char *inName, QT3DSVec2 &outValue) @@ -1499,83 +1530,85 @@ struct SRenderUIPLoader : public IDOMReferenceResolver const char8_t *theId; m_Reader.Att("ref", theId); CRegisteredString theIdStr(m_StrTable.RegisterStr(theId + 1)); - TIdObjectMap::iterator theObject = m_ObjectMap.find(theIdStr); - if (theObject != m_ObjectMap.end()) { - SDomReaderPropertyParser parser(m_Reader, m_TempBuf, *this, *theObject->second); - switch (theObject->second->m_Type) { - case GraphObjectTypes::Scene: - ParseProperties(*reinterpret_cast<SScene *>(theObject->second), parser); - break; - case GraphObjectTypes::Node: - ParseProperties(*reinterpret_cast<SNode *>(theObject->second), parser); - break; - case GraphObjectTypes::Layer: - ParseProperties(*reinterpret_cast<SLayer *>(theObject->second), parser); - break; - case GraphObjectTypes::Camera: - ParseProperties(*reinterpret_cast<SCamera *>(theObject->second), parser); - break; - case GraphObjectTypes::Light: - ParseProperties(*reinterpret_cast<SLight *>(theObject->second), parser); - break; - case GraphObjectTypes::Model: - ParseProperties(*reinterpret_cast<SModel *>(theObject->second), parser); - break; - case GraphObjectTypes::DefaultMaterial: - ParseProperties(*reinterpret_cast<SDefaultMaterial *>(theObject->second), - parser); - break; - case GraphObjectTypes::ReferencedMaterial: - ParseProperties(*static_cast<SReferencedMaterial *>(theObject->second), - parser); - break; - case GraphObjectTypes::Image: - ParseProperties(*reinterpret_cast<SImage *>(theObject->second), parser); - break; - case GraphObjectTypes::Text: - ParseProperties(*static_cast<SText *>(theObject->second), parser); - break; - case GraphObjectTypes::Effect: - ParseProperties(*static_cast<SEffect *>(theObject->second), parser); - break; - case GraphObjectTypes::RenderPlugin: - ParseProperties( - *static_cast<qt3ds::render::SRenderPlugin *>(theObject->second), parser); - break; - case GraphObjectTypes::CustomMaterial: - ParseProperties( - *static_cast<qt3ds::render::SCustomMaterial *>(theObject->second), - parser); - break; - case GraphObjectTypes::Path: - ParseProperties(*static_cast<qt3ds::render::SPath *>(theObject->second), - parser); - break; - case GraphObjectTypes::PathSubPath: - ParseProperties( - *static_cast<qt3ds::render::SPathSubPath *>(theObject->second), parser); - break; - default: - QT3DS_ASSERT(false); - break; - } - } else { - TIdPathAnchorIndexMap::iterator iter = - m_AnchorIdToPathAndAnchorIndexMap.find(theIdStr); - if (iter != m_AnchorIdToPathAndAnchorIndexMap.end()) { - SDomReaderPropertyParser parser(m_Reader, m_TempBuf, *this, - *iter->second.m_Segment); - NVDataRef<qt3ds::render::SPathAnchorPoint> thePathBuffer = - m_PathManager.GetPathSubPathBuffer(*iter->second.m_Segment); - QT3DSU32 anchorIndex = iter->second.m_AnchorIndex; - QT3DSU32 numAnchors = thePathBuffer.size(); - if (anchorIndex < numAnchors) { - qt3ds::render::SPathAnchorPoint &thePoint(thePathBuffer[anchorIndex]); - ParseVec2(parser, "position", thePoint.m_Position); - ParseFloat(parser, "incomingangle", thePoint.m_IncomingAngle); - thePoint.m_OutgoingAngle = thePoint.m_IncomingAngle + 180.0f; - ParseFloat(parser, "incomingdistance", thePoint.m_IncomingDistance); - ParseFloat(parser, "outgoingdistance", thePoint.m_OutgoingDistance); + if (m_ObjectMap.contains(theIdStr)) { + TIdObjectMap::iterator theObject = m_ObjectMap.find(theIdStr); + if (theObject != m_ObjectMap.end()) { + SDomReaderPropertyParser parser(m_Reader, m_TempBuf, *this, *theObject->second); + switch (theObject->second->m_Type) { + case GraphObjectTypes::Scene: + ParseProperties(*reinterpret_cast<SScene *>(theObject->second), parser); + break; + case GraphObjectTypes::Node: + ParseProperties(*reinterpret_cast<SNode *>(theObject->second), parser); + break; + case GraphObjectTypes::Layer: + ParseProperties(*reinterpret_cast<SLayer *>(theObject->second), parser); + break; + case GraphObjectTypes::Camera: + ParseProperties(*reinterpret_cast<SCamera *>(theObject->second), parser); + break; + case GraphObjectTypes::Light: + ParseProperties(*reinterpret_cast<SLight *>(theObject->second), parser); + break; + case GraphObjectTypes::Model: + ParseProperties(*reinterpret_cast<SModel *>(theObject->second), parser); + break; + case GraphObjectTypes::DefaultMaterial: + ParseProperties(*reinterpret_cast<SDefaultMaterial *>(theObject->second), + parser); + break; + case GraphObjectTypes::ReferencedMaterial: + ParseProperties(*static_cast<SReferencedMaterial *>(theObject->second), + parser); + break; + case GraphObjectTypes::Image: + ParseProperties(*reinterpret_cast<SImage *>(theObject->second), parser); + break; + case GraphObjectTypes::Text: + ParseProperties(*static_cast<SText *>(theObject->second), parser); + break; + case GraphObjectTypes::Effect: + ParseProperties(*static_cast<SEffect *>(theObject->second), parser); + break; + case GraphObjectTypes::RenderPlugin: + ParseProperties( + *static_cast<qt3ds::render::SRenderPlugin *>(theObject->second), parser); + break; + case GraphObjectTypes::CustomMaterial: + ParseProperties( + *static_cast<qt3ds::render::SCustomMaterial *>(theObject->second), + parser); + break; + case GraphObjectTypes::Path: + ParseProperties(*static_cast<qt3ds::render::SPath *>(theObject->second), + parser); + break; + case GraphObjectTypes::PathSubPath: + ParseProperties( + *static_cast<qt3ds::render::SPathSubPath *>(theObject->second), parser); + break; + default: + QT3DS_ASSERT(false); + break; + } + } else { + TIdPathAnchorIndexMap::iterator iter = + m_AnchorIdToPathAndAnchorIndexMap.find(theIdStr); + if (iter != m_AnchorIdToPathAndAnchorIndexMap.end()) { + SDomReaderPropertyParser parser(m_Reader, m_TempBuf, *this, + *iter->second.m_Segment); + NVDataRef<qt3ds::render::SPathAnchorPoint> thePathBuffer = + m_PathManager.GetPathSubPathBuffer(*iter->second.m_Segment); + QT3DSU32 anchorIndex = iter->second.m_AnchorIndex; + QT3DSU32 numAnchors = thePathBuffer.size(); + if (anchorIndex < numAnchors) { + qt3ds::render::SPathAnchorPoint &thePoint(thePathBuffer[anchorIndex]); + ParseVec2(parser, "position", thePoint.m_Position); + ParseFloat(parser, "incomingangle", thePoint.m_IncomingAngle); + thePoint.m_OutgoingAngle = thePoint.m_IncomingAngle + 180.0f; + ParseFloat(parser, "incomingdistance", thePoint.m_IncomingDistance); + ParseFloat(parser, "outgoingdistance", thePoint.m_OutgoingDistance); + } } } } @@ -1811,12 +1844,12 @@ SPresentation *qt3ds::render::IUIPLoader::LoadUIPFile( const char8_t *inPresentationDir, IRenderPluginManager &inPluginManager, ICustomMaterialSystem &inCMS, IDynamicObjectSystem &inDynamicSystem, qt3ds::render::IPathManager &inPathManager, IUIPReferenceResolver *inResolver, - bool inSetValuesFromSlides) + const Q3DSVariantConfig &variantConfig, bool inSetValuesFromSlides) { SRenderUIPLoader theLoader(inReader, inFullPathToPresentationFile, inMetaData, inStrTable, inFoundation, inPresentationAllocator, ioObjectMap, inBufferManager, inEffectSystem, inPresentationDir, inPluginManager, inCMS, - inDynamicSystem, inPathManager, inResolver); + inDynamicSystem, inPathManager, inResolver, variantConfig); return theLoader.Load(inSetValuesFromSlides); } using namespace qt3dsdm; diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSApplication.h b/src/Runtime/Source/Runtime/Include/Qt3DSApplication.h index e078f4f3..d825fe0f 100644 --- a/src/Runtime/Source/Runtime/Include/Qt3DSApplication.h +++ b/src/Runtime/Source/Runtime/Include/Qt3DSApplication.h @@ -134,7 +134,8 @@ public: virtual void DisableStateMachine() = 0; // nonblocking call to begin loading, loads uia file alone and returns. - virtual bool BeginLoad(const char8_t *inFilePath) = 0; + virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) = 0; + // blocking call to end all loading threads and such/wait till finished virtual void EndLoad() = 0; // Will EndLoad cause nontrivial blocking. diff --git a/src/Runtime/Source/Runtime/Include/Qt3DSSceneManager.h b/src/Runtime/Source/Runtime/Include/Qt3DSSceneManager.h index 079e67ed..7b8a4aab 100644 --- a/src/Runtime/Source/Runtime/Include/Qt3DSSceneManager.h +++ b/src/Runtime/Source/Runtime/Include/Qt3DSSceneManager.h @@ -48,6 +48,7 @@ namespace foundation { } namespace qt3ds { +class Q3DSVariantConfig; namespace render { class IQt3DSRenderContextCore; class ILoadedBuffer; @@ -109,7 +110,7 @@ struct FacePositionPlanes class ISceneManager : public qt3ds::foundation::NVRefCounted { protected: - virtual ~ISceneManager(){}; + virtual ~ISceneManager(){} public: // Presentations //============================================================================== @@ -121,7 +122,8 @@ public: // Presentations * @param inPresentation the current presentation loaded */ virtual IScene *LoadScene(IPresentation *inPresentation, IUIPParser *inParser, - IScriptBridge &inBridge) = 0; + IScriptBridge &inBridge, + const qt3ds::Q3DSVariantConfig &variantConfig) = 0; virtual void LoadRenderPlugin(const CHAR *inAssetIDString, const CHAR *inPath, const CHAR *inArgs) = 0; diff --git a/src/Runtime/Source/Runtime/Include/q3dsvariantconfig_p.h b/src/Runtime/Source/Runtime/Include/q3dsvariantconfig_p.h new file mode 100644 index 00000000..1905f44a --- /dev/null +++ b/src/Runtime/Source/Runtime/Include/q3dsvariantconfig_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: http://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$ +** +****************************************************************************/ +#ifndef Q3DSVARIANTCONFIG_P_H +#define Q3DSVARIANTCONFIG_P_H + +#include <QtCore/qobject.h> +#include <QtCore/qhash.h> +#include <QtCore/qvector.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of a number of Qt sources files. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// +namespace qt3ds { + +class Q3DSVariantConfig +{ +public: + Q3DSVariantConfig(); + ~Q3DSVariantConfig(); + + inline bool operator==(const Q3DSVariantConfig &other) const + { + return (this->m_variantList == other.m_variantList); + } + + inline bool operator!=(const Q3DSVariantConfig &other) const + { + return (this->m_variantList != other.m_variantList); + } + + inline bool isEmpty() const { return m_variantList.isEmpty(); } + + void setVariantList(const QStringList &variantList); + + bool isPartOfConfig(const QStringRef &variantAttributes) const; + + inline const QStringList &variantList() const { return m_variantList; } + +private: + QStringList m_variantList; + QList<QString *> m_internalVariantList; + QHash<QStringRef, QVector<QStringRef>> m_variantFilter; +}; + +}; +#endif // Q3DSVARIANTCONFIG_P_H diff --git a/src/Runtime/Source/Runtime/Source/Qt3DSApplication.cpp b/src/Runtime/Source/Runtime/Source/Qt3DSApplication.cpp index 25b1f4b0..249070c2 100644 --- a/src/Runtime/Source/Runtime/Source/Qt3DSApplication.cpp +++ b/src/Runtime/Source/Runtime/Source/Qt3DSApplication.cpp @@ -82,6 +82,7 @@ #include <QtCore/qlibraryinfo.h> #include <QtCore/qpair.h> #include <QtCore/qdir.h> +#include "q3dsvariantconfig_p.h" using namespace qt3ds; using namespace qt3ds::runtime; @@ -444,6 +445,7 @@ struct SApp : public IApplication Q3DStudio::INT32 m_FrameCount; // the name of the file without extension. eastl::string m_Filename; + Q3DSVariantConfig m_variantConfig; qt3ds::foundation::NVScopedReleasable<IRuntimeMetaData> m_MetaData; nvvector<eastl::pair<SBehaviorAsset, bool>> m_Behaviors; @@ -1069,7 +1071,8 @@ struct SApp : public IApplication // Load the scene graph portion of the scene. newScene = m_RuntimeFactory->GetSceneManager().LoadScene( thePresentation, theUIPParser.mPtr, - m_CoreFactory->GetScriptEngineQml()); + m_CoreFactory->GetScriptEngineQml(), + m_variantConfig); } if (newScene == NULL) { @@ -1288,13 +1291,13 @@ struct SApp : public IApplication } } - bool BeginLoad(const char8_t *inFilePath) override + virtual bool BeginLoad(const QString &sourcePath, const QStringList &variantList) override { SStackPerfTimer __loadTimer(m_CoreFactory->GetPerfTimer(), "Application: Begin Load"); eastl::string directory; eastl::string filename; eastl::string extension; - CFileTools::Split(inFilePath, directory, filename, extension); + CFileTools::Split(sourcePath.toUtf8().constData(), directory, filename, extension); eastl::string projectDirectory(directory); m_ProjectDir.assign(projectDirectory.c_str()); @@ -1319,6 +1322,7 @@ struct SApp : public IApplication m_CoreFactory->GetRenderContextCore().GetPerfTimer()); } m_Filename = filename; + m_variantConfig.setVariantList(variantList); bool retval = false; if (extension.comparei("uip") == 0) { #if !defined(_LINUXPLATFORM) && !defined(_INTEGRITYPLATFORM) @@ -1339,27 +1343,28 @@ struct SApp : public IApplication #if !defined(_LINUXPLATFORM) && !defined(_INTEGRITYPLATFORM) ConnectDebugger(); #endif - CFileSeekableIOStream inputStream(inFilePath, FileReadFlags()); + CFileSeekableIOStream inputStream(sourcePath, FileReadFlags()); if (inputStream.IsOpen()) { NVScopedRefCounted<IStringTable> strTable( IStringTable::CreateStringTable(fnd.getAllocator())); NVScopedRefCounted<IDOMFactory> domFactory( IDOMFactory::CreateDOMFactory(fnd.getAllocator(), strTable)); - SAppXMLErrorHandler errorHandler(fnd, inFilePath); + SAppXMLErrorHandler errorHandler(fnd, sourcePath.toUtf8().constData()); eastl::pair<SNamespacePairNode *, SDOMElement *> readResult = CDOMSerializer::Read(*domFactory, inputStream, &errorHandler); if (!readResult.second) { qCCritical(INVALID_PARAMETER, "%s doesn't appear to be valid xml", - inFilePath); + sourcePath.toUtf8().constData()); } else { NVScopedRefCounted<IDOMReader> domReader = IDOMReader::CreateDOMReader( fnd.getAllocator(), *readResult.second, strTable, domFactory); if (m_visitor) - m_visitor->visit(inFilePath); + m_visitor->visit(sourcePath.toUtf8().constData()); retval = LoadUIA(*domReader, fnd); } } else { - qCCritical(INVALID_PARAMETER, "Unable to open input file %s", inFilePath); + qCCritical(INVALID_PARAMETER, "Unable to open input file %s", + sourcePath.toUtf8().constData()); } } else { QT3DS_ASSERT(false); @@ -1717,8 +1722,8 @@ struct SXMLLoader : public IAppLoadContext if (!m_App.LoadUIP(thePresentationAsset, toConstDataRef(theUIPReferences.data(), (QT3DSU32)theUIPReferences.size()))) { - qCWarning(INVALID_OPERATION, "Unable to load presentation %s", - thePathStr.c_str()); + qCCritical(INVALID_OPERATION, "Unable to load presentation %s", + thePathStr.c_str()); } } break; case AssetValueTypes::Behavior: { diff --git a/src/Runtime/Source/Runtime/Source/q3dsvariantconfig.cpp b/src/Runtime/Source/Runtime/Source/q3dsvariantconfig.cpp new file mode 100644 index 00000000..e1fa04c6 --- /dev/null +++ b/src/Runtime/Source/Runtime/Source/q3dsvariantconfig.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: http://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$ +** +****************************************************************************/ +#include "q3dsvariantconfig_p.h" + +namespace qt3ds { + +Q3DSVariantConfig::Q3DSVariantConfig() +{ + +} + +Q3DSVariantConfig::~Q3DSVariantConfig() +{ + for (auto str : qAsConst(m_internalVariantList)) + delete str; + m_internalVariantList.clear(); +} + +void Q3DSVariantConfig::setVariantList(const QStringList &variantList) +{ + // Store the QStringList to be returned from the API + m_variantList = variantList; + + for (auto str : qAsConst(m_internalVariantList)) + delete str; + m_internalVariantList.clear(); + + // Build a fixed (in mem location) list of the variant strings + for (auto tag : variantList) + m_internalVariantList.append(new QString(tag)); + + // Parse the variantGroup:variant list to map using the fixed list + m_variantFilter.clear(); + for (auto tag : qAsConst(m_internalVariantList)) { + QStringRef refTag = QStringRef(tag); + int separatorIdx = refTag.indexOf(QLatin1Char(':')); + QStringRef group = refTag.left(separatorIdx); + QStringRef variant = refTag.mid(separatorIdx + 1); + m_variantFilter[group].append(variant); + } +} + +bool Q3DSVariantConfig::isPartOfConfig(const QStringRef &variantAttributes) const +{ + // Variant filter is ignored when it's not defined + // or if the object has no variant attributes + if (m_variantFilter.isEmpty() || variantAttributes.isEmpty()) + return true; + + // Collect all variant tags per group from the element + QHash<QStringRef, QVector<QStringRef>> groupToVariants; + const QVector<QStringRef> variantTags = variantAttributes.split( + QLatin1Char(','), + QString::SkipEmptyParts); + + for (auto tag : variantTags) { + // Break each variantGroup:value to group and value strings + int groupSeparatorIdx = tag.indexOf(QLatin1Char(':')); + QStringRef group = tag.left(groupSeparatorIdx); + + // Only collect variant tags that are relevant to variant filtering + if (m_variantFilter.contains(group)) { + QStringRef variant = tag.mid(groupSeparatorIdx + 1); + groupToVariants[group].append(variant); + } + } + + // If no relevant variant tags found in element, load the element + if (groupToVariants.isEmpty()) + return true; + + // Verify that the element matches the variant filtering per group. + // To match the element must either: + // - Have no variant tag defined for the group + // - Have a matching tag for the group + bool isLoaded = true; + const auto filteredGroups = m_variantFilter.keys(); + for (auto group : filteredGroups) { + const QVector<QStringRef> variants = groupToVariants[group]; + const QVector<QStringRef> filteredVariants = m_variantFilter[group]; + + if (variants.size() > 0) { + // Check if ANY of the variant values of the element matches ANY + // of the included variants in the filter for this variant group + bool matchesFilter = false; + for (auto variant : variants) + matchesFilter |= filteredVariants.contains(variant); + + isLoaded &= matchesFilter; + } + } + + return isLoaded; +} + +} diff --git a/src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp b/src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp index 1eac8e56..d393f2af 100644 --- a/src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp +++ b/src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp @@ -302,6 +302,7 @@ void Q3DSViewerApp::setOffscreenId(int offscreenID) bool Q3DSViewerApp::InitializeApp(int winWidth, int winHeight, const QSurfaceFormat &format, int offscreenID, const QString &source, + const QStringList &variantList, qt3ds::Qt3DSAssetVisitor *assetVisitor) { bool hasValidPresentationFile = !source.isEmpty(); @@ -332,7 +333,7 @@ bool Q3DSViewerApp::InitializeApp(int winWidth, int winHeight, const QSurfaceFor if (assetVisitor) m_Impl.m_tegraApp->getNDDView()->setAssetVisitor(assetVisitor); - m_Impl.m_appInitSuccessful = m_Impl.m_tegraApp->BeginLoad(source) ? true : false; + m_Impl.m_appInitSuccessful = m_Impl.m_tegraApp->BeginLoad(source, variantList); // Simulate killing the application during loading. Useful for finding serious issues with // loading. diff --git a/src/Runtime/Source/Viewer/Qt3DSViewerApp.h b/src/Runtime/Source/Viewer/Qt3DSViewerApp.h index 0b7f9351..0d56c3a1 100644 --- a/src/Runtime/Source/Viewer/Qt3DSViewerApp.h +++ b/src/Runtime/Source/Viewer/Qt3DSViewerApp.h @@ -115,6 +115,7 @@ public: */ bool InitializeApp(int winWidth, int winHeight, const QSurfaceFormat& format, int offscreenID, const QString &source, + const QStringList &variantList, qt3ds::Qt3DSAssetVisitor *assetVisitor = nullptr); bool IsInitialised(void); diff --git a/src/Runtime/qt3d-runtime b/src/Runtime/qt3d-runtime -Subproject 5e0bfe934b9930b7e41d457b4f88fce91342a0e +Subproject 228b1c7ce76a134e4d2e67809ef8b86f371a15e |