summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp')
-rw-r--r--src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp709
1 files changed, 513 insertions, 196 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
index ac3c3b31..f2627e05 100644
--- a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
+++ b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
@@ -92,6 +92,11 @@
#include "StudioProjectSettings.h"
#include "StudioApp.h"
#include "StudioUtils.h"
+#include "Qt3DSDMHandles.h"
+#include "IStudioRenderer.h"
+#include "Qt3DSRenderBufferManager.h"
+#include "Qt3DSRenderDynamicObjectSystem.h"
+#include "Qt3DSRenderUIPSharedTranslation.h"
namespace {
@@ -155,7 +160,7 @@ class CDocEditor : public Q3DStudio::IInternalDocumentEditor
ISlideSystem &m_SlideSystem;
ISlideCore &m_SlideCore;
ISlideGraphCore &m_SlideGraphCore;
- IAnimationCore &m_AnimationCore;
+ IAnimationCore &m_animCore;
CClientDataModelBridge &m_Bridge;
IPropertySystem &m_PropertySystem;
IMetaData &m_MetaData;
@@ -182,7 +187,7 @@ public:
, m_SlideSystem(*m_StudioSystem.GetFullSystem()->GetSlideSystem())
, m_SlideCore(*m_StudioSystem.GetFullSystem()->GetCoreSystem()->GetSlideCore())
, m_SlideGraphCore(*m_StudioSystem.GetFullSystem()->GetCoreSystem()->GetSlideGraphCore())
- , m_AnimationCore(*m_StudioSystem.GetFullSystem()->GetAnimationCore())
+ , m_animCore(*m_StudioSystem.GetFullSystem()->GetAnimationCore())
, m_Bridge(*m_StudioSystem.GetClientDataModelBridge())
, m_PropertySystem(*m_StudioSystem.GetPropertySystem())
, m_MetaData(*m_StudioSystem.GetActionMetaData())
@@ -241,7 +246,7 @@ public:
Qt3DSDMSlideHandle theMaster = theSlideInfo.m_MasterSlide;
Qt3DSDMSlideHandle theActiveSlide = theSlideInfo.m_ActiveSlide;
if (theAssociatedSlide == theMaster || theAssociatedSlide == theActiveSlide) {
- long theViewTime = theSlideInfo.m_ComponentMilliseconds;
+ long theViewTime = theSlideInfo.m_ComponentTime;
return eyeballVal && theStart <= theViewTime && theEnd > 0 && theEnd >= theViewTime;
}
}
@@ -287,7 +292,8 @@ public:
if (m_SlideCore.GetSpecificInstancePropertyValue(theAssociatedSlide, instance, inProperty,
theGuid)
|| m_DataCore.GetInstancePropertyValue(instance, inProperty, theGuid)) {
- return m_Bridge.GetInstanceByGUID(get<SLong4>(theGuid));
+ if (theGuid.getType() == qt3dsdm::DataModelDataType::Long4)
+ return m_Bridge.GetInstanceByGUID(get<SLong4>(theGuid));
}
return TInstanceHandle();
}
@@ -423,7 +429,7 @@ public:
void GetPathToInstanceMap(TCharPtrToSlideInstanceMap &outInstanceMap,
qt3dsdm::Qt3DSDMPropertyHandle property,
- bool checkMaterialContainers = true,
+ bool skipMaterialContainers = true,
bool includeIdentifiers = true) const
{
SComposerObjectDefinitions &theDefinitions(m_Bridge.GetObjectDefinitions());
@@ -434,7 +440,7 @@ public:
for (size_t idx = 0, end = existing.size(); idx < end; ++idx) {
Qt3DSDMInstanceHandle theAsset(existing[idx]);
- if (checkMaterialContainers && m_Bridge.isInsideMaterialContainer(theAsset))
+ if (skipMaterialContainers && m_Bridge.isInsideMaterialContainer(theAsset))
continue;
thePaths.clear();
@@ -457,12 +463,12 @@ public:
}
void GetSourcePathToInstanceMap(TCharPtrToSlideInstanceMap &outInstanceMap,
- bool checkMaterialContainers = true,
+ bool skipMaterialContainers = true,
bool includeIdentifiers = true) const override
{
SComposerObjectDefinitions &theDefinitions(m_Bridge.GetObjectDefinitions());
GetPathToInstanceMap(outInstanceMap, theDefinitions.m_Asset.m_SourcePath,
- checkMaterialContainers, includeIdentifiers);
+ skipMaterialContainers, includeIdentifiers);
}
void GetImportPathToInstanceMap(TCharPtrToSlideInstanceMap &outInstanceMap) const override
@@ -666,7 +672,7 @@ public:
theSlide = m_SlideSystem.GetMasterSlide(theSlide);
inSlide = theSlide;
}
- return m_AnimationCore.GetAnimation(inSlide, instance, propHdl, subIndex).Valid();
+ return m_animCore.GetAnimation(inSlide, instance, propHdl, subIndex).Valid();
}
bool IsAnimationArtistEdited(TSlideHandle inSlide, Qt3DSDMInstanceHandle instance,
@@ -690,14 +696,14 @@ public:
}
Qt3DSDMAnimationHandle animHandle =
- m_AnimationCore.GetAnimation(inSlide, instance, propHdl, subIndex);
+ m_animCore.GetAnimation(inSlide, instance, propHdl, subIndex);
if (animHandle.Valid() == false)
return false;
- return m_AnimationCore.IsArtistEdited(animHandle);
+ return m_animCore.IsArtistEdited(animHandle);
}
pair<std::shared_ptr<qt3dsdm::IDOMWriter>, CFilePath>
- DoCopySceneGraphObject(const TInstanceHandleList &inInstances)
+ DoCopySceneGraphObject(const TInstanceHandleList &inInstances, bool preserveFileIds)
{
if (inInstances.empty())
return pair<std::shared_ptr<qt3dsdm::IDOMWriter>, CFilePath>();
@@ -705,7 +711,8 @@ public:
std::shared_ptr<IDOMWriter> theWriter(m_Doc.CreateDOMWriter());
TInstanceHandleList theInstances = ToGraphOrdering(inInstances);
m_Doc.CreateSerializer()->SerializeSceneGraphObjects(*theWriter, theInstances,
- GetActiveSlide(inInstances[0]));
+ GetActiveSlide(inInstances[0]),
+ preserveFileIds);
CFilePath theFile = WriteWriterToFile(*theWriter, L"SceneGraph");
return make_pair(theWriter, theFile);
}
@@ -714,7 +721,7 @@ public:
std::shared_ptr<qt3dsdm::IDOMReader>
CopySceneGraphObjectsToMemory(const qt3dsdm::TInstanceHandleList &instanceList)
{
- return DoCopySceneGraphObject(instanceList).first->CreateDOMReader();
+ return DoCopySceneGraphObject(instanceList, false).first->CreateDOMReader();
}
// Exposed through document reader interface
@@ -760,7 +767,7 @@ public:
return theFinalPath;
}
- CFilePath CopySceneGraphObjects(TInstanceHandleList inInstances) override
+ CFilePath CopySceneGraphObjects(TInstanceHandleList inInstances, bool preserveFileIds) override
{
if (inInstances.empty())
return L"";
@@ -771,7 +778,7 @@ public:
if (!shouldCopy)
return L"";
- return DoCopySceneGraphObject(inInstances).second;
+ return DoCopySceneGraphObject(inInstances, preserveFileIds).second;
}
CFilePath CopyAction(Qt3DSDMActionHandle inAction, Qt3DSDMSlideHandle inSlide) override
@@ -1064,6 +1071,18 @@ public:
m_Bridge.GetOrCreateGraphRoot(retval);
}
+ // Only one camera is active by default. If we already have one active, set the new camera
+ // to inactive.
+ if (inType == ComposerObjectTypes::Camera) {
+ auto cameraLayer = m_Bridge.GetResidingLayer(retval);
+ if (!m_Doc.getActiveCamera(cameraLayer).Valid()) {
+ m_Doc.setActiveCamera(cameraLayer, retval);
+ } else {
+ SetInstancePropertyValue(
+ retval, m_Bridge.GetSceneAsset().m_Eyeball.m_Property, false);
+ }
+ }
+
// if we did not set time range earlier, let's set it now to match parent
TInstanceHandle handle = FinalizeAddOrDrop(retval, inParent, inInsertType, inPosition,
!setTimeRange, selectCreatedInstance, false);
@@ -1164,8 +1183,15 @@ public:
if (!m_Bridge.GetMaterialFromImageInstance(instance, theParent, theProperty))
m_Bridge.GetLayerFromImageProbeInstance(instance, theParent, theProperty);
- if (theParent.Valid())
- m_PropertySystem.SetInstancePropertyValue(theParent, theProperty, SLong4());
+ if (theParent.Valid()) {
+ auto type = m_PropertySystem.GetAdditionalMetaDataType(theParent, theProperty);
+ if (type == AdditionalMetaDataType::Image) {
+ m_PropertySystem.SetInstancePropertyValue(theParent, theProperty, SLong4());
+ } else if (type == AdditionalMetaDataType::Texture) {
+ m_PropertySystem.SetInstancePropertyValue(theParent, theProperty,
+ std::make_shared<CDataStr>(Q3DStudio::CString()));
+ }
+ }
} else if (m_Bridge.IsBehaviorInstance(instance) || m_Bridge.IsEffectInstance(instance)
|| m_Bridge.IsCustomMaterialInstance(instance)) {
// Check if this is the last instance that uses the same sourcepath property
@@ -1421,6 +1447,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
@@ -1429,25 +1473,64 @@ public:
AdditionalMetaDataType::Value theProperytMetaData =
thePropertySystem.GetAdditionalMetaDataType(instance, propName);
TSlideHandle theNewSlide(GetSlideForProperty(instance, propName));
- if (theProperytMetaData == AdditionalMetaDataType::Image) {
+ if (theProperytMetaData == AdditionalMetaDataType::Image
+ || theProperytMetaData == AdditionalMetaDataType::Texture) {
TDataStrPtr theImageSourcePath = get<TDataStrPtr>(value);
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);
@@ -1511,7 +1594,7 @@ public:
m_AssetGraph.GetParent(instance), instance, theNewSlide, docDir, log,
std::bind(CPerformImport::ImportToComposerFromImportFile,
std::placeholders::_1, std::placeholders::_2),
- DocumentEditorInsertType::Unknown, CPt(), times.first);
+ DocumentEditorInsertType::Unknown, CPt(), times.first, false);
}
thePropertySystem.SetInstancePropertyValue(instance, propName, value);
} else if (propName == m_Bridge.GetObjectDefinitions().m_Path.m_PathType
@@ -1571,6 +1654,20 @@ public:
}
// Now set the property for reals
thePropertySystem.SetInstancePropertyValue(instance, propName, value);
+ } else if (propName == m_Bridge.GetSceneAsset().m_Eyeball
+ && m_Bridge.IsCameraInstance(instance)) {
+ auto cameraLayer = m_Bridge.GetResidingLayer(instance);
+ auto activeCamera = m_Doc.getActiveCamera(cameraLayer);
+ if ((instance != activeCamera) && get<bool>(value)) {
+ // Only one camera per layer should be active. Set the previous one to inactive if
+ // we are activating another one.
+ if (activeCamera.Valid())
+ thePropertySystem.SetInstancePropertyValue(activeCamera, propName, false);
+ m_Doc.setActiveCamera(cameraLayer, instance);
+ } else if (!get<bool>(value) && activeCamera == instance) {
+ m_Doc.setActiveCamera(cameraLayer, {}); // Inactivating current active camera.
+ }
+ thePropertySystem.SetInstancePropertyValue(instance, propName, value);
} else {
if (propName != m_Bridge.GetAlias().m_ReferencedNode.m_Property) {
thePropertySystem.SetInstancePropertyValue(instance, propName, value);
@@ -1852,6 +1949,7 @@ public:
// Keep material names the same so that if you change the material type
// any relative path links will still work.
// Next bug is harder (keep id's the same).
+ Q3DStudio::CString fileId = GetFileId(instance);
Q3DStudio::CString theName = GetName(instance);
SLong4 theGuid = m_Bridge.GetInstanceGUID(instance);
TInstanceHandle nextChild = m_AssetGraph.GetSibling(instance, true);
@@ -1911,6 +2009,9 @@ public:
m_Bridge.GetObjectDefinitions().m_Lightmaps.m_LightmapShadow,
theLightmapShadowValue, false);
+ m_DataCore.SetInstancePropertyValue(newMaterial,
+ m_Bridge.GetObjectDefinitions().m_Asset.m_FileId,
+ std::make_shared<CDataStr>(fileId.c_str()));
SetName(newMaterial, theName, false);
m_Bridge.SetInstanceGUID(newMaterial, theGuid);
// Copy all actions from old material instance to new material instance
@@ -2031,7 +2132,7 @@ public:
&& name != QLatin1String("timebartext");
}
- void saveIfMaterial(Qt3DSDMInstanceHandle instance)
+ void saveIfMaterial(Qt3DSDMInstanceHandle instance) override
{
Qt3DSDMInstanceHandle material;
if (m_Bridge.isInsideMaterialContainer(instance)) {
@@ -2123,7 +2224,8 @@ public:
}
const QFileInfo fileInfo(file);
- writeProperty(file, QStringLiteral("path"), fileInfo.absoluteFilePath());
+ writeProperty(file, QStringLiteral("path"),
+ projDir.relativeFilePath(fileInfo.absoluteFilePath()));
QMapIterator<QString, Qt3DSDMInstanceHandle> i(textureHandles);
while (i.hasNext()) {
@@ -2496,6 +2598,16 @@ public:
void copyMaterialProperties(Qt3DSDMInstanceHandle src, Qt3DSDMInstanceHandle dst) override
{
+ const EStudioObjectType matType = m_Bridge.GetObjectType(src);
+ QString materialTypeString;
+ if (matType == OBJTYPE_CUSTOMMATERIAL)
+ materialTypeString = m_Bridge.GetSourcePath(src);
+ else if (matType == OBJTYPE_MATERIAL)
+ materialTypeString = QStringLiteral("Standard Material");
+ else
+ return;
+ SetMaterialType(dst, materialTypeString);
+
const auto srcSlide = m_SlideSystem.GetApplicableSlide(src);
const auto dstSlide = m_SlideSystem.GetApplicableSlide(dst);
const auto name = GetName(dst);
@@ -2542,8 +2654,7 @@ public:
TSlideHandle inDestSlide, TInstanceHandle inDestInstance)
{
m_SlideCore.CopyProperties(inSourceSlide, inSourceInstance, inDestSlide, inDestInstance);
- m_AnimationCore.CopyAnimations(inSourceSlide, inSourceInstance, inDestSlide,
- inDestInstance);
+ m_animCore.CopyAnimations(inSourceSlide, inSourceInstance, inDestSlide, inDestInstance);
}
void UnlinkProperty(TInstanceHandle instance, TPropertyHandle propName) override
@@ -2726,7 +2837,7 @@ public:
}
SetTimeRange(inInstance, theTimeRange.first + inOffset, theTimeRange.second + inOffset);
// Offset all the keyframes linked to animations of this instance by this offset.
- m_AnimationCore.OffsetAnimations(m_Doc.GetActiveSlide(), inInstance, inOffset);
+ m_animCore.OffsetAnimations(m_Doc.GetActiveSlide(), inInstance, inOffset);
// Offset children time as well
CGraphIterator theChildren;
@@ -2809,8 +2920,8 @@ public:
}
template <typename TKeyframeType>
- void AddKeyframes(Qt3DSDMAnimationHandle animHandle, const float *keyframeValues, long numValues,
- long inOffsetInSeconds)
+ void AddKeyframes(Qt3DSDMAnimationHandle animHandle, const float *keyframeValues,
+ long numValues, long timeOffset)
{
long numFloatsPerKeyframe = sizeof(TKeyframeType) / sizeof(float);
if (numValues % numFloatsPerKeyframe) {
@@ -2820,27 +2931,74 @@ public:
long numKeyframes = numValues / numFloatsPerKeyframe;
for (long idx = 0; idx < numKeyframes; ++idx) {
TKeyframeType theData(keyframes[idx]);
- theData.m_KeyframeSeconds += inOffsetInSeconds;
- m_AnimationCore.InsertKeyframe(animHandle, theData);
+ theData.m_time += timeOffset;
+ m_animCore.InsertKeyframe(animHandle, theData);
}
}
- void SetKeyframeTime(TKeyframeHandle inKeyframe, long inTime) override
+ void SetKeyframeTime(TKeyframeHandle kfHandle, long time) override
{
- float theTimeinSecs = static_cast<float>(inTime) / 1000.f;
- // round off to 4 decimal place to workaround precision issues
- // TODO: fix this, either all talk float OR long. choose one.
- theTimeinSecs = ceilf(theTimeinSecs * 10000.0f) / 10000.0f;
- TKeyframe theData = m_AnimationCore.GetKeyframeData(inKeyframe);
- // Function programming paradigm, returns new value instead of changing
- // current value.
- theData = qt3dsdm::SetKeyframeSeconds(theData, theTimeinSecs);
- m_AnimationCore.SetKeyframeData(inKeyframe, theData);
+ TKeyframe kfData = m_animCore.GetKeyframeData(kfHandle);
+
+ // offset control points for bezier keyframes
+ offsetBezier(kfData, time - getKeyframeTime(kfData));
+
+ // Functional programming paradigm, returns new value instead of changing current value.
+ kfData = qt3dsdm::setKeyframeTime(kfData, time);
+ m_animCore.SetKeyframeData(kfHandle, kfData);
+
+ // For bezier keyframes check that control points of the moved keyframe and the keyframes
+ // before and after it don't go beyond its adjacent keyframes times.
+ Qt3DSDMAnimationHandle anim = m_animCore.GetAnimationForKeyframe(kfHandle);
+ EAnimationType animType = m_animCore.GetAnimationInfo(anim).m_AnimationType;
+ if (animType == EAnimationTypeBezier) {
+ TKeyframeHandleList keyframes;
+ m_animCore.GetKeyframes(anim, keyframes);
+ for (size_t i = 0; i < keyframes.size(); ++i) {
+ if (keyframes[i] == kfHandle) {
+ SBezierKeyframe kfCurr = get<SBezierKeyframe>(m_animCore.GetKeyframeData(
+ kfHandle));
+ if (i > 0) { // check overlap with prev keyframe
+ SBezierKeyframe kfPrev = get<SBezierKeyframe>(m_animCore.GetKeyframeData(
+ keyframes[i - 1]));
+ if (kfPrev.m_OutTangentTime > kfCurr.m_time)
+ kfPrev.m_OutTangentTime = kfCurr.m_time;
+
+ if (kfCurr.m_InTangentTime < kfPrev.m_time)
+ kfCurr.m_InTangentTime = kfPrev.m_time;
+
+ m_animCore.SetKeyframeData(keyframes[i - 1], kfPrev);
+
+ // Mahmoud_TODO: trim the value proportinally also so that the control
+ // point lines maintains the same slope after the time is trimmed
+ }
+
+ if (i < keyframes.size() - 1) { // check overlap with next keyframe
+ SBezierKeyframe kfNext = get<SBezierKeyframe>(m_animCore.GetKeyframeData(
+ keyframes[i + 1]));
+ if (kfNext.m_InTangentTime < kfCurr.m_time)
+ kfNext.m_InTangentTime = kfCurr.m_time;
+
+ if (kfCurr.m_OutTangentTime > kfNext.m_time)
+ kfCurr.m_OutTangentTime = kfNext.m_time;
+
+ m_animCore.SetKeyframeData(keyframes[i + 1], kfNext);
+ }
+ m_animCore.SetKeyframeData(kfHandle, kfCurr);
+ break;
+ }
+ }
+ }
+ }
+
+ void setBezierKeyframeValue(TKeyframeHandle kfHandle, const TKeyframe &kfData) override
+ {
+ m_animCore.SetKeyframeData(kfHandle, kfData);
}
void DeleteAllKeyframes(Qt3DSDMAnimationHandle inAnimation) override
{
- m_AnimationCore.DeleteAllKeyframes(inAnimation);
+ m_animCore.DeleteAllKeyframes(inAnimation);
}
void KeyframeProperty(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
@@ -2854,52 +3012,48 @@ public:
const wchar_t *propName, long subIndex, EAnimationType animType,
const float *keyframeValues, long numValues, bool /*inUserEdited*/) override
{
- Qt3DSDMPropertyHandle propHdl =
- m_DataCore.GetAggregateInstancePropertyByName(instance, propName);
- if (propHdl.Valid() == false) {
+ Qt3DSDMPropertyHandle property = m_DataCore.GetAggregateInstancePropertyByName(instance,
+ propName);
+ if (!property.Valid()) {
QT3DS_ASSERT(false);
return 0;
}
- if (inSlide.Valid() == false) {
+ if (!inSlide.Valid()) {
Qt3DSDMSlideHandle theSlide = m_SlideSystem.GetAssociatedSlide(instance);
- if (theSlide.Valid() == false) {
+ if (!theSlide.Valid()) {
assert(0);
return 0;
}
- if (m_SlideSystem.IsPropertyLinked(instance, propHdl))
+ if (m_SlideSystem.IsPropertyLinked(instance, property))
theSlide = m_SlideSystem.GetMasterSlide(theSlide);
inSlide = theSlide;
}
Qt3DSDMAnimationHandle animHandle =
- m_AnimationCore.GetAnimation(inSlide, instance, propHdl, subIndex);
+ m_animCore.GetAnimation(inSlide, instance, property, subIndex);
- if (animHandle.Valid() == true)
- m_AnimationCore.DeleteAnimation(animHandle);
+ if (animHandle.Valid())
+ m_animCore.DeleteAnimation(animHandle);
animHandle =
- m_AnimationCore.CreateAnimation(inSlide, instance, propHdl, subIndex, animType, false);
+ m_animCore.CreateAnimation(inSlide, instance, property, subIndex, animType, false);
long theStartTime = GetTimeRange(instance).first;
- long theTimeOffsetInSeconds = long(theStartTime / 1000.f);
switch (animType) {
case EAnimationTypeLinear:
- AddKeyframes<SLinearKeyframe>(animHandle, keyframeValues, numValues,
- theTimeOffsetInSeconds);
+ AddKeyframes<SLinearKeyframe>(animHandle, keyframeValues, numValues, theStartTime);
break;
case EAnimationTypeBezier:
- AddKeyframes<SBezierKeyframe>(animHandle, keyframeValues, numValues,
- theTimeOffsetInSeconds);
+ AddKeyframes<SBezierKeyframe>(animHandle, keyframeValues, numValues, theStartTime);
break;
case EAnimationTypeEaseInOut:
AddKeyframes<SEaseInEaseOutKeyframe>(animHandle, keyframeValues, numValues,
- theTimeOffsetInSeconds);
+ theStartTime);
break;
default:
QT3DS_ASSERT(false);
- AddKeyframes<SLinearKeyframe>(animHandle, keyframeValues, numValues,
- theTimeOffsetInSeconds);
+ AddKeyframes<SLinearKeyframe>(animHandle, keyframeValues, numValues, theStartTime);
break;
}
return animHandle;
@@ -2914,9 +3068,9 @@ public:
return false;
}
Qt3DSDMAnimationHandle animHandle =
- m_AnimationCore.GetAnimation(inSlide, instance, propHdl, subIndex);
+ m_animCore.GetAnimation(inSlide, instance, propHdl, subIndex);
if (animHandle.Valid()) {
- m_AnimationCore.DeleteAnimation(animHandle);
+ m_animCore.DeleteAnimation(animHandle);
return true;
}
return false;
@@ -2924,7 +3078,7 @@ public:
void SetIsArtistEdited(Qt3DSDMAnimationHandle inAnimation, bool inEdited = true) override
{
- m_AnimationCore.SetIsArtistEdited(inAnimation, inEdited);
+ m_animCore.SetIsArtistEdited(inAnimation, inEdited);
}
qt3dsdm::Qt3DSDMInstanceHandle
@@ -3000,11 +3154,13 @@ public:
bool inGenerateUniqueName,
DocumentEditorInsertType::Enum inInsertType,
const CPt &inPosition,
+ bool preserveFileIds,
bool notifyRename = true)
{
std::shared_ptr<IComposerSerializer> theSerializer = m_Doc.CreateSerializer();
TInstanceHandleList retval = theSerializer->SerializeSceneGraphObject(
- *inReader, m_Doc.GetDocumentDirectory(), inNewRoot, GetActiveSlide(inNewRoot));
+ *inReader, m_Doc.GetDocumentDirectory(), inNewRoot, GetActiveSlide(inNewRoot),
+ preserveFileIds);
for (size_t idx = 0, end = retval.size(); idx < end; ++idx) {
qt3dsdm::Qt3DSDMInstanceHandle theInstance(retval[idx]);
if (inInsertType == DocumentEditorInsertType::NextSibling)
@@ -3023,7 +3179,8 @@ public:
TInstanceHandle inNewRoot,
bool inGenerateUniqueName,
DocumentEditorInsertType::Enum inInsertType,
- const CPt &inPosition) override
+ const CPt &inPosition,
+ bool preserveFileIds) override
{
qt3ds::QT3DSI32 theVersion = 0;
std::shared_ptr<IDOMReader> theReader = m_Doc.CreateDOMReader(
@@ -3031,13 +3188,14 @@ public:
if (!theReader)
return TInstanceHandleList();
return DoPasteSceneGraphObject(theReader, inNewRoot, inGenerateUniqueName, inInsertType,
- inPosition, false);
+ inPosition, preserveFileIds, false);
}
virtual TInstanceHandleList
PasteSceneGraphObjectMaster(const CFilePath &inFilePath, TInstanceHandle inNewRoot,
bool inGenerateUniqueName,
- DocumentEditorInsertType::Enum inInsertType, const CPt &inPosition) override
+ DocumentEditorInsertType::Enum inInsertType, const CPt &inPosition,
+ bool preserveFileIds) override
{
qt3ds::QT3DSI32 theVersion = 0;
std::shared_ptr<IDOMReader> theReader = m_Doc.CreateDOMReader(
@@ -3048,7 +3206,8 @@ public:
std::shared_ptr<IComposerSerializer> theSerializer = m_Doc.CreateSerializer();
TInstanceHandleList retval = theSerializer->SerializeSceneGraphObject(
*theReader, m_Doc.GetDocumentDirectory(), inNewRoot,
- m_Doc.GetStudioSystem()->GetSlideSystem()->GetMasterSlide(GetActiveSlide(inNewRoot)));
+ m_Doc.GetStudioSystem()->GetSlideSystem()->GetMasterSlide(GetActiveSlide(inNewRoot)),
+ preserveFileIds);
for (size_t idx = 0, end = retval.size(); idx < end; ++idx) {
qt3dsdm::Qt3DSDMInstanceHandle theInstance(retval[idx]);
if (inInsertType == DocumentEditorInsertType::NextSibling)
@@ -3253,7 +3412,7 @@ public:
// Paste into the master slide of the new component
TInstanceHandleList insertedHandles = theSerializer->SerializeSceneGraphObject(
*theReader,m_Doc.GetDocumentDirectory(), component,
- m_SlideSystem.GetMasterSlide(theComponentSlide));
+ m_SlideSystem.GetMasterSlide(theComponentSlide), true);
// Restore the original time range for all objects.
if (insertedHandles.size()) {
@@ -3278,19 +3437,10 @@ public:
if (oldType == "ReferencedMaterial") {
Qt3DSDMInstanceHandle refMaterial = m_Bridge.getMaterialReference(instance);
- if (refMaterial.Valid()) {
- const Q3DStudio::CString refType = GetObjectTypeName(refMaterial);
- QString v;
- if (refType == "CustomMaterial")
- v = m_Bridge.GetSourcePath(refMaterial);
- else
- v = QStringLiteral("Standard Material");
-
- SetMaterialType(instance, v);
+ if (refMaterial.Valid())
copyMaterialProperties(refMaterial, instance);
- } else {
+ else
SetMaterialType(instance, QStringLiteral("Standard Material"));
- }
const auto name = GetName(instance);
if (!name.toQString().endsWith(QLatin1String("_animatable")))
@@ -3336,7 +3486,7 @@ public:
theSerializer->SerializeSceneGraphObject(
*theReader, m_Doc.GetDocumentDirectory(),
targetComponent,
- m_SlideSystem.GetMasterSlide(theComponentSlide));
+ m_SlideSystem.GetMasterSlide(theComponentSlide), true);
if (insertedHandles.size()) {
// Restore the original time range for all objects.
@@ -3381,7 +3531,7 @@ public:
{
qt3dsdm::TInstanceHandleList theInstances(ToGraphOrdering(inInstances));
std::shared_ptr<IDOMReader> theReader(CopySceneGraphObjectsToMemory(theInstances));
- return DoPasteSceneGraphObject(theReader, inDest, true, inInsertType, CPt(), false);
+ return DoPasteSceneGraphObject(theReader, inDest, true, inInsertType, CPt(), false, false);
}
Qt3DSDMActionHandle AddAction(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
@@ -3515,6 +3665,8 @@ public:
int newSlideIndex = m_SlideSystem.GetSlideIndex(theNewSlide);
m_SlideSystem.SetActiveSlide(inMasterSlide, newSlideIndex);
m_Doc.NotifyActiveSlideChanged(theNewSlide, true);
+ // Make sure layer is reseted
+ m_Doc.SetActiveLayer(0);
CheckSlideGroupPlayThroughTo(theNewSlide);
Qt3DSDMInstanceHandle theInstance = m_Doc.GetSelectedInstance();
if (theInstance.Valid() && GetAssociatedSlide(theInstance) != inMasterSlide)
@@ -3578,6 +3730,18 @@ public:
m_Bridge.GetObjectDefinitions().m_Named.m_NameProp,
std::make_shared<CDataStr>(theNewName.c_str()));
+ // Change non-masterslide instance names to unique.
+ TInstanceHandleList slideInstances;
+ m_SlideSystem.GetAssociatedInstances(theNewSlide, slideInstances);
+ for (size_t idx = 0, end = slideInstances.size(); idx < end; ++idx) {
+ TInstanceHandle theInstance(slideInstances[idx]);
+ if (m_SlideSystem.GetApplicableSlide(theInstance)
+ != m_SlideSystem.GetMasterSlide(theInstance)
+ && !m_Bridge.GetName(theInstance).IsEmpty()) {
+ SetName(theInstance, m_Bridge.GetName(theInstance), true);
+ }
+ }
+
// Ensure the active slide change gets recorded in the transaction system so that
// undo will place us back at the old slide before things start reading from the object
// model.
@@ -3586,6 +3750,8 @@ public:
m_Doc.SetActiveSlideWithTransaction(theNewSlide);
m_Doc.NotifyActiveSlideChanged(theNewSlide, true);
+ // Make sure layer is reseted
+ m_Doc.SetActiveLayer(0);
CheckSlideGroupPlayThroughTo(theNewSlide);
return theNewSlide;
}
@@ -3718,7 +3884,8 @@ public:
Qt3DSDMInstanceHandle inRoot, Qt3DSDMSlideHandle inSlide, Q3DStudio::CString inDocDir,
STranslationLog &inTranslationLog,
function<SImportResult(IComposerEditorInterface &, Q3DStudio::CString)> inImportFunction,
- DocumentEditorInsertType::Enum inInsertType, const CPt &inPosition, long inStartTime)
+ DocumentEditorInsertType::Enum inInsertType, const CPt &inPosition, long inStartTime,
+ bool selectAfterImport)
{
CFilePath outputDir(inImportFilePath.GetDirectory());
bool alwaysKeepDirectory = outputDir.Exists();
@@ -3761,7 +3928,7 @@ public:
// Do not check for unique name as we set it anyway after getting new handle
Qt3DSDMInstanceHandle retval =
FinalizeAddOrDrop(importToComposer->GetRoot(), inParent, inInsertType,
- inPosition, inStartTime == -1, true, false);
+ inPosition, inStartTime == -1, selectAfterImport, false);
SetName(retval, theRelPath.GetFileStem(), true);
updateMaterialFiles();
@@ -3821,7 +3988,7 @@ public:
inParent, 0, inSlide, docDir, translator.m_TranslationLog,
std::bind(CPerformImport::ImportToComposer, translator,
std::placeholders::_1, std::placeholders::_2), inDropType,
- inPosition, inStartTime);
+ inPosition, inStartTime, true);
if (retval.Valid()) {
CFilePath theRelativeImport = m_Doc.GetRelativePathToDoc(outputFileName);
m_ImportFileToDAEMap.insert(
@@ -3844,7 +4011,7 @@ public:
return DoImport(inFullPathToDocument, inFullPathToDocument, inParent, 0, inSlide, docDir,
log, std::bind(CPerformImport::ImportToComposerFromImportFile,
std::placeholders::_1, std::placeholders::_2),
- inDropType, inPosition, inStartTime);
+ inDropType, inPosition, inStartTime, true);
}
QString findUniqueMaterialName(const QString &name, const QString &importPath)
@@ -4009,18 +4176,6 @@ public:
inStartTime == -1);
}
- static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
- {
- Q_UNUSED(ud)
- Q_UNUSED(osize)
-
- if (nsize == 0) {
- free(ptr);
- return nullptr;
- } else
- return realloc(ptr, nsize);
- }
-
QString LoadScriptFile(const CFilePath &inFile)
{
QString retval;
@@ -4097,12 +4252,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;
@@ -4172,6 +4340,62 @@ public:
m_DataCore.SetInstancePropertyValue(inDynamic, theInfo.m_Property, theRef);
}
}
+ } else if (theInfo.m_CompleteType == CompleteMetaDataType::Texture
+ && GetValueType(theInfo.m_DefaultValue) == DataModelDataType::String) {
+ SValue value;
+ m_DataCore.GetInstancePropertyValue(inDynamic, theInfo.m_Property, value);
+ // Set default value to the instance
+ if (!value.empty()) {
+ TDataStrPtr theImageSourcePath = get<TDataStrPtr>(value);
+ bool hasValue = theImageSourcePath && theImageSourcePath->GetLength() > 0;
+ qt3dsdm::Qt3DSDMInstanceHandle theImageInstance =
+ GetImageInstanceForProperty(inDynamicInstance, theInfo.m_Property);
+ 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
+ SetInstancePropertyValue(theImageInstance,
+ m_Bridge.GetSceneImage().m_SubPresentation,
+ make_shared<CDataStr>(Q3DStudio::CString()));
+ }
+ } else {
+ m_DataCore.SetInstancePropertyValue(inDynamicInstance, theInfo.m_Property,
+ make_shared<CDataStr>(Q3DStudio::CString()));
+ }
+ }
}
}
}
@@ -4239,11 +4463,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);
@@ -4438,7 +4663,6 @@ public:
if (theRelativePath.toCString() == GetSourcePath(existing[idx]))
theParentInstance = existing[idx];
}
-
if (theParentInstance.Valid() == false) {
if (theShaderFile.Exists()) {
theParentInstance = m_DataCore.CreateInstance();
@@ -4463,18 +4687,31 @@ public:
IDocumentEditor::fixDefaultTexturePaths(theParentInstance);
DisplayLoadWarnings(shaderFile, theWarnings, QString());
} else {
- if (theHandler)
+ if (theHandler) {
theHandler->DisplayImportFailed(theShaderFile.toQString(),
QObject::tr("Unable to load Shader File"),
false);
+ }
return 0;
}
}
+ const SMetaDataDynamicObject *dynObj;
+ dynObj = m_MetaData.GetDynamicObjectByInstance(theParentInstance);
+ if (!dynObj) {
+ if (theHandler) {
+ theHandler->DisplayImportFailed(theShaderFile.toQString(),
+ QObject::tr("Unable to load Shader File"),
+ false);
+ }
+ return 0;
+ }
TInstanceHandle retval(IDocumentEditor::CreateSceneGraphInstance(
theParentInstance, inParent, inSlide, m_DataCore, m_SlideSystem,
m_Bridge.GetObjectDefinitions(), m_AssetGraph, m_MetaData, inTargetId));
+ ApplyDynamicMetaData(retval, theParentInstance, *dynObj);
+
if (inStartTime != -1)
SetStartTime(retval, inStartTime);
@@ -4602,10 +4839,13 @@ public:
// Precondition is that our source path to instance map
// has all of the source-path-to-instance hooks already looked up.
- void DoRefreshImport(const CFilePath &inOldFile, const CFilePath &inNewFile)
+ void DoRefreshImport(const CFilePath &inOldFile, const CFilePath &inNewFile,
+ const CFilePath &importFilePath)
{
ScopedBoolean __ignoredDirs(m_IgnoreDirChange);
vector<CFilePath> importFileList;
+ if (importFilePath.Exists() && importFilePath.IsFile())
+ importFileList.push_back(importFilePath.filePath());
// Find which import files use this dae file.
for (TCharPtrToSlideInstanceMap::iterator theIter = m_SourcePathInstanceMap.begin(),
@@ -4639,75 +4879,73 @@ public:
// OK, for each import file
// 1. Find each group in the system using that import file as its source path.
// 2. for each group we find, build a map of import id->item that we will use to
- // communicate the import changes to the item.
- // 4. Run the refresh process using a composer editor that runs off of our
- // mappings
+ // communicate the import changes to the item.
+ // 4. Run the refresh process using a composer editor that runs off of our mappings
TIdMultiMap theGroupIdMap;
for (size_t importIdx = 0, end = importFileList.size(); importIdx < end; ++importIdx) {
theGroupIdMap.clear();
CFilePath theImportFilePath = importFileList[importIdx];
CFilePath theImportRelativePath = m_Doc.GetRelativePathToDoc(theImportFilePath);
TCharPtrToSlideInstanceMap::iterator theIter =
- m_SourcePathInstanceMap.find(m_StringTable.RegisterStr(theImportRelativePath.toCString()));
- if (theIter == m_SourcePathInstanceMap.end())
- continue;
- // First pass just build the group id entries. This avoids us copying hashtables which
- // may
- // be quite expensive
- for (TSlideInstanceList::iterator theSlideInst = theIter->second.begin(),
- theSlideInstEnd = theIter->second.end();
- theSlideInst != theSlideInstEnd; ++theSlideInst) {
- TInstanceHandle theRoot = theSlideInst->second;
- TSlideHandle theSlide = theSlideInst->first;
-
- // For a depth first search of all children of this object *in this slide*,
- // if they have an import id then add them to the map.
- DepthFirstAddImportChildren(theSlide, theRoot, theGroupIdMap, theAddedInstances);
- TIdMultiMap::iterator theGroupId =
- theGroupIdMap
- .insert(make_pair(m_StringTable.GetWideStr(GetImportId(theRoot)),
- vector<pair<Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle>>()))
- .first;
- insert_unique(theGroupId->second, make_pair(theSlide, theRoot));
- theAddedInstances.insert(theRoot);
- }
- // Since some objects may be completely free standing, we need to go through *all*
- // objects.
- // Unfortunately the first revision of the system didn't put import paths on objects so
- // we need both the above loop *and* to consider every object who's import path matches
- // out import document's relative path.
- theIter = theImportPaths.find(m_StringTable.RegisterStr(theImportRelativePath.toCString()));
- TSlideHandleList theAssociatedSlides;
- if (theIter != theImportPaths.end()) {
- vector<pair<Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle>> &theInstances =
- theIter->second;
- for (size_t freeInstanceIdx = 0, end = theInstances.size(); freeInstanceIdx < end;
- ++freeInstanceIdx) {
- if (theAddedInstances.find(theInstances[freeInstanceIdx].second)
- != theAddedInstances.end())
- continue;
- theAssociatedSlides.clear();
- Qt3DSDMInstanceHandle theInstance(theInstances[freeInstanceIdx].second);
- GetAllAssociatedSlides(theInstance, theAssociatedSlides);
- TIdMultiMap::iterator theInstanceId =
- theGroupIdMap
- .insert(
- make_pair(m_StringTable.GetWideStr(GetImportId(theInstance)),
- vector<pair<Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle>>()))
- .first;
- for (size_t slideIdx = 0, slideEnd = theAssociatedSlides.size();
- slideIdx < slideEnd; ++slideIdx)
- insert_unique(theInstanceId->second,
- make_pair(theAssociatedSlides[slideIdx], theInstance));
- theAddedInstances.insert(theInstance);
+ m_SourcePathInstanceMap.find(m_StringTable.RegisterStr(theImportRelativePath
+ .toCString()));
+ if (theIter != m_SourcePathInstanceMap.end()) {
+ // First pass just build the group id entries. This avoids us copying hashtables
+ // which may be quite expensive
+ for (TSlideInstanceList::iterator theSlideInst = theIter->second.begin(),
+ theSlideInstEnd = theIter->second.end();
+ theSlideInst != theSlideInstEnd; ++theSlideInst) {
+ TInstanceHandle theRoot = theSlideInst->second;
+ TSlideHandle theSlide = theSlideInst->first;
+
+ // For a depth first search of all children of this object *in this slide*,
+ // if they have an import id then add them to the map.
+ DepthFirstAddImportChildren(theSlide, theRoot, theGroupIdMap,
+ theAddedInstances);
+ TIdMultiMap::iterator theGroupId
+ = theGroupIdMap.insert({m_StringTable.GetWideStr(GetImportId(theRoot)),
+ {}}).first;
+ insert_unique(theGroupId->second, make_pair(theSlide, theRoot));
+ theAddedInstances.insert(theRoot);
+ }
+ // Since some objects may be completely free standing, we need to go through *all*
+ // objects.
+ // Unfortunately the first revision of the system didn't put import paths on objects
+ // so we need both the above loop *and* to consider every object who's import path
+ // matches out import document's relative path.
+ theIter = theImportPaths.find(m_StringTable.RegisterStr(theImportRelativePath
+ .toCString()));
+ TSlideHandleList theAssociatedSlides;
+ if (theIter != theImportPaths.end()) {
+ vector<pair<Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle>> &theInstances
+ = theIter->second;
+ for (size_t i = 0, end = theInstances.size(); i < end; ++i) {
+ if (theAddedInstances.find(theInstances[i].second)
+ != theAddedInstances.end()) {
+ continue;
+ }
+ theAssociatedSlides.clear();
+ Qt3DSDMInstanceHandle theInstance(theInstances[i].second);
+ GetAllAssociatedSlides(theInstance, theAssociatedSlides);
+ TIdMultiMap::iterator theInstanceId
+ = theGroupIdMap
+ .insert({m_StringTable.GetWideStr(GetImportId(theInstance)),
+ {}}).first;
+ for (size_t slideIdx = 0, slideEnd = theAssociatedSlides.size();
+ slideIdx < slideEnd; ++slideIdx) {
+ insert_unique(theInstanceId->second,
+ make_pair(theAssociatedSlides[slideIdx], theInstance));
+ }
+ theAddedInstances.insert(theInstance);
+ }
}
}
- //
// OK, we have distinct maps sorted on a per-slide basis for all trees of children
// of this asset. We now need to attempt to run the refresh algorithm.
- qt3dsimp::ImportPtrOrError theImportPtr = qt3dsimp::Import::Load(theImportFilePath.toCString());
+ qt3dsimp::ImportPtrOrError theImportPtr
+ = qt3dsimp::Import::Load(theImportFilePath.toCString());
if (!theImportPtr.m_Value) {
QT3DS_ASSERT(false);
continue;
@@ -4727,7 +4965,8 @@ public:
Q3DStudio::CString::ENDOFSTRING, false)
&& oldExtension.Compare(CDialogs::GetWideDAEFileExtension(),
Q3DStudio::CString::ENDOFSTRING, false)) {
- SColladaTranslator *colladaTranslator = new SColladaTranslator(inNewFile.toQString());
+ SColladaTranslator *colladaTranslator
+ = new SColladaTranslator(inNewFile.toQString());
translationLog = &(colladaTranslator->m_TranslationLog);
translator = colladaTranslator;
#ifdef QT_3DSTUDIO_FBX
@@ -4763,18 +5002,21 @@ public:
updateMaterialFiles();
}
- void RefreshImport(const CFilePath &inOldFile, const CFilePath &inNewFile) override
+ void RefreshImport(const CFilePath &inOldFile, const CFilePath &inNewFile,
+ const CFilePath &importFilePath) override
{
CDispatch &theDispatch(*m_Doc.GetCore()->GetDispatch());
+
theDispatch.FireOnProgressBegin(
QObject::tr("Refreshing Import "), QFileInfo(inNewFile.toQString()).fileName());
ScopedBoolean __ignoredDirs(m_IgnoreDirChange);
try {
m_SourcePathInstanceMap.clear();
GetSourcePathToInstanceMap(m_SourcePathInstanceMap, true, false);
- DoRefreshImport(inOldFile, inNewFile);
+ DoRefreshImport(inOldFile, inNewFile, importFilePath);
} catch (...) {
}
+
theDispatch.FireOnProgressEnd();
}
@@ -5115,6 +5357,8 @@ public:
if (selectedInstances.size() > 0) {
bool boolValue = false;
SValue value;
+ qt3dsdm::Qt3DSDMInstanceHandle firstFoundCamera;
+ qt3dsdm::Qt3DSDMInstanceHandle foundCameraLayer;
for (size_t idx = 0, end = selectedInstances.size(); idx < end; ++idx) {
qt3dsdm::Qt3DSDMInstanceHandle handle(selectedInstances[idx]);
if (handle.Valid()) {
@@ -5123,7 +5367,21 @@ public:
propertySystem->GetInstancePropertyValue(handle, property, value);
boolValue = !qt3dsdm::get<bool>(value);
}
- propertySystem->SetInstancePropertyValue(handle, property, boolValue);
+ // First found camera is the one that ends up being activated if there are
+ // several in selection, per-layer. Skip the rest if setting eyeball to true.
+ // It is ok to deactivate (hide) all cameras, though.
+ if (m_DataCore.IsInstanceOrDerivedFrom(
+ handle, m_Bridge.GetObjectDefinitions().m_Camera.m_Instance)) {
+ auto currCameraLayer = m_Bridge.GetResidingLayer(handle);
+ if ((!firstFoundCamera.Valid() || boolValue)
+ && !(foundCameraLayer == currCameraLayer)) {
+ firstFoundCamera = handle;
+ foundCameraLayer = currCameraLayer;
+ } else if (boolValue) {
+ continue;
+ }
+ }
+ SetInstancePropertyValue(handle, property, boolValue);
}
}
}
@@ -5215,23 +5473,27 @@ public:
}
m_SourcePathInstanceMap.clear();
- GetSourcePathToInstanceMap(m_SourcePathInstanceMap);
+ GetSourcePathToInstanceMap(m_SourcePathInstanceMap, false);
TInstanceHandleList theParents;
SComposerObjectDefinitions &theDefinitions(m_Bridge.GetObjectDefinitions());
+ QSet<QString> imageLoadSet;
+
+ g_StudioApp.getRenderer().MakeContextCurrent();
for (size_t fileIdx = 0, fileEnd = inList.size(); fileIdx < fileEnd; ++fileIdx) {
const SFileModificationRecord &theRecord(inList[fileIdx]);
- CString theExtension = theRecord.m_File.GetExtension();
- bool isImport = theExtension.Compare(L"import", CString::ENDOFSTRING, false);
+ QString theExtension = theRecord.m_File.GetExtension().toQString().toLower();
+ bool isImport = theExtension == QLatin1String("import");
CFilePath theRelativePath(m_Doc.GetRelativePathToDoc(theRecord.m_File));
const wchar_t *theString(
m_DataCore.GetStringTable().RegisterStr(theRelativePath.toCString()));
- if ((theExtension.CompareNoCase(L"ttf")
- || theExtension.CompareNoCase(L"otf")) // should use CDialogs::IsFontFileExtension
+ if (CDialogs::fontExtensions().contains(theExtension)
&& m_Doc.GetSceneGraph() && m_Doc.GetSceneGraph()->GetTextRenderer()) {
m_Doc.GetSceneGraph()->GetTextRenderer()->ReloadFonts();
+ if (m_Doc.GetSceneGraph()->GetDistanceFieldRenderer())
+ m_Doc.GetSceneGraph()->GetDistanceFieldRenderer()->ReloadFonts();
CFilePath thePath = m_Doc.GetDocumentDirectory();
CFilePath theFontCache = CFilePath::CombineBaseAndRelative(thePath, L"fontcache");
theFontCache.DeleteThisDirectory(true);
@@ -5286,9 +5548,9 @@ public:
if (theInsertResult.second == false)
theInsertResult.first->second = theDAERelativePath;
}
- } else if (theExtension.Compare(L"qml", CString::ENDOFSTRING, false)
+ } else if (CDialogs::behaviorExtensions().contains(theExtension)
&& theRecord.m_ModificationType != FileModificationType::Created
- && theInstances.empty() == false) {
+ && !theInstances.empty()) {
// First, refresh the parent behavior.
if (!hasDispatchNotificationScope) {
theDispatch.FireBeginDataModelNotifications();
@@ -5331,38 +5593,74 @@ public:
}
}
}
- } else if (theExtension.Compare(L"effect", CString::ENDOFSTRING, false)
+ } else if (CDialogs::effectExtensions().contains(theExtension)
&& theRecord.m_ModificationType != FileModificationType::Created
- && theInstances.empty() == false) {
- CString theNameStr = GetName(theInstances[0].second);
+ && !theInstances.empty()) {
std::vector<SMetaDataLoadWarning> theWarnings;
NVScopedRefCounted<qt3ds::render::IRefCountedInputStream> theStream(
m_InputStreamFactory->GetStreamForFile(theRecord.m_File.toQString()));
if (theStream) {
- m_MetaData.LoadEffectInstance(m_StringTable.GetNarrowStr(theRelativePath.toCString()),
+ m_MetaData.LoadEffectInstance(m_StringTable.GetNarrowStr(
+ theRelativePath.toCString()),
theInstances[0].second,
- TCharStr(theNameStr),
+ theRelativePath.GetFileStem().c_str(),
theWarnings, *theStream);
IDocumentEditor::fixDefaultTexturePaths(theInstances[0].second);
}
+ QList<qt3dsdm::Qt3DSDMInstanceHandle> insts;
for (size_t i = 0; i < theInstances.size(); ++i) {
theDispatch.FireReloadEffectInstance(theInstances[i].second);
- theDispatch.FireImmediateRefreshInstance(theInstances[i].second);
+ insts.append(theInstances[i].second);
+ }
+ theDispatch.FireImmediateRefreshInstance(&insts[0], theInstances.size());
+
+ } else if (CDialogs::shaderExtensions().contains(theExtension)
+ && theRecord.m_ModificationType != FileModificationType::Created
+ && !theInstances.empty()) {
+ std::vector<SMetaDataLoadWarning> theWarnings;
+ NVScopedRefCounted<qt3ds::render::IRefCountedInputStream> theStream(
+ m_InputStreamFactory->GetStreamForFile(theRecord.m_File.toQString()));
+ if (theStream) {
+ m_MetaData.LoadMaterialInstance(m_StringTable.GetNarrowStr(
+ theRelativePath.toCString()),
+ theInstances[0].second,
+ theRelativePath.GetFileStem().c_str(),
+ theWarnings,
+ *theStream);
+ IDocumentEditor::fixDefaultTexturePaths(theInstances[0].second);
}
+
+ for (size_t i = 0; i < theInstances.size(); ++i)
+ theDispatch.fireReloadMaterialInstance(theInstances[i].second);
+ } else if (CDialogs::mapExtensions().contains(theExtension)
+ && theRecord.m_ModificationType != FileModificationType::Created
+ && !theInstances.empty()) {
+ imageLoadSet.insert(theRecord.m_File.toQString());
}
// There used to be an extension here for meshes
// but that causes the product to delete materials in some cases which loses work.
- // so that experiment failed and we will just have to let the users manually updated
- // their
- // meshes through the dropdown if they need them updated.
+ // so that experiment failed and we will just have to let the users manually update
+ // their meshes through the dropdown if they need them updated.
+ }
+
+
+ if (!imageLoadSet.isEmpty()) {
+ auto settings = m_Doc.GetCore()->GetStudioProjectSettings();
+ m_Doc.GetBufferCache().reloadImageSet(
+ IBufferManager::resolveImageSet(imageLoadSet,
+ settings->getPreferCompressedTextures()),
+ settings->getFlipCompressedTextures());
}
+
+ g_StudioApp.getRenderer().ReleaseContext();
+
if (hasProgressFired)
theDispatch.FireOnProgressEnd();
- if (requestRender && m_Doc.GetSceneGraph())
- m_Doc.GetSceneGraph()->RequestRender();
if (hasDispatchNotificationScope)
theDispatch.FireEndDataModelNotifications();
+ if (requestRender && m_Doc.GetSceneGraph())
+ m_Doc.GetSceneGraph()->RenderNow();
}
};
}
@@ -5383,24 +5681,37 @@ void IDocumentEditor::DisplayImportErrors(const QString &inImportSource,
for (size_t idx = 0; idx < inTranslationLog.m_Warnings.size(); ++idx) {
const std::pair<ESceneGraphWarningCode, Q3DStudio::CString> &warning(
inTranslationLog.m_Warnings[idx]);
- const wchar_t *formatStr = L"Unrecognized warning";
+ const wchar_t *formatStr = L"Unrecognized warning: \"%ls\"";
switch (warning.first) {
case ESceneGraphWarningCode_OnlySupportTriangles:
- formatStr = L"Model %ls contains geometric elements other than triangles";
+ formatStr = L"Model \"%ls\" contains geometric elements other than triangles";
break;
case ESceneGraphWarningCode_TrianglesDuplicateSemantic:
formatStr = L"Triangle contains duplicate semantics, ex: 1 triangle has multiple "
L"TEXCOORD (multiple UV maps)";
break;
case ESceneGraphWarningCode_MissingSourceFile:
- formatStr = L"Couldn't find a source image file %ls";
+ formatStr = L"Couldn't find a source image file \"%ls\"";
break;
case ESceneGraphWarningCode_LockedDestFile:
- formatStr = L"An image or mesh file %ls is not writeable";
+ formatStr = L"An image or mesh file \"%ls\" is not writeable";
break;
case ESceneGraphWarningCode_VertexBufferTooLarge:
formatStr = L"A single mesh exceeds the maximum vertex count of 65535";
break;
+ case ESceneGraphWarningCode_MissingMaterial:
+ formatStr = L"Materials are missing from mesh \"%ls\", it was not created";
+ break;
+ case ESceneGraphWarningCode_UnsupportedLight:
+ formatStr = L"Light type for \"%ls\" is not supported, it was converted to Directional";
+ break;
+ case ESceneGraphWarningCode_Rotations:
+ formatStr = L"Rotation issue: %ls";
+ break;
+ case ESceneGraphWarningCode_UnknownMaterial:
+ formatStr = L"Unknown material type(s) encountered. Some material properties may be "
+ "incorrect. Make sure your FBX export settings are correct.";
+ break;
default:
break;
}
@@ -5446,16 +5757,17 @@ void IDocumentEditor::fixDefaultTexturePaths(Qt3DSDMInstanceHandle instance)
= propertySystem->GetAdditionalMetaDataType(instance, prop);
if (additionalMetaDataType == AdditionalMetaDataType::Texture) {
propertySystem->GetInstancePropertyValue(instance, prop, value);
- TDataStrPtr strPtr = get<TDataStrPtr>(value);
- const QString strValue = QString::fromWCharArray(strPtr->GetData());
- const QString docRelative = docDir.relativeFilePath(strValue);
- const QString projRelative = projDir.relativeFilePath(strValue);
- if (!QFileInfo(docRelative).exists() && !QFileInfo(projRelative).exists()) {
- // Convert path to presentation relative
- const QVariant newVarValue = QVariant::fromValue(
- docDir.relativeFilePath(projDir.absoluteFilePath(strValue)));
- const SValue newValue = newVarValue;
- propertySystem->SetInstancePropertyValue(instance, prop, newValue);
+ if (value.getType() == DataModelDataType::String) {
+ TDataStrPtr strPtr = get<TDataStrPtr>(value);
+ const QString strValue = QString::fromWCharArray(strPtr->GetData());
+ const QString docRelative = docDir.relativeFilePath(strValue);
+ if (!QFileInfo(docDir.filePath(docRelative)).exists()) {
+ // Convert path to presentation relative
+ const QVariant newVarValue = QVariant::fromValue(
+ docDir.relativeFilePath(projDir.absoluteFilePath(strValue)));
+ const SValue newValue = newVarValue;
+ propertySystem->SetInstancePropertyValue(instance, prop, newValue);
+ }
}
}
}
@@ -5499,6 +5811,11 @@ Qt3DSDMInstanceHandle IDocumentEditor::CreateSceneGraphInstance(
TInstanceHandle theDerivationParent(inMaster);
inDataCore.DeriveInstance(retval, theDerivationParent);
+ // Clear file id derived from the parent
+ // This happens for custom shaders and causes id conflicts (QT3DS-4018)
+ inDataCore.SetInstancePropertyValue(retval, inObjectDefs.m_Asset.m_FileId,
+ std::make_shared<CDataStr>(L""));
+
if (inParent.Valid())
inAssetGraph.AddChild(inParent, retval);
else