diff --git a/code/OpenGEXImporter.cpp b/code/OpenGEXImporter.cpp index 361ef4c4e..f385cc11d 100644 --- a/code/OpenGEXImporter.cpp +++ b/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 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 buffer; + TextFileToBuffer( file, buffer ); + OpenGEXParser myParser( buffer ); + myParser.parse(); } //------------------------------------------------------------------------------------------------ @@ -85,7 +106,7 @@ const aiImporterDesc *OpenGEXImporter::GetInfo() const { //------------------------------------------------------------------------------------------------ void OpenGEXImporter::SetupProperties( const Importer *pImp ) { - + } //------------------------------------------------------------------------------------------------ diff --git a/code/OpenGEXImporter.h b/code/OpenGEXImporter.h index f658c9fa1..821692c25 100644 --- a/code/OpenGEXImporter.h +++ b/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 diff --git a/code/OpenGEXParser.cpp b/code/OpenGEXParser.cpp index dd7006e1e..7e73520ac 100644 --- a/code/OpenGEXParser.cpp +++ b/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 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 &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 diff --git a/code/OpenGEXParser.h b/code/OpenGEXParser.h index 34b48e561..0bdb7909a 100644 --- a/code/OpenGEXParser.h +++ b/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 namespace Assimp { namespace OpenGEX { class OpenGEXParser { public: - OpenGEXParser(); + OpenGEXParser( const std::vector &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 &m_buffer; + size_t m_index; + size_t m_buffersize; }; } // Namespace openGEX diff --git a/code/OpenGEXStructs.h b/code/OpenGEXStructs.h index 5a0899710..d54bf32d1 100644 --- a/code/OpenGEXStructs.h +++ b/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 {