From bf6425c35f793592738eef5fe371314a0732f9be Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 26 Sep 2016 13:16:01 +0200 Subject: [PATCH] Utility/OBJParser: Add Check() method to quickly check if any OBJ token is present at the beginning Former-commit-id: 27f09e4351e6721eab338576075a161f62a4c262 [formerly d2cc64b6b6ec984210fd187adfc0797087ea3a0a] [formerly 58c7a39be0a0fdb8c89c516d5e8d19b18d34ba60 [formerly a9d80e257c27b60319e0d1b03b1534e133e1244e]] Former-commit-id: 9ccaa30b87462af58390478d4d6b956d9b5faa5f [formerly 615171770a9a8c87b37b50940c7342bdeb6876a2] Former-commit-id: c49b38dc42936ba3f696f9436fd9f6b5527244c0 --- include/Nazara/Utility/Formats/OBJParser.hpp | 2 + src/Nazara/Utility/Formats/OBJParser.cpp | 81 +++++++++++++++++++- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index 6c0c35af4..82c1220bf 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -29,6 +29,8 @@ namespace Nz inline void Clear(); + bool Check(Stream& stream); + inline String* GetMaterials(); inline const String* GetMaterials() const; inline UInt32 GetMaterialCount() const; diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index a520d6be1..3b03b7f78 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -13,9 +13,87 @@ namespace Nz { + bool OBJParser::Check(Stream& stream) + { + m_currentStream = &stream; + m_errorCount = 0; + m_keepLastLine = false; + m_lineCount = 0; + + // Force stream in text mode, reset it at the end + Nz::CallOnExit resetTextMode; + if ((stream.GetStreamOptions() & StreamOption_Text) == 0) + { + stream.EnableTextMode(true); + + resetTextMode.Reset([&stream] () + { + stream.EnableTextMode(false); + }); + } + + unsigned int failureCount = 0; + while (Advance(false)) + { + switch (std::tolower(m_currentLine[0])) + { + case '#': //< Comment + failureCount--; + break; + + case 'f': //< Face + case 'g': //< Group (inside a mesh) + case 'o': //< Object (defines a mesh) + case 's': //< Smooth + { + if (m_currentLine.GetSize() > 1 && m_currentLine[1] == ' ') + return true; + + break; + } + + case 'm': //< MTLLib + if (m_currentLine.GetWord(0).ToLower() == "mtllib") + return true; + + break; + + case 'u': //< Usemtl + if (m_currentLine.GetWord(0).ToLower() == "usemtl") + return true; + + break; + + case 'v': //< Position/Normal/Texcoords + { + String word = m_currentLine.GetWord(0).ToLower(); + if (word == 'v') + return true; + else if (word == "vn") + return true; + else if (word == "vt") + return true; + + break; + } + + default: + break; + } + + if (++failureCount > 20U) + return false; + } + + return false; + } + bool OBJParser::Parse(Nz::Stream& stream, UInt32 reservedVertexCount) { m_currentStream = &stream; + m_errorCount = 0; + m_keepLastLine = false; + m_lineCount = 0; // Force stream in text mode, reset it at the end Nz::CallOnExit resetTextMode; @@ -31,9 +109,6 @@ namespace Nz String matName, meshName; matName = meshName = "default"; - m_errorCount = 0; - m_keepLastLine = false; - m_lineCount = 0; m_meshes.clear(); m_mtlLib.Clear();