2
0
Эх сурвалжийг харах

Xml: introduce helper for attribute parsing.

Kim Kulling 5 жил өмнө
parent
commit
7adfe1f2d8

+ 50 - 7
code/AssetLib/Collada/ColladaParser.cpp

@@ -246,19 +246,18 @@ ai_real ColladaParser::ReadFloatFromTextContent() {
 // Reads the contents of the file
 void ColladaParser::ReadContents(XmlNode &node) {
     for (pugi::xml_node &curNode : node.children()) {
-        pugi::xml_attribute attr = curNode.attribute("version");
-        if (attr) {
-            const char *version = attr.as_string();
+        std::string version;
+        if (XmlParser::getStdStrAttribute(curNode, "version", version)) {
             aiString v;
-            v.Set(version);
+            v.Set(version.c_str());
             mAssetMetaData.emplace(AI_METADATA_SOURCE_FORMAT_VERSION, v);
-            if (!::strncmp(version, "1.5", 3)) {
+            if (!::strncmp(version.c_str(), "1.5", 3)) {
                 mFormat = FV_1_5_n;
                 ASSIMP_LOG_DEBUG("Collada schema version is 1.5.n");
-            } else if (!::strncmp(version, "1.4", 3)) {
+            } else if (!::strncmp(version.c_str(), "1.4", 3)) {
                 mFormat = FV_1_4_n;
                 ASSIMP_LOG_DEBUG("Collada schema version is 1.4.n");
-            } else if (!::strncmp(version, "1.3", 3)) {
+            } else if (!::strncmp(version.c_str(), "1.3", 3)) {
                 mFormat = FV_1_3_n;
                 ASSIMP_LOG_DEBUG("Collada schema version is 1.3.n");
             }
@@ -1244,6 +1243,50 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
         return;
     }
 
+    for (XmlNode &currentNode : node.children()) {
+        const std::string &currentName = currentNode.name();
+        if (currentName == "color") {
+            // text content contains 4 floats
+            const char *content = currentNode.value();
+
+            content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
+            SkipSpacesAndLineEnd(&content);
+
+            content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g);
+            SkipSpacesAndLineEnd(&content);
+
+            content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b);
+            SkipSpacesAndLineEnd(&content);
+
+            content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a);
+            SkipSpacesAndLineEnd(&content);
+        } else if (currentName == "texture") {
+            // get name of source texture/sampler
+            int attrTex = GetAttribute("texture");
+            pSampler.mName = mReader->getAttributeValue(attrTex);
+
+            // get name of UV source channel. Specification demands it to be there, but some exporters
+            // don't write it. It will be the default UV channel in case it's missing.
+            attrTex = TestAttribute("texcoord");
+            if (attrTex >= 0)
+                pSampler.mUVChannel = mReader->getAttributeValue(attrTex);
+            //SkipElement();
+
+            // as we've read texture, the color needs to be 1,1,1,1
+            pColor = aiColor4D(1.f, 1.f, 1.f, 1.f);
+        } else if (currentName == "technique" ) {
+            const int _profile = GetAttribute("profile");
+            const char *profile = mReader->getAttributeValue(_profile);
+
+            // Some extensions are quite useful ... ReadSamplerProperties processes
+            // several extensions in MAYA, OKINO and MAX3D profiles.
+            if (!::strcmp(profile, "MAYA") || !::strcmp(profile, "MAX3D") || !::strcmp(profile, "OKINO")) {
+                // get more information on this sampler
+                ReadSamplerProperties(pSampler);
+            }
+        } 
+    }
+
     // Save current element name
     const std::string curElem = mReader->getNodeName();
 

+ 0 - 1
code/AssetLib/Collada/ColladaParser.h

@@ -4,7 +4,6 @@
 
  Copyright (c) 2006-2020, assimp team
 
-
  All rights reserved.
 
  Redistribution and use of this software in source and binary forms,

+ 61 - 41
include/assimp/XmlParser.h

@@ -52,22 +52,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 
 struct find_node_by_name_predicate {
-	std::string mName;
-	find_node_by_name_predicate(const std::string &name) :
-			mName(name) {
+    std::string mName;
+    find_node_by_name_predicate(const std::string &name) :
+            mName(name) {
         // empty
-	}
+    }
 
-	bool operator()(pugi::xml_node node) const {
-		return node.name() == mName;
-	}
+    bool operator()(pugi::xml_node node) const {
+        return node.name() == mName;
+    }
 };
 
-template<class TNodeType>
+template <class TNodeType>
 struct NodeConverter {
 public:
-    static int to_int(TNodeType &node, const char *attribName ) {
-		ai_assert(nullptr != attribName);
+    static int to_int(TNodeType &node, const char *attribName) {
+        ai_assert(nullptr != attribName);
         return node.attribute(attribName).to_int();
     }
 };
@@ -75,72 +75,73 @@ public:
 using XmlNode = pugi::xml_node;
 using XmlAttribute = pugi::xml_attribute;
 
-template<class TNodeType>
+template <class TNodeType>
 class TXmlParser {
 public:
-	TXmlParser() :
-			mDoc(nullptr), mRoot(nullptr), mData() {
+    TXmlParser() :
+            mDoc(nullptr),
+            mRoot(nullptr),
+            mData() {
         // empty
-	}
+    }
 
     ~TXmlParser() {
-		clear();
+        clear();
     }
 
     void clear() {
-		mData.resize(0);
-		mRoot = nullptr;
-		delete mDoc;
-		mDoc = nullptr;
+        mData.resize(0);
+        mRoot = nullptr;
+        delete mDoc;
+        mDoc = nullptr;
     }
 
     TNodeType *findNode(const std::string &name) {
-		if (name.empty()) {
-			return nullptr;
-		}
+        if (name.empty()) {
+            return nullptr;
+        }
 
-		if (nullptr == mDoc) {
-			return nullptr;
+        if (nullptr == mDoc) {
+            return nullptr;
         }
 
         find_node_by_name_predicate predicate(name);
         mCurrent = mDoc->find_node(predicate);
         if (mCurrent.empty()) {
-			return nullptr;
+            return nullptr;
         }
 
         return &mCurrent;
     }
 
-    bool hasNode( const std::string &name ) {
+    bool hasNode(const std::string &name) {
         return nullptr != findNode(name);
     }
 
     TNodeType *parse(IOStream *stream) {
-		if (nullptr == stream) {
-			return nullptr;
-		}
+        if (nullptr == stream) {
+            return nullptr;
+        }
 
         mData.resize(stream->FileSize());
-		stream->Read(&mData[0], mData.size(), 1);
-		mDoc = new pugi::xml_document();
-		pugi::xml_parse_result result = mDoc->load_string(&mData[0]);
+        stream->Read(&mData[0], mData.size(), 1);
+        mDoc = new pugi::xml_document();
+        pugi::xml_parse_result result = mDoc->load_string(&mData[0]);
         if (result.status == pugi::status_ok) {
             pugi::xml_node root = *(mDoc->children().begin());
-            
+
             mRoot = &root;
-			//mRoot = &mDoc->root();
         }
 
         return mRoot;
     }
 
     pugi::xml_document *getDocument() const {
-		return mDoc;
+        return mDoc;
     }
 
     const TNodeType *getRootNode() const {
-		return mRoot;
+        return mRoot;
     }
 
     TNodeType *getRootNode() {
@@ -157,16 +158,35 @@ public:
         return !attr.empty();
     }
 
-    private:
-	pugi::xml_document *mDoc;
-	TNodeType *mRoot;
+    static inline bool getIntAttribute(XmlNode &xmlNode, const char *name, int &val ) {
+        pugi::xml_attribute attr = xmlNode.attribute(name);
+        if (attr.empty()) {
+            return false;
+        }
+
+        val = attr.as_int();
+        return true;
+    }
+
+    static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) {
+        pugi::xml_attribute attr = xmlNode.attribute(name);
+        if (attr.empty()) {
+            return false;
+        }
+
+        val = attr.as_string();
+        return true;
+    }
+
+private:
+    pugi::xml_document *mDoc;
+    TNodeType *mRoot;
     TNodeType mCurrent;
-	std::vector<char> mData;
+    std::vector<char> mData;
 };
 
 using XmlParser = TXmlParser<pugi::xml_node>;
 
-
 } // namespace Assimp
 
 #endif // !! INCLUDED_AI_IRRXML_WRAPPER