summaryrefslogtreecommitdiffstats
path: root/src/Runtime/Source/datamodel/Qt3DSMetadata.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Runtime/Source/datamodel/Qt3DSMetadata.cpp')
-rw-r--r--src/Runtime/Source/datamodel/Qt3DSMetadata.cpp985
1 files changed, 985 insertions, 0 deletions
diff --git a/src/Runtime/Source/datamodel/Qt3DSMetadata.cpp b/src/Runtime/Source/datamodel/Qt3DSMetadata.cpp
new file mode 100644
index 00000000..99d7cb8e
--- /dev/null
+++ b/src/Runtime/Source/datamodel/Qt3DSMetadata.cpp
@@ -0,0 +1,985 @@
+/****************************************************************************
+**
+** Copyright (C) 1993-2009 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "Qt3DSDMPrefix.h"
+#include "Qt3DSMetadata.h"
+#include "SimpleDataCore.h"
+#include "Qt3DSDMXML.h"
+#include "foundation/IOStreams.h"
+#include "Qt3DSEulerAngles.h"
+#include "Qt3DSDMWindowsCompatibility.h"
+#include "Qt3DSDMComposerTypeDefinitions.h"
+#include "DocumentResourceManagerScriptParser.h"
+#include "foundation/StrConvertUTF.h"
+#include "Qt3DSRenderInputStreamFactory.h"
+#include "foundation/FileTools.h"
+#include "foundation/TrackingAllocator.h"
+#include "EASTL/hash_map.h"
+#include "DocumentResourceManagerRenderPluginParser.h"
+#include "foundation/Qt3DSFoundation.h"
+#include "foundation/StringTable.h"
+
+using qt3ds::render::IInputStreamFactory;
+using qt3ds::render::IRefCountedInputStream;
+
+using namespace qt3dsdm;
+using namespace Q3DStudio;
+
+namespace {
+
+
+struct SImportXmlErrorHandler : public CXmlErrorHandler
+{
+ void OnXmlError(const QString &errorName, int line, int) override
+ {
+ qCCritical(INTERNAL_ERROR) << "XML error:"
+ << errorName << "on line" << line;
+ }
+};
+
+struct SRuntimeMetaDataPropertyInfo
+{
+ ERuntimeDataModelDataType m_DataType;
+ ERuntimeAdditionalMetaDataType m_AdditionalType;
+ Option<SValue> m_Value;
+ bool m_Exist;
+ SRuntimeMetaDataPropertyInfo(ERuntimeDataModelDataType inDataType,
+ ERuntimeAdditionalMetaDataType inAdditionalType,
+ const Option<SValue> &inValue, bool inExist)
+ : m_DataType(inDataType)
+ , m_AdditionalType(inAdditionalType)
+ , m_Value(inValue)
+ , m_Exist(inExist)
+ {
+ }
+ SRuntimeMetaDataPropertyInfo()
+ : m_DataType(ERuntimeDataModelDataTypeNone)
+ , m_AdditionalType(ERuntimeAdditionalMetaDataTypeNone)
+ , m_Exist(false)
+ {
+ }
+};
+
+struct SPropertyKey
+{
+ const char8_t *m_TypeOrId;
+ const char8_t *m_PropertyName;
+
+ // The character pointers are expected to have come from the string table
+ // thus we can safely use their exact pointer addresses for the hash code.
+ SPropertyKey(const char8_t *typeOrId, const char8_t *inPname)
+ : m_TypeOrId(typeOrId)
+ , m_PropertyName(inPname)
+ {
+ }
+ bool operator==(const SPropertyKey &inOther) const
+ {
+ // equality comparison safe since strings are assumed to come from string table.
+ return m_TypeOrId == inOther.m_TypeOrId && m_PropertyName == inOther.m_PropertyName;
+ }
+};
+}
+
+namespace eastl {
+template <>
+struct hash<SPropertyKey>
+{
+ size_t operator()(const SPropertyKey &inKey) const
+ {
+ return reinterpret_cast<size_t>(inKey.m_TypeOrId)
+ ^ reinterpret_cast<size_t>(inKey.m_PropertyName);
+ }
+};
+}
+
+namespace {
+
+//===========================================================================
+/**
+ * @class SRuntimeMetaDataImpl
+ * @brief implements the IRumtimeMetaData interface class
+ */
+struct SRuntimeMetaDataImpl : public IRuntimeMetaData
+{
+
+private:
+ typedef std::map<TCharStr, int> TIdToHandleMap;
+ typedef eastl::hash_map<SPropertyKey, SRuntimeMetaDataPropertyInfo> TPropertyLookupHash;
+
+ //==============================================================================
+ // Fields
+ //==============================================================================
+ std::shared_ptr<qt3dsdm::IStringTable> m_StrTable;
+ std::shared_ptr<IDataCore> m_DataCore;
+ std::shared_ptr<IMetaData> m_NewMetaData;
+ std::shared_ptr<SComposerObjectDefinitions> m_Objects;
+ std::vector<TCharStr> m_TempReferences;
+
+ TIdToHandleMap m_IdToHandleMap;
+ // We cache properties by id or by instance so that the same query for the same value
+ // will return an answer instantly instead of calling GetAggregateInstancePropertyByName which
+ // is really
+ // expensive.
+ TPropertyLookupHash m_PropertyLookupHash;
+ IInputStreamFactory &m_InputStreamFactory;
+
+ // Helper to convert char to wchar_t
+ eastl::basic_string<qt3ds::foundation::TWCharEASTLConverter::TCharType> m_Buf[4];
+
+public:
+ static void SimpleDataModelLogger(const char *inMessage)
+ {
+ qCInfo(TRACE_INFO) << SRuntimeMetaDataImpl::SimpleDataModelLogger
+ << inMessage;
+ }
+ //==============================================================================
+ /**
+ * Constructor
+ */
+ SRuntimeMetaDataImpl(IInputStreamFactory &inFactory)
+ : m_InputStreamFactory(inFactory)
+ {
+ // Use this to enable some simple uicdm debug logging. Beware of a *lot* of log output.
+ // g_DataModelDebugLogger = SimpleDataModelLogger;
+ try {
+ // need to pause here to hook up the debugger
+ m_StrTable = qt3dsdm::IStringTable::CreateStringTable();
+ m_DataCore = std::make_shared<CSimpleDataCore>(m_StrTable);
+ m_NewMetaData = IMetaData::CreateNewMetaData(m_DataCore);
+
+ m_Objects = std::make_shared<SComposerObjectDefinitions>(std::ref(*m_DataCore),
+ std::ref(*m_NewMetaData));
+ } catch (qt3dsdm::Qt3DSDMError &error) {
+ qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl Qt3DSDMError: "
+ << m_StrTable->GetNarrowStr(error.m_Message);
+ } catch (std::runtime_error &exc) {
+ if (exc.what()) {
+ qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::runtime_error: "
+ << exc.what();
+ } else {
+ qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::runtime_error";
+ }
+ } catch (std::exception &exc) {
+ if (exc.what()) {
+ qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::exception: "
+ << exc.what();
+ } else {
+ qCCritical(INTERNAL_ERROR) << "SRuntimeMetaDataImpl std::exception";
+ }
+ }
+ }
+
+ void Load()
+ {
+ // Create the base types.
+ std::shared_ptr<IDOMFactory> theFactory(IDOMFactory::CreateDOMFactory(m_StrTable));
+ const char8_t *theMetaDataPath = GetMetaDataDirectory();
+ NVScopedRefCounted<IRefCountedInputStream> theInStream(
+ m_InputStreamFactory.GetStreamForFile(theMetaDataPath));
+ SDOMElement *topElement = NULL;
+ if (theInStream)
+ topElement = CDOMSerializer::Read(*theFactory, *theInStream);
+ if (topElement) {
+ shared_ptr<IDOMReader> theReader =
+ IDOMReader::CreateDOMReader(*topElement, m_StrTable, theFactory);
+ m_NewMetaData->Load(*theReader);
+
+ } else {
+ qCCritical(INVALID_OPERATION) << "Metadata loading failed", "Failed to find meta data file";
+ // Q3DStudio_ASSERT requires static linkage to UICSystem, which is only used
+ // by UICEngine and UICRuntime
+ // QT3DS_ASSERT requires the qt3ds foundation libraries which are used by all products.
+ QT3DS_ASSERT(false);
+ return;
+ }
+ }
+
+ // Helper to convert wchar_t to eastl::string
+ static inline void ConvertWide(const wchar_t *inType, eastl::string &outStr)
+ {
+ if (inType && *inType)
+ qt3ds::foundation::ConvertUTF(
+ reinterpret_cast<const qt3ds::foundation::TWCharEASTLConverter::TCharType *>(inType),
+ 0, outStr);
+ else
+ outStr.clear();
+ }
+
+ // Helper to convert char to wchar_t
+ const wchar_t *ConvertChar(const char *inName, int inBufferIndex)
+ {
+ if (inName && *inName) {
+ qt3ds::foundation::ConvertUTF(inName, 0, m_Buf[inBufferIndex]);
+ return reinterpret_cast<const wchar_t *>(m_Buf[inBufferIndex].c_str());
+ }
+ return NULL;
+ }
+ inline const wchar_t *Convert0(const char *inName) { return ConvertChar(inName, 0); }
+ inline const wchar_t *Convert1(const char *inName) { return ConvertChar(inName, 1); }
+ inline const wchar_t *Convert2(const char *inName) { return ConvertChar(inName, 2); }
+ inline const wchar_t *Convert3(const char *inName) { return ConvertChar(inName, 3); }
+
+ inline Qt3DSDMInstanceHandle GetInstanceForType(const wchar_t *inType)
+ {
+ return m_Objects->GetInstanceForType(ComposerObjectTypes::Convert(inType));
+ }
+
+ Qt3DSDMInstanceHandle GetInstanceById(const wchar_t *inId)
+ {
+ if (IsTrivial(inId))
+ return 0;
+ if (inId[0] == '#')
+ ++inId;
+
+ TIdToHandleMap::iterator find = m_IdToHandleMap.find(inId);
+ if (find != m_IdToHandleMap.end())
+ return find->second;
+ return 0;
+ }
+
+ virtual bool IsPropertyExist(const wchar_t *inType, const wchar_t *inProperty,
+ const wchar_t *inId)
+ {
+ Qt3DSDMInstanceHandle theInstance =
+ IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId);
+ if (theInstance.Valid()) {
+ Qt3DSDMPropertyHandle theProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty);
+
+ return theProperty.Valid();
+ }
+ return false;
+ }
+
+ ERuntimeDataModelDataType Convert(DataModelDataType::Value inType)
+ {
+ switch (inType) {
+ case DataModelDataType::None:
+ return ERuntimeDataModelDataTypeNone;
+ case DataModelDataType::Float:
+ return ERuntimeDataModelDataTypeFloat;
+ case DataModelDataType::Float2:
+ return ERuntimeDataModelDataTypeFloat2;
+ case DataModelDataType::Float3:
+ return ERuntimeDataModelDataTypeFloat3;
+ case DataModelDataType::Long:
+ return ERuntimeDataModelDataTypeLong;
+ case DataModelDataType::String:
+ return ERuntimeDataModelDataTypeString;
+ case DataModelDataType::Bool:
+ return ERuntimeDataModelDataTypeBool;
+ case DataModelDataType::Long4:
+ return ERuntimeDataModelDataTypeLong4;
+ case DataModelDataType::StringRef:
+ return ERuntimeDataModelDataTypeStringRef;
+ case DataModelDataType::ObjectRef:
+ return ERuntimeDataModelDataTypeObjectRef;
+ case DataModelDataType::StringOrInt:
+ return ERuntimeDataModelDataTypeStringOrInt;
+ default:
+ QT3DS_ASSERT(false);
+ return ERuntimeDataModelDataTypeNone;
+ }
+ }
+
+ virtual ERuntimeDataModelDataType
+ GetPropertyType(const wchar_t *inType, const wchar_t *inProperty, const wchar_t *inId)
+ {
+ Qt3DSDMInstanceHandle theInstance =
+ IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId);
+ Qt3DSDMPropertyHandle theProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty);
+ return Convert(m_DataCore->GetProperty(theProperty).m_Type);
+ }
+
+ ERuntimeAdditionalMetaDataType Convert(AdditionalMetaDataType::Value inType)
+ {
+ switch (inType) {
+ case AdditionalMetaDataType::None:
+ return ERuntimeAdditionalMetaDataTypeNone;
+ case AdditionalMetaDataType::StringList:
+ return ERuntimeAdditionalMetaDataTypeStringList;
+ case AdditionalMetaDataType::Range:
+ return ERuntimeAdditionalMetaDataTypeRange;
+ case AdditionalMetaDataType::Image:
+ return ERuntimeAdditionalMetaDataTypeImage;
+ case AdditionalMetaDataType::Color:
+ return ERuntimeAdditionalMetaDataTypeColor;
+ case AdditionalMetaDataType::Rotation:
+ return ERuntimeAdditionalMetaDataTypeRotation;
+ case AdditionalMetaDataType::Font:
+ return ERuntimeAdditionalMetaDataTypeFont;
+ case AdditionalMetaDataType::FontSize:
+ return ERuntimeAdditionalMetaDataTypeFontSize;
+ case AdditionalMetaDataType::MultiLine:
+ return ERuntimeAdditionalMetaDataTypeMultiLine;
+ case AdditionalMetaDataType::ObjectRef:
+ return ERuntimeAdditionalMetaDataTypeObjectRef;
+ case AdditionalMetaDataType::Mesh:
+ return ERuntimeAdditionalMetaDataTypeMesh;
+ case AdditionalMetaDataType::Import:
+ return ERuntimeAdditionalMetaDataTypeImport;
+ case AdditionalMetaDataType::Texture:
+ return ERuntimeAdditionalMetaDataTypeTexture;
+ case AdditionalMetaDataType::Renderable:
+ return ERuntimeAdditionalMetaDataTypeRenderable;
+ case AdditionalMetaDataType::PathBuffer:
+ return ERuntimeAdditionalMetaDataTypePathBuffer;
+ case AdditionalMetaDataType::ShadowMapResolution:
+ return ERuntimeAdditionalMetaDataTypeShadowMapResolution;
+ case AdditionalMetaDataType::String:
+ return ERuntimeAdditionalMetaDataTypeString;
+ default:
+ QT3DS_ASSERT(false);
+ return ERuntimeAdditionalMetaDataTypeNone;
+ }
+ }
+
+ virtual ERuntimeAdditionalMetaDataType
+ GetAdditionalType(const wchar_t *inType, const wchar_t *inProperty, const wchar_t *inId)
+ {
+ Qt3DSDMInstanceHandle theInstance =
+ IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId);
+ Qt3DSDMPropertyHandle theProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty);
+ return Convert(m_NewMetaData->GetAdditionalMetaDataType(theInstance, theProperty));
+ }
+
+ bool GetPropertyValue(const wchar_t *inType, const wchar_t *inProperty, const wchar_t *inId,
+ SValue &outValue)
+ {
+ Qt3DSDMInstanceHandle theInstance =
+ IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId);
+ if (theInstance.Valid()) {
+ Qt3DSDMPropertyHandle theProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty);
+ return m_DataCore->GetInstancePropertyValue(theInstance, theProperty, outValue);
+ } else {
+ eastl::string typeStr;
+ eastl::string propertyStr;
+ eastl::string idStr;
+ ConvertWide(inType, typeStr);
+ ConvertWide(inProperty, propertyStr);
+ ConvertWide(inId, idStr);
+ qCCritical(INVALID_OPERATION) << "GetPropertyValueString: "
+ << typeStr.c_str() << " "
+ << propertyStr.c_str() << " "
+ << idStr.c_str();
+ QT3DS_ASSERT(false);
+ }
+ return false;
+ }
+
+ SRuntimeMetaDataPropertyInfo &FindProperty(TStrTableStr inType, TStrTableStr inProperty,
+ TStrTableStr inId)
+ {
+ TStrTableStr theTypeOrId = inId.IsValid() ? inId : inType;
+ SPropertyKey theKey(theTypeOrId, inProperty);
+ eastl::pair<TPropertyLookupHash::iterator, bool> theLookup =
+ m_PropertyLookupHash.insert(eastl::make_pair(theKey, SRuntimeMetaDataPropertyInfo()));
+ if (theLookup.second) {
+ const wchar_t *theType(Convert0(inType));
+ const wchar_t *theProperty(Convert1(inProperty));
+ const wchar_t *theId(Convert2(inId));
+ if (IsPropertyExist(theType, theProperty, theId)) {
+ ERuntimeDataModelDataType theDataType(GetPropertyType(theType, theProperty, theId));
+ ERuntimeAdditionalMetaDataType theAdditionalType(
+ GetAdditionalType(theType, theProperty, theId));
+ Option<SValue> theValue;
+ SValue theValueData;
+ if (GetPropertyValue(theType, theProperty, theId, theValueData))
+ theValue = theValueData.toOldSkool();
+ theLookup.first->second =
+ SRuntimeMetaDataPropertyInfo(theDataType, theAdditionalType, theValue, true);
+ }
+ }
+ return theLookup.first->second;
+ }
+
+ bool IsPropertyExist(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override
+ {
+ return FindProperty(inType, inProperty, inId).m_Exist;
+ }
+
+ ERuntimeDataModelDataType GetPropertyType(TStrTableStr inType, TStrTableStr inProperty,
+ TStrTableStr inId) override
+ {
+ return FindProperty(inType, inProperty, inId).m_DataType;
+ }
+
+ virtual ERuntimeAdditionalMetaDataType
+ GetAdditionalType(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override
+ {
+ return FindProperty(inType, inProperty, inId).m_AdditionalType;
+ }
+
+ Option<float> GetPropertyValueFloat(TStrTableStr inType, TStrTableStr inProperty,
+ TStrTableStr inId) override
+ {
+ SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId));
+ if (theInfo.m_Value.hasValue())
+ return qt3dsdm::get<float>(*theInfo.m_Value);
+ return Empty();
+ }
+
+ Option<qt3ds::QT3DSVec3> GetPropertyValueVector2(TStrTableStr inType, TStrTableStr inProperty,
+ TStrTableStr inId) override
+ {
+ SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId));
+ if (theInfo.m_Value.hasValue()) {
+ SFloat2 theFloat2 = qt3dsdm::get<SFloat2>(*theInfo.m_Value);
+ return qt3ds::QT3DSVec3(theFloat2[0], theFloat2[1], 0);
+ }
+ return Empty();
+ }
+
+ Option<qt3ds::QT3DSVec3> GetPropertyValueVector3(TStrTableStr inType, TStrTableStr inProperty,
+ TStrTableStr inId) override
+ {
+ SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId));
+ if (theInfo.m_Value.hasValue()) {
+ SFloat3 theFloat3 = qt3dsdm::get<SFloat3>(*theInfo.m_Value);
+ return qt3ds::QT3DSVec3(theFloat3[0], theFloat3[1], theFloat3[2]);
+ }
+ return Empty();
+ }
+
+ virtual Option<qt3ds::QT3DSI32> GetPropertyValueLong(TStrTableStr inType, TStrTableStr inProperty,
+ TStrTableStr inId) override
+ {
+ SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId));
+ if (theInfo.m_Value.hasValue())
+ return qt3dsdm::get<qt3ds::QT3DSI32>(*theInfo.m_Value);
+ return Empty();
+ }
+
+ virtual Option<TRuntimeMetaDataStrType>
+ GetPropertyValueString(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override
+ {
+ SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId));
+ if (theInfo.m_Value.hasValue()) {
+ TDataStrPtr theStr = qt3dsdm::get<TDataStrPtr>(*theInfo.m_Value);
+ TRuntimeMetaDataStrType retval;
+ qt3ds::foundation::ConvertUTF(
+ reinterpret_cast<const qt3ds::foundation::TWCharEASTLConverter::TCharType *>(
+ theStr->GetData()),
+ 0, retval);
+ return retval;
+ }
+ return Empty();
+ }
+
+ virtual Option<TRuntimeMetaDataStrType>
+ GetPropertyValueObjectRef(TStrTableStr inType, TStrTableStr inProperty, TStrTableStr inId) override
+ {
+ SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId));
+ if (theInfo.m_Value.hasValue()) {
+ SObjectRefType theObjectRef = ConvertToObjectRef(*theInfo.m_Value);
+ if (theObjectRef.GetReferenceType() == ObjectReferenceType::Relative) {
+ TDataStrPtr theStr = qt3dsdm::get<TDataStrPtr>(theObjectRef.m_Value);
+ TRuntimeMetaDataStrType retval;
+ qt3ds::foundation::ConvertUTF(
+ reinterpret_cast<const qt3ds::foundation::TWCharEASTLConverter::TCharType *>(
+ theStr->GetData()),
+ 0, retval);
+ return retval;
+ } else // we don't know how to solve absolute reference type
+ {
+ // QT3DS_ASSERT( false );
+ return TRuntimeMetaDataStrType("");
+ }
+ }
+ return Empty();
+ }
+
+ Option<bool> GetPropertyValueBool(TStrTableStr inType, TStrTableStr inProperty,
+ TStrTableStr inId) override
+ {
+ SRuntimeMetaDataPropertyInfo &theInfo(FindProperty(inType, inProperty, inId));
+ if (theInfo.m_Value.hasValue())
+ return qt3dsdm::get<bool>(*theInfo.m_Value);
+ return Empty();
+ }
+
+ virtual void GetReferences(const wchar_t *inType,
+ eastl::vector<TRuntimeMetaDataStrType> &outReferences,
+ const wchar_t *inId)
+ {
+ Qt3DSDMInstanceHandle theInstance =
+ IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId);
+
+ if (theInstance.Valid()) {
+ m_TempReferences.clear();
+ m_NewMetaData->GetReferences(theInstance, m_TempReferences);
+ outReferences.resize((uint32_t)m_TempReferences.size());
+ for (uint32_t idx = 0, end = (uint32_t)m_TempReferences.size(); idx < end; ++idx) {
+ qt3ds::foundation::ConvertUTF(m_TempReferences[idx].c_str(),
+ m_TempReferences[idx].size(), outReferences[idx]);
+ }
+ }
+ }
+
+ void GetReferences(const char *inType,
+ eastl::vector<TRuntimeMetaDataStrType> &outReferences,
+ const char *inId) override
+ {
+ GetReferences(Convert0(inType), outReferences, Convert2(inId));
+ }
+
+ virtual bool IsCustomProperty(const wchar_t *inId, const wchar_t *inProperty)
+ {
+ Qt3DSDMInstanceHandle theInstance = GetInstanceById(inId);
+ Qt3DSDMPropertyHandle theProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(theInstance, inProperty);
+ return m_NewMetaData->IsCustomProperty(theInstance, theProperty);
+ }
+
+ bool IsCustomProperty(const char *inId, const char *inProperty) override
+ {
+ return IsCustomProperty(Convert2(inId), Convert1(inProperty));
+ }
+
+ virtual bool IsCustomHandler(const wchar_t *inId, const wchar_t *inHandlerName)
+ {
+ Qt3DSDMInstanceHandle theInstance = GetInstanceById(inId);
+ Qt3DSDMHandlerHandle theHandle =
+ m_NewMetaData->FindHandlerByName(theInstance, inHandlerName);
+ return m_NewMetaData->IsCustomHandler(theHandle);
+ }
+
+ inline void SetDataType(SAttOrArg &arg, const SMetaPropertyBase &argInfo)
+ {
+ arg.m_DataType = Convert(argInfo.GetDataType());
+ arg.m_MetaType = Convert(argInfo.GetAdditionalType());
+ qt3ds::foundation::ConvertUTF(argInfo.m_Name.c_str(), argInfo.m_Name.size(), arg.m_Name);
+ qt3ds::foundation::ConvertUTF(argInfo.m_FormalName.c_str(), argInfo.m_FormalName.size(),
+ arg.m_FormalName);
+ switch (argInfo.GetAdditionalType()) {
+ case qt3dsdm::AdditionalMetaDataType::StringList: {
+ const eastl::vector<TCharStr> &theData =
+ argInfo.m_MetaDataData.getData<eastl::vector<TCharStr>>();
+ arg.m_MetaDataList.resize(theData.size());
+ for (uint32_t metaIdx = 0, metaEnd = theData.size(); metaIdx < metaEnd; ++metaIdx)
+ qt3ds::foundation::ConvertUTF(theData[metaIdx].c_str(), theData[metaIdx].size(),
+ arg.m_MetaDataList[metaIdx]);
+ } break;
+ case qt3dsdm::AdditionalMetaDataType::Range: {
+ const SMetaDataRange &range = argInfo.m_MetaDataData.getData<SMetaDataRange>();
+ arg.m_MetaDataRange = eastl::make_pair(range.m_Min, range.m_Max);
+ } break;
+ default:
+ break;
+ }
+ }
+
+ THandlerList GetCustomHandlers(const char *inId) override
+ {
+ THandlerList retval;
+ Qt3DSDMInstanceHandle theInstance = GetInstanceById(Convert0(inId));
+ THandlerHandleList handlerList;
+ m_NewMetaData->GetHandlers(theInstance, handlerList);
+ retval.reserve((uint32_t)handlerList.size());
+ for (size_t idx = 0, end = handlerList.size(); idx < end; ++idx) {
+ if (m_NewMetaData->IsCustomHandler(handlerList[idx])) {
+ SHandlerInfo theInfo(m_NewMetaData->GetHandlerInfo(handlerList[idx]));
+ retval.push_back(SHandler());
+ SHandler &handler(retval.back());
+ qt3ds::foundation::ConvertUTF(theInfo.m_Name.c_str(), theInfo.m_Name.size(),
+ handler.m_Name);
+ qt3ds::foundation::ConvertUTF(theInfo.m_FormalName.c_str(),
+ theInfo.m_FormalName.size(), handler.m_FormalName);
+ vector<SMetaDataHandlerArgumentInfo> theArgInfo;
+ m_NewMetaData->GetHandlerArguments(handlerList[idx], theArgInfo);
+ handler.m_Arguments.resize((uint32_t)theArgInfo.size());
+ for (uint32_t argIdx = 0, argEnd = (uint32_t)theArgInfo.size(); argIdx < argEnd;
+ ++argIdx) {
+ const SMetaDataHandlerArgumentInfo &argInfo(theArgInfo[argIdx]);
+ SAttOrArg &arg = handler.m_Arguments[argIdx];
+ SetDataType(arg, argInfo);
+ }
+ }
+ }
+ return retval;
+ }
+
+ TVisualEventList GetVisualEvents(const char *inId) override
+ {
+ TVisualEventList theRetval;
+ Qt3DSDMInstanceHandle theInstance = GetInstanceById(Convert0(inId));
+ TEventHandleList theEventList;
+ m_NewMetaData->GetEvents(theInstance, theEventList);
+ theRetval.reserve((uint32_t)theEventList.size());
+ for (uint32_t idx = 0, end = (uint32_t)theEventList.size(); idx < end; ++idx) {
+ SEventInfo theInfo(m_NewMetaData->GetEventInfo(theEventList[idx]));
+ theRetval.push_back(SVisualEvent());
+ SVisualEvent &theEvent(theRetval.back());
+ qt3ds::foundation::ConvertUTF(theInfo.m_Name.c_str(), theInfo.m_Name.size(),
+ theEvent.m_Name);
+ qt3ds::foundation::ConvertUTF(theInfo.m_FormalName.c_str(), theInfo.m_FormalName.size(),
+ theEvent.m_FormalName);
+ }
+ return theRetval;
+ }
+
+ void MetaPropertiesToAttList(vector<Qt3DSDMMetaDataPropertyHandle> &theProperties,
+ TAttOrArgList &outAtts)
+ {
+ outAtts.reserve((uint32_t)theProperties.size());
+ for (uint32_t idx = 0, end = (uint32_t)theProperties.size(); idx < end; ++idx) {
+ SMetaDataPropertyInfo thePropInfo =
+ m_NewMetaData->GetMetaDataPropertyInfo(theProperties[idx]);
+ outAtts.push_back(SAttOrArg());
+ SAttOrArg &arg(outAtts.back());
+ arg.m_DataType = Convert(thePropInfo.GetDataType());
+ arg.m_MetaType = Convert(thePropInfo.GetAdditionalType());
+ qt3ds::foundation::ConvertUTF(thePropInfo.m_Name.c_str(), thePropInfo.m_Name.size(),
+ arg.m_Name);
+ qt3ds::foundation::ConvertUTF(thePropInfo.m_FormalName.c_str(),
+ thePropInfo.m_FormalName.size(), arg.m_FormalName);
+ SetDataType(arg, thePropInfo);
+ }
+ }
+
+ SElementInfo LoadElement(const char *clsName, const char *clsRef, const char *inId) override
+ {
+ SElementInfo retval;
+ Qt3DSDMInstanceHandle theInstance;
+ Qt3DSDMInstanceHandle parentInstance;
+ if (!qt3ds::foundation::isTrivial(clsRef)) {
+ if (clsRef[0] == '#')
+ ++clsRef;
+ parentInstance = GetInstanceById(Convert0(clsRef));
+ } else {
+ parentInstance = m_NewMetaData->GetCanonicalInstanceForType(Convert0(clsName));
+ }
+ if (parentInstance.Valid() == false) {
+ QT3DS_ASSERT(false);
+ return retval;
+ }
+ theInstance = m_DataCore->CreateInstance();
+ m_DataCore->DeriveInstance(theInstance, parentInstance);
+ m_IdToHandleMap.insert(std::make_pair(TCharStr(Convert0(inId)), theInstance));
+ // setup isComponent
+ Qt3DSDMInstanceHandle slideOwner = m_NewMetaData->GetCanonicalInstanceForType(L"SlideOwner");
+ retval.m_IsComponent = m_DataCore->IsInstanceOrDerivedFrom(theInstance, slideOwner);
+ TCharStr type = m_NewMetaData->GetTypeForInstance(theInstance);
+ qt3ds::foundation::ConvertUTF(type.c_str(), type.size(), retval.m_ClassName);
+ vector<Qt3DSDMMetaDataPropertyHandle> theProperties;
+ m_NewMetaData->GetMetaDataProperties(theInstance, theProperties);
+ MetaPropertiesToAttList(theProperties, retval.m_Attributes);
+ return retval;
+ }
+
+ TAttOrArgList GetSlideAttributes() override
+ {
+ TAttOrArgList retval;
+ Qt3DSDMInstanceHandle slideOwner = m_NewMetaData->GetCanonicalInstanceForType(L"Slide");
+ vector<Qt3DSDMMetaDataPropertyHandle> theProperties;
+ m_NewMetaData->GetSpecificMetaDataProperties(slideOwner, theProperties);
+ MetaPropertiesToAttList(theProperties, retval);
+ return retval;
+ }
+
+ bool IsCustomHandler(const char *inId, const char *inHandlerName) override
+ {
+ return IsCustomHandler(Convert0(inId), Convert1(inHandlerName));
+ }
+
+ virtual void GetHandlerArgumentType(const wchar_t *inId, const wchar_t *inHandlerName,
+ const wchar_t *inArgumentName,
+ ERuntimeDataModelDataType &outType,
+ ERuntimeAdditionalMetaDataType &outAdditionalType)
+ {
+ outType = ERuntimeDataModelDataTypeNone;
+ outAdditionalType = ERuntimeAdditionalMetaDataTypeNone;
+
+ Qt3DSDMInstanceHandle theInstance = GetInstanceById(inId);
+ Qt3DSDMHandlerHandle theHandle =
+ m_NewMetaData->FindHandlerByName(theInstance, inHandlerName);
+ Option<SMetaDataHandlerArgumentInfo> theArgMetaData(
+ m_NewMetaData->FindHandlerArgumentByName(theHandle, inArgumentName));
+ if (theArgMetaData.hasValue()) {
+ outType = Convert(theArgMetaData->GetDataType());
+ outAdditionalType = Convert(theArgMetaData->GetAdditionalType());
+ }
+
+ // Check if the type is something that we support
+ QT3DS_ASSERT(outType != ERuntimeDataModelDataTypeNone);
+ }
+
+ void GetHandlerArgumentType(const char *inId, const char *inHandlerName,
+ const char *inArgumentName,
+ ERuntimeDataModelDataType &outType,
+ ERuntimeAdditionalMetaDataType &outAdditionalType) override
+ {
+ GetHandlerArgumentType(Convert0(inId), Convert1(inHandlerName), Convert2(inArgumentName),
+ outType, outAdditionalType);
+ }
+
+ std::shared_ptr<IDOMReader> ParseScriptFile(const wchar_t *inFullPathToDocument,
+ std::shared_ptr<qt3dsdm::IStringTable> inStringTable)
+ {
+ using namespace ScriptParser;
+ std::shared_ptr<qt3dsdm::IStringTable> theStringTable(inStringTable);
+ std::shared_ptr<IDOMFactory> theFactory(IDOMFactory::CreateDOMFactory(theStringTable));
+ SImportXmlErrorHandler theXmlErrorHandler;
+ const QString path = QString::fromWCharArray(inFullPathToDocument);
+ std::shared_ptr<IDOMReader> theReaderPtr(
+ SScriptParser::ParseScriptFile(theFactory, inStringTable,
+ path,
+ theXmlErrorHandler, m_InputStreamFactory));
+ if (!theReaderPtr)
+ qCCritical(INVALID_OPERATION) << "Failed to open script file: " << path;
+ return theReaderPtr;
+ }
+
+ Qt3DSDMInstanceHandle CreateAndDeriveInstance(const wchar_t *inType, const wchar_t *inId)
+ {
+ // Make sure that the same id has not been created before
+ TCharStr theId(inId);
+ QT3DS_ASSERT(m_IdToHandleMap.find(theId) == m_IdToHandleMap.end());
+
+ Qt3DSDMInstanceHandle theCanonicalType(m_NewMetaData->GetCanonicalInstanceForType(inType));
+ if (theCanonicalType.Valid() == false) {
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ Qt3DSDMInstanceHandle theMaster = m_DataCore->CreateInstance();
+ m_DataCore->DeriveInstance(theMaster, theCanonicalType);
+ m_IdToHandleMap.insert(std::make_pair(theId, theMaster));
+ return theMaster;
+ }
+
+ virtual bool LoadScriptFile(const wchar_t *inType, const wchar_t *inId, const wchar_t *inName,
+ const wchar_t *inSourcePath)
+ {
+ TCharStr theId(inId);
+ if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end())
+ return true;
+
+ Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(inType, inId);
+ if (!theMaster.Valid())
+ return false;
+
+ std::shared_ptr<IDOMReader> theScriptPtr =
+ ParseScriptFile(inSourcePath, m_DataCore->GetStringTablePtr());
+ if (theScriptPtr) {
+ std::vector<SMetaDataLoadWarning> warnings;
+ // Now the magic section
+ m_NewMetaData->LoadInstance(*theScriptPtr, theMaster, inName, warnings);
+
+ // Set the name
+ Qt3DSDMPropertyHandle theProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(theMaster, L"name");
+ m_DataCore->SetInstancePropertyValue(theMaster, theProperty,
+ std::make_shared<CDataStr>(inName));
+ return true;
+ }
+
+ return false;
+ }
+
+ bool LoadScriptFile(const char *inType, const char *inId, const char *inName,
+ const char *inSourcePath) override
+ {
+ return LoadScriptFile(Convert0(inType), Convert1(inId), Convert2(inName),
+ Convert3(inSourcePath));
+ }
+
+ bool LoadEffectXMLFile(const char *inType, const char *inId, const char *inName,
+ const char *inSourcePath) override
+ {
+ const wchar_t *theType(Convert0(inType));
+ const wchar_t *theId(Convert1(inId));
+ const wchar_t *theName(Convert2(inName));
+ if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end())
+ return true;
+
+ Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(theType, theId);
+ if (!theMaster.Valid())
+ return false;
+ NVScopedRefCounted<IRefCountedInputStream> theStream(
+ m_InputStreamFactory.GetStreamForFile(inSourcePath));
+ if (theStream) {
+ std::vector<SMetaDataLoadWarning> warnings;
+ bool success = m_NewMetaData->LoadEffectXMLFromSourcePath(
+ inSourcePath, theMaster, theName, warnings, *theStream);
+ (void)success;
+ QT3DS_ASSERT(success);
+ return success;
+ }
+ return false;
+ }
+
+ bool LoadMaterialXMLFile(const char *inType, const char *inId, const char *inName,
+ const char *inSourcePath) override
+ {
+ const wchar_t *theType(Convert0(inType));
+ const wchar_t *theId(Convert1(inId));
+ const wchar_t *theName(Convert2(inName));
+ (void)theName;
+ if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end())
+ return true;
+
+ Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(theType, theId);
+ if (!theMaster.Valid())
+ return false;
+
+ NVScopedRefCounted<IRefCountedInputStream> theStream(
+ m_InputStreamFactory.GetStreamForFile(inSourcePath));
+ if (theStream) {
+ std::vector<SMetaDataLoadWarning> warnings;
+ bool success = m_NewMetaData->LoadMaterialClassFromSourcePath(
+ inSourcePath, theMaster, theId, warnings, *theStream);
+ (void)success;
+ QT3DS_ASSERT(success);
+ return success;
+ }
+ return false;
+ }
+
+ struct PluginErrorHandler : public qt3dsdm::CXmlErrorHandler
+ {
+ void OnXmlError(const QString &, int, int) override {}
+ };
+
+ bool LoadPluginXMLFile(const char *inType, const char *inId, const char *inName,
+ const char *inSourcePath) override
+ {
+ const wchar_t *theType(Convert0(inType));
+ const wchar_t *theId(Convert1(inId));
+ const wchar_t *theName(Convert2(inName));
+ if (m_IdToHandleMap.find(theId) != m_IdToHandleMap.end())
+ return true;
+
+ Qt3DSDMInstanceHandle theMaster = CreateAndDeriveInstance(theType, theId);
+ if (!theMaster.Valid())
+ return false;
+
+ std::shared_ptr<qt3dsdm::IDOMFactory> theFactory =
+ qt3dsdm::IDOMFactory::CreateDOMFactory(m_StrTable);
+
+ PluginErrorHandler dummyHandler;
+ std::shared_ptr<qt3dsdm::IDOMReader> theReader = Q3DStudio::CRenderPluginParser::ParseFile(
+ theFactory, m_StrTable, inSourcePath, dummyHandler, m_InputStreamFactory);
+ if (theReader) {
+ Q3DStudio::CRenderPluginParser::NavigateToMetadata(theReader);
+ std::vector<SMetaDataLoadWarning> theWarnings;
+ m_NewMetaData->LoadInstance(*theReader, theMaster, theName, theWarnings);
+ Qt3DSDMPropertyHandle theProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(theMaster, L"name");
+ m_DataCore->SetInstancePropertyValue(theMaster, theProperty,
+ std::make_shared<CDataStr>(theName));
+ return true;
+ }
+ return false;
+ }
+
+ Option<qt3dsdm::SMetaDataEffect> GetEffectMetaDataBySourcePath(const char *inName) override
+ {
+ return m_NewMetaData->GetEffectBySourcePath(inName);
+ }
+
+ virtual Option<qt3dsdm::SMetaDataCustomMaterial>
+ GetMaterialMetaDataBySourcePath(const char *inName) override
+ {
+ return m_NewMetaData->GetMaterialBySourcePath(inName);
+ }
+
+ virtual void GetInstanceProperties(const wchar_t *inType, const wchar_t *inId,
+ eastl::vector<TRuntimeMetaDataStrType> &outProperties,
+ bool inSearchParent)
+ {
+ // Get the instance handle given the type or id
+ Qt3DSDMInstanceHandle theInstance =
+ IsTrivial(inId) ? GetInstanceForType(inType) : GetInstanceById(inId);
+ if (!theInstance.Valid()) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ vector<Qt3DSDMMetaDataPropertyHandle> theProperties;
+ if (inSearchParent)
+ // Get the meta data properties defined on this object or its derivation parents
+ m_NewMetaData->GetMetaDataProperties(theInstance, theProperties);
+ else
+ // Get the meta data properties defined on *only* this object, don't search parents
+ m_NewMetaData->GetSpecificMetaDataProperties(theInstance, theProperties);
+
+ outProperties.clear();
+ // Iterate each property and fill outProperties
+ for (size_t propIdx = 0, propEnd = theProperties.size(); propIdx < propEnd; ++propIdx) {
+ SMetaDataPropertyInfo theInfo(
+ m_NewMetaData->GetMetaDataPropertyInfo(theProperties[propIdx]));
+ outProperties.push_back(TRuntimeMetaDataStrType());
+ qt3ds::foundation::ConvertUTF(theInfo.m_Name.c_str(), 0, outProperties.back());
+ }
+ }
+
+ void GetInstanceProperties(const char *inType, const char *inId,
+ eastl::vector<TRuntimeMetaDataStrType> &outProperties,
+ bool inSearchParent) override
+ {
+ GetInstanceProperties(Convert0(inType), Convert2(inId), outProperties, inSearchParent);
+ }
+
+ std::shared_ptr<qt3dsdm::IStringTable> GetStringTable() override { return m_StrTable; }
+
+ TStrTableStr Register(const char *inStr) override
+ {
+ return m_StrTable->GetRenderStringTable().RegisterStr(inStr);
+ }
+
+ //==============================================================================
+ /**
+ * @Self release
+ */
+ void release() override { delete this; }
+
+ void ClearPerProjectData() override
+ {
+
+ m_IdToHandleMap.clear();
+ m_PropertyLookupHash.clear();
+ }
+
+}; // end of struct SRuntimeMetaDataImpl
+}
+
+IRuntimeMetaData &IRuntimeMetaData::Create(IInputStreamFactory &inInputStreamFactory)
+{
+ SRuntimeMetaDataImpl &retval = *new SRuntimeMetaDataImpl(inInputStreamFactory);
+ retval.Load();
+ return retval;
+}