summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp')
-rw-r--r--src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp450
1 files changed, 336 insertions, 114 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp b/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp
index 07b24bc6..d3355260 100644
--- a/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp
+++ b/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp
@@ -48,9 +48,14 @@
#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>
+
using namespace qt3dsdm;
using namespace std;
using namespace Q3DStudio;
@@ -120,47 +125,60 @@ using std::hash;
template <typename TOperator>
static void HandleKeyframe(SLinearKeyframe &inKeyframe, TOperator &inOperator)
{
- inOperator(inKeyframe.m_KeyframeSeconds);
- inOperator(inKeyframe.m_KeyframeSeconds);
+ float kfTime = float(inKeyframe.m_time / 1000.f);
+
+ inOperator(kfTime);
+ inOperator(inKeyframe.m_value);
+
+ inKeyframe.m_time = long(kfTime * 1000.f);
}
template <typename TOperator>
static void HandleKeyframe(SBezierKeyframe &inKeyframe, TOperator &inOperator)
{
- inOperator(inKeyframe.m_KeyframeSeconds);
- inOperator(inKeyframe.m_KeyframeValue);
- inOperator(inKeyframe.m_InTangentTime);
+ float kfTime = float(inKeyframe.m_time / 1000.f);
+ float tangentInTime = float(inKeyframe.m_InTangentTime / 1000.f);
+ float tangentOutTime = float(inKeyframe.m_OutTangentTime / 1000.f);
+
+ inOperator(kfTime);
+ inOperator(inKeyframe.m_value);
+ inOperator(tangentInTime);
inOperator(inKeyframe.m_InTangentValue);
- inOperator(inKeyframe.m_OutTangentTime);
+ inOperator(tangentOutTime);
inOperator(inKeyframe.m_OutTangentValue);
+
+ inKeyframe.m_time = long(kfTime * 1000.f);
+ inKeyframe.m_InTangentTime = long(tangentInTime * 1000.f);
+ inKeyframe.m_OutTangentTime = long(tangentOutTime * 1000.f);
}
template <typename TOperator>
static void HandleKeyframe(SEaseInEaseOutKeyframe &inKeyframe, TOperator &inOperator)
{
- inOperator(inKeyframe.m_KeyframeSeconds);
- inOperator(inKeyframe.m_KeyframeValue);
+ float kfTime = float(inKeyframe.m_time / 1000.f);
+ inOperator(kfTime);
+ inOperator(inKeyframe.m_value);
inOperator(inKeyframe.m_EaseIn);
inOperator(inKeyframe.m_EaseOut);
+
+ inKeyframe.m_time = long(kfTime * 1000.f);
}
-template <typename TItemType>
-struct SVectorWriteOperator
+struct KeyframeWriter
{
- vector<TItemType> &m_Vector;
- SVectorWriteOperator(vector<TItemType> &vec)
- : m_Vector(vec)
+ vector<float> &m_vector;
+ KeyframeWriter(vector<float> &vec)
+ : m_vector(vec)
{
}
- void operator()(const TItemType &inValue) { m_Vector.push_back(inValue); }
+ void operator()(const float &inValue) { m_vector.push_back(inValue); }
};
-template <typename TItemType>
-struct SMemReadOperator
+struct KeyframeReader
{
- const TItemType *m_Ptr;
- const TItemType *m_End;
- SMemReadOperator(const TItemType *s, const TItemType *e)
+ const float *m_Ptr;
+ const float *m_End;
+ KeyframeReader(const float *s, const float *e)
: m_Ptr(s)
, m_End(e)
{
@@ -168,7 +186,7 @@ struct SMemReadOperator
bool IsDone() { return m_Ptr >= m_End; }
- void operator()(TItemType &outValue)
+ void operator()(float &outValue)
{
if (m_Ptr < m_End) {
outValue = *m_Ptr;
@@ -183,7 +201,7 @@ template <typename TKeyframeType>
static void WriteKeyframes(TKeyframeHandleList &inKeyframes, IAnimationCore &inCore,
vector<float> &outValues)
{
- SVectorWriteOperator<float> theOperator(outValues);
+ KeyframeWriter theOperator(outValues);
for (size_t idx = 0, end = inKeyframes.size(); idx < end; ++idx) {
TKeyframe theKeyframeVariant(inCore.GetKeyframeData(inKeyframes[idx]));
TKeyframeType theData(get<TKeyframeType>(theKeyframeVariant));
@@ -195,7 +213,7 @@ template <typename TKeyframeType>
static void ReadKeyframes(Qt3DSDMAnimationHandle inAnimation, IAnimationCore &inCore,
const float *inStart, const float *inEnd)
{
- SMemReadOperator<float> theOperator(inStart, inEnd);
+ KeyframeReader theOperator(inStart, inEnd);
while (theOperator.IsDone() == false) {
TKeyframeType theData;
HandleKeyframe(theData, theOperator);
@@ -290,22 +308,21 @@ struct SMetaDataPropertyEraser
};
using std::unordered_set;
using std::unordered_map;
-using std::tuple;
// Algorithm to write is to run through the graph, starting at the root instances
// and write out the instances as we come to them.
struct SComposerSerializerImpl : public IComposerSerializer
{
- typedef unordered_set<Qt3DSDMInstanceHandle, hash<int>> TInstanceSet;
- typedef unordered_set<Qt3DSDMSlideHandle, hash<int>> TSlideSet;
- typedef unordered_set<Qt3DSDMActionHandle, hash<int>> TActionSet;
- typedef vector<Qt3DSDMInstanceHandle> TInstanceList;
typedef unordered_map<int, TCharPtr> THandleToIdMap;
typedef unordered_map<TCharPtr, int> TIdToHandleMap;
typedef unordered_map<SLong4, int> TGUIDToHandleMap;
typedef unordered_map<int, SLong4> THandleToGUIDMap;
typedef unordered_map<Qt3DSDMInstanceHandle, int, hash<int>> TInstanceIntMap;
typedef unordered_map<Qt3DSDMInstanceHandle, TCharPtr, hash<int>> TInstanceToSiblingMap;
+ typedef unordered_set<Qt3DSDMInstanceHandle, hash<int>> TInstanceSet;
+ typedef unordered_set<Qt3DSDMSlideHandle, hash<int>> TSlideSet;
+ typedef unordered_set<Qt3DSDMActionHandle, hash<int>> TActionSet;
+ typedef vector<Qt3DSDMInstanceHandle> TInstanceList;
IDataCore &m_DataCore;
IMetaData &m_MetaData;
@@ -323,19 +340,16 @@ struct SComposerSerializerImpl : public IComposerSerializer
qt3ds::render::IPathManager &m_PathManager;
IPropertySystem &m_propertySystem;
- // The instances we have discovered when we are writing
+ Qt3DSDMSlideHandle m_ActiveSlide;
+ Qt3DSDMSlideHandle m_ActiveSlideParent;
+
+ // The unique ids for instances
THandleToIdMap m_HandleToIdMap;
TIdToHandleMap m_IdToHandleMap;
-
TGUIDToHandleMap m_GUIDToHandleMap;
THandleToGUIDMap m_HandleToGUIDMap;
-
- Qt3DSDMSlideHandle m_ActiveSlide;
- Qt3DSDMSlideHandle m_ActiveSlideParent;
-
THandleToIdMap m_ActionToIdMap;
TIdToHandleMap m_IdToActionMap;
-
THandleToIdMap m_SlideToIdMap;
TIdToHandleMap m_IdToSlideMap;
@@ -365,6 +379,9 @@ struct SComposerSerializerImpl : public IComposerSerializer
Option<int> m_UIPVersion;
+ QRandomGenerator m_randomGenerator;
+ QString m_documentPath;
+
SComposerSerializerImpl(IDataCore &inDataCore, IMetaData &inMetaData, ISlideCore &inSlideCore,
IAnimationCore &inAnimationCore, IActionCore &inActionCore,
CGraph &inAssetGraph, ISlideSystem &inSlideSystem,
@@ -372,7 +389,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
SComposerObjectDefinitions &inObjectDefinitions,
std::shared_ptr<Q3DStudio::IImportFailedHandler> inFailedHandler,
IGuideSystem &inGuideSystem, qt3ds::render::IPathManager &inPathManager,
- IPropertySystem &inPropSystem)
+ IPropertySystem &inPropSystem, const QString &documentPath)
: m_DataCore(inDataCore)
, m_MetaData(inMetaData)
, m_SlideCore(inSlideCore)
@@ -391,7 +408,9 @@ struct SComposerSerializerImpl : public IComposerSerializer
, m_Foundation(Q3DStudio::Foundation::SStudioFoundation::Create())
, m_InputStreamFactory(qt3ds::render::IInputStreamFactory::Create(*m_Foundation.m_Foundation))
, m_PreserveFileIds(true)
+ , m_documentPath(documentPath)
{
+ m_randomGenerator.seed(quint32(QTime::currentTime().msecsSinceStartOfDay()));
}
void reset()
@@ -402,15 +421,15 @@ struct SComposerSerializerImpl : public IComposerSerializer
m_GUIDToHandleMap.clear();
m_HandleToGUIDMap.clear();
- m_ActiveSlide = 0;
- m_ActiveSlideParent = 0;
-
m_ActionToIdMap.clear();
m_IdToActionMap.clear();
m_SlideToIdMap.clear();
m_IdToSlideMap.clear();
+ m_ActiveSlide = 0;
+ m_ActiveSlideParent = 0;
+
m_InstanceSet.clear();
m_SlideSet.clear();
m_ExternalReferences.clear();
@@ -430,6 +449,13 @@ struct SComposerSerializerImpl : public IComposerSerializer
TCharPtr AddId(const wstring &inId, Qt3DSDMInstanceHandle inHandle)
{
TCharPtr theIdStr = m_StringTable.RegisterStr(inId.c_str());
+ if (m_IdToHandleMap.find(theIdStr) != m_IdToHandleMap.end()
+ && m_IdToHandleMap.find(theIdStr)->second != inHandle) {
+ m_ImportFailedHandler->DisplayImportFailed(
+ m_documentPath, QObject::tr("Duplicate object id detected: ")
+ + QString::fromWCharArray(theIdStr), false);
+ return theIdStr;
+ }
m_IdToHandleMap.insert(make_pair(theIdStr, inHandle));
m_HandleToIdMap.insert(make_pair(inHandle, theIdStr));
if (m_PreserveFileIds)
@@ -452,16 +478,39 @@ struct SComposerSerializerImpl : public IComposerSerializer
TCharPtr AddActionId(const wstring &inId, Qt3DSDMActionHandle inHandle)
{
TCharPtr theIdStr = m_StringTable.RegisterStr(inId.c_str());
+ if (m_IdToActionMap.find(theIdStr) != m_IdToActionMap.end()
+ && m_IdToActionMap.find(theIdStr)->second != inHandle) {
+ m_ImportFailedHandler->DisplayImportFailed(
+ m_documentPath, QObject::tr("Duplicate action id detected: ")
+ + QString::fromWCharArray(theIdStr), false);
+ return theIdStr;
+ }
m_IdToActionMap.insert(make_pair(theIdStr, inHandle));
m_ActionToIdMap.insert(make_pair(inHandle, theIdStr));
+ if (m_PreserveFileIds) {
+ m_DataCore.SetInstancePropertyValue(m_ActionCore.GetActionInstance(inHandle),
+ m_ObjectDefinitions.m_Action.m_FileId,
+ std::make_shared<CDataStr>(inId.c_str()));
+ }
return theIdStr;
}
TCharPtr AddSlideId(const wstring &inId, Qt3DSDMSlideHandle inHandle)
{
TCharPtr theIdStr = m_StringTable.RegisterStr(inId.c_str());
+ if (m_IdToActionMap.find(theIdStr) != m_IdToActionMap.end()
+ && m_IdToActionMap.find(theIdStr)->second != inHandle) {
+ m_ImportFailedHandler->DisplayImportFailed(
+ m_documentPath, QObject::tr("Duplicate slide id detected: ")
+ + QString::fromWCharArray(theIdStr), false);
+ return theIdStr;
+ }
m_IdToSlideMap.insert(make_pair(theIdStr, inHandle));
m_SlideToIdMap.insert(make_pair(inHandle, theIdStr));
+ if (m_PreserveFileIds)
+ m_DataCore.SetInstancePropertyValue(m_SlideCore.GetSlideInstance(inHandle),
+ m_ObjectDefinitions.m_Slide.m_FileId,
+ std::make_shared<CDataStr>(inId.c_str()));
return theIdStr;
}
@@ -569,30 +618,69 @@ struct SComposerSerializerImpl : public IComposerSerializer
return GetInstanceName(inInstance);
}
- TCharPtr GetId(const wstring &inIdStem)
+ TCharPtr GetId(const wstring &inIdStem, CDataModelHandle instance)
{
// Create an ID for this instance
- wstring theTypeStr(inIdStem);
- wstring theTypeStem(theTypeStr);
- wstring::size_type thePos = theTypeStem.find_last_of('_');
- if (thePos != wstring::npos && thePos < theTypeStem.size() - 2) {
- if (theTypeStem[thePos + 1] >= '0' && theTypeStem[thePos + 1] <= '1')
- theTypeStem = theTypeStem.substr(0, thePos);
- }
- QT3DSU32 idIdx = 1;
+ if (m_PreserveFileIds) {
+ // permanent id
+ QString stem = instanceId(instance);
+ if (stem.isEmpty())
+ stem = QString::fromWCharArray(inIdStem.c_str());
+ int pos = stem.lastIndexOf(QLatin1Char('_'));
+ if (pos > 0) {
+ // Already has unique id
+ bool isNumber;
+ stem.mid(pos+2).toInt(&isNumber);
+ if (stem.at(pos+1) == QLatin1Char('u') && isNumber) {
+ QByteArray warr;
+ warr.resize(sizeof(wchar_t) * (stem.length() + 1));
+ warr.fill(0);
+ stem.toWCharArray(reinterpret_cast<wchar_t *>(warr.data()));
+ return m_StringTable.RegisterStr(reinterpret_cast<wchar_t *>(warr.data()));
+ }
+ }
- while (m_IdToActionMap.find(m_StringTable.RegisterStr(theTypeStr.c_str()))
- != m_IdToActionMap.end()
- || m_IdToHandleMap.find(m_StringTable.RegisterStr(theTypeStr.c_str()))
- != m_IdToHandleMap.end()
- || m_IdToSlideMap.find(m_StringTable.RegisterStr(theTypeStr.c_str()))
- != m_IdToSlideMap.end()) {
- wchar_t theBuffer[16];
- swprintf(theBuffer, 16, L"_%03d", idIdx);
- theTypeStr = theTypeStem + theBuffer;
- ++idIdx;
+ // Create an ID for this instance
+ QByteArray buffer;
+ wchar_t *str;
+ do {
+ int rid = m_randomGenerator.bounded(65536);
+ QString nid = QStringLiteral("%1_u%2").arg(stem).arg(rid);
+ buffer.resize((nid.length() + 1) * sizeof(wchar_t));
+ buffer.fill(0);
+ str = reinterpret_cast<wchar_t *>(buffer.data());
+ nid.toWCharArray(str);
+ } while (m_IdToActionMap.find(m_StringTable.RegisterStr(str)) != m_IdToActionMap.end()
+ || m_IdToHandleMap.find(m_StringTable.RegisterStr(str))
+ != m_IdToHandleMap.end()
+ || m_IdToSlideMap.find(m_StringTable.RegisterStr(str))
+ != m_IdToSlideMap.end());
+
+ return m_StringTable.RegisterStr(str);
+ } else {
+ // temporary id
+ wstring theTypeStr(inIdStem);
+ wstring theTypeStem(theTypeStr);
+ wstring::size_type thePos = theTypeStem.find_last_of('_');
+ if (thePos != wstring::npos && thePos < theTypeStem.size() - 2) {
+ if (theTypeStem[thePos + 1] >= '0' && theTypeStem[thePos + 1] <= '9')
+ theTypeStem = theTypeStem.substr(0, thePos);
+ }
+ QT3DSU32 idIdx = 1;
+
+ while (m_IdToActionMap.find(m_StringTable.RegisterStr(theTypeStr.c_str()))
+ != m_IdToActionMap.end()
+ || m_IdToHandleMap.find(m_StringTable.RegisterStr(theTypeStr.c_str()))
+ != m_IdToHandleMap.end()
+ || m_IdToSlideMap.find(m_StringTable.RegisterStr(theTypeStr.c_str()))
+ != m_IdToSlideMap.end()) {
+ wchar_t theBuffer[16];
+ swprintf(theBuffer, 16, L"_%03d", idIdx);
+ theTypeStr = theTypeStem + theBuffer;
+ ++idIdx;
+ }
+ return m_StringTable.RegisterStr(theTypeStr.c_str());
}
- return m_StringTable.RegisterStr(theTypeStr.c_str());
}
TCharPtr GetInstanceId(Qt3DSDMInstanceHandle inInstance)
@@ -647,13 +735,13 @@ struct SComposerSerializerImpl : public IComposerSerializer
}
if (theProperty.Valid()) {
theIdStr.append(m_DataCore.GetProperty(theProperty).m_Name.wide_str());
- theNewId = GetId(theIdStr);
+ theNewId = GetId(theIdStr, inInstance);
}
}
}
if (IsTrivial(theNewId))
- theNewId = GetId(theName.wide_str());
+ theNewId = GetId(theName.wide_str(), inInstance);
return AddId(theNewId, inInstance);
}
@@ -667,13 +755,23 @@ struct SComposerSerializerImpl : public IComposerSerializer
wstring theActionName(GetInstanceName(inInstance, inSlide));
theActionName.append(L"-Action");
-
- TCharPtr theNewId = GetId(theActionName);
+ TCharPtr theNewId;
+ if (m_PreserveFileIds) {
+ Qt3DSDMInstanceHandle actionInstance = m_ActionCore.GetActionInstance(inAction);
+ SValue theValue;
+ if (m_DataCore.GetInstancePropertyValue(
+ actionInstance, m_ObjectDefinitions.m_Action.m_FileId, theValue)) {
+ TDataStrPtr fileId(get<TDataStrPtr>(theValue));
+ theNewId = fileId->GetData();
+ if (!IsTrivial(theNewId))
+ return AddSlideId(GetId(theNewId, actionInstance), inSlide);
+ return AddSlideId(GetId(theActionName, actionInstance), inSlide);
+ }
+ }
+ theNewId = GetId(theActionName, inInstance);
return AddActionId(theNewId, inAction);
}
- // If this function is called with an invalid instance and we don't already have an id
- // then we assume we have an external reference and lookup the instance via the component id.
TCharPtr GetSlideId(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance)
{
QT3DS_ASSERT(inSlide.Valid());
@@ -697,7 +795,21 @@ struct SComposerSerializerImpl : public IComposerSerializer
theSlideName.append(L"-");
theSlideName.append(GetSlideName(inSlide));
- TCharPtr theNewId = GetId(theSlideName);
+ TCharPtr theNewId;
+ if (m_PreserveFileIds) {
+ Qt3DSDMInstanceHandle slideInstance = m_SlideCore.GetSlideInstance(inSlide);
+ SValue theValue;
+ if (m_DataCore.GetInstancePropertyValue(
+ slideInstance, m_ObjectDefinitions.m_Slide.m_FileId, theValue)) {
+ TDataStrPtr fileId(get<TDataStrPtr>(theValue));
+ theNewId = fileId->GetData();
+ if (!IsTrivial(theNewId))
+ return AddSlideId(GetId(theNewId, slideInstance), inSlide);
+ return AddSlideId(GetId(theSlideName, slideInstance), inSlide);
+ }
+ }
+
+ theNewId = GetId(theSlideName, inInstance);
return AddSlideId(theNewId, inSlide);
}
@@ -721,6 +833,24 @@ struct SComposerSerializerImpl : public IComposerSerializer
return SLong4();
}
+ QString instanceId(CDataModelHandle inInstance) {
+ SValue theInstanceIdValue;
+ TDataStrPtr theNamePtr;
+ if (!m_DataCore.GetInstancePropertyValue(
+ inInstance, m_ObjectDefinitions.m_Asset.m_FileId, theInstanceIdValue)) {
+ if (!m_DataCore.GetInstancePropertyValue(
+ inInstance, m_ObjectDefinitions.m_Slide.m_FileId, theInstanceIdValue)) {
+ m_DataCore.GetInstancePropertyValue(
+ inInstance, m_ObjectDefinitions.m_Action.m_FileId, theInstanceIdValue);
+ }
+ }
+ theNamePtr = qt3dsdm::get<TDataStrPtr>(theInstanceIdValue);
+ if (theNamePtr && !IsTrivial(theNamePtr->GetData()))
+ return theNamePtr->toQString();
+ return {};
+ }
+
+
void GetAllInstanceGuids()
{
TInstanceHandleList theInstances;
@@ -739,9 +869,23 @@ struct SComposerSerializerImpl : public IComposerSerializer
theInstance, m_ObjectDefinitions.m_Asset.m_FileId, theInstanceIdValue)) {
TDataStrPtr theNamePtr = qt3dsdm::get<TDataStrPtr>(theInstanceIdValue);
if (theNamePtr && !IsTrivial(theNamePtr->GetData())) {
- const wchar_t *theId = GetId(theNamePtr->GetData());
+ const wchar_t *theId = GetId(theNamePtr->GetData(), theInstance);
AddId(theId, theInstance);
}
+ } else if (m_DataCore.GetInstancePropertyValue(
+ theInstance, m_ObjectDefinitions.m_Slide.m_FileId, theInstanceIdValue)) {
+ TDataStrPtr theNamePtr = qt3dsdm::get<TDataStrPtr>(theInstanceIdValue);
+ if (theNamePtr && !IsTrivial(theNamePtr->GetData())) {
+ const wchar_t *theId = GetId(theNamePtr->GetData(), theInstance);
+ AddSlideId(theId, theInstance);
+ }
+ } else if (m_DataCore.GetInstancePropertyValue(
+ theInstance, m_ObjectDefinitions.m_Action.m_FileId, theInstanceIdValue)) {
+ TDataStrPtr theNamePtr = qt3dsdm::get<TDataStrPtr>(theInstanceIdValue);
+ if (theNamePtr && !IsTrivial(theNamePtr->GetData())) {
+ const wchar_t *theId = GetId(theNamePtr->GetData(), theInstance);
+ AddActionId(theId, theInstance);
+ }
}
}
}
@@ -834,9 +978,15 @@ struct SComposerSerializerImpl : public IComposerSerializer
} else {
m_TempBuffer.clear();
WCharTWriter theWriter(m_TempBuffer);
- WStrOps<SValue>().ToBuf(theValue, theWriter);
-
- if (GetValueType(theValue) == DataModelDataType::String || m_TempBuffer.size()) {
+ if (theValueType == DataModelDataType::String || !theValue.empty()) {
+ // QT3DS-3993: store line feeds as replacement chars in UIP
+ if (theValueType == DataModelDataType::String) {
+ TDataStrPtr strPtr = get<TDataStrPtr>(theValue);
+ auto strValue = QString::fromWCharArray(strPtr->GetData());
+ strValue.replace("\n", LINE_BREAK_SUBSTITUTE);
+ theValue = std::make_shared<CDataStr>(CString::fromQString(strValue));
+ }
+ WStrOps<SValue>().ToBuf(theValue, theWriter);
char buffer[] = { 0, 0, 0, 0 };
m_TempBuffer.write(buffer, 4);
theValueStr.assign((const wchar_t *)m_TempBuffer.begin());
@@ -865,8 +1015,13 @@ struct SComposerSerializerImpl : public IComposerSerializer
return SStringOrInt(std::make_shared<CDataStr>(inValue));
}
- if (inType == DataModelDataType::String)
- return std::make_shared<CDataStr>(inValue);
+ if (inType == DataModelDataType::String) {
+ // QT3DS-3993: store line feeds as replacement chars in UIP
+ auto valueStr = std::make_shared<CDataStr>(inValue);
+ auto val = QString::fromStdWString(valueStr->GetData());
+ val.replace(LINE_BREAK_SUBSTITUTE, "\n");
+ return std::make_shared<CDataStr>(CString::fromQString(val));
+ }
qt3ds::foundation::ConvertUTF(
reinterpret_cast<const qt3ds::foundation::TWCharEASTLConverter::TCharType *>(inValue), 0,
@@ -916,6 +1071,19 @@ struct SComposerSerializerImpl : public IComposerSerializer
}
}
+ SLong4 ParseGUID(TCharPtr inValue)
+ {
+ // One of two things, either an ID reference *or* pure string.
+ if (IsTrivial(inValue))
+ return SLong4();
+ if (inValue[0] == '#') {
+ // absolute reference.
+ Qt3DSDMInstanceHandle theInstance = GetInstanceById(inValue + 1);
+ return theInstance.Valid() ? GetInstanceGuid(theInstance) : SLong4();
+ }
+ return SLong4();
+ }
+
void SerializePropertyList(qt3dsdm::IDOMWriter &inWriter, TPropertyHandleValuePairList &inList)
{
sort(inList.begin(), inList.end(), SAttributeNameSorter(m_DataCore));
@@ -977,7 +1145,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
SMetaDataPropertyInfo thePropertyInfo(
m_MetaData.GetMetaDataPropertyInfo(theMetaDataProperty));
wstring theName = thePropertyInfo.m_Name.wide_str();
- size_t theArity = get<1>(GetDatatypeAnimatableAndArity(thePropertyInfo.GetDataType()));
+ size_t theArity = getDatatypeAnimatableArity(thePropertyInfo.GetDataType());
if (theArity > 1) {
theName.append(L".");
switch (theInfo.m_Index) {
@@ -1081,12 +1249,8 @@ struct SComposerSerializerImpl : public IComposerSerializer
return;
}
SMetaDataPropertyInfo theInfo(m_MetaData.GetMetaDataPropertyInfo(theProperty));
- std::tuple<bool, size_t> theAnimAndArity = GetDatatypeAnimatableAndArity(theInfo.GetDataType());
- if (std::get<0>(theAnimAndArity) == false) {
- QT3DS_ASSERT(false);
- return;
- }
- if (std::get<1>(theAnimAndArity) <= subIndex) {
+ size_t theArity = getDatatypeAnimatableArity(theInfo.GetDataType());
+ if (theArity == 0 || theArity <= subIndex) {
QT3DS_ASSERT(false);
return;
}
@@ -1470,6 +1634,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
erase_if(outList, SPropertyMatches(m_ObjectDefinitions.m_Slide.m_ComponentId));
erase_if(outList, SPropertyMatches(m_ObjectDefinitions.m_Named.m_NameProp));
erase_if(outList, SPropertyMatches(m_ObjectDefinitions.m_Typed.m_TypeProp));
+ erase_if(outList, SPropertyMatches(m_ObjectDefinitions.m_Slide.m_FileId));
}
Option<pair<Qt3DSDMPropertyHandle, SValue>> ParseValue(Qt3DSDMInstanceHandle inInstance,
@@ -1485,7 +1650,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
}
void ParseInstanceProperties(IDOMReader &inReader, Qt3DSDMInstanceHandle inInstance,
- vector<pair<TCharPtr, TCharPtr>> &outExtraAttributes,
+ QVector<pair<TCharPtr, TCharPtr>> &outExtraAttributes,
TPropertyHandleValuePairList &outProperties)
{
bool hasNoLifetime =
@@ -1512,7 +1677,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
void ParseAndSetInstanceProperties(IDOMReader &inReader, Qt3DSDMSlideHandle inSlide,
Qt3DSDMInstanceHandle inInstance,
- vector<pair<TCharPtr, TCharPtr>> &outExtraAttributes,
+ QVector<pair<TCharPtr, TCharPtr>> &outExtraAttributes,
TPropertyHandleValuePairList &ioProperties)
{
outExtraAttributes.clear();
@@ -1526,13 +1691,28 @@ 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)
hasTilingH = true;
if (ioProperties[idx].first == m_ObjectDefinitions.m_Image.m_TextureMapping
&& ioProperties[idx].second.toQVariant() == QVariant("Light Probe")) {
hasMappingAsProbe = true;
}
+ 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('#'))) {
+ SLong4 guid = ParseGUID(value->GetData());
+ prop.second = SValue(guid);
+ }
+ }
}
if (!hasTilingH && hasMappingAsProbe) {
@@ -1652,6 +1832,34 @@ 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]);
+ if (!dynObj)
+ return false;
+ 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())
@@ -1742,10 +1950,6 @@ struct SComposerSerializerImpl : public IComposerSerializer
m_NewInstancesToSiblings.insert(std::make_pair(theNewInstance, theSiblingRef + 1));
SLong4 theGuid = GetGuid(theNewInstance, m_ObjectDefinitions.m_Guided.m_GuidProp);
- if (m_PreserveFileIds)
- m_DataCore.SetInstancePropertyValue(theNewInstance,
- m_ObjectDefinitions.m_Asset.m_FileId,
- std::make_shared<CDataStr>(theId));
SetId(theId, theNewInstance);
AddGuid(theGuid, theNewInstance);
@@ -1786,7 +1990,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
}
TPropertyHandleValuePairList theValues;
- vector<pair<TCharPtr, TCharPtr>> theExtraAtts;
+ QVector<pair<TCharPtr, TCharPtr>> theExtraAtts;
ParseAndSetInstanceProperties(inReader, 0, theNewInstance, theExtraAtts, theValues);
ReadInstanceProperties(inReader);
@@ -2109,7 +2313,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
{
IDOMReader::Scope __stateScope(inReader);
TPropertyHandleValuePairList theValues;
- vector<pair<TCharPtr, TCharPtr>> theExtraAtts;
+ QVector<pair<TCharPtr, TCharPtr>> theExtraAtts;
ParseAndSetInstanceProperties(inReader, 0, m_SlideCore.GetSlideInstance(inSlide),
theExtraAtts, theValues);
// Slides require a two-pass parsing system because slides can refer to each other via id.
@@ -2385,7 +2589,8 @@ struct SComposerSerializerImpl : public IComposerSerializer
}
void DoSerializeScene(IDOMWriter &inWriter, const Qt3DSDMInstanceHandle *inTopInstances,
- QT3DSU32 inCount, bool inWriteParentRefs = false)
+ QT3DSU32 inCount, bool inWriteParentRefs = false,
+ const Q3DStudio::CFilePath *inDocumentDirectory = nullptr)
{
GetAllInstanceGuids();
{
@@ -2411,15 +2616,27 @@ struct SComposerSerializerImpl : public IComposerSerializer
QT3DS_ASSERT(false);
continue;
}
- IDOMWriter::Scope instScope(inWriter, theType->wide_str());
- inWriter.Att(L"id", GetInstanceId(theMaster));
- // Write out all the properties that are on the instance but are not on *this*
- // instance in the meta data.
- TPropertyHandleValuePairList theProperties;
- GetSpecificInstancePropertyValues(theMaster, theProperties);
- erase_if(theProperties,
- SMetaDataPropertyEraser(theMaster, m_ObjectDefinitions));
- SerializePropertyList(inWriter, theProperties);
+ SValue value;
+ m_DataCore.GetInstancePropertyValue(theMaster,
+ m_ObjectDefinitions.m_Asset.m_SourcePath,
+ value);
+ if (!value.empty()) {
+ CFilePath sourcePath(value.getData<qt3dsdm::TDataStrPtr>()->GetData());
+ CFilePath theFullPath = CFilePath::CombineBaseAndRelative(
+ (inDocumentDirectory ? (*inDocumentDirectory) : CFilePath()),
+ sourcePath);
+ if (!inDocumentDirectory || theFullPath.Exists()) {
+ IDOMWriter::Scope instScope(inWriter, theType->wide_str());
+ inWriter.Att(L"id", GetInstanceId(theMaster));
+ // Write out all the properties that are on the instance but are not on *this*
+ // instance in the meta data.
+ TPropertyHandleValuePairList theProperties;
+ GetSpecificInstancePropertyValues(theMaster, theProperties);
+ erase_if(theProperties,
+ SMetaDataPropertyEraser(theMaster, m_ObjectDefinitions));
+ SerializePropertyList(inWriter, theProperties);
+ }
+ }
}
}
inWriter.MoveBefore(L"Classes", L"Graph");
@@ -2517,7 +2734,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
theMaster = m_DataCore.CreateInstance();
m_DataCore.DeriveInstance(theMaster, theCanonicalType);
TPropertyHandleValuePairList theValues;
- vector<pair<TCharPtr, TCharPtr>> theExtraAtts;
+ QVector<pair<TCharPtr, TCharPtr>> theExtraAtts;
m_SourcePathToMasterInstances.insert(
make_pair(m_StringTable.RegisterStr(theSourcePath), theMaster));
@@ -2676,7 +2893,8 @@ struct SComposerSerializerImpl : public IComposerSerializer
}
};
- void SerializeScene(IDOMWriter &inWriter) override
+ void SerializeScene(IDOMWriter &inWriter,
+ const Q3DStudio::CFilePath &inDocumentDirectory) override
{
reset();
ScopedPreserveFileIds __preserveFileIds(m_PreserveFileIds);
@@ -2690,7 +2908,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
if (theGraphRoots.empty())
return;
QT3DS_ASSERT(theGraphRoots.size() == 1);
- DoSerializeScene(inWriter, &theGraphRoots[0], 1);
+ DoSerializeScene(inWriter, &theGraphRoots[0], 1, false, &inDocumentDirectory);
TGuideHandleList theGuides = m_GuideSystem.GetAllGuides();
// sort the guides by handle value to keep the file as stable as possible.
std::sort(theGuides.begin(), theGuides.end());
@@ -2735,26 +2953,28 @@ struct SComposerSerializerImpl : public IComposerSerializer
// new root.
virtual qt3dsdm::TInstanceHandleList
SerializeSceneGraphObject(IDOMReader &inReader, const CFilePath &inDocumentDirectory,
- Qt3DSDMInstanceHandle inNewRoot, Qt3DSDMSlideHandle inActiveSlide) override
+ Qt3DSDMInstanceHandle inNewRoot, Qt3DSDMSlideHandle inActiveSlide,
+ bool preserveFileIds) override
{
reset();
m_ActiveSlide = inActiveSlide;
- m_PreserveFileIds = false;
+ m_PreserveFileIds = preserveFileIds;
return DoSerializeScene(inReader, inDocumentDirectory, inNewRoot);
}
// Write this instance and its children (and possibly its slides) to a writer.
// Equivalent to the older partial serialization system
void SerializeSceneGraphObjects(IDOMWriter &inWriter,
- const TInstanceHandleList &inInstances,
- Qt3DSDMSlideHandle inActiveSlide) override
+ const TInstanceHandleList &inInstances,
+ Qt3DSDMSlideHandle inActiveSlide,
+ bool preserveFileIds) override
{
if (inInstances.empty())
return;
reset();
QT3DS_ASSERT(inActiveSlide.Valid());
m_ActiveSlide = inActiveSlide;
- m_PreserveFileIds = false;
+ m_PreserveFileIds = preserveFileIds;
// It is fine if the parent is invalid
m_ActiveSlideParent = m_SlideCore.GetParentSlide(m_ActiveSlide);
DoSerializeScene(inWriter, inInstances.data(), (QT3DSU32)inInstances.size());
@@ -2844,8 +3064,8 @@ struct SComposerSerializerImpl : public IComposerSerializer
}
Qt3DSDMSlideHandle SerializeSlide(qt3dsdm::IDOMReader &inReader,
- const CFilePath &inDocumentDirectory,
- qt3dsdm::Qt3DSDMSlideHandle inMaster, int newIndex) override
+ const CFilePath &inDocumentDirectory,
+ qt3dsdm::Qt3DSDMSlideHandle inMaster, int newIndex) override
{
reset();
m_PreserveFileIds = false;
@@ -2867,13 +3087,15 @@ struct SComposerSerializerImpl : public IComposerSerializer
std::shared_ptr<IComposerSerializer> IComposerSerializer::CreateGraphSlideSerializer(
IDataCore &inDataCore, IMetaData &inMetaData, ISlideCore &inSlideCore,
IAnimationCore &inAnimationCore, IActionCore &inActionCore, CGraph &inAssetGraph,
- ISlideSystem &inSlideSystem, IActionSystem &inActionSystem, ISlideGraphCore &inSlideGraphCore,
- SComposerObjectDefinitions &inObjectDefinitions,
- std::shared_ptr<Q3DStudio::IImportFailedHandler> inFailedHandler, IGuideSystem &inGuideSystem,
- qt3ds::render::IPathManager &inPathManager, IPropertySystem &inPropSystem)
+ ISlideSystem &inSlideSystem, IActionSystem &inActionSystem,
+ ISlideGraphCore &inSlideGraphCore, SComposerObjectDefinitions &inObjectDefinitions,
+ std::shared_ptr<Q3DStudio::IImportFailedHandler> inFailedHandler,
+ IGuideSystem &inGuideSystem, qt3ds::render::IPathManager &inPathManager,
+ IPropertySystem &inPropSystem, const QString &documentPath)
{
- return std::shared_ptr<SComposerSerializerImpl>(new SComposerSerializerImpl(
- inDataCore, inMetaData, inSlideCore, inAnimationCore, inActionCore, inAssetGraph,
- inSlideSystem, inActionSystem, inSlideGraphCore, inObjectDefinitions, inFailedHandler,
- inGuideSystem, inPathManager, inPropSystem));
+ return std::shared_ptr<SComposerSerializerImpl>(
+ new SComposerSerializerImpl(
+ inDataCore, inMetaData, inSlideCore, inAnimationCore, inActionCore, inAssetGraph,
+ inSlideSystem, inActionSystem, inSlideGraphCore, inObjectDefinitions, inFailedHandler,
+ inGuideSystem, inPathManager, inPropSystem, documentPath));
}