diff options
author | Antti Määttä <antti.maatta@qt.io> | 2020-10-06 15:55:01 +0300 |
---|---|---|
committer | Antti Määttä <antti.maatta@qt.io> | 2020-10-15 12:11:51 +0300 |
commit | c6b698f5e2ea47e6e1e188ab653cd0fe67ed544b (patch) | |
tree | d73f51c9cb8059cba1bce1c10a49ccf8534923da /src/Authoring | |
parent | 30824ecce6f5ea94b65a6bf958060bc6df5b3745 (diff) |
Fix issues in dynamic object texture change
-Apply texture filter and repeat mode to the created image.
-Set the image names so that they work with setAttribute.
-Do not show default texture parameters in inspector.
-When dynamic object texture is set after being cleared, reset the texture
parameters from the default parameters.
-Ensure that the conversion of old-style dynamic objects is only done when
the UIP file version is old so that it happens only once. We do not wan't
to apply the default values for later sessions. Do not serialize dynamic
object default textures.
Task-number: QT3DS-4063
Change-Id: I5c9eed110999430ad95cda2354dbcc4b7795c136
Reviewed-by: Kaj Grönholm <kaj.gronholm@qt.io>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'src/Authoring')
6 files changed, 180 insertions, 31 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/Doc.cpp b/src/Authoring/Client/Code/Core/Doc/Doc.cpp index 484b20b6..453c2a91 100644 --- a/src/Authoring/Client/Code/Core/Doc/Doc.cpp +++ b/src/Authoring/Client/Code/Core/Doc/Doc.cpp @@ -2244,11 +2244,9 @@ int CDoc::LoadStudioData(CBufferedInputStream *inInputStream) CreateDOMReader(*inInputStream, theVersion); if (!theReaderPtr) throw CInvalidFileFormatException(); - + g_StudioApp.setDocumentVersion(theVersion); IDOMReader &theReader(*theReaderPtr); - theReader.Att("version", theVersion); - CProjectSettingsSerializer theProjectSettingsSerializer( m_Core->GetStudioProjectSettings()); theReader.Serialize(L"ProjectSettings", theProjectSettingsSerializer); @@ -2509,6 +2507,7 @@ void CDoc::SavePresentationFile(CBufferedOutputStream *inOutputStream) using namespace qt3dsdm; using namespace Q3DStudio; + g_StudioApp.setDocumentVersion(UIP_VERSION); std::shared_ptr<IDOMWriter> theWriterPtr(CreateDOMWriter()); IDOMWriter &theWriter(*theWriterPtr); diff --git a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp index bc42627f..60cc6dfb 100644 --- a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp +++ b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp @@ -95,6 +95,8 @@ #include "Qt3DSDMHandles.h" #include "IStudioRenderer.h" #include "Qt3DSRenderBufferManager.h" +#include "Qt3DSRenderDynamicObjectSystem.h" +#include "Qt3DSRenderUIPSharedTranslation.h" namespace { @@ -1437,6 +1439,24 @@ public: SetName(theMaterial, materialName); } + const dynamic::SPropertyDefinition *findDynamicProperty(const SMetaDataDynamicObject &dynObj, + CRegisteredString name) + { + for (int i = 0; i < dynObj.m_Properties.size(); i++) { + if (dynObj.m_Properties[i].m_Name == name) + return &dynObj.m_Properties[i]; + } + return nullptr; + } + + bool isDynamicObjectInstance(TInstanceHandle instance) const + { + return m_DataCore.IsInstanceOrDerivedFrom( + instance, m_Bridge.GetObjectDefinitions().m_CustomMaterial.m_Instance) + || m_DataCore.IsInstanceOrDerivedFrom( + instance, m_Bridge.GetObjectDefinitions().m_Effect.m_Instance); + } + // Normal way in to the system. void SetInstancePropertyValue(TInstanceHandle instance, TPropertyHandle propName, const SValue &value, bool inAutoDelete = true) override @@ -1451,20 +1471,58 @@ public: bool hasValue = theImageSourcePath && theImageSourcePath->GetLength() > 0; qt3dsdm::Qt3DSDMInstanceHandle theImageInstance = GetImageInstanceForProperty(instance, propName); + SMetaDataDynamicObject *dynObj = nullptr; + if (isDynamicObjectInstance(instance)) { + TInstanceHandleList parents; + m_DataCore.GetInstanceParents(instance, parents); + if (parents.size() > 0) + dynObj = m_MetaData.GetDynamicObjectByInstance(parents[0]); + } if (hasValue) { - if (theImageInstance.Valid() == false) + bool imageInstanceCreated = false; + if (theImageInstance.Valid() == false) { theImageInstance = CreateImageInstanceForMaterialOrLayer(instance, propName); + imageInstanceCreated = true; + } if (theImageInstance) { SetInstancePropertyValue(theImageInstance, m_Bridge.GetSourcePathProperty(), value, inAutoDelete); + SetInstancePropertyValue(theImageInstance, m_Bridge.GetNameProperty(), + std::make_shared<CDataStr>( + Q3DStudio::CString(thePropertySystem + .GetName(propName).wide_str()))); + if (dynObj && (g_StudioApp.IsConvertingPresentationOn() + || imageInstanceCreated)) { + // In this case we are just loading the presentation and need to convert old-style + // texture paths into images. + // Set the image defaults from the dynamic object + const dynamic::SPropertyDefinition *dynamicProperty + = findDynamicProperty(*dynObj, m_StringTable.GetRenderStringTable() + .RegisterStr(thePropertySystem.GetName(propName).c_str())); + m_PropertySystem.SetInstancePropertyValue(theImageInstance, + m_Bridge.GetObjectDefinitions().m_Image.m_MinFilter, + std::make_shared<CDataStr>( + Q3DStudio::CString(MapEnum(dynamicProperty->m_MinFilterOp)))); + m_PropertySystem.SetInstancePropertyValue(theImageInstance, + m_Bridge.GetObjectDefinitions().m_Image.m_MagFilter, + std::make_shared<CDataStr>( + Q3DStudio::CString(MapEnum(dynamicProperty->m_MagFilterOp)))); + m_PropertySystem.SetInstancePropertyValue(theImageInstance, + m_Bridge.GetObjectDefinitions().m_Image.m_TilingU, + std::make_shared<CDataStr>( + Q3DStudio::CString(MapEnum(dynamicProperty->m_CoordOp)))); + m_PropertySystem.SetInstancePropertyValue(theImageInstance, + m_Bridge.GetObjectDefinitions().m_Image.m_TilingV, + std::make_shared<CDataStr>( + Q3DStudio::CString(MapEnum(dynamicProperty->m_CoordOp)))); + } // Clear subpresentation value SetInstancePropertyValue(theImageInstance, m_Bridge.GetSceneImage().m_SubPresentation, std::make_shared<CDataStr>(Q3DStudio::CString()), inAutoDelete); } - } else { if (theImageInstance.Valid()) { TSlideHandle theInstanceSlide = GetAssociatedSlide(instance); @@ -4186,12 +4244,25 @@ public: theHandler->DisplayImportFailed(inSrcPath, resultDialogStr, true); } + template <typename T> + const wchar_t *MapEnum(T enumValue) { + SEnumNameMap *map = SEnumParseMap<T>::GetMap(); + while (map->m_Enum != -1) { + if (map->m_Enum == enumValue) + return map->m_WideName; + map = map + 1; + } + return nullptr; + } + // Apply meta data to a new dynamic instance. This sets up the default properties to // be what the meta data specifies. void ApplyDynamicMetaData(Qt3DSDMInstanceHandle inDynamicInstance, - Qt3DSDMInstanceHandle inDynamic) + Qt3DSDMInstanceHandle inDynamic, + const SMetaDataDynamicObject &dynObj) { std::vector<SMetaDataLoadWarning> theWarnings; + // For all of the object std::ref properties, check if they have an absolute path // reference (path starts with "Scene". If they do, then attempt to resolve the reference. vector<Qt3DSDMMetaDataPropertyHandle> theProperties; @@ -4271,12 +4342,40 @@ public: bool hasValue = theImageSourcePath && theImageSourcePath->GetLength() > 0; qt3dsdm::Qt3DSDMInstanceHandle theImageInstance = GetImageInstanceForProperty(inDynamicInstance, theInfo.m_Property); - if (hasValue) { + const dynamic::SPropertyDefinition *dynamicProperty + = findDynamicProperty(dynObj, m_StringTable.GetRenderStringTable(). + RegisterStr(theInfo.m_Name.wide_str())); + if (hasValue || (dynamicProperty && dynamicProperty->m_ImagePath.IsValid())) { if (!theImageInstance.Valid()) { theImageInstance = CreateImageInstanceForMaterialOrLayer( inDynamicInstance, theInfo.m_Property); + if (dynamicProperty) { + m_PropertySystem.SetInstancePropertyValue(theImageInstance, + m_Bridge.GetObjectDefinitions().m_Image.m_MinFilter, + std::make_shared<CDataStr>( + Q3DStudio::CString(MapEnum(dynamicProperty->m_MinFilterOp)))); + m_PropertySystem.SetInstancePropertyValue(theImageInstance, + m_Bridge.GetObjectDefinitions().m_Image.m_MagFilter, + std::make_shared<CDataStr>( + Q3DStudio::CString(MapEnum(dynamicProperty->m_MagFilterOp)))); + m_PropertySystem.SetInstancePropertyValue(theImageInstance, + m_Bridge.GetObjectDefinitions().m_Image.m_TilingU, + std::make_shared<CDataStr>( + Q3DStudio::CString(MapEnum(dynamicProperty->m_CoordOp)))); + m_PropertySystem.SetInstancePropertyValue(theImageInstance, + m_Bridge.GetObjectDefinitions().m_Image.m_TilingV, + std::make_shared<CDataStr>( + Q3DStudio::CString(MapEnum(dynamicProperty->m_CoordOp)))); + if (!hasValue) { + value = std::make_shared<CDataStr>( + Q3DStudio::CString(dynamicProperty->m_ImagePath.c_str())); + } + } } if (theImageInstance) { + SetInstancePropertyValue(theImageInstance, m_Bridge.GetNameProperty(), + std::make_shared<CDataStr>(Q3DStudio::CString( + m_PropertySystem.GetName(theInfo.m_Property).wide_str()))); SetInstancePropertyValue(theImageInstance, m_Bridge.GetSourcePathProperty(), value); // Clear subpresentation value @@ -4286,7 +4385,7 @@ public: } } else { m_DataCore.SetInstancePropertyValue(inDynamicInstance, theInfo.m_Property, - value); + make_shared<CDataStr>(Q3DStudio::CString())); } } } @@ -4356,11 +4455,12 @@ public: } } if (theParentInstance.Valid()) { + SMetaDataDynamicObject dynObj; TInstanceHandle retval(IDocumentEditor::CreateSceneGraphInstance( theParentInstance, inParent, inSlide, m_DataCore, m_SlideSystem, m_Bridge.GetObjectDefinitions(), m_AssetGraph, m_MetaData)); - ApplyDynamicMetaData(retval, theParentInstance); + ApplyDynamicMetaData(retval, theParentInstance, dynObj); if (inStartTime != -1) SetStartTime(retval, inStartTime); @@ -4555,7 +4655,6 @@ public: if (theRelativePath.toCString() == GetSourcePath(existing[idx])) theParentInstance = existing[idx]; } - if (theParentInstance.Valid() == false) { if (theShaderFile.Exists()) { theParentInstance = m_DataCore.CreateInstance(); @@ -4587,12 +4686,14 @@ public: return 0; } } + const SMetaDataDynamicObject *dynObj; + dynObj = m_MetaData.GetDynamicObjectByInstance(theParentInstance); TInstanceHandle retval(IDocumentEditor::CreateSceneGraphInstance( theParentInstance, inParent, inSlide, m_DataCore, m_SlideSystem, m_Bridge.GetObjectDefinitions(), m_AssetGraph, m_MetaData, inTargetId)); - ApplyDynamicMetaData(retval, theParentInstance); + ApplyDynamicMetaData(retval, theParentInstance, *dynObj); if (inStartTime != -1) SetStartTime(retval, inStartTime); diff --git a/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp b/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp index 47658c50..820c8faf 100644 --- a/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp +++ b/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp @@ -48,8 +48,11 @@ #include "Qt3DSRenderPathManager.h" #include "Qt3DSDMGuides.h" #include "foundation/Qt3DSLogging.h" +#include "Qt3DSRenderDynamicObjectSystem.h" + #include <unordered_map> #include <unordered_set> + #include <QtCore/qrandom.h> #include <QtCore/qdatetime.h> @@ -1688,6 +1691,11 @@ struct SComposerSerializerImpl : public IComposerSerializer // is to preserve behavior on old presentations that relied on hardcoding. bool hasMappingAsProbe = false; bool hasTilingH = false; + bool isDynamicObjectInstance + = m_DataCore.IsInstanceOrDerivedFrom(inInstance, + m_ObjectDefinitions.m_CustomMaterial.m_Instance) + || m_DataCore.IsInstanceOrDerivedFrom(inInstance, + m_ObjectDefinitions.m_Effect.m_Instance); for (size_t idx = 0, end = ioProperties.size(); idx < end; ++idx) { auto &prop = ioProperties[idx]; if (ioProperties[idx].first == m_ObjectDefinitions.m_Image.m_TilingU) @@ -1696,11 +1704,8 @@ struct SComposerSerializerImpl : public IComposerSerializer && ioProperties[idx].second.toQVariant() == QVariant("Light Probe")) { hasMappingAsProbe = true; } - if (prop.second.getType() == qt3dsdm::DataModelDataType::String && - (m_DataCore.IsInstanceOrDerivedFrom(inInstance, - m_ObjectDefinitions.m_CustomMaterial.m_Instance) - || m_DataCore.IsInstanceOrDerivedFrom(inInstance, - m_ObjectDefinitions.m_Effect.m_Instance))) { + if (prop.second.getType() == qt3dsdm::DataModelDataType::String + && isDynamicObjectInstance) { qt3dsdm::TDataStrPtr value = qt3dsdm::get<qt3dsdm::TDataStrPtr>(prop.second); QString string = QString::fromWCharArray(value->GetData()); if (string.startsWith(QLatin1Char('#'))) { @@ -1827,6 +1832,32 @@ struct SComposerSerializerImpl : public IComposerSerializer // Write out the properties for the active slide. TPropertyHandleValuePairList theValues; GetSpecificInstancePropertyValues(inInstance, theValues); + bool isDynamicObjectInstance + = m_DataCore.IsInstanceOrDerivedFrom(inInstance, + m_ObjectDefinitions.m_CustomMaterial.m_Instance) + || m_DataCore.IsInstanceOrDerivedFrom(inInstance, + m_ObjectDefinitions.m_Effect.m_Instance); + + if (isDynamicObjectInstance) { + // Remove default string values from serialized values + TInstanceHandleList parents; + m_DataCore.GetInstanceParents(inInstance, parents); + SMetaDataDynamicObject *dynObj = m_MetaData.GetDynamicObjectByInstance(parents[0]); + for (int i = 0; i < dynObj->m_Properties.size(); i++) { + auto &prop = dynObj->m_Properties[i]; + for (auto iter = theValues.begin(); iter != theValues.end(); iter++) { + const pair<Qt3DSDMPropertyHandle, SValue> &theValue(*iter); + TCharStr theName(m_DataCore.GetProperty(theValue.first).m_Name); + CRegisteredString name = m_StringTable.GetRenderStringTable() + .RegisterStr(theName.c_str()); + if (name == prop.m_Name && prop.m_DataType + == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + theValues.erase(iter); + break; + } + } + } + } SerializePropertyList(inWriter, theValues); if (theMasterRef.size()) diff --git a/src/Authoring/Qt3DStudio/Application/StudioApp.h b/src/Authoring/Qt3DStudio/Application/StudioApp.h index 7e4391a3..11e50138 100644 --- a/src/Authoring/Qt3DStudio/Application/StudioApp.h +++ b/src/Authoring/Qt3DStudio/Application/StudioApp.h @@ -263,10 +263,19 @@ public: { return m_convertPresentation; } + int getDocumentVersion() const + { + return m_docVersion; + } + void setDocumentVersion(int version) + { + m_docVersion = version; + } QString m_helpFilePath; QString m_gettingStartedFilePath; bool m_convertPresentation = false; + int m_docVersion = 0; QVector<SubPresentationRecord> m_subpresentations; QMap<QString, CDataInputDialogItem *> m_dataInputDialogItems; diff --git a/src/Authoring/Qt3DStudio/Palettes/Inspector/InspectorControlModel.cpp b/src/Authoring/Qt3DStudio/Palettes/Inspector/InspectorControlModel.cpp index 4a845425..4542f72d 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Inspector/InspectorControlModel.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/Inspector/InspectorControlModel.cpp @@ -1224,7 +1224,8 @@ void InspectorControlModel::updatePropertyValue(InspectorControlBase *element) c info = metaDataProvider->GetMetaDataPropertyInfo( metaDataProvider->GetMetaDataProperty(instance, element->m_property)); } - + bool isTexture = info.hasValue() + && info->GetAdditionalType() == qt3dsdm::AdditionalMetaDataType::Texture; bool skipEmits = false; switch (element->m_dataType) { case qt3dsdm::DataModelDataType::String: { @@ -1247,7 +1248,10 @@ void InspectorControlModel::updatePropertyValue(InspectorControlBase *element) c stringValue = stringValue.mid(index + 1); } - element->m_value = stringValue; + if (!isTexture) + element->m_value = stringValue; + else + element->m_value = {}; } } Q_FALLTHROUGH(); // fall-through for other String-derived datatypes @@ -1349,8 +1353,7 @@ void InspectorControlModel::updatePropertyValue(InspectorControlBase *element) c element->m_value = QVariant(QString()); } } else { - QFileInfo fileInfo(qt3dsdm::get<QString>(value)); - element->m_value = fileInfo.fileName(); + element->m_value = {}; } } else if (element->m_propertyType == qt3dsdm::AdditionalMetaDataType::PathBuffer) { element->m_value = qt3dsdm::get<QString>(value); diff --git a/src/Authoring/Qt3DStudio/Render/StudioRendererTranslation.cpp b/src/Authoring/Qt3DStudio/Render/StudioRendererTranslation.cpp index 7f7e9ea3..1aacdc7b 100644 --- a/src/Authoring/Qt3DStudio/Render/StudioRendererTranslation.cpp +++ b/src/Authoring/Qt3DStudio/Render/StudioRendererTranslation.cpp @@ -1170,17 +1170,23 @@ struct SDynamicObjectTranslator : public SGraphObjectTranslator qt3ds::render::ConvertWideUTF(theData->GetData(), 0, theStr); eastl::string theWorkspace; if (theDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - // Assume old style texture. This needs to be run trough document editor - Qt3DSDMInstanceHandle instance = GetInstanceHandle(); - Qt3DSDMPropertyHandle property = theProperty; - SValue value = theValue; - CDoc &doc = inContext.m_Doc; - QTimer::singleShot(10, [instance, property, value, &doc](){ - Q3DStudio::CUpdateableDocumentEditor updatableEditor(doc); - updatableEditor.EnsureEditor("Set Property", __FILE__, __LINE__) - .SetInstancePropertyValue(instance, property, value); - }); - g_StudioApp.SetConvertingPresentationOn(); + if (g_StudioApp.getDocumentVersion() < 7) { + // Old style texture. This needs to be run trough document editor + Qt3DSDMInstanceHandle instance = GetInstanceHandle(); + Qt3DSDMPropertyHandle property = theProperty; + SValue value = theValue; + CDoc &doc = inContext.m_Doc; + QTimer::singleShot(10, [instance, property, value, &doc](){ + Q3DStudio::CUpdateableDocumentEditor updatableEditor(doc); + updatableEditor.EnsureEditor("Set Property", __FILE__, + __LINE__) + .SetInstancePropertyValue(instance, property, + value); + }); + g_StudioApp.SetConvertingPresentationOn(); + } else { + // Ignore the value + } } else { dynObj.SetPropertyValue( theDefinition, theStr.c_str(), |