diff options
author | Jere Tuliniemi <jere.tuliniemi@qt.io> | 2020-01-10 11:41:53 +0200 |
---|---|---|
committer | Jere Tuliniemi <jere.tuliniemi@qt.io> | 2020-01-16 11:52:10 +0200 |
commit | 29eab4197f6cd2d6725c71bc612356c43f872993 (patch) | |
tree | 1e86ba2a26e0844b90ea2313bdd0b2bb32447851 | |
parent | c9439aa3b34085563e0e50657d71a01c13b50d7b (diff) |
Load referenced material assets upon use
When using delayed loading, assets used by materials inside the
material container are not loaded upon startup anymore. Instead
the assets are loaded when entering the slide in which the material
is referenced.
This also fixes referenced materials that refer to an animatable
material in another slide.
Task-number: QT3DS-3100
Change-Id: If55c73e8f91389f3c47ae16357ebe6a473f43585
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Janne Kangas <janne.kangas@qt.io>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Reviewed-by: Antti Määttä <antti.maatta@qt.io>
-rw-r--r-- | src/runtime/Qt3DSSlideSystem.cpp | 7 | ||||
-rw-r--r-- | src/runtime/Qt3DSSlideSystem.h | 1 | ||||
-rw-r--r-- | src/uipparser/Qt3DSUIPParserImpl.cpp | 117 | ||||
-rw-r--r-- | src/uipparser/Qt3DSUIPParserImpl.h | 7 |
4 files changed, 117 insertions, 15 deletions
diff --git a/src/runtime/Qt3DSSlideSystem.cpp b/src/runtime/Qt3DSSlideSystem.cpp index 32d5ea3..7e7d77f 100644 --- a/src/runtime/Qt3DSSlideSystem.cpp +++ b/src/runtime/Qt3DSSlideSystem.cpp @@ -223,6 +223,13 @@ struct SSlideSystem : public ISlideSystem m_CurrentSlide->m_sourcePaths.push_back(QString::fromUtf8(path)); } + void AddSourcePath(SSlideKey key, const char8_t *path) override + { + auto slide = FindSlide(key); + if (slide) + slide->m_sourcePaths.push_back(QString::fromUtf8(path)); + } + void AddSubPresentation(const char8_t *subpresentationId) override { if (m_CurrentSlide) diff --git a/src/runtime/Qt3DSSlideSystem.h b/src/runtime/Qt3DSSlideSystem.h index ddde8ac..2d8e84b 100644 --- a/src/runtime/Qt3DSSlideSystem.h +++ b/src/runtime/Qt3DSSlideSystem.h @@ -135,6 +135,7 @@ namespace runtime { virtual SSlideAnimAction *AddSlideAnimAction(bool inAnimation, QT3DSI32 inIndex, bool inActive) = 0; virtual void AddSourcePath(const char8_t *path) = 0; + virtual void AddSourcePath(SSlideKey key, const char8_t *path) = 0; virtual void AddSubPresentation(const char8_t *subpresentationId) = 0; virtual QVector<QString> GetSourcePaths(SSlideKey inKey) = 0; virtual QVector<QString> GetSubPresentations(SSlideKey inKey) = 0; diff --git a/src/uipparser/Qt3DSUIPParserImpl.cpp b/src/uipparser/Qt3DSUIPParserImpl.cpp index 80187bf..d0868ee 100644 --- a/src/uipparser/Qt3DSUIPParserImpl.cpp +++ b/src/uipparser/Qt3DSUIPParserImpl.cpp @@ -1021,7 +1021,7 @@ EElementType GetElementType(const char *inType) */ BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &inReader, qt3ds::runtime::element::SElement *inNewStyleParent, - bool initInRenderThread) + bool initInRenderThread, bool isInsideLayer) { IDOMReader::Scope __childScope(inReader); IScriptBridge *theScriptBridgeQml = inPresentation.GetScriptBridgeQml(); @@ -1046,6 +1046,7 @@ BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &i UINT32 theLoopTime = 0; bool isComponent = false; bool isBehavior = false; + bool isChildInsideLayer = isInsideLayer; // Create SElement if (AreEqual(theType, "Scene") || AreEqual(theType, "Component")) { @@ -1055,7 +1056,14 @@ BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &i Q3DStudio_ASSERT(theLoopTime != 0); // Something is wrong here isComponent = true; } else { - if (AreEqual(theType, "Behavior") && !IsTrivial(theClass)) { + if (AreEqual(theType, "Layer")) { + isChildInsideLayer = true; + } else if ((AreEqual(theType, "Material") || AreEqual(theType, "CustomMaterial") + || AreEqual(theType, "Image")) && !isInsideLayer) { + // Identify objects outside a Layer object with types of Material, CustomMaterial + // or Image to be inside the material container + m_materialContainerIds.append(QString::fromUtf8(theId)); + } else if (AreEqual(theType, "Behavior") && !IsTrivial(theClass)) { // Find the sourcepath and load the script ++theClass; // remove the '#' TIdSourcePathMap::iterator theSourcePathIter = m_IdScriptMap.find(theClass); @@ -1156,7 +1164,8 @@ BOOL CUIPParserImpl::LoadSceneGraph(IPresentation &inPresentation, IDOMReader &i theFileString.c_str(), initInRenderThread); } } - LoadSceneGraph(inPresentation, inReader, &theNewElem, initInRenderThread); + LoadSceneGraph(inPresentation, inReader, &theNewElem, initInRenderThread, + isChildInsideLayer); } return true; @@ -1627,6 +1636,32 @@ BOOL CUIPParserImpl::LoadStateGraph(IPresentation &inPresentation, qt3dsdm::IDOM } } + // Add source paths of the source materials of the ReferencedMaterials + // to the slide source paths + for (const auto &slideRefMats : qAsConst(m_referencedMaterialsBySlide)) { + const auto &slideKey = slideRefMats.first; + const auto &refMats = slideRefMats.second; + + QVector<QString> sourcePathRefs; + for (const auto &refMat : refMats) { + // CustomMaterials contains their own source paths + sourcePathRefs.append(refMat); + // Materials have their source paths inside Image objects + if (m_imagesByMaterial.contains(refMat)) + sourcePathRefs.append(m_imagesByMaterial[refMat]); + } + + for (const auto &sourcePathRef : qAsConst(sourcePathRefs)) { + if (m_sourcePathsById.contains(sourcePathRef)) { + const auto &sourcePaths = m_sourcePathsById[sourcePathRef]; + for (const auto &sourcePath : sourcePaths) { + inPresentation.GetSlideSystem().AddSourcePath(slideKey, + sourcePath.toUtf8().constData()); + } + } + } + } + return theStatus; } @@ -1643,6 +1678,7 @@ BOOL CUIPParserImpl::LoadState(IPresentation &inPresentation, SElement *inCompon BOOL theResult = true; ISlideSystem &theBuilder = inPresentation.GetSlideSystem(); + m_currentSlideReferencedMaterials.clear(); eastl::string theSlideName = GetSlideName(inReader); @@ -1673,6 +1709,16 @@ BOOL CUIPParserImpl::LoadState(IPresentation &inPresentation, SElement *inCompon if (theMaxTime != 0) theBuilder.SetSlideMaxTime((QT3DSU32)theMaxTime); + if (!m_currentSlideReferencedMaterials.empty()) { + qt3ds::runtime::SSlideKey key; + key.m_Component = inComponent; + key.m_Index = inSlideIndex; + QPair<qt3ds::runtime::SSlideKey, QVector<QString>> pair; + pair.first = key; + pair.second = m_currentSlideReferencedMaterials; + m_referencedMaterialsBySlide.append(pair); + } + return theResult; } @@ -2155,6 +2201,9 @@ BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool m inReader.Att("ref", theRef); if (theRef && *theRef && theRef[0] == '#') ++theRef; + + bool isInsideMaterialContainer = m_materialContainerIds.contains(theRef); + bool isSet = AreEqual(inReader.GetNarrowElementName(), "Set"); const char8_t *sourcepath; if (inReader.UnregisteredAtt("sourcepath", sourcepath)) { @@ -2165,21 +2214,53 @@ BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool m ibl = true; } if (!IsTrivial(sourcepath) && sourcepath[0] != '#') { - AddSourcePath(sourcepath, ibl); - theBuilder.AddSourcePath(sourcepath); - if (!masterSlide) + m_sourcePathsById[QLatin1Char('#') + QString::fromUtf8(theRef)].append( + QString::fromUtf8(sourcepath)); + // Don't add material container assets to the Master Slide source path list + if (!isInsideMaterialContainer) { + AddSourcePath(sourcepath, ibl); + theBuilder.AddSourcePath(sourcepath); + } + // Add the material container assets to the list of source paths used by slides + // other than the Master Slide, so that the assets are not loaded at startup + if (!masterSlide || isInsideMaterialContainer) m_slideSourcePaths.push_back(QString::fromLatin1(sourcepath)); if (AreEqual(inElementData.m_Type.c_str(), "Layer")) theBuilder.AddSubPresentation(sourcepath); - } } + const char8_t *subpres; if (inReader.UnregisteredAtt("subpresentation", subpres)) { if (!IsTrivial(subpres)) theBuilder.AddSubPresentation(subpres); } + const char8_t *referencedmaterial; + if (inReader.UnregisteredAtt("referencedmaterial", referencedmaterial)) { + if (!IsTrivial(referencedmaterial)) + m_currentSlideReferencedMaterials.append(referencedmaterial); + } + + if (strcmp(inElementData.m_Type, "Material") == 0) { + eastl::vector<eastl::string> propertyList; + m_MetaData.GetInstanceProperties(inElementData.m_Type, inElementData.m_Class, + propertyList, false); + for (int i = 0; i < propertyList.size(); ++i) { + ERuntimeDataModelDataType type = m_MetaData.GetPropertyType(inElementData.m_Type, + m_MetaData.Register(propertyList[i].c_str()), + inElementData.m_Class); + if (type == ERuntimeDataModelDataTypeLong4) { + const char8_t *attValue = ""; + bool hasAtt = inReader.UnregisteredAtt(propertyList[i].c_str(), attValue); + if (hasAtt) { + m_imagesByMaterial[QLatin1Char('#') + inElementData.m_Id.c_str()] + .append(QString::fromUtf8(attValue)); + } + } + } + } + const bool dyn = IsDynamicObject(inElementData.m_Type); Option<qt3dsdm::SMetaDataCustomMaterial> mat; Option<qt3dsdm::SMetaDataEffect> eff; @@ -2226,9 +2307,13 @@ BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool m // Handle dynamic object texture source paths if (hasAtt && !IsTrivial(theAttValue) && IsDynamicObject(inElementData.m_Type) && theIter->second.m_AdditionalType == ERuntimeAdditionalMetaDataTypeTexture) { - AddSourcePath(theAttValue, false); - theBuilder.AddSourcePath(theAttValue); - if (!masterSlide) + m_sourcePathsById[QLatin1Char('#') + QString::fromUtf8(theRef)].append( + QString::fromUtf8(theAttValue)); + if (!isInsideMaterialContainer) { + AddSourcePath(theAttValue, false); + theBuilder.AddSourcePath(theAttValue); + } + if (!masterSlide || isInsideMaterialContainer) m_slideSourcePaths.push_back(QString::fromLatin1(theAttValue)); } if (isSet == false && theIter->second.m_SlideForceFlag == false) { @@ -2251,10 +2336,14 @@ BOOL CUIPParserImpl::LoadSlideElementAttrs(IPresentation &inPresentation, bool m if (prop.m_DataType == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) { const char8_t *theAttValue = ""; bool hasAtt = inReader.UnregisteredAtt(prop.m_Name, theAttValue); - if (hasAtt && !IsTrivial(theAttValue) ) { - AddSourcePath(theAttValue, false); - theBuilder.AddSourcePath(theAttValue); - if (!masterSlide) + if (hasAtt && !IsTrivial(theAttValue)) { + m_sourcePathsById[QLatin1Char('#') + QString::fromUtf8(theRef)].append( + QString::fromUtf8(theAttValue)); + if (!isInsideMaterialContainer) { + AddSourcePath(theAttValue, false); + theBuilder.AddSourcePath(theAttValue); + } + if (!masterSlide || isInsideMaterialContainer) m_slideSourcePaths.push_back(QString::fromLatin1(theAttValue)); } } diff --git a/src/uipparser/Qt3DSUIPParserImpl.h b/src/uipparser/Qt3DSUIPParserImpl.h index f89227b..85f8c18 100644 --- a/src/uipparser/Qt3DSUIPParserImpl.h +++ b/src/uipparser/Qt3DSUIPParserImpl.h @@ -430,6 +430,11 @@ protected: TStringVector m_SourcePathList; TStringSet m_iblSources; QVector<QString> m_slideSourcePaths; + QVector<QString> m_materialContainerIds; + QHash<QString, QVector<QString>> m_imagesByMaterial; + QHash<QString, QVector<QString>> m_sourcePathsById; + QVector<QString> m_currentSlideReferencedMaterials; + QVector<QPair<qt3ds::runtime::SSlideKey, QVector<QString>>> m_referencedMaterialsBySlide; struct SElementRefCache { @@ -554,7 +559,7 @@ protected: // Operation bool initInRenderThread); BOOL LoadSceneGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader, qt3ds::runtime::element::SElement *inNewStyleParent, - bool initInRenderThread); + bool initInRenderThread, bool isInsideLayer = false); BOOL LoadLogic(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); BOOL LoadStateGraph(IPresentation &inPresentation, qt3dsdm::IDOMReader &inReader); |