summaryrefslogtreecommitdiffstats
path: root/src/Runtime
diff options
context:
space:
mode:
authorPasi Keränen <pasi.keranen@qt.io>2019-03-21 14:49:23 +0200
committerPasi Keränen <pasi.keranen@qt.io>2019-04-11 09:38:40 +0000
commit00b40db9326f0b951b423a97b7302d87280f029b (patch)
tree54bf9df9aaabd98171dc2066b33a83adee4385e1 /src/Runtime
parent9992c70d914fba4348e236a525deb273db213de1 (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')
-rw-r--r--src/Runtime/Qt3DSRuntimeStatic/Qt3DSRuntimeStatic.pro2
-rw-r--r--src/Runtime/Source/Engine/Include/Qt3DSTegraApplication.h4
-rw-r--r--src/Runtime/Source/Engine/Source/Qt3DSRenderRuntimeBinding.cpp6
-rw-r--r--src/Runtime/Source/Engine/Source/Qt3DSTegraApplication.cpp10
-rw-r--r--src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderUIPLoader.h7
-rw-r--r--src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderUIPLoader.cpp495
-rw-r--r--src/Runtime/Source/Runtime/Include/Qt3DSApplication.h3
-rw-r--r--src/Runtime/Source/Runtime/Include/Qt3DSSceneManager.h6
-rw-r--r--src/Runtime/Source/Runtime/Include/q3dsvariantconfig_p.h79
-rw-r--r--src/Runtime/Source/Runtime/Source/Qt3DSApplication.cpp25
-rw-r--r--src/Runtime/Source/Runtime/Source/q3dsvariantconfig.cpp122
-rw-r--r--src/Runtime/Source/Viewer/Qt3DSViewerApp.cpp3
-rw-r--r--src/Runtime/Source/Viewer/Qt3DSViewerApp.h1
m---------src/Runtime/qt3d-runtime0
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