Kaynağa Gözat

Merge branch 'master' into assimpview_unicode

RichardTea 6 yıl önce
ebeveyn
işleme
51be6236a7
4 değiştirilmiş dosya ile 137 ekleme ve 7 silme
  1. 34 4
      code/ColladaExporter.cpp
  2. 11 0
      code/ColladaLoader.cpp
  3. 77 3
      code/ColladaParser.cpp
  4. 15 0
      code/ColladaParser.h

+ 34 - 4
code/ColladaExporter.cpp

@@ -238,7 +238,11 @@ void ColladaExporter::WriteHeader()
     mOutput << startstr << "<contributor>" << endstr;
     PushTag();
 
-    aiMetadata* meta = mScene->mRootNode->mMetaData;
+    // If no Scene metadata, use root node metadata
+    aiMetadata* meta = mScene->mMetaData;
+    if (!meta)
+        meta = mScene->mRootNode->mMetaData;
+
     aiString value;
     if (!meta || !meta->Get("Author", value))
         mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
@@ -250,13 +254,39 @@ void ColladaExporter::WriteHeader()
     else
         mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
 
-    //mOutput << startstr << "<author>" << mScene->author.C_Str() << "</author>" << endstr;
-    //mOutput << startstr << "<authoring_tool>" << mScene->authoringTool.C_Str() << "</authoring_tool>" << endstr;
+    if (meta)
+    {
+        if (meta->Get("Comments", value))
+            mOutput << startstr << "<comments>" << XMLEscape(value.C_Str()) << "</comments>" << endstr;
+        if (meta->Get("Copyright", value))
+            mOutput << startstr << "<copyright>" << XMLEscape(value.C_Str()) << "</copyright>" << endstr;
+        if (meta->Get("SourceData", value))
+            mOutput << startstr << "<source_data>" << XMLEscape(value.C_Str()) << "</source_data>" << endstr;
+    }
 
     PopTag();
     mOutput << startstr << "</contributor>" << endstr;
-    mOutput << startstr << "<created>" << date_str << "</created>" << endstr;
+
+    if (!meta || !meta->Get("Created", value))
+        mOutput << startstr << "<created>" << date_str << "</created>" << endstr;
+    else
+        mOutput << startstr << "<created>" << XMLEscape(value.C_Str()) << "</created>" << endstr;
+
+    // Modified date is always the date saved
     mOutput << startstr << "<modified>" << date_str << "</modified>" << endstr;
+
+    if (meta)
+    {
+        if (meta->Get("Keywords", value))
+            mOutput << startstr << "<keywords>" << XMLEscape(value.C_Str()) << "</keywords>" << endstr;
+        if (meta->Get("Revision", value))
+            mOutput << startstr << "<revision>" << XMLEscape(value.C_Str()) << "</revision>" << endstr;
+        if (meta->Get("Subject", value))
+            mOutput << startstr << "<subject>" << XMLEscape(value.C_Str()) << "</subject>" << endstr;
+        if (meta->Get("Title", value))
+            mOutput << startstr << "<title>" << XMLEscape(value.C_Str()) << "</title>" << endstr;
+    }
+
     mOutput << startstr << "<unit name=\"meter\" meter=\"" << scale << "\" />" << endstr;
     mOutput << startstr << "<up_axis>" << up_axis << "</up_axis>" << endstr;
     PopTag();

+ 11 - 0
code/ColladaLoader.cpp

@@ -207,6 +207,17 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
                 0,  0,  0,  1);
     }
 
+    // Store scene metadata
+    if (!parser.mAssetMetaData.empty()) {
+        const size_t numMeta(parser.mAssetMetaData.size());
+        pScene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
+        size_t i = 0;
+        for (auto it = parser.mAssetMetaData.cbegin(); it != parser.mAssetMetaData.cend(); ++it, ++i)
+        {
+            pScene->mMetaData->Set(static_cast<unsigned int>(i), (*it).first, (*it).second);
+        }
+    }
+
     // store all meshes
     StoreSceneMeshes( pScene);
 

