浏览代码

update: metric parsing ongoing.

Signed-off-by: Kim Kulling <[email protected]>
Kim Kulling 11 年之前
父节点
当前提交
75d3c8e9f2
共有 5 个文件被更改,包括 275 次插入8 次删除
  1. 25 4
      code/OpenGEXImporter.cpp
  2. 5 0
      code/OpenGEXImporter.h
  3. 222 1
      code/OpenGEXParser.cpp
  4. 19 2
      code/OpenGEXParser.h
  5. 4 1
      code/OpenGEXStructs.h

+ 25 - 4
code/OpenGEXImporter.cpp

@@ -41,6 +41,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "AssimpPCH.h"
 #include "OpenGEXImporter.h"
+#include "OpenGEXParser.h"
+#include "DefaultIOSystem.h"
+
+#include <vector>
 
 static const aiImporterDesc desc = {
     "Open Game Engine Exchange",
@@ -70,12 +74,29 @@ OpenGEXImporter::~OpenGEXImporter() {
 
 //------------------------------------------------------------------------------------------------
 bool OpenGEXImporter::CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const {
-    return false;
+    bool canRead( false );
+    if( !checkSig ) {
+        canRead = SimpleExtensionCheck( file, "ogex" );
+    } else {
+        static const char *token[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" };
+        canRead = BaseImporter::SearchFileHeaderForToken( pIOHandler, file, token, 4 );
+    }
+
+    return canRead;
 }
 
 //------------------------------------------------------------------------------------------------
-void OpenGEXImporter::InternReadFile( const std::string &file, aiScene *pScene, IOSystem *pIOHandler ) {
-
+void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pScene, IOSystem *pIOHandler ) {
+    // open source file
+    IOStream *file = pIOHandler->Open( filename, "rb" );
+    if( !file ) {
+        throw DeadlyImportError( "Failed to open file " + filename );
+    }
+
+    std::vector<char> buffer;
+    TextFileToBuffer( file, buffer );
+    OpenGEXParser myParser( buffer );
+    myParser.parse();
 }
 
 //------------------------------------------------------------------------------------------------
@@ -85,7 +106,7 @@ const aiImporterDesc *OpenGEXImporter::GetInfo() const {
 
 //------------------------------------------------------------------------------------------------
 void OpenGEXImporter::SetupProperties( const Importer *pImp ) {
-    
+
 }
 
 //------------------------------------------------------------------------------------------------

+ 5 - 0
code/OpenGEXImporter.h

@@ -70,6 +70,11 @@ public:
 
     /// BaseImporter override.
     virtual void SetupProperties( const Importer *pImp );
+
+protected:
+    void ParseMetric();
+    void ParseGeoObject();
+    void ParseMaterial();
 };
 
 } // Namespace OpenGEX

+ 222 - 1
code/OpenGEXParser.cpp

@@ -41,18 +41,239 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER
 
 #include "OpenGEXParser.h"
+#include "OpenGEXStructs.h"
+#include "ParsingUtils.h"
+#include "fast_atof.h"
+
+#include <vector>
 
 namespace Assimp {
 namespace OpenGEX {
 
-OpenGEXParser::OpenGEXParser() {
+//------------------------------------------------------------------------------------------------
+static const std::string Metric         = "Metric";
+static const std::string GeometryNode   = "GeometryNode";
+static const std::string GeometryObject = "GeometryObject";
+static const std::string Material       = "Material";
+static const size_t NumObjects = 4;
+
+static const std::string RootNodes[ NumObjects ] = {
+    Metric,
+    GeometryNode,
+    GeometryObject,
+    Material
+};
+
+static bool containsNode( const char *bufferPtr, size_t size, const std::string *nodes, size_t numNodes,
+                          const std::string *tokenFound ) {
+    tokenFound = NULL;
+    if( 0 == numNodes ) {
+        return false;
+    }
+
+    bool found( false );
+    for( size_t i = 0; i < numNodes; ++i ) {
+        if( TokenMatch( bufferPtr, nodes[ i ].c_str(), nodes[ i ].size() ) ) {
+            tokenFound = &nodes[ i ];
+            found = true;
+            break;
+        }
+    }
+
+    return found;
+}
+
+//------------------------------------------------------------------------------------------------
+OpenGEXParser::OpenGEXParser( const std::vector<char> &buffer ) 
+: m_buffer( buffer ) 
+, m_index( 0 )
+, m_buffersize( buffer.size() ) {
 
 }
 
+//------------------------------------------------------------------------------------------------
 OpenGEXParser::~OpenGEXParser() {
 
 }
 
+//------------------------------------------------------------------------------------------------
+void OpenGEXParser::parse() {
+    while( parseNextNode() ) {
+
+    }
+}
+
+//------------------------------------------------------------------------------------------------
+std::string OpenGEXParser::getNextToken() {
+    std::string token;
+    while( m_index < m_buffersize && IsSpace( m_buffer[ m_index ] ) ) {
+        ++m_index;
+    }
+
+    while( m_index < m_buffersize && !IsSpace( m_buffer[ m_index ] ) ) {
+        token += m_buffer[ m_index ];
+        m_index++;
+    }
+
+    if( token == "//" ) {
+        skipComments();
+        token = getNextToken();
+    }
+
+    return token;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::skipComments() {
+    bool skipped( false );
+    if( strncmp( &m_buffer[ m_index ], "//", 2 ) == 0) {
+        while( !IsLineEnd( m_buffer[ m_index ] ) ) {
+            ++m_index;
+        }
+        skipped = true;
+    }
+
+    return skipped;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::parseNextNode() {
+    std::string token( getNextToken() );
+    std::string rootNodeName;
+    if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, &rootNodeName ) ) {
+        if( !getNodeHeader( rootNodeName ) ) {
+            return false;
+        }
+
+        if( !getNodeData() ) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::getNodeHeader( const std::string &name ) {
+    if( name == Metric ) {
+        std::string token( getNextToken() );
+
+    }
+
+    return false;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::getBracketOpen() {
+    const std::string token( getNextToken() );
+    if( "{" == token ) {
+        return true;
+    }
+
+    return false;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::getBracketClose() {
+    const std::string token( getNextToken() );
+    if( "}" == token ) {
+        return true;
+    }
+
+    return false;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::getStringData( std::string &data ) {
+    if( !getBracketOpen() ) {
+        return false;
+    }
+
+    if( !getBracketClose() ) {
+        return false;
+    }
+    return false;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::getFloatData( size_t num, float *data ) {
+    ai_assert( nullptr != data );
+
+    if( !getBracketOpen() ) {
+        return false;
+    }
+
+    bool ok( true );
+    size_t dataIdx( 0 );
+    for( unsigned int i = 0; i < num; ++i ) {
+        data[ dataIdx ] = fast_atof( &m_buffer[ m_index ] );
+        ++dataIdx;
+        std::string tk = getNextToken();
+        if( tk == "," ) {
+            if( i >= ( num - 1 ) ) {
+                ok = false;
+                break;
+            }
+        }
+    }
+
+    if( !getBracketClose() ) {
+        return false;
+    }
+
+    return ok;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::getNodeData() {
+    if( !getBracketOpen() ) {
+        return false;
+    }
+
+    if( !onMetricNode() ) {
+        return false;
+    }
+
+    if( !getBracketClose() ) {
+        return false;
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::getMetricAttribute( std::string &attribName ) {
+    return false;
+}
+
+//------------------------------------------------------------------------------------------------
+bool OpenGEXParser::onMetricNode() {
+    std::string attribName;
+    if( !getMetricAttribute( attribName ) ) {
+        return false;
+    }
+
+    if( "distance" == attribName ) {
+        float distance( 0.0f );
+        getFloatData( 1, &distance );
+    } else if( "angle" == attribName ) {
+        float angle( 0.0f );
+        getFloatData( 1, &angle );
+    } else if( "time" == attribName ) {
+        float time( 0.0f );
+        getFloatData( 1, &time );
+    } else if( "up" == attribName ) {
+        std::string up;
+        getStringData( up );
+    } else {
+        return false;
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------------------------
+
 } // Namespace openGEX
 } // Namespace Assimp
 

+ 19 - 2
code/OpenGEXParser.h

@@ -41,21 +41,38 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define ASSIMP_OPENGEX_OPENGEXPARSER_H_INC
 
 #ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER
+#include <vector>
 
 namespace Assimp {
 namespace OpenGEX {
 
 class OpenGEXParser {
 public:
-    OpenGEXParser();
+    OpenGEXParser( const std::vector<char> &buffer );
     ~OpenGEXParser();
+    void parse();
+
+protected:
+    std::string getNextToken();
+    bool skipComments();
+    bool parseNextNode();
+    bool getNodeHeader( const std::string &name );
+    bool getBracketOpen();
+    bool getBracketClose();
+    bool getStringData( std::string &data );
+    bool getFloatData( size_t num, float *data );
+    bool getNodeData();
+    bool getMetricAttribute( std::string &attribName );
+    bool onMetricNode();
 
 private:
     OpenGEXParser( const OpenGEXParser & );
     OpenGEXParser &operator = ( const OpenGEXParser & );
 
 private:
-
+    const std::vector<char> &m_buffer;
+    size_t m_index;
+    size_t m_buffersize;
 };
 
 } // Namespace openGEX

+ 4 - 1
code/OpenGEXStructs.h

@@ -57,7 +57,10 @@ struct BoneIndexArray;
 struct BoneWeightArray;
 
 struct Metric {
-    std::string metricKey;
+    float m_distance;
+    float m_angle;
+    float m_time;
+    float m_up;
 };
 
 struct VertexArray {