summaryrefslogtreecommitdiffstats
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
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>
-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
-rw-r--r--src/Viewer/Qt3DViewer/main.cpp17
-rw-r--r--src/Viewer/Qt3DViewer/viewer.cpp17
-rw-r--r--src/Viewer/Qt3DViewer/viewer.h5
-rw-r--r--src/Viewer/qmlviewer/Qt3DSRenderer.cpp13
-rw-r--r--src/Viewer/qmlviewer/Qt3DSView.cpp2
-rw-r--r--src/Viewer/studio3d/q3dscommandqueue.cpp5
-rw-r--r--src/Viewer/studio3d/q3dscommandqueue_p.h2
-rw-r--r--src/Viewer/studio3d/q3dspresentation.cpp26
-rw-r--r--src/Viewer/studio3d/q3dspresentation.h4
-rw-r--r--src/Viewer/studio3d/q3dspresentation_p.h2
-rw-r--r--src/Viewer/studio3d/q3dssurfaceviewer.cpp1
-rw-r--r--src/Viewer/studio3d/q3dswidget.cpp2
26 files changed, 599 insertions, 260 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
diff --git a/src/Viewer/Qt3DViewer/main.cpp b/src/Viewer/Qt3DViewer/main.cpp
index 6b020a4f..12abd3b2 100644
--- a/src/Viewer/Qt3DViewer/main.cpp
+++ b/src/Viewer/Qt3DViewer/main.cpp
@@ -208,6 +208,14 @@ int main(int argc, char *argv[])
"The default value is 'center'."),
QCoreApplication::translate("main", "center|fit|fill"),
QStringLiteral("center")});
+ QCommandLineOption variantListOption({QStringLiteral("v"),
+ QStringLiteral("variants")},
+ QObject::tr("Gives list of variant groups and variants\n"
+ "to be loaded from the presentation.\n"
+ "For example VarGroupA:var1,VarGroupB:var4"),
+ QStringLiteral("variants"));
+ parser.addOption(variantListOption);
+
parser.process(a);
const QStringList files = parser.positionalArguments();
@@ -222,6 +230,13 @@ int main(int argc, char *argv[])
|| parser.isSet("seq-height") || parser.isSet("seq-outpath")
|| parser.isSet("seq-outfile");
+ QStringList variantList;
+ if (parser.isSet(variantListOption)) {
+ QString variantOption = parser.value(variantListOption);
+ variantList = variantOption.split(QLatin1Char(','),
+ QString::SkipEmptyParts);
+ }
+
#ifndef Q_OS_ANDROID
Q3DSImageSequenceGenerator *generator = nullptr;
#endif
@@ -320,6 +335,8 @@ int main(int argc, char *argv[])
appWindow->setProperty("scaleMode", Q3DSViewerSettings::ScaleModeCenter);
}
+ viewer.setVariantList(variantList);
+
#ifndef Q_OS_ANDROID
if (generateSequence) {
if (files.count() != 1) {
diff --git a/src/Viewer/Qt3DViewer/viewer.cpp b/src/Viewer/Qt3DViewer/viewer.cpp
index 4d6bcea3..2a32cb76 100644
--- a/src/Viewer/Qt3DViewer/viewer.cpp
+++ b/src/Viewer/Qt3DViewer/viewer.cpp
@@ -95,6 +95,19 @@ void Viewer::disconnectRemote()
m_remoteDeploymentReceiver->disconnectRemote();
}
+void Viewer::setVariantList(const QStringList &variantList)
+{
+ if (m_variantList != variantList) {
+ m_variantList = variantList;
+ Q_EMIT variantListChanged();
+ }
+}
+
+QStringList Viewer::variantList() const
+{
+ return m_variantList;
+}
+
// Used to load files via command line and when using remote deployment
void Viewer::loadFile(const QString &filename)
{
@@ -122,8 +135,10 @@ void Viewer::loadFile(const QString &filename)
setContentView(StudioView);
- if (qmlStudio())
+ if (qmlStudio()) {
+ qmlStudio()->presentation()->setVariantList(m_variantList);
qmlStudio()->presentation()->setSource(sourceUrl);
+ }
}
QString Viewer::convertUrlListToFilename(const QList<QUrl> &list)
diff --git a/src/Viewer/Qt3DViewer/viewer.h b/src/Viewer/Qt3DViewer/viewer.h
index 9931483e..989481b9 100644
--- a/src/Viewer/Qt3DViewer/viewer.h
+++ b/src/Viewer/Qt3DViewer/viewer.h
@@ -47,6 +47,7 @@ class Viewer : public QObject
Q_PROPERTY(int connectPort READ connectPort WRITE setConnectPort NOTIFY connectPortChanged)
Q_PROPERTY(QString connectText READ connectText NOTIFY connectTextChanged)
Q_PROPERTY(bool connected READ isConnected NOTIFY connectedChanged)
+ Q_PROPERTY(QStringList variantList READ variantList WRITE setVariantList NOTIFY variantListChanged)
public:
enum ContentView {
@@ -72,6 +73,8 @@ public:
Q_INVOKABLE void handleMouseRelease(int x, int y, int button, int buttons, int modifiers);
Q_INVOKABLE void handleMouseMove(int x, int y, int button, int buttons, int modifiers);
+ void setVariantList(const QStringList &variantList);
+ QStringList variantList() const;
void setContentView(ContentView view);
ContentView contentView() const;
void setOpenFolder(const QUrl &folder);
@@ -104,12 +107,14 @@ Q_SIGNALS:
void connectPortChanged();
void connectTextChanged();
void connectedChanged();
+ void variantListChanged();
void showInfoOverlay(const QString &infoStr);
private:
Q3DSView *qmlStudio();
QString m_openFileDir;
+ QStringList m_variantList;
RemoteDeploymentReceiver *m_remoteDeploymentReceiver = nullptr;
bool m_generatorMode = false;
ContentView m_contentView = DefaultView;
diff --git a/src/Viewer/qmlviewer/Qt3DSRenderer.cpp b/src/Viewer/qmlviewer/Qt3DSRenderer.cpp
index 39d0c9d6..53f6d388 100644
--- a/src/Viewer/qmlviewer/Qt3DSRenderer.cpp
+++ b/src/Viewer/qmlviewer/Qt3DSRenderer.cpp
@@ -88,9 +88,11 @@ void Q3DSRenderer::synchronize(QQuickFramebufferObject *inView)
if (m_initializationFailure)
static_cast<Q3DSView *>(inView)->setError(m_error);
- if (m_commands.m_sourceChanged) {
+ if (m_commands.m_sourceChanged || m_commands.m_variantListChanged) {
releaseRuntime();
- // Need to update source here rather than processCommands, as source is needed for init
+ // Need to update source and variant list here rather than
+ // processCommands, as both are needed for init
+ m_presentation->setVariantList(m_commands.m_variantList);
m_presentation->setSource(m_commands.m_source);
m_initialized = false;
m_initializationFailure = false;
@@ -176,8 +178,11 @@ bool Q3DSRenderer::initializeRuntime(QOpenGLFramebufferObject *inFbo)
const QString localSource = Q3DSUtils::urlToLocalFileOrQrc(m_presentation->source());
- if (!m_runtime->InitializeApp(theWidth, theHeight, QOpenGLContext::currentContext()->format(),
- inFbo->handle(), localSource, m_visitor)) {
+ if (!m_runtime->InitializeApp(theWidth, theHeight,
+ QOpenGLContext::currentContext()->format(),
+ inFbo->handle(), localSource,
+ m_presentation->variantList(),
+ m_visitor)) {
m_error = m_runtime->error();
releaseRuntime();
return false;
diff --git a/src/Viewer/qmlviewer/Qt3DSView.cpp b/src/Viewer/qmlviewer/Qt3DSView.cpp
index 08103d5e..13a2845d 100644
--- a/src/Viewer/qmlviewer/Qt3DSView.cpp
+++ b/src/Viewer/qmlviewer/Qt3DSView.cpp
@@ -161,6 +161,8 @@ void Q3DSView::reset()
// Fake a source change to trigger a reloading of the presentation
m_pendingCommands.m_sourceChanged = true;
m_pendingCommands.m_source = m_presentation->source();
+ m_pendingCommands.m_variantListChanged = true;
+ m_pendingCommands.m_variantList = m_presentation->variantList();
}
void Q3DSView::requestResponseHandler(const QString &elementPath, CommandType commandType,
diff --git a/src/Viewer/studio3d/q3dscommandqueue.cpp b/src/Viewer/studio3d/q3dscommandqueue.cpp
index aec8cc26..ba0816d4 100644
--- a/src/Viewer/studio3d/q3dscommandqueue.cpp
+++ b/src/Viewer/studio3d/q3dscommandqueue.cpp
@@ -48,6 +48,7 @@ CommandQueue::CommandQueue()
, m_showRenderStatsChanged(false)
, m_matteColorChanged(false)
, m_sourceChanged(false)
+ , m_variantListChanged(false)
, m_globalAnimationTimeChanged(false)
, m_visible(false)
, m_scaleMode(Q3DSViewerSettings::ScaleModeCenter)
@@ -144,6 +145,7 @@ void CommandQueue::copyCommands(const CommandQueue &fromQueue)
m_showRenderStatsChanged = m_showRenderStatsChanged || fromQueue.m_showRenderStatsChanged;
m_matteColorChanged = m_matteColorChanged || fromQueue.m_matteColorChanged;
m_sourceChanged = m_sourceChanged || fromQueue.m_sourceChanged;
+ m_variantListChanged = m_variantListChanged || fromQueue.m_variantListChanged;
m_globalAnimationTimeChanged
= m_globalAnimationTimeChanged || fromQueue.m_globalAnimationTimeChanged;
@@ -159,6 +161,8 @@ void CommandQueue::copyCommands(const CommandQueue &fromQueue)
m_matteColor = fromQueue.m_matteColor;
if (fromQueue.m_sourceChanged)
m_source = fromQueue.m_source;
+ if (fromQueue.m_variantListChanged)
+ m_variantList = fromQueue.m_variantList;
if (fromQueue.m_globalAnimationTimeChanged)
m_globalAnimationTime = fromQueue.m_globalAnimationTime;
@@ -215,6 +219,7 @@ void CommandQueue::clear()
m_showRenderStatsChanged = false;
m_matteColorChanged = false;
m_sourceChanged = false;
+ m_variantListChanged = false;
m_globalAnimationTimeChanged = false;
// We do not clear the actual queued commands, those will be reused the next frame
diff --git a/src/Viewer/studio3d/q3dscommandqueue_p.h b/src/Viewer/studio3d/q3dscommandqueue_p.h
index 42e3bc5c..567fae29 100644
--- a/src/Viewer/studio3d/q3dscommandqueue_p.h
+++ b/src/Viewer/studio3d/q3dscommandqueue_p.h
@@ -118,6 +118,7 @@ public:
bool m_showRenderStatsChanged;
bool m_matteColorChanged;
bool m_sourceChanged;
+ bool m_variantListChanged;
bool m_globalAnimationTimeChanged;
bool m_visible;
@@ -126,6 +127,7 @@ public:
bool m_showRenderStats;
QColor m_matteColor;
QUrl m_source;
+ QStringList m_variantList;
qint64 m_globalAnimationTime;
void clear();
diff --git a/src/Viewer/studio3d/q3dspresentation.cpp b/src/Viewer/studio3d/q3dspresentation.cpp
index 27c050b1..9e73c2c4 100644
--- a/src/Viewer/studio3d/q3dspresentation.cpp
+++ b/src/Viewer/studio3d/q3dspresentation.cpp
@@ -57,6 +57,11 @@ QUrl Q3DSPresentation::source() const
return d_ptr->m_source;
}
+QStringList Q3DSPresentation::variantList() const
+{
+ return d_ptr->m_variantList;
+}
+
void Q3DSPresentation::registerElement(Q3DSElement *element)
{
d_ptr->registerElement(element);
@@ -95,6 +100,14 @@ void Q3DSPresentation::setSource(const QUrl &source)
}
}
+void Q3DSPresentation::setVariantList(const QStringList &variantList)
+{
+ if (d_ptr->m_variantList != variantList) {
+ d_ptr->setVariantList(variantList);
+ Q_EMIT variantListChanged(variantList);
+ }
+}
+
void Q3DSPresentation::goToSlide(const QString &elementPath, unsigned int index)
{
if (d_ptr->m_viewerApp) {
@@ -314,6 +327,15 @@ void Q3DSPresentationPrivate::setSource(const QUrl &source)
}
}
+void Q3DSPresentationPrivate::setVariantList(const QStringList &variantList)
+{
+ m_variantList = variantList;
+ if (m_commandQueue) {
+ m_commandQueue->m_variantListChanged = true;
+ m_commandQueue->m_variantList = variantList;
+ }
+}
+
void Q3DSPresentationPrivate::setViewerApp(Q3DSViewer::Q3DSViewerApp *app, bool connectApp)
{
Q3DSViewer::Q3DSViewerApp *oldApp = m_viewerApp;
@@ -353,8 +375,10 @@ void Q3DSPresentationPrivate::setCommandQueue(CommandQueue *queue)
for (Q3DSDataInput *di : dataInputs)
di->d_ptr->setCommandQueue(queue);
- if (m_commandQueue)
+ if (m_commandQueue) {
setSource(m_source);
+ setVariantList(m_variantList);
+ }
}
// Doc note: The ownership of the registered scenes remains with the caller, who needs to
diff --git a/src/Viewer/studio3d/q3dspresentation.h b/src/Viewer/studio3d/q3dspresentation.h
index cbae780a..d904641d 100644
--- a/src/Viewer/studio3d/q3dspresentation.h
+++ b/src/Viewer/studio3d/q3dspresentation.h
@@ -48,12 +48,14 @@ class Q_STUDIO3D_EXPORT Q3DSPresentation : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(Q3DSPresentation)
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(QStringList variantList READ variantList WRITE setVariantList NOTIFY variantListChanged)
public:
explicit Q3DSPresentation(QObject *parent = nullptr);
~Q3DSPresentation();
QUrl source() const;
+ QStringList variantList() const;
void registerElement(Q3DSElement *scene);
void unregisterElement(Q3DSElement *scene);
@@ -73,6 +75,7 @@ public:
public Q_SLOTS:
void setSource(const QUrl &source);
+ void setVariantList(const QStringList &variantList);
void goToSlide(const QString &elementPath, unsigned int index);
void goToSlide(const QString &elementPath, const QString &name);
void goToSlide(const QString &elementPath, bool next, bool wrap);
@@ -85,6 +88,7 @@ public Q_SLOTS:
void setDataInputValue(const QString &name, const QVariant &value);
Q_SIGNALS:
+ void variantListChanged(const QStringList &variantList);
void sourceChanged(const QUrl &source);
void slideEntered(const QString &elementPath, unsigned int index, const QString &name);
void slideExited(const QString &elementPath, unsigned int index, const QString &name);
diff --git a/src/Viewer/studio3d/q3dspresentation_p.h b/src/Viewer/studio3d/q3dspresentation_p.h
index 27e553ca..d3803719 100644
--- a/src/Viewer/studio3d/q3dspresentation_p.h
+++ b/src/Viewer/studio3d/q3dspresentation_p.h
@@ -65,6 +65,7 @@ public:
~Q3DSPresentationPrivate();
void setSource(const QUrl &source);
+ void setVariantList(const QStringList &variantList);
void setViewerApp(Q3DSViewer::Q3DSViewerApp *app, bool connectApp = true);
void setCommandQueue(CommandQueue *queue);
@@ -91,6 +92,7 @@ private:
ElementMap m_elements;
DataInputMap m_dataInputs;
QUrl m_source;
+ QStringList m_variantList;
ViewerQmlStreamProxy *m_streamProxy;
};
diff --git a/src/Viewer/studio3d/q3dssurfaceviewer.cpp b/src/Viewer/studio3d/q3dssurfaceviewer.cpp
index fd20eb3d..f477723b 100644
--- a/src/Viewer/studio3d/q3dssurfaceviewer.cpp
+++ b/src/Viewer/studio3d/q3dssurfaceviewer.cpp
@@ -355,6 +355,7 @@ bool Q3DSSurfaceViewerPrivate::initializeRuntime()
if (!m_viewerApp->InitializeApp(int(m_size.width() * m_pixelRatio),
int(m_size.height() * m_pixelRatio),
m_context->format(), m_fboId, localSource,
+ m_presentation->variantList(),
m_presentation->d_ptr->streamProxy())) {
releaseRuntime();
qWarning("Failed to initialize runtime");
diff --git a/src/Viewer/studio3d/q3dswidget.cpp b/src/Viewer/studio3d/q3dswidget.cpp
index 4db1b7be..8a2f52b2 100644
--- a/src/Viewer/studio3d/q3dswidget.cpp
+++ b/src/Viewer/studio3d/q3dswidget.cpp
@@ -34,6 +34,7 @@
#include "q3dsviewersettings_p.h"
#include "q3dspresentation_p.h"
#include "studioutils_p.h"
+#include "q3dsvariantconfig_p.h"
#include <QtGui/qevent.h>
#include <QtGui/qopenglcontext.h>
@@ -282,6 +283,7 @@ bool Q3DSWidgetPrivate::initializeRuntime()
int(q_ptr->height() * m_pixelRatio),
q_ptr->context()->format(),
q_ptr->defaultFramebufferObject(), localSource,
+ m_presentation->variantList(),
m_presentation->d_ptr->streamProxy())) {
releaseRuntime();
qWarning("Failed to initialize runtime");