+ 77 - 3
code/ColladaParser.cpp

@@ -264,14 +264,19 @@ void ColladaParser::ReadAssetInfo()
 
                 // check element end
                 TestClosing( "up_axis");
-            } else
+            }
+            else if(IsElement("contributor"))
             {
-                SkipElement();
+                ReadContributorInfo();
+            }
+            else
+            {
+                ReadMetaDataItem(mAssetMetaData);
             }
         }
         else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
         {
-            if( strcmp( mReader->getNodeName(), "asset") != 0)
+            if (strcmp( mReader->getNodeName(), "asset") != 0)
                 ThrowException( "Expected end of <asset> element.");
 
             break;
@@ -279,6 +284,75 @@ void ColladaParser::ReadAssetInfo()
     }
 }
 
+// ------------------------------------------------------------------------------------------------
+// Reads the contributor info
+void ColladaParser::ReadContributorInfo()
+{
+    if (mReader->isEmptyElement())
+        return;
+
+    while (mReader->read())
+    {
+        if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
+        {
+            ReadMetaDataItem(mAssetMetaData);
+        }
+        else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
+        {
+            if (strcmp(mReader->getNodeName(), "contributor") != 0)
+                ThrowException("Expected end of <contributor> element.");
+            break;
+        }
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads a single string metadata item
+void ColladaParser::ReadMetaDataItem(StringMetaData &metadata)
+{
+    // Metadata such as created, keywords, subject etc
+    const char* key_char = mReader->getNodeName();
+    if (key_char != nullptr)
+    {
+        const std::string key_str(key_char);
+        const char* value_char = TestTextContent();
+        if (value_char != nullptr)
+        {
+            std::string camel_key_str = key_str;
+            ToCamelCase(camel_key_str);
+            aiString aistr;
+            aistr.Set(value_char);
+            metadata.emplace(camel_key_str, aistr);
+            TestClosing(key_str.c_str());
+        }
+        else
+            SkipElement();
+    }
+    else
+        SkipElement();
+}
+
+// ------------------------------------------------------------------------------------------------
+// Convert underscore_seperated to CamelCase: "authoring_tool" becomes "AuthoringTool"
+void ColladaParser::ToCamelCase(std::string &text)
+{
+    if (text.empty())
+        return;
+    // Capitalise first character
+    text[0] = ToUpper(text[0]);
+    for (auto it = text.begin(); it != text.end(); /*iterated below*/)
+    {
+        if ((*it) == '_')
+        {
+            it = text.erase(it);
+            if (it != text.end())
+                (*it) = ToUpper(*it);
+        }
+        else
+            ++it;
+    }
+}
+
 // ------------------------------------------------------------------------------------------------
 // Reads the animation clips
 void ColladaParser::ReadAnimationClipLibrary()

+ 15 - 0
code/ColladaParser.h

@@ -66,6 +66,9 @@ namespace Assimp
         friend class ColladaLoader;
 
     protected:
+        /** Map for generic metadata as aiString */
+        typedef std::map<std::string, aiString> StringMetaData;
+
         /** Constructor from XML file */
         ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
 
@@ -81,6 +84,15 @@ namespace Assimp
         /** Reads asset information such as coordinate system information and legal blah */
         void ReadAssetInfo();
 
+        /** Reads contributor information such as author and legal blah */
+        void ReadContributorInfo();
+
+        /** Reads generic metadata into provided map */
+        void ReadMetaDataItem(StringMetaData &metadata);
+
+        /** Convert underscore_seperated to CamelCase "authoring_tool" becomes "AuthoringTool" */
+        static void ToCamelCase(std::string &text);
+
         /** Reads the animation library */
         void ReadAnimationLibrary();
 
@@ -343,6 +355,9 @@ namespace Assimp
         /** Which is the up vector */
         enum { UP_X, UP_Y, UP_Z } mUpDirection;
 
+        /** Asset metadata (global for scene) */
+        StringMetaData mAssetMetaData;
+
         /** Collada file format version */
         Collada::FormatVersion mFormat;
     };