commit
9da69190e0
|
@ -10,7 +10,7 @@ build
|
|||
# Output
|
||||
bin/
|
||||
lib/
|
||||
contrib/
|
||||
|
||||
|
||||
# Generated
|
||||
assimp.pc
|
||||
|
|
|
@ -11,6 +11,8 @@ set (PROJECT_VERSION "${ASSIMP_VERSION}")
|
|||
|
||||
set(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources")
|
||||
|
||||
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||
|
||||
# Get the current working branch
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref HEAD
|
||||
|
|
|
@ -265,8 +265,6 @@ SET( LWS_SRCS
|
|||
)
|
||||
SOURCE_GROUP( LWS FILES ${LWS_SRCS})
|
||||
|
||||
|
||||
|
||||
SET( MD2_SRCS
|
||||
MD2FileData.h
|
||||
MD2Loader.cpp
|
||||
|
@ -360,6 +358,13 @@ SET( Ogre_SRCS
|
|||
)
|
||||
SOURCE_GROUP( Ogre FILES ${Ogre_SRCS})
|
||||
|
||||
SET( OpenGEX_SRCS
|
||||
OpenGEXImporter.cpp
|
||||
OpenGEXImporter.h
|
||||
OpenGEXStructs.h
|
||||
)
|
||||
SOURCE_GROUP( OpenGEX FILES ${OpenGEX_SRCS})
|
||||
|
||||
SET( Ply_SRCS
|
||||
PlyLoader.cpp
|
||||
PlyLoader.h
|
||||
|
@ -635,6 +640,17 @@ SET( unzip_SRCS
|
|||
)
|
||||
SOURCE_GROUP( unzip FILES ${unzip_SRCS})
|
||||
|
||||
SET ( openddl_parser_SRCS
|
||||
../contrib/openddlparser/code/OpenDDLParser.cpp
|
||||
../contrib/openddlparser/code/DDLNode.cpp
|
||||
../contrib/openddlparser/code/Value.cpp
|
||||
../contrib/openddlparser/include/openddlparser/OpenDDLParser.h
|
||||
../contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
|
||||
../contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
|
||||
../contrib/openddlparser/include/openddlparser/DDLNode.h
|
||||
../contrib/openddlparser/include/openddlparser/Value.h
|
||||
)
|
||||
SOURCE_GROUP( openddl_parser FILES ${openddl_parser_SRCS})
|
||||
|
||||
# VC2010 fixes
|
||||
if(MSVC10)
|
||||
|
@ -690,6 +706,7 @@ SET( assimp_src
|
|||
${OFFFormat_SRCS}
|
||||
${Obj_SRCS}
|
||||
${Ogre_SRCS}
|
||||
${OpenGEX_SRCS}
|
||||
${Ply_SRCS}
|
||||
${Q3D_SRCS}
|
||||
${Q3BSP_SRCS}
|
||||
|
@ -714,6 +731,7 @@ SET( assimp_src
|
|||
${unzip_compile_SRCS}
|
||||
${Poly2Tri_SRCS}
|
||||
${Clipper_SRCS}
|
||||
${openddl_parser_SRCS}
|
||||
# Necessary to show the headers in the project when using the VC++ generator:
|
||||
${Boost_SRCS}
|
||||
|
||||
|
@ -725,6 +743,11 @@ SET( assimp_src
|
|||
# Moreover it's a drag to recompile assimp entirely each time a modification is made to one of the included header, which is definitely counter-productive.)
|
||||
AssimpPCH.cpp
|
||||
)
|
||||
add_definitions( -DOPENDDLPARSER_BUILD )
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
../contrib/openddlparser/include
|
||||
)
|
||||
|
||||
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||
SET( assimp_src ${assimp_src} ${C4D_SRCS})
|
||||
|
@ -735,7 +758,7 @@ ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
|||
|
||||
ADD_LIBRARY( assimp ${assimp_src} )
|
||||
|
||||
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} )
|
||||
|
||||
if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
set(ASSIMP_ANDROID_JNIIOSYSTEM_PATH port/AndroidJNI)
|
||||
|
|
|
@ -142,6 +142,9 @@ corresponding preprocessor flag to selectively disable formats.
|
|||
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
|
||||
# include "OgreImporter.h"
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_OPEMGEX_IMPORTER
|
||||
# include "OpenGEXImporter.h"
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
|
||||
# include "MS3DLoader.h"
|
||||
#endif
|
||||
|
@ -179,127 +182,130 @@ namespace Assimp {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
||||
{
|
||||
// ----------------------------------------------------------------------------
|
||||
// Add an instance of each worker class here
|
||||
// (register_new_importers_here)
|
||||
// ----------------------------------------------------------------------------
|
||||
out.reserve(64);
|
||||
// ----------------------------------------------------------------------------
|
||||
// Add an instance of each worker class here
|
||||
// (register_new_importers_here)
|
||||
// ----------------------------------------------------------------------------
|
||||
out.reserve(64);
|
||||
#if (!defined ASSIMP_BUILD_NO_X_IMPORTER)
|
||||
out.push_back( new XFileImporter());
|
||||
out.push_back( new XFileImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_OBJ_IMPORTER)
|
||||
out.push_back( new ObjFileImporter());
|
||||
out.push_back( new ObjFileImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
|
||||
out.push_back( new Discreet3DSImporter());
|
||||
out.push_back( new Discreet3DSImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
|
||||
out.push_back( new MD3Importer());
|
||||
out.push_back( new MD3Importer());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_MD2_IMPORTER)
|
||||
out.push_back( new MD2Importer());
|
||||
out.push_back( new MD2Importer());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_PLY_IMPORTER)
|
||||
out.push_back( new PLYImporter());
|
||||
out.push_back( new PLYImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_MDL_IMPORTER)
|
||||
out.push_back( new MDLImporter());
|
||||
out.push_back( new MDLImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER)
|
||||
out.push_back( new ASEImporter());
|
||||
out.push_back( new ASEImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER)
|
||||
out.push_back( new HMPImporter());
|
||||
out.push_back( new HMPImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_SMD_IMPORTER)
|
||||
out.push_back( new SMDImporter());
|
||||
out.push_back( new SMDImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_MDC_IMPORTER)
|
||||
out.push_back( new MDCImporter());
|
||||
out.push_back( new MDCImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_MD5_IMPORTER)
|
||||
out.push_back( new MD5Importer());
|
||||
out.push_back( new MD5Importer());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_STL_IMPORTER)
|
||||
out.push_back( new STLImporter());
|
||||
out.push_back( new STLImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER)
|
||||
out.push_back( new LWOImporter());
|
||||
out.push_back( new LWOImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_DXF_IMPORTER)
|
||||
out.push_back( new DXFImporter());
|
||||
out.push_back( new DXFImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_NFF_IMPORTER)
|
||||
out.push_back( new NFFImporter());
|
||||
out.push_back( new NFFImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_RAW_IMPORTER)
|
||||
out.push_back( new RAWImporter());
|
||||
out.push_back( new RAWImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_OFF_IMPORTER)
|
||||
out.push_back( new OFFImporter());
|
||||
out.push_back( new OFFImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_AC_IMPORTER)
|
||||
out.push_back( new AC3DImporter());
|
||||
out.push_back( new AC3DImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_BVH_IMPORTER)
|
||||
out.push_back( new BVHLoader());
|
||||
out.push_back( new BVHLoader());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_IRRMESH_IMPORTER)
|
||||
out.push_back( new IRRMeshImporter());
|
||||
out.push_back( new IRRMeshImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_IRR_IMPORTER)
|
||||
out.push_back( new IRRImporter());
|
||||
out.push_back( new IRRImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_Q3D_IMPORTER)
|
||||
out.push_back( new Q3DImporter());
|
||||
out.push_back( new Q3DImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_B3D_IMPORTER)
|
||||
out.push_back( new B3DImporter());
|
||||
out.push_back( new B3DImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_COLLADA_IMPORTER)
|
||||
out.push_back( new ColladaLoader());
|
||||
out.push_back( new ColladaLoader());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_TERRAGEN_IMPORTER)
|
||||
out.push_back( new TerragenImporter());
|
||||
out.push_back( new TerragenImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_CSM_IMPORTER)
|
||||
out.push_back( new CSMImporter());
|
||||
out.push_back( new CSMImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_3D_IMPORTER)
|
||||
out.push_back( new UnrealImporter());
|
||||
out.push_back( new UnrealImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
|
||||
out.push_back( new LWSImporter());
|
||||
out.push_back( new LWSImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER)
|
||||
out.push_back( new Ogre::OgreImporter());
|
||||
out.push_back( new Ogre::OgreImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_OPEMGEX_IMPORTER )
|
||||
out.push_back( new OpenGEX::OpenGEXImporter() );
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER)
|
||||
out.push_back( new MS3DImporter());
|
||||
out.push_back( new MS3DImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_COB_IMPORTER)
|
||||
out.push_back( new COBImporter());
|
||||
out.push_back( new COBImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_BLEND_IMPORTER)
|
||||
out.push_back( new BlenderImporter());
|
||||
out.push_back( new BlenderImporter());
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER)
|
||||
out.push_back( new Q3BSPFileImporter() );
|
||||
out.push_back( new Q3BSPFileImporter() );
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER)
|
||||
out.push_back( new NDOImporter() );
|
||||
out.push_back( new NDOImporter() );
|
||||
#endif
|
||||
#if (!defined ASSIMP_BUILD_NO_IFC_IMPORTER)
|
||||
out.push_back( new IFCImporter() );
|
||||
out.push_back( new IFCImporter() );
|
||||
#endif
|
||||
#if ( !defined ASSIMP_BUILD_NO_XGL_IMPORTER )
|
||||
out.push_back( new XGLImporter() );
|
||||
out.push_back( new XGLImporter() );
|
||||
#endif
|
||||
#if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER )
|
||||
out.push_back( new FBXImporter() );
|
||||
out.push_back( new FBXImporter() );
|
||||
#endif
|
||||
#if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER )
|
||||
out.push_back( new AssbinImporter() );
|
||||
out.push_back( new AssbinImporter() );
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -64,57 +64,57 @@ struct Model;
|
|||
class ObjFileImporter : public BaseImporter
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
ObjFileImporter();
|
||||
/// \brief Default constructor
|
||||
ObjFileImporter();
|
||||
|
||||
/// \brief Destructor
|
||||
~ObjFileImporter();
|
||||
/// \brief Destructor
|
||||
~ObjFileImporter();
|
||||
|
||||
public:
|
||||
/// \brief Returns whether the class can handle the format of the given file.
|
||||
/// \remark See BaseImporter::CanRead() for details.
|
||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
||||
/// \brief Returns whether the class can handle the format of the given file.
|
||||
/// \remark See BaseImporter::CanRead() for details.
|
||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
||||
|
||||
private:
|
||||
|
||||
//! \brief Appends the supported extension.
|
||||
const aiImporterDesc* GetInfo () const;
|
||||
//! \brief Appends the supported extension.
|
||||
const aiImporterDesc* GetInfo () const;
|
||||
|
||||
//! \brief File import implementation.
|
||||
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||
//! \brief File import implementation.
|
||||
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||
|
||||
//! \brief Create the data from imported content.
|
||||
void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
|
||||
//! \brief Create the data from imported content.
|
||||
void CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene);
|
||||
|
||||
//! \brief Creates all nodes stored in imported content.
|
||||
aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||
aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
|
||||
//! \brief Creates all nodes stored in imported content.
|
||||
aiNode *createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||
aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
|
||||
|
||||
//! \brief Creates topology data like faces and meshes for the geometry.
|
||||
//! \brief Creates topology data like faces and meshes for the geometry.
|
||||
aiMesh *createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||
unsigned int uiMeshIndex );
|
||||
unsigned int uiMeshIndex );
|
||||
|
||||
//! \brief Creates vertices from model.
|
||||
void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
|
||||
unsigned int uiMeshIndex, aiMesh* pMesh,unsigned int uiIdxCount);
|
||||
//! \brief Creates vertices from model.
|
||||
void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
|
||||
unsigned int uiMeshIndex, aiMesh* pMesh,unsigned int uiIdxCount);
|
||||
|
||||
//! \brief Object counter helper method.
|
||||
void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
|
||||
//! \brief Object counter helper method.
|
||||
void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
|
||||
|
||||
//! \brief Material creation.
|
||||
void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
|
||||
void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1);
|
||||
//! \brief Material creation.
|
||||
void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
|
||||
void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1);
|
||||
|
||||
//! \brief Appends a child node to a parent node and updates the data structures.
|
||||
void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
|
||||
//! \brief Appends a child node to a parent node and updates the data structures.
|
||||
void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
|
||||
|
||||
private:
|
||||
//! Data buffer
|
||||
std::vector<char> m_Buffer;
|
||||
//! Pointer to root object instance
|
||||
ObjFile::Object *m_pRootObject;
|
||||
//! Absolute pathname of model in file system
|
||||
std::string m_strAbsPath;
|
||||
//! Data buffer
|
||||
std::vector<char> m_Buffer;
|
||||
//! Pointer to root object instance
|
||||
ObjFile::Object *m_pRootObject;
|
||||
//! Absolute pathname of model in file system
|
||||
std::string m_strAbsPath;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -63,76 +63,76 @@ class IOSystem;
|
|||
class ObjFileParser
|
||||
{
|
||||
public:
|
||||
static const size_t BUFFERSIZE = 4096;
|
||||
typedef std::vector<char> DataArray;
|
||||
typedef std::vector<char>::iterator DataArrayIt;
|
||||
typedef std::vector<char>::const_iterator ConstDataArrayIt;
|
||||
static const size_t BUFFERSIZE = 4096;
|
||||
typedef std::vector<char> DataArray;
|
||||
typedef std::vector<char>::iterator DataArrayIt;
|
||||
typedef std::vector<char>::const_iterator ConstDataArrayIt;
|
||||
|
||||
public:
|
||||
/// \brief Constructor with data array.
|
||||
ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem* io);
|
||||
/// \brief Destructor
|
||||
~ObjFileParser();
|
||||
/// \brief Model getter.
|
||||
ObjFile::Model *GetModel() const;
|
||||
/// \brief Constructor with data array.
|
||||
ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem* io);
|
||||
/// \brief Destructor
|
||||
~ObjFileParser();
|
||||
/// \brief Model getter.
|
||||
ObjFile::Model *GetModel() const;
|
||||
|
||||
private:
|
||||
/// Parse the loaded file
|
||||
void parseFile();
|
||||
/// Method to copy the new delimited word in the current line.
|
||||
void copyNextWord(char *pBuffer, size_t length);
|
||||
/// Method to copy the new line.
|
||||
void copyNextLine(char *pBuffer, size_t length);
|
||||
/// Parse the loaded file
|
||||
void parseFile();
|
||||
/// Method to copy the new delimited word in the current line.
|
||||
void copyNextWord(char *pBuffer, size_t length);
|
||||
/// Method to copy the new line.
|
||||
void copyNextLine(char *pBuffer, size_t length);
|
||||
/// Stores the vector
|
||||
void getVector( std::vector<aiVector3D> &point3d_array );
|
||||
/// Stores the following 3d vector.
|
||||
void getVector3( std::vector<aiVector3D> &point3d_array );
|
||||
/// Stores the following 3d vector.
|
||||
void getVector2(std::vector<aiVector2D> &point2d_array);
|
||||
void getVector3( std::vector<aiVector3D> &point3d_array );
|
||||
/// Stores the following 3d vector.
|
||||
void getVector2(std::vector<aiVector2D> &point2d_array);
|
||||
/// Stores the following face.
|
||||
void getFace(aiPrimitiveType type);
|
||||
/// Reads the material description.
|
||||
void getFace(aiPrimitiveType type);
|
||||
/// Reads the material description.
|
||||
void getMaterialDesc();
|
||||
/// Gets a comment.
|
||||
void getComment();
|
||||
/// Gets a a material library.
|
||||
void getMaterialLib();
|
||||
/// Creates a new material.
|
||||
void getNewMaterial();
|
||||
/// Gets the group name from file.
|
||||
void getGroupName();
|
||||
/// Gets the group number from file.
|
||||
void getGroupNumber();
|
||||
/// Gets the group number and resolution from file.
|
||||
void getGroupNumberAndResolution();
|
||||
/// Returns the index of the material. Is -1 if not material was found.
|
||||
int getMaterialIndex( const std::string &strMaterialName );
|
||||
/// Parse object name
|
||||
void getObjectName();
|
||||
/// Creates a new object.
|
||||
void createObject(const std::string &strObjectName);
|
||||
/// Creates a new mesh.
|
||||
void createMesh();
|
||||
/// Returns true, if a new mesh instance must be created.
|
||||
bool needsNewMesh( const std::string &rMaterialName );
|
||||
/// Error report in token
|
||||
void reportErrorTokenInFace();
|
||||
/// Gets a comment.
|
||||
void getComment();
|
||||
/// Gets a a material library.
|
||||
void getMaterialLib();
|
||||
/// Creates a new material.
|
||||
void getNewMaterial();
|
||||
/// Gets the group name from file.
|
||||
void getGroupName();
|
||||
/// Gets the group number from file.
|
||||
void getGroupNumber();
|
||||
/// Gets the group number and resolution from file.
|
||||
void getGroupNumberAndResolution();
|
||||
/// Returns the index of the material. Is -1 if not material was found.
|
||||
int getMaterialIndex( const std::string &strMaterialName );
|
||||
/// Parse object name
|
||||
void getObjectName();
|
||||
/// Creates a new object.
|
||||
void createObject(const std::string &strObjectName);
|
||||
/// Creates a new mesh.
|
||||
void createMesh();
|
||||
/// Returns true, if a new mesh instance must be created.
|
||||
bool needsNewMesh( const std::string &rMaterialName );
|
||||
/// Error report in token
|
||||
void reportErrorTokenInFace();
|
||||
|
||||
private:
|
||||
/// Default material name
|
||||
static const std::string DEFAULT_MATERIAL;
|
||||
//! Iterator to current position in buffer
|
||||
DataArrayIt m_DataIt;
|
||||
//! Iterator to end position of buffer
|
||||
DataArrayIt m_DataItEnd;
|
||||
//! Pointer to model instance
|
||||
ObjFile::Model *m_pModel;
|
||||
//! Current line (for debugging)
|
||||
unsigned int m_uiLine;
|
||||
//! Helper buffer
|
||||
char m_buffer[BUFFERSIZE];
|
||||
/// Pointer to IO system instance.
|
||||
IOSystem *m_pIO;
|
||||
/// Default material name
|
||||
static const std::string DEFAULT_MATERIAL;
|
||||
//! Iterator to current position in buffer
|
||||
DataArrayIt m_DataIt;
|
||||
//! Iterator to end position of buffer
|
||||
DataArrayIt m_DataItEnd;
|
||||
//! Pointer to model instance
|
||||
ObjFile::Model *m_pModel;
|
||||
//! Current line (for debugging)
|
||||
unsigned int m_uiLine;
|
||||
//! Helper buffer
|
||||
char m_buffer[BUFFERSIZE];
|
||||
/// Pointer to IO system instance.
|
||||
IOSystem *m_pIO;
|
||||
};
|
||||
|
||||
} // Namespace Assimp
|
||||
|
|
|
@ -0,0 +1,510 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2014, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
#include "OpenGEXImporter.h"
|
||||
#include "DefaultIOSystem.h"
|
||||
|
||||
#include <openddlparser/OpenDDLParser.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
"Open Game Engine Exchange",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
aiImporterFlags_SupportTextFlavour,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"ogex"
|
||||
};
|
||||
|
||||
namespace Grammar {
|
||||
static const char *MetricType = "Metric";
|
||||
static const char *Metric_DistanceType = "distance";
|
||||
static const char *Metric_AngleType = "angle";
|
||||
static const char *Metric_TimeType = "time";
|
||||
static const char *Metric_UpType = "up";
|
||||
static const char *NameType = "Name";
|
||||
static const char *ObjectRefType = "ObjectRef";
|
||||
static const char *MaterialRefType = "MaterialRef";
|
||||
static const char *MetricKeyType = "key";
|
||||
static const char *GeometryNodeType = "GeometryNode";
|
||||
static const char *GeometryObjectType = "GeometryObject";
|
||||
static const char *TransformType = "Transform";
|
||||
static const char *MeshType = "Mesh";
|
||||
static const char *VertexArrayType = "VertexArray";
|
||||
static const char *IndexArrayType = "IndexArray";
|
||||
static const char *MaterialType = "Material";
|
||||
static const char *ColorType = "Color";
|
||||
static const char *TextureType = "Texture";
|
||||
|
||||
enum TokenType {
|
||||
NoneType = -1,
|
||||
MetricToken,
|
||||
NameToken,
|
||||
ObjectRefToken,
|
||||
MaterialRefToken,
|
||||
MetricKeyToken,
|
||||
GeometryNodeToken,
|
||||
GeometryObjectToken,
|
||||
TransformToken,
|
||||
MeshToken,
|
||||
VertexArrayToken,
|
||||
IndexArrayToken,
|
||||
MaterialToken,
|
||||
ColorToken,
|
||||
TextureToken
|
||||
};
|
||||
|
||||
static const char *ValidMetricToken[ 4 ] = {
|
||||
Metric_DistanceType,
|
||||
Metric_AngleType,
|
||||
Metric_TimeType,
|
||||
Metric_UpType
|
||||
};
|
||||
|
||||
static int isValidMetricType( const char *token ) {
|
||||
if( NULL == token ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int idx( -1 );
|
||||
for( size_t i = 0; i < 4; i++ ) {
|
||||
if( 0 == strncmp( ValidMetricToken[ i ], token, strlen( token ) ) ) {
|
||||
idx = (int) i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static TokenType matchTokenType( const char *tokenType ) {
|
||||
if( 0 == strncmp( MetricType, tokenType, strlen( tokenType ) ) ) {
|
||||
return MetricToken;
|
||||
} else if( 0 == strncmp( NameType, tokenType, strlen( tokenType ) ) ) {
|
||||
return NameToken;
|
||||
} else if( 0 == strncmp( ObjectRefType, tokenType, strlen( tokenType ) ) ) {
|
||||
return ObjectRefToken;
|
||||
} else if( 0 == strncmp( MaterialRefType, tokenType, strlen( tokenType ) ) ) {
|
||||
return MaterialRefToken;
|
||||
} else if( 0 == strncmp( MetricKeyType, tokenType, strlen( tokenType ) ) ) {
|
||||
return MetricKeyToken;
|
||||
} else if( 0 == strncmp( GeometryNodeType, tokenType, strlen( tokenType ) ) ) {
|
||||
return GeometryNodeToken;
|
||||
} else if( 0 == strncmp( GeometryObjectType, tokenType, strlen( tokenType ) ) ) {
|
||||
return GeometryObjectToken;
|
||||
} else if( 0 == strncmp( TransformType, tokenType, strlen( tokenType ) ) ) {
|
||||
return TransformToken;
|
||||
} else if( 0 == strncmp( MeshType, tokenType, strlen( tokenType ) ) ) {
|
||||
return MeshToken;
|
||||
} else if( 0 == strncmp( VertexArrayType, tokenType, strlen( tokenType ) ) ) {
|
||||
return VertexArrayToken;
|
||||
} else if( 0 == strncmp( IndexArrayType, tokenType, strlen( tokenType ) ) ) {
|
||||
return IndexArrayToken;
|
||||
} else if( 0 == strncmp( MaterialType, tokenType, strlen( tokenType ) ) ) {
|
||||
return MaterialToken;
|
||||
} else if( 0 == strncmp( ColorType, tokenType, strlen( tokenType ) ) ) {
|
||||
return ColorToken;
|
||||
} else if( 0 == strncmp( TextureType, tokenType, strlen( tokenType ) ) ) {
|
||||
return TextureToken;
|
||||
}
|
||||
|
||||
return NoneType;
|
||||
}
|
||||
|
||||
} // Namespace Grammar
|
||||
|
||||
namespace Assimp {
|
||||
namespace OpenGEX {
|
||||
|
||||
USE_ODDLPARSER_NS
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
OpenGEXImporter::RefInfo::RefInfo( aiNode *node, Type type, std::vector<std::string> &names )
|
||||
: m_node( node )
|
||||
, m_type( type )
|
||||
, m_Names( names ) {
|
||||
// empty
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
OpenGEXImporter::RefInfo::~RefInfo() {
|
||||
// empty
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
OpenGEXImporter::OpenGEXImporter()
|
||||
: m_meshCache()
|
||||
, m_mesh2refMap()
|
||||
, m_ctx( NULL )
|
||||
, m_currentNode( NULL )
|
||||
, m_nodeStack()
|
||||
, m_unresolvedRefStack() {
|
||||
// empty
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
OpenGEXImporter::~OpenGEXImporter() {
|
||||
m_ctx = NULL;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
bool OpenGEXImporter::CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const {
|
||||
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 &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 );
|
||||
|
||||
OpenDDLParser myParser;
|
||||
myParser.setBuffer( &buffer[ 0 ], buffer.size() );
|
||||
bool success( myParser.parse() );
|
||||
if( success ) {
|
||||
m_ctx = myParser.getContext();
|
||||
pScene->mRootNode = new aiNode;
|
||||
pScene->mRootNode->mName.Set( filename );
|
||||
handleNodes( m_ctx->m_root, pScene );
|
||||
}
|
||||
|
||||
resolveReferences();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
const aiImporterDesc *OpenGEXImporter::GetInfo() const {
|
||||
return &desc;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::SetupProperties( const Importer *pImp ) {
|
||||
if( NULL == pImp ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
DDLNode::DllNodeList childs = node->getChildNodeList();
|
||||
for( DDLNode::DllNodeList::iterator it = childs.begin(); it != childs.end(); it++ ) {
|
||||
Grammar::TokenType tokenType( Grammar::matchTokenType( ( *it )->getType().c_str() ) );
|
||||
switch( tokenType ) {
|
||||
case Grammar::MetricToken:
|
||||
handleMetricNode( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::NameToken:
|
||||
handleNameNode( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::ObjectRefToken:
|
||||
handleObjectRefNode( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::MaterialRefToken:
|
||||
handleMaterialRefNode( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::MetricKeyToken:
|
||||
break;
|
||||
|
||||
case Grammar::GeometryNodeToken:
|
||||
handleGeometryNode( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::GeometryObjectToken:
|
||||
handleGeometryObject( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::TransformToken:
|
||||
break;
|
||||
|
||||
case Grammar::MeshToken:
|
||||
break;
|
||||
|
||||
case Grammar::VertexArrayToken:
|
||||
break;
|
||||
|
||||
case Grammar::IndexArrayToken:
|
||||
break;
|
||||
|
||||
case Grammar::MaterialToken:
|
||||
handleMaterial( *it, pScene );
|
||||
break;
|
||||
|
||||
case Grammar::ColorToken:
|
||||
break;
|
||||
|
||||
case Grammar::TextureToken:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == node || NULL == m_ctx ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_ctx->m_root != node->getParent() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Property *prop( node->getProperties() );
|
||||
while( NULL != prop ) {
|
||||
if( NULL != prop->m_id ) {
|
||||
if( Value::ddl_string == prop->m_primData->m_type ) {
|
||||
std::string valName( (char*) prop->m_primData->m_data );
|
||||
int type( Grammar::isValidMetricType( valName.c_str() ) );
|
||||
if( Grammar::NoneType != type ) {
|
||||
Value *val( node->getValue() );
|
||||
if( NULL != val ) {
|
||||
if( Value::ddl_float == val->m_type ) {
|
||||
m_metrics[ type ].m_floatValue = val->getFloat();
|
||||
} else if( Value::ddl_int32 == val->m_type ) {
|
||||
m_metrics[ type ].m_intValue = val->getInt32();
|
||||
} else if( Value::ddl_string == val->m_type ) {
|
||||
m_metrics[type].m_stringValue = std::string( val->getString() );
|
||||
} else {
|
||||
throw DeadlyImportError( "OpenGEX: invalid data type for Metric node." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prop = prop->m_next;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == m_currentNode ) {
|
||||
throw DeadlyImportError( "No parent node for name." );
|
||||
return;
|
||||
}
|
||||
|
||||
Value *val( node->getValue() );
|
||||
if( NULL != val ) {
|
||||
if( Value::ddl_string != val->m_type ) {
|
||||
throw DeadlyImportError( "OpenGEX: invalid data type for value in node name." );
|
||||
}
|
||||
|
||||
std::string name( val->getString() );
|
||||
m_currentNode->mName.Set( name.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
static void getRefNames( DDLNode *node, std::vector<std::string> &names ) {
|
||||
ai_assert( NULL != node );
|
||||
|
||||
Reference *ref = node->getReferences();
|
||||
if( NULL != ref ) {
|
||||
for( size_t i = 0; i < ref->m_numRefs; i++ ) {
|
||||
Name *currentName( ref->m_referencedName[ i ] );
|
||||
if( NULL != currentName && NULL != currentName->m_id ) {
|
||||
const std::string name( currentName->m_id->m_buffer );
|
||||
if( !name.empty() ) {
|
||||
names.push_back( name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == m_currentNode ) {
|
||||
throw DeadlyImportError( "No parent node for name." );
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> objRefNames;
|
||||
getRefNames( node, objRefNames );
|
||||
m_currentNode->mNumMeshes = objRefNames.size();
|
||||
m_currentNode->mMeshes = new unsigned int[ objRefNames.size() ];
|
||||
if( !objRefNames.empty() ) {
|
||||
m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MeshRef, objRefNames ) );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
if( NULL == m_currentNode ) {
|
||||
throw DeadlyImportError( "No parent node for name." );
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> matRefNames;
|
||||
getRefNames( node, matRefNames );
|
||||
if( !matRefNames.empty() ) {
|
||||
m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MaterialRef, matRefNames ) );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleGeometryNode( DDLNode *node, aiScene *pScene ) {
|
||||
aiNode *newNode = new aiNode;
|
||||
pushNode( newNode, pScene );
|
||||
m_currentNode = newNode;
|
||||
handleNodes( node, pScene );
|
||||
|
||||
popNode();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleGeometryObject( DDLNode *node, aiScene *pScene ) {
|
||||
aiMesh *currentMesh( new aiMesh );
|
||||
const size_t idx( m_meshCache.size() );
|
||||
m_meshCache.push_back( currentMesh );
|
||||
|
||||
// store name to reference relation
|
||||
m_mesh2refMap[ node->getName() ] = idx;
|
||||
|
||||
// todo: child nodes?
|
||||
|
||||
handleNodes( node, pScene );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleMaterial( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::resolveReferences() {
|
||||
if( m_unresolvedRefStack.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefInfo *currentRefInfo( NULL );
|
||||
for( std::vector<RefInfo*>::iterator it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it ) {
|
||||
currentRefInfo = *it;
|
||||
if( NULL != currentRefInfo ) {
|
||||
aiNode *node( currentRefInfo->m_node );
|
||||
if( RefInfo::MeshRef == currentRefInfo->m_type ) {
|
||||
for( size_t i = 0; i < currentRefInfo->m_Names.size(); i++ ) {
|
||||
const std::string &name(currentRefInfo->m_Names[ i ] );
|
||||
unsigned int meshIdx = m_mesh2refMap[ name ];
|
||||
node->mMeshes[ i ] = meshIdx;
|
||||
}
|
||||
} else if( RefInfo::MaterialRef == currentRefInfo->m_type ) {
|
||||
// ToDo
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) {
|
||||
ai_assert( NULL != pScene );
|
||||
|
||||
if( NULL != node ) {
|
||||
if( m_nodeStack.empty() ) {
|
||||
node->mParent = pScene->mRootNode;
|
||||
} else {
|
||||
aiNode *parent( m_nodeStack.back() );
|
||||
ai_assert( NULL != parent );
|
||||
node->mParent = parent;
|
||||
}
|
||||
m_nodeStack.push_back( node );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
aiNode *OpenGEXImporter::popNode() {
|
||||
if( m_nodeStack.empty() ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aiNode *node( top() );
|
||||
m_nodeStack.pop_back();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
aiNode *OpenGEXImporter::top() const {
|
||||
if( m_nodeStack.empty() ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m_nodeStack.back();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::clearNodeStack() {
|
||||
m_nodeStack.clear();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
} // Namespace OpenGEX
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2014, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef AI_OPENGEX_IMPORTER_H
|
||||
#define AI_OPENGEX_IMPORTER_H
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
||||
|
||||
#include "BaseImporter.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ODDLParser {
|
||||
class DDLNode;
|
||||
struct Context;
|
||||
}
|
||||
|
||||
namespace Assimp {
|
||||
namespace OpenGEX {
|
||||
|
||||
struct MetricInfo {
|
||||
enum Type {
|
||||
Distance = 0,
|
||||
Angle,
|
||||
Time,
|
||||
Up,
|
||||
Max
|
||||
};
|
||||
|
||||
std::string m_stringValue;
|
||||
float m_floatValue;
|
||||
int m_intValue;
|
||||
|
||||
MetricInfo()
|
||||
: m_stringValue( "" )
|
||||
, m_floatValue( 0.0f )
|
||||
, m_intValue( -1 ) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief This class is used to implement the OpenGEX importer
|
||||
*
|
||||
* See http://opengex.org/OpenGEX.pdf for spec.
|
||||
*/
|
||||
class OpenGEXImporter : public BaseImporter {
|
||||
public:
|
||||
/// The class constructor.
|
||||
OpenGEXImporter();
|
||||
|
||||
/// The class destructor.
|
||||
virtual ~OpenGEXImporter();
|
||||
|
||||
/// BaseImporter override.
|
||||
virtual bool CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const;
|
||||
|
||||
/// BaseImporter override.
|
||||
virtual void InternReadFile( const std::string &file, aiScene *pScene, IOSystem *pIOHandler );
|
||||
|
||||
/// BaseImporter override.
|
||||
virtual const aiImporterDesc *GetInfo() const;
|
||||
|
||||
/// BaseImporter override.
|
||||
virtual void SetupProperties( const Importer *pImp );
|
||||
|
||||
protected:
|
||||
void handleNodes( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleMetricNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleNameNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleObjectRefNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleGeometryNode( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleGeometryObject( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void handleMaterial( ODDLParser::DDLNode *node, aiScene *pScene );
|
||||
void resolveReferences();
|
||||
void pushNode( aiNode *node, aiScene *pScene );
|
||||
aiNode *popNode();
|
||||
aiNode *top() const;
|
||||
void clearNodeStack();
|
||||
|
||||
private:
|
||||
struct RefInfo {
|
||||
enum Type {
|
||||
MeshRef,
|
||||
MaterialRef
|
||||
};
|
||||
|
||||
aiNode *m_node;
|
||||
Type m_type;
|
||||
std::vector<std::string> m_Names;
|
||||
|
||||
RefInfo( aiNode *node, Type type, std::vector<std::string> &names );
|
||||
~RefInfo();
|
||||
|
||||
private:
|
||||
RefInfo( const RefInfo & );
|
||||
RefInfo &operator = ( const RefInfo & );
|
||||
};
|
||||
|
||||
std::vector<aiMesh*> m_meshCache;
|
||||
std::map<std::string, size_t> m_mesh2refMap;
|
||||
|
||||
ODDLParser::Context *m_ctx;
|
||||
MetricInfo m_metrics[ MetricInfo::Max ];
|
||||
aiNode *m_currentNode;
|
||||
std::vector<aiNode*> m_nodeStack;
|
||||
std::vector<RefInfo*> m_unresolvedRefStack;
|
||||
};
|
||||
|
||||
} // Namespace OpenGEX
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER
|
||||
|
||||
#endif // AI_OPENGEX_IMPORTER_H
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2014, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef AI_OPENGEXSTRUCTS_H_INC
|
||||
#define AI_OPENGEXSTRUCTS_H_INC
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace Assimp {
|
||||
namespace OpenGEX {
|
||||
|
||||
struct Skin;
|
||||
struct Object;
|
||||
struct LightObject;
|
||||
struct CameraObject;
|
||||
struct Material;
|
||||
struct BoneNode;
|
||||
struct BoneCountArray;
|
||||
struct BoneIndexArray;
|
||||
struct BoneWeightArray;
|
||||
|
||||
struct Metric {
|
||||
float m_distance;
|
||||
float m_angle;
|
||||
float m_time;
|
||||
float m_up;
|
||||
};
|
||||
|
||||
struct VertexArray {
|
||||
std::string arrayAttrib;
|
||||
unsigned int morphIndex;
|
||||
};
|
||||
|
||||
struct IndexArray {
|
||||
unsigned int materialIndex;
|
||||
unsigned int restartIndex;
|
||||
std::string frontFace;
|
||||
};
|
||||
|
||||
struct Mesh {
|
||||
unsigned int meshLevel;
|
||||
std::string meshPrimitive;
|
||||
Skin *skinStructure;
|
||||
};
|
||||
|
||||
struct Node {
|
||||
std::string nodeName;
|
||||
};
|
||||
|
||||
struct GeometryNode {
|
||||
bool visibleFlag[ 2 ];
|
||||
bool shadowFlag[ 2 ];
|
||||
bool motionBlurFlag[ 2 ];
|
||||
};
|
||||
|
||||
struct LightNode {
|
||||
bool shadowFlag[ 2 ];
|
||||
const LightObject *lightObjectStructure;
|
||||
};
|
||||
|
||||
struct CameraNode {
|
||||
const CameraObject *cameraObjectStructure;
|
||||
};
|
||||
|
||||
struct GeometryObject {
|
||||
Object *object;
|
||||
bool visibleFlag;
|
||||
bool shadowFlag;
|
||||
bool motionBlurFlag;
|
||||
std::map<std::string, Mesh*> meshMap;
|
||||
};
|
||||
|
||||
struct LightObject {
|
||||
Object *object;
|
||||
std::string typeString;
|
||||
bool shadowFlag;
|
||||
};
|
||||
|
||||
|
||||
struct CameraObject {
|
||||
float focalLength;
|
||||
float nearDepth;
|
||||
float farDepth;
|
||||
};
|
||||
|
||||
struct Matrix {
|
||||
bool objectFlag;
|
||||
};
|
||||
|
||||
struct Transform {
|
||||
Matrix *matrix;
|
||||
int transformCount;
|
||||
const float *transformArray;
|
||||
};
|
||||
|
||||
struct Translation {
|
||||
std::string translationKind;
|
||||
};
|
||||
|
||||
struct Rotation {
|
||||
std::string rotationKind;
|
||||
};
|
||||
|
||||
struct Scale {
|
||||
std::string scaleKind;
|
||||
};
|
||||
|
||||
struct Name {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
|
||||
struct ObjectRef {
|
||||
Object *targetStructure;
|
||||
};
|
||||
|
||||
struct MaterialRef {
|
||||
unsigned int materialIndex;
|
||||
const Material *targetStructure;
|
||||
};
|
||||
|
||||
struct BoneRefArray {
|
||||
int boneCount;
|
||||
const BoneNode **boneNodeArray;
|
||||
};
|
||||
|
||||
struct BoneCount {
|
||||
int vertexCount;
|
||||
const unsigned short *boneCountArray;
|
||||
unsigned short *arrayStorage;
|
||||
};
|
||||
|
||||
struct BoneIndex {
|
||||
int boneIndexCount;
|
||||
const unsigned short *boneIndexArray;
|
||||
unsigned short *arrayStorage;
|
||||
};
|
||||
|
||||
|
||||
struct BoneWeight {
|
||||
int boneWeightCount;
|
||||
const float *boneWeightArray;
|
||||
};
|
||||
|
||||
struct Skeleton {
|
||||
const BoneRefArray *boneRefArrayStructure;
|
||||
const Transform *transformStructure;
|
||||
};
|
||||
|
||||
struct Skin {
|
||||
const Skeleton *skeletonStructure;
|
||||
const BoneCountArray *boneCountArrayStructure;
|
||||
const BoneIndexArray *boneIndexArrayStructure;
|
||||
const BoneWeightArray *boneWeightArrayStructure;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
bool twoSidedFlag;
|
||||
const char *materialName;
|
||||
};
|
||||
|
||||
struct Attrib {
|
||||
std::string attribString;
|
||||
};
|
||||
|
||||
struct Param {
|
||||
float param;
|
||||
};
|
||||
|
||||
struct Color {
|
||||
float color[ 4 ];
|
||||
};
|
||||
|
||||
struct Texture {
|
||||
std::string textureName;
|
||||
unsigned int texcoordIndex;
|
||||
};
|
||||
|
||||
struct Atten {
|
||||
std::string attenKind;
|
||||
std::string curveType;
|
||||
|
||||
float beginParam;
|
||||
float endParam;
|
||||
|
||||
float scaleParam;
|
||||
float offsetParam;
|
||||
|
||||
float constantParam;
|
||||
float linearParam;
|
||||
float quadraticParam;
|
||||
|
||||
float powerParam;
|
||||
};
|
||||
|
||||
struct Key {
|
||||
std::string keyKind;
|
||||
bool scalarFlag;
|
||||
};
|
||||
|
||||
struct Curve {
|
||||
std::string curveType;
|
||||
const Key *keyValueStructure;
|
||||
const Key *keyControlStructure[ 2 ];
|
||||
const Key *keyTensionStructure;
|
||||
const Key *keyContinuityStructure;
|
||||
const Key *keyBiasStructure;
|
||||
};
|
||||
|
||||
struct Animation {
|
||||
int clipIndex;
|
||||
bool beginFlag;
|
||||
bool endFlag;
|
||||
float beginTime;
|
||||
float endTime;
|
||||
};
|
||||
|
||||
struct OpenGexDataDescription {
|
||||
float distanceScale;
|
||||
float angleScale;
|
||||
float timeScale;
|
||||
int upDirection;
|
||||
};
|
||||
|
||||
} // Namespace OpenGEX
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // AI_OPENGEXSTRUCTS_H_INC
|
|
@ -0,0 +1,64 @@
|
|||
CMAKE_MINIMUM_REQUIRED( VERSION 2.6 )
|
||||
PROJECT( OpenDDL-Parser )
|
||||
SET ( OPENDDL_PARSER_VERSION_MAJOR 0 )
|
||||
SET ( OPENDDL_PARSER_VERSION_MINOR 1 )
|
||||
SET ( OPENDDL_PARSER_VERSION_PATCH 0 )
|
||||
SET ( OPENDDL_PARSER_VERSION ${CPPCORE_VERSION_MAJOR}.${CPPCORE_VERSION_MINOR}.${CPPCORE_VERSION_PATCH} )
|
||||
SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" )
|
||||
|
||||
if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||
find_package(Threads)
|
||||
else()
|
||||
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
|
||||
endif()
|
||||
|
||||
add_definitions( -DOPENDDLPARSER_BUILD )
|
||||
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||
add_definitions( -D_VARIADIC_MAX=10 )
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
./
|
||||
include/
|
||||
contrib/gtest-1.7.0/include
|
||||
contrib/gtest-1.7.0/
|
||||
)
|
||||
|
||||
link_directories(
|
||||
./
|
||||
)
|
||||
|
||||
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
||||
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
|
||||
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin )
|
||||
|
||||
if( WIN32 AND NOT CYGWIN )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc" ) # Force to always compile with W4
|
||||
if( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" )
|
||||
string( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" )
|
||||
else()
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" )
|
||||
endif()
|
||||
elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
|
||||
# Update if necessary
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++0x")
|
||||
elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -std=c++11")
|
||||
endif()
|
||||
|
||||
SET ( openddl_parser_src
|
||||
code/OpenDDLParser.cpp
|
||||
code/DDLNode.cpp
|
||||
code/Value.cpp
|
||||
include/openddlparser/OpenDDLParser.h
|
||||
include/openddlparser/OpenDDLParserUtils.h
|
||||
include/openddlparser/OpenDDLCommon.h
|
||||
include/openddlparser/DDLNode.h
|
||||
include/openddlparser/Value.h
|
||||
README.md
|
||||
)
|
||||
|
||||
SOURCE_GROUP( code FILES ${openddl_parser_src} )
|
||||
|
||||
ADD_LIBRARY( openddl_parser SHARED
|
||||
${openddl_parser_src}
|
||||
)
|
|
@ -0,0 +1,111 @@
|
|||
The OpenDDL-Parser
|
||||
==================
|
||||
|
||||
A simple and fast OpenDDL Parser
|
||||
Current build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser)
|
||||
|
||||
Get the source code
|
||||
===================
|
||||
You can get the code from our git repository, which is located at GitHub. You can clone the repository like:
|
||||
|
||||
> git clone https://github.com/kimkulling/openddl-parser.git
|
||||
|
||||
Build from repo
|
||||
===============
|
||||
To build the library you need to install cmake first ( see http://www.cmake.org/ for more information ). Make also sure that a compiler toolchain is installed on your machine.
|
||||
After installing it you can open a console and type:
|
||||
|
||||
> cmake CMakeLists.txt
|
||||
|
||||
This command will generate a build environment for your installed build enrironment ( for Visual Studio the project files will be generated, for gcc the makefiles will be generated ).
|
||||
When using an IDE open the IDE and run the build. When using GNU-make type in your console:
|
||||
|
||||
> make
|
||||
|
||||
and that's all.
|
||||
|
||||
Use the library
|
||||
===============
|
||||
To use the OpenDDL-parser you need to build the lib first. Now add the
|
||||
> <Repo-folder>/include
|
||||
|
||||
to your include-path and the
|
||||
|
||||
> <Repo-folder>/lib
|
||||
|
||||
to your lib-folder. Link the openddl.lib to your application.
|
||||
|
||||
Here is a small example how to use the lib:
|
||||
|
||||
```cpp
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <openddlparser/OpenDDLParser.h>
|
||||
|
||||
USE_ODDLPARSER_NS;
|
||||
|
||||
int main( int argc, char *argv[] ) {
|
||||
if( argc < 3 ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *filename( nullptr );
|
||||
if( 0 == strncmp( FileOption, argv[ 1 ], strlen( FileOption ) ) ) {
|
||||
filename = argv[ 2 ];
|
||||
}
|
||||
std::cout << "file to import: " << filename << std::endl;
|
||||
if( nullptr == filename ) {
|
||||
std::cerr << "Invalid filename." << std::endl;
|
||||
return Error;
|
||||
}
|
||||
|
||||
FILE *fileStream = fopen( filename, "r+" );
|
||||
if( NULL == filename ) {
|
||||
std::cerr << "Cannot open file " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// obtain file size:
|
||||
fseek( fileStream, 0, SEEK_END );
|
||||
const size_t size( ftell( fileStream ) );
|
||||
rewind( fileStream );
|
||||
if( size > 0 ) {
|
||||
char *buffer = new char[ size ];
|
||||
const size_t readSize( fread( buffer, sizeof( char ), size, fileStream ) );
|
||||
assert( readSize == size );
|
||||
OpenDDLParser theParser;
|
||||
theParser.setBuffer( buffer, size );
|
||||
const bool result( theParser.parse() );
|
||||
if( !result ) {
|
||||
std::cerr << "Error while parsing file " << filename << "." << std::endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
How to access the imported data
|
||||
===============================
|
||||
The data is organized as a tree. You can get the root tree with the following code:
|
||||
|
||||
```
|
||||
OpenDDLParser theParser;
|
||||
theParser.setBuffer( buffer, size );
|
||||
const bool result( theParser.parse() );
|
||||
if ( result ) {
|
||||
DDLNode *root = theParser.getRoot();
|
||||
|
||||
DDLNode::DllNodeList childs = root->getChildNodeList();
|
||||
for ( size_t i=0; i<childs.size(); i++ ) {
|
||||
DDLNode *child = childs[ i ];
|
||||
Property *prop = child->getProperty(); // to get properties
|
||||
std:.string type = child->getType(); // to get the node type
|
||||
Value *values = child->getValue(); // to get the data;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The instance called root contains the data.
|
|
@ -0,0 +1,184 @@
|
|||
/*-----------------------------------------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Kim Kulling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
-----------------------------------------------------------------------------------------------*/
|
||||
#include <openddlparser/DDLNode.h>
|
||||
#include <openddlparser/OpenDDLParser.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
DDLNode::DllNodeList DDLNode::s_allocatedNodes;
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
static void releaseDataType( T *ptr ) {
|
||||
if( ddl_nullptr == ptr ) {
|
||||
return;
|
||||
}
|
||||
|
||||
T *current( ddl_nullptr );
|
||||
while( ptr ) {
|
||||
current = ptr;
|
||||
ptr = ptr->m_next;
|
||||
delete current;
|
||||
}
|
||||
}
|
||||
|
||||
static void releaseReferencedNames( Reference *ref ) {
|
||||
if( ddl_nullptr == ref ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( ref->m_referencedName ) {
|
||||
for( size_t i = 0; i < ref->m_numRefs; i++ ) {
|
||||
delete ref->m_referencedName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent )
|
||||
: m_type( type )
|
||||
, m_name( name )
|
||||
, m_parent( parent )
|
||||
, m_children()
|
||||
, m_properties( ddl_nullptr )
|
||||
, m_value( ddl_nullptr )
|
||||
, m_dtArrayList( ddl_nullptr )
|
||||
, m_references( ddl_nullptr )
|
||||
, m_idx( idx ) {
|
||||
if( m_parent ) {
|
||||
m_parent->m_children.push_back( this );
|
||||
}
|
||||
}
|
||||
|
||||
DDLNode::~DDLNode() {
|
||||
releaseDataType<Property>( m_properties );
|
||||
releaseDataType<Value>( m_value );
|
||||
releaseReferencedNames( m_references );
|
||||
|
||||
delete m_dtArrayList;
|
||||
m_dtArrayList = ddl_nullptr;
|
||||
if( s_allocatedNodes[ m_idx ] == this ) {
|
||||
s_allocatedNodes[ m_idx ] = ddl_nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void DDLNode::attachParent( DDLNode *parent ) {
|
||||
if( m_parent == parent ) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_parent = parent;
|
||||
if( ddl_nullptr != m_parent ) {
|
||||
m_parent->m_children.push_back( this );
|
||||
}
|
||||
}
|
||||
|
||||
void DDLNode::detachParent() {
|
||||
if( m_parent ) {
|
||||
std::vector<DDLNode*>::iterator it;
|
||||
it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this );
|
||||
if( m_parent->m_children.end() != it ) {
|
||||
m_parent->m_children.erase( it );
|
||||
}
|
||||
m_parent = ddl_nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DDLNode *DDLNode::getParent() const {
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
const DDLNode::DllNodeList &DDLNode::getChildNodeList() const {
|
||||
return m_children;
|
||||
}
|
||||
|
||||
void DDLNode::setType( const std::string &type ) {
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
const std::string &DDLNode::getType() const {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
|
||||
void DDLNode::setName( const std::string &name ) {
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
const std::string &DDLNode::getName() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void DDLNode::setProperties( Property *prop ) {
|
||||
m_properties = prop;
|
||||
}
|
||||
|
||||
Property *DDLNode::getProperties() const {
|
||||
return m_properties;
|
||||
}
|
||||
|
||||
void DDLNode::setValue( Value *val ) {
|
||||
m_value = val;
|
||||
}
|
||||
|
||||
Value *DDLNode::getValue() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void DDLNode::setDataArrayList( DataArrayList *dtArrayList ) {
|
||||
m_dtArrayList = dtArrayList;
|
||||
}
|
||||
|
||||
DataArrayList *DDLNode::getDataArrayList() const {
|
||||
return m_dtArrayList;
|
||||
}
|
||||
|
||||
void DDLNode::setReferences( Reference *refs ) {
|
||||
m_references = refs;
|
||||
}
|
||||
|
||||
Reference *DDLNode::getReferences() const {
|
||||
return m_references;
|
||||
}
|
||||
|
||||
DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) {
|
||||
const size_t idx( s_allocatedNodes.size() );
|
||||
DDLNode *node = new DDLNode( type, name, idx, parent );
|
||||
s_allocatedNodes.push_back( node );
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void DDLNode::releaseNodes() {
|
||||
if( s_allocatedNodes.size() > 0 ) {
|
||||
for( DllNodeList::iterator it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
|
||||
if( *it ) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
s_allocatedNodes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
END_ODDLPARSER_NS
|
|
@ -0,0 +1,888 @@
|
|||
/*-----------------------------------------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Kim Kulling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
-----------------------------------------------------------------------------------------------*/
|
||||
#include <openddlparser/OpenDDLParser.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#define DEBUG_HEADER_NAME
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
static const char *Version = "0.1.0";
|
||||
|
||||
namespace Grammar {
|
||||
static const char *OpenBracketToken = "{";
|
||||
static const char *CloseBracketToken = "}";
|
||||
static const char *OpenPropertyToken = "(";
|
||||
static const char *ClosePropertyToken = ")";
|
||||
static const char *BoolTrue = "true";
|
||||
static const char *BoolFalse = "false";
|
||||
static const char *RefToken = "ref";
|
||||
|
||||
static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
|
||||
"bool",
|
||||
"int8",
|
||||
"int16",
|
||||
"int32",
|
||||
"int64",
|
||||
"unsigned_int8",
|
||||
"unsigned_int16",
|
||||
"unsigned_int32",
|
||||
"unsigned_int64",
|
||||
"half",
|
||||
"float",
|
||||
"double",
|
||||
"string",
|
||||
"ref"
|
||||
};
|
||||
} // Namespace Grammar
|
||||
|
||||
|
||||
static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
|
||||
std::stringstream stream;
|
||||
stream << "Invalid token " << *in << ", " << exp << " expected." << std::endl;
|
||||
callback( ddl_error_msg, stream.str() );
|
||||
}
|
||||
|
||||
static bool isIntegerType( Value::ValueType integerType ) {
|
||||
if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 &&
|
||||
integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static DDLNode *createDDLNode( Identifier *id, OpenDDLParser *parser ) {
|
||||
if( ddl_nullptr == id || ddl_nullptr == parser ) {
|
||||
return ddl_nullptr;
|
||||
}
|
||||
|
||||
const std::string type( id->m_buffer );
|
||||
DDLNode *parent( parser->top() );
|
||||
DDLNode *node = DDLNode::create( type, "", parent );
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static void logMessage( LogSeverity severity, const std::string &msg ) {
|
||||
std::string log;
|
||||
if( ddl_debug_msg == severity ) {
|
||||
log += "Debug:";
|
||||
} else if( ddl_info_msg == severity ) {
|
||||
log += "Info :";
|
||||
} else if( ddl_warn_msg == severity ) {
|
||||
log += "Warn :";
|
||||
} else if( ddl_error_msg == severity ) {
|
||||
log += "Error:";
|
||||
} else {
|
||||
log += "None :";
|
||||
}
|
||||
|
||||
log += msg;
|
||||
std::cout << log;
|
||||
}
|
||||
|
||||
OpenDDLParser::OpenDDLParser()
|
||||
: m_logCallback( logMessage )
|
||||
, m_buffer()
|
||||
, m_stack()
|
||||
, m_context( ddl_nullptr ) {
|
||||
// empty
|
||||
}
|
||||
|
||||
OpenDDLParser::OpenDDLParser( char *buffer, size_t len )
|
||||
: m_logCallback( &logMessage )
|
||||
, m_buffer()
|
||||
, m_context( ddl_nullptr ) {
|
||||
if( 0 != len ) {
|
||||
setBuffer( buffer, len );
|
||||
}
|
||||
}
|
||||
|
||||
OpenDDLParser::~OpenDDLParser() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void OpenDDLParser::setLogCallback( logCallback callback ) {
|
||||
if( ddl_nullptr != callback ) {
|
||||
// install user-specific log callback
|
||||
m_logCallback = callback;
|
||||
} else {
|
||||
// install default log callback
|
||||
m_logCallback = &logMessage;
|
||||
}
|
||||
}
|
||||
|
||||
OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const {
|
||||
return m_logCallback;
|
||||
}
|
||||
|
||||
void OpenDDLParser::setBuffer( char *buffer, size_t len ) {
|
||||
clear();
|
||||
if( 0 == len ) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_buffer.resize( len );
|
||||
::memcpy(&m_buffer[ 0 ], buffer, len );
|
||||
}
|
||||
|
||||
void OpenDDLParser::setBuffer( const std::vector<char> &buffer ) {
|
||||
clear();
|
||||
m_buffer.resize( buffer.size() );
|
||||
std::copy( buffer.begin(), buffer.end(), m_buffer.begin() );
|
||||
}
|
||||
|
||||
const char *OpenDDLParser::getBuffer() const {
|
||||
if( m_buffer.empty() ) {
|
||||
return ddl_nullptr;
|
||||
}
|
||||
|
||||
return &m_buffer[ 0 ];
|
||||
}
|
||||
|
||||
size_t OpenDDLParser::getBufferSize() const {
|
||||
return m_buffer.size();
|
||||
}
|
||||
|
||||
void OpenDDLParser::clear() {
|
||||
m_buffer.resize( 0 );
|
||||
if( m_context ) {
|
||||
m_context->m_root = ddl_nullptr;
|
||||
}
|
||||
|
||||
DDLNode::releaseNodes();
|
||||
}
|
||||
|
||||
bool OpenDDLParser::parse() {
|
||||
if( m_buffer.empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
normalizeBuffer( m_buffer );
|
||||
|
||||
m_context = new Context;
|
||||
m_context->m_root = DDLNode::create( "root", "", ddl_nullptr );
|
||||
pushNode( m_context->m_root );
|
||||
|
||||
// do the main parsing
|
||||
char *current( &m_buffer[ 0 ] );
|
||||
char *end( &m_buffer[ m_buffer.size() - 1 ] + 1 );
|
||||
size_t pos( current - &m_buffer[ 0 ] );
|
||||
while( pos < m_buffer.size() ) {
|
||||
current = parseNextNode( current, end );
|
||||
pos = current - &m_buffer[ 0 ];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseNextNode( char *in, char *end ) {
|
||||
in = parseHeader( in, end );
|
||||
in = parseStructure( in, end );
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
static void dumpId( Identifier *id ) {
|
||||
if( ddl_nullptr != id ) {
|
||||
std::cout << id->m_buffer << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
Identifier *id( ddl_nullptr );
|
||||
in = OpenDDLParser::parseIdentifier( in, end, &id );
|
||||
|
||||
#ifdef DEBUG_HEADER_NAME
|
||||
dumpId( id );
|
||||
#endif // DEBUG_HEADER_NAME
|
||||
|
||||
in = getNextToken( in, end );
|
||||
Property *first( ddl_nullptr );
|
||||
if( ddl_nullptr != id ) {
|
||||
if( *in == '(' ) {
|
||||
in++;
|
||||
Property *prop( ddl_nullptr ), *prev( ddl_nullptr );
|
||||
while( *in != ')' && in != end ) {
|
||||
in = OpenDDLParser::parseProperty( in, end, &prop );
|
||||
in = getNextToken( in, end );
|
||||
|
||||
if( *in != ',' && *in != ')' ) {
|
||||
logInvalidTokenError( in, ")", m_logCallback );
|
||||
return in;
|
||||
}
|
||||
|
||||
if( ddl_nullptr != prop && *in != ',' ) {
|
||||
if( ddl_nullptr == first ) {
|
||||
first = prop;
|
||||
}
|
||||
if( ddl_nullptr != prev ) {
|
||||
prev->m_next = prop;
|
||||
}
|
||||
prev = prop;
|
||||
}
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
// store the node
|
||||
DDLNode *node( createDDLNode( id, this ) );
|
||||
if( ddl_nullptr != node ) {
|
||||
pushNode( node );
|
||||
} else {
|
||||
std::cerr << "nullptr returned by creating DDLNode." << std::endl;
|
||||
}
|
||||
|
||||
// set the properties
|
||||
if( ddl_nullptr != first ) {
|
||||
node->setProperties( first );
|
||||
}
|
||||
|
||||
Name *name( ddl_nullptr );
|
||||
in = OpenDDLParser::parseName( in, end, &name );
|
||||
if( ddl_nullptr != name ) {
|
||||
const std::string nodeName( name->m_id->m_buffer );
|
||||
node->setName( nodeName );
|
||||
}
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseStructure( char *in, char *end ) {
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
bool error( false );
|
||||
in = getNextToken( in, end );
|
||||
if( *in == '{' ) {
|
||||
do {
|
||||
// loop over all childs ( data and nodes )
|
||||
in = parseStructureBody( in, end, error );
|
||||
} while ( *in != '}' );
|
||||
in++;
|
||||
}
|
||||
else {
|
||||
in++;
|
||||
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
|
||||
error = true;
|
||||
return in;
|
||||
}
|
||||
in = getNextToken( in, end );
|
||||
|
||||
// pop node from stack after successful parsing
|
||||
if( !error ) {
|
||||
popNode();
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
static void setNodeValues( DDLNode *currentNode, Value *values ) {
|
||||
if( ddl_nullptr != values ){
|
||||
if( ddl_nullptr != currentNode ) {
|
||||
currentNode->setValue( values );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setNodeReferences( DDLNode *currentNode, Reference *refs ) {
|
||||
if( ddl_nullptr != refs ) {
|
||||
if( ddl_nullptr != currentNode ) {
|
||||
currentNode->setReferences( refs );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayList ) {
|
||||
if( ddl_nullptr != dtArrayList ) {
|
||||
if( ddl_nullptr != currentNode ) {
|
||||
currentNode->setDataArrayList( dtArrayList );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
|
||||
if( !isNumeric( *in ) && !isCharacter( *in ) ) {
|
||||
in++;
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
Value::ValueType type( Value::ddl_none );
|
||||
size_t arrayLen( 0 );
|
||||
in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen );
|
||||
if( Value::ddl_none != type ) {
|
||||
in = getNextToken( in, end );
|
||||
if( *in == '{' ) {
|
||||
Reference *refs( ddl_nullptr );
|
||||
DataArrayList *dtArrayList( ddl_nullptr );
|
||||
Value *values( ddl_nullptr );
|
||||
if( 1 == arrayLen ) {
|
||||
in = parseDataList( in, end, &values, &refs );
|
||||
setNodeValues( top(), values );
|
||||
setNodeReferences( top(), refs );
|
||||
} else if( arrayLen > 1 ) {
|
||||
in = parseDataArrayList( in, end, &dtArrayList );
|
||||
setNodeDataArrayList( top(), dtArrayList );
|
||||
} else {
|
||||
std::cerr << "0 for array is invalid." << std::endl;
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
if( *in != '}' ) {
|
||||
logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback );
|
||||
} else {
|
||||
//in++;
|
||||
}
|
||||
} else {
|
||||
in = parseNextNode( in, end );
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
void OpenDDLParser::pushNode( DDLNode *node ) {
|
||||
if( ddl_nullptr == node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_stack.push_back( node );
|
||||
}
|
||||
|
||||
DDLNode *OpenDDLParser::popNode() {
|
||||
if( m_stack.empty() ) {
|
||||
return ddl_nullptr;
|
||||
}
|
||||
|
||||
DDLNode *topNode( top() );
|
||||
m_stack.pop_back();
|
||||
|
||||
return topNode;
|
||||
}
|
||||
|
||||
DDLNode *OpenDDLParser::top() {
|
||||
if( m_stack.empty() ) {
|
||||
return ddl_nullptr;
|
||||
}
|
||||
|
||||
DDLNode *top( m_stack.back() );
|
||||
return top;
|
||||
}
|
||||
|
||||
DDLNode *OpenDDLParser::getRoot() const {
|
||||
if( ddl_nullptr == m_context ) {
|
||||
return ddl_nullptr;
|
||||
}
|
||||
|
||||
return m_context->m_root;
|
||||
}
|
||||
|
||||
Context *OpenDDLParser::getContext() const {
|
||||
return m_context;
|
||||
}
|
||||
|
||||
void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
|
||||
if( buffer.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<char> newBuffer;
|
||||
const size_t len( buffer.size() );
|
||||
char *end( &buffer[ len-1 ] + 1 );
|
||||
for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
|
||||
char *c( &buffer[readIdx] );
|
||||
// check for a comment
|
||||
if( !isComment<char>( c, end ) ) {
|
||||
newBuffer.push_back( buffer[ readIdx ] );
|
||||
} else {
|
||||
readIdx++;
|
||||
// skip the comment and the rest of the line
|
||||
while( !isEndofLine( buffer[ readIdx ] ) ) {
|
||||
readIdx++;
|
||||
}
|
||||
newBuffer.push_back( '\n' );
|
||||
}
|
||||
}
|
||||
buffer = newBuffer;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
|
||||
*name = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
// ignore blanks
|
||||
in = getNextToken( in, end );
|
||||
if( *in != '$' && *in != '%' ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
NameType ntype( GlobalName );
|
||||
if( *in == '%' ) {
|
||||
ntype = LocalName;
|
||||
}
|
||||
|
||||
Name *currentName( ddl_nullptr );
|
||||
Identifier *id( ddl_nullptr );
|
||||
in = parseIdentifier( in, end, &id );
|
||||
if( id ) {
|
||||
currentName = new Name( ntype, id );
|
||||
if( currentName ) {
|
||||
*name = currentName;
|
||||
}
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) {
|
||||
*id = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
// ignore blanks
|
||||
in = getNextToken( in, end );
|
||||
|
||||
// staring with a number is forbidden
|
||||
if( isNumeric<const char>( *in ) ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
// get size of id
|
||||
size_t idLen( 0 );
|
||||
char *start( in );
|
||||
while( !isSeparator( *in ) && ( in != end ) && *in != '(' && *in != ')' ) {
|
||||
in++;
|
||||
idLen++;
|
||||
}
|
||||
|
||||
const size_t len( idLen + 1 );
|
||||
Identifier *newId = new Identifier( len, new char[ len ] );
|
||||
::strncpy( newId->m_buffer, start, newId->m_len-1 );
|
||||
newId->m_buffer[ newId->m_len - 1 ] = '\0';
|
||||
*id = newId;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ) {
|
||||
type = Value::ddl_none;
|
||||
len = 0;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
size_t prim_len( 0 );
|
||||
for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
|
||||
prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] );
|
||||
if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) {
|
||||
type = ( Value::ValueType ) i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( Value::ddl_none == type ) {
|
||||
in = getNextToken( in, end );
|
||||
return in;
|
||||
} else {
|
||||
in += prim_len;
|
||||
}
|
||||
|
||||
bool ok( true );
|
||||
if( *in == '[' ) {
|
||||
ok = false;
|
||||
in++;
|
||||
char *start( in );
|
||||
while ( in != end ) {
|
||||
in++;
|
||||
if( *in == ']' ) {
|
||||
len = atoi( start );
|
||||
ok = true;
|
||||
in++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
len = 1;
|
||||
}
|
||||
if( !ok ) {
|
||||
type = Value::ddl_none;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseReference( char *in, char *end, std::vector<Name*> &names ) {
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
Name *nextName( ddl_nullptr );
|
||||
in = parseName( in, end, &nextName );
|
||||
if( nextName ) {
|
||||
names.push_back( nextName );
|
||||
}
|
||||
while( ',' == *in ) {
|
||||
in = getNextSeparator( in, end );
|
||||
if( ',' == *in ) {
|
||||
in = parseName( in, end, &nextName );
|
||||
if( nextName ) {
|
||||
names.push_back( nextName );
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) {
|
||||
*boolean = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
char *start( in );
|
||||
size_t len( 0 );
|
||||
while( !isSeparator( *in ) && in != end ) {
|
||||
in++;
|
||||
len++;
|
||||
}
|
||||
len++;
|
||||
int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
|
||||
if( 0 != res ) {
|
||||
res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
|
||||
if( 0 != res ) {
|
||||
*boolean = ddl_nullptr;
|
||||
return in;
|
||||
}
|
||||
*boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
|
||||
(*boolean)->setBool( false );
|
||||
} else {
|
||||
*boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
|
||||
(*boolean)->setBool( true );
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) {
|
||||
*integer = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
if( !isIntegerType( integerType ) ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
char *start( in );
|
||||
while( !isSeparator( *in ) && in != end ) {
|
||||
in++;
|
||||
}
|
||||
|
||||
if( isNumeric( *start ) ) {
|
||||
const int value( atoi( start ) );
|
||||
*integer = ValueAllocator::allocPrimData( integerType );
|
||||
switch( integerType ) {
|
||||
case Value::ddl_int8:
|
||||
( *integer )->setInt8( (int8) value );
|
||||
break;
|
||||
case Value::ddl_int16:
|
||||
( *integer )->setInt16( ( int16 ) value );
|
||||
break;
|
||||
case Value::ddl_int32:
|
||||
( *integer )->setInt32( ( int32 ) value );
|
||||
break;
|
||||
case Value::ddl_int64:
|
||||
( *integer )->setInt64( ( int64 ) value );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating ) {
|
||||
*floating = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
char *start( in );
|
||||
while( !isSeparator( *in ) && in != end ) {
|
||||
in++;
|
||||
}
|
||||
|
||||
// parse the float value
|
||||
bool ok( false );
|
||||
if( isNumeric( *start ) ) {
|
||||
ok = true;
|
||||
} else {
|
||||
if( *start == '-' ) {
|
||||
if( isNumeric( *(start+1) ) ) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( ok ) {
|
||||
const float value( ( float ) atof( start ) );
|
||||
*floating = ValueAllocator::allocPrimData( Value::ddl_float );
|
||||
( *floating )->setFloat( value );
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData ) {
|
||||
*stringData = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
size_t len( 0 );
|
||||
char *start( in );
|
||||
if( *start == '\"' ) {
|
||||
start++;
|
||||
in++;
|
||||
while( *in != '\"' && in != end ) {
|
||||
in++;
|
||||
len++;
|
||||
}
|
||||
|
||||
*stringData = ValueAllocator::allocPrimData( Value::ddl_string, len );
|
||||
::strncpy( ( char* ) ( *stringData )->m_data, start, len );
|
||||
( *stringData )->m_data[len] = '\0';
|
||||
in++;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
static void createPropertyWithData( Identifier *id, Value *primData, Property **prop ) {
|
||||
if( ddl_nullptr != primData ) {
|
||||
( *prop ) = new Property( id );
|
||||
( *prop )->m_primData = primData;
|
||||
}
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
|
||||
*data = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
if( *in != '0' ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in++;
|
||||
if( *in != 'x' && *in != 'X' ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in++;
|
||||
bool ok( true );
|
||||
char *start( in );
|
||||
int pos( 0 );
|
||||
while( !isSeparator( *in ) && in != end ) {
|
||||
if( ( *in < '0' && *in > '9' ) || ( *in < 'a' && *in > 'f' ) || ( *in < 'A' && *in > 'F' ) ) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
in++;
|
||||
}
|
||||
|
||||
if( !ok ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
int value( 0 );
|
||||
while( pos > 0 ) {
|
||||
pos--;
|
||||
value += hex2Decimal( *start ) * static_cast<int>( pow( 16.0, pos ) );
|
||||
start++;
|
||||
}
|
||||
|
||||
*data = ValueAllocator::allocPrimData( Value::ddl_int32 );
|
||||
(*data)->setInt32( value );
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
|
||||
*prop = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
Identifier *id( ddl_nullptr );
|
||||
in = parseIdentifier( in, end, &id );
|
||||
if( ddl_nullptr != id ) {
|
||||
in = getNextToken( in, end );
|
||||
if( *in == '=' ) {
|
||||
in++;
|
||||
in = getNextToken( in, end );
|
||||
Value *primData( ddl_nullptr );
|
||||
if( isInteger( in, end ) ) {
|
||||
in = parseIntegerLiteral( in, end, &primData );
|
||||
createPropertyWithData( id, primData, prop );
|
||||
} else if( isFloat( in, end ) ) {
|
||||
in = parseFloatingLiteral( in, end, &primData );
|
||||
createPropertyWithData( id, primData, prop );
|
||||
} else if( isStringLiteral( *in ) ) { // string data
|
||||
in = parseStringLiteral( in, end, &primData );
|
||||
createPropertyWithData( id, primData, prop );
|
||||
} else { // reference data
|
||||
std::vector<Name*> names;
|
||||
in = parseReference( in, end, names );
|
||||
if( !names.empty() ) {
|
||||
Reference *ref = new Reference( names.size(), &names[ 0 ] );
|
||||
( *prop ) = new Property( id );
|
||||
( *prop )->m_ref = ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseDataList( char *in, char *end, Value **data, Reference **refs ) {
|
||||
*data = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
if( *in == '{' ) {
|
||||
in++;
|
||||
Value *current( ddl_nullptr ), *prev( ddl_nullptr );
|
||||
while( '}' != *in ) {
|
||||
current = ddl_nullptr;
|
||||
in = getNextToken( in, end );
|
||||
if( isInteger( in, end ) ) {
|
||||
in = parseIntegerLiteral( in, end, ¤t );
|
||||
} else if( isFloat( in, end ) ) {
|
||||
in = parseFloatingLiteral( in, end, ¤t );
|
||||
} else if( isStringLiteral( *in ) ) {
|
||||
in = parseStringLiteral( in, end, ¤t );
|
||||
} else if( isHexLiteral( in, end ) ) {
|
||||
in = parseHexaLiteral( in, end, ¤t );
|
||||
} else { // reference data
|
||||
std::vector<Name*> names;
|
||||
in = parseReference( in, end, names );
|
||||
if( !names.empty() ) {
|
||||
Reference *ref = new Reference( names.size(), &names[ 0 ] );
|
||||
*refs = ref;
|
||||
}
|
||||
}
|
||||
|
||||
if( ddl_nullptr != current ) {
|
||||
if( ddl_nullptr == *data ) {
|
||||
*data = current;
|
||||
prev = current;
|
||||
} else {
|
||||
prev->setNext( current );
|
||||
prev = current;
|
||||
}
|
||||
}
|
||||
|
||||
in = getNextSeparator( in, end );
|
||||
if( ',' != *in && '}' != *in && !isSpace( *in ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **dataList ) {
|
||||
*dataList = ddl_nullptr;
|
||||
if( ddl_nullptr == in || in == end ) {
|
||||
return in;
|
||||
}
|
||||
|
||||
in = getNextToken( in, end );
|
||||
if( *in == '{' ) {
|
||||
in++;
|
||||
Value *current( ddl_nullptr );
|
||||
Reference *refs( ddl_nullptr );
|
||||
DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
|
||||
do {
|
||||
in = parseDataList( in, end, ¤t, &refs );
|
||||
if( ddl_nullptr != current ) {
|
||||
if( ddl_nullptr == prev ) {
|
||||
*dataList = new DataArrayList;
|
||||
(*dataList)->m_dataList = current;
|
||||
prev = *dataList;
|
||||
} else {
|
||||
currentDataList = new DataArrayList;
|
||||
if( ddl_nullptr != prev ) {
|
||||
prev->m_next = currentDataList;
|
||||
prev = currentDataList;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while( ',' == *in && in != end );
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
const char *OpenDDLParser::getVersion() {
|
||||
return Version;
|
||||
}
|
||||
|
||||
END_ODDLPARSER_NS
|
|
@ -0,0 +1,256 @@
|
|||
/*-----------------------------------------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Kim Kulling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
-----------------------------------------------------------------------------------------------*/
|
||||
#include <openddlparser/Value.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
Value::Value()
|
||||
: m_type( ddl_none )
|
||||
, m_size( 0 )
|
||||
, m_data( ddl_nullptr )
|
||||
, m_next( ddl_nullptr ) {
|
||||
// empty
|
||||
}
|
||||
|
||||
Value::~Value() {
|
||||
// empty
|
||||
}
|
||||
|
||||
void Value::setBool( bool value ) {
|
||||
assert( ddl_bool == m_type );
|
||||
::memcpy( m_data, &value, m_size );
|
||||
}
|
||||
|
||||
bool Value::getBool() {
|
||||
assert( ddl_bool == m_type );
|
||||
return ( bool ) ( *m_data );
|
||||
}
|
||||
|
||||
void Value::setInt8( int8 value ) {
|
||||
assert( ddl_int8 == m_type );
|
||||
::memcpy( m_data, &value, m_size );
|
||||
}
|
||||
|
||||
int8 Value::getInt8() {
|
||||
assert( ddl_int8 == m_type );
|
||||
return ( int8 ) ( *m_data );
|
||||
}
|
||||
|
||||
void Value::setInt16( int16 value ) {
|
||||
assert( ddl_int16 == m_type );
|
||||
::memcpy( m_data, &value, m_size );
|
||||
}
|
||||
|
||||
int16 Value::getInt16() {
|
||||
assert( ddl_int16 == m_type );
|
||||
return ( int16 ) ( *m_data );
|
||||
}
|
||||
|
||||
void Value::setInt32( int32 value ) {
|
||||
assert( ddl_int32 == m_type );
|
||||
::memcpy( m_data, &value, m_size );
|
||||
}
|
||||
|
||||
int32 Value::getInt32() {
|
||||
assert( ddl_int32 == m_type );
|
||||
return ( int32 ) ( *m_data );
|
||||
}
|
||||
|
||||
void Value::setInt64( int64 value ) {
|
||||
assert( ddl_int32 == m_type );
|
||||
::memcpy( m_data, &value, m_size );
|
||||
}
|
||||
|
||||
int64 Value::getInt64() {
|
||||
return ( int64 ) ( *m_data );
|
||||
}
|
||||
|
||||
void Value::setFloat( float value ) {
|
||||
assert( ddl_float == m_type );
|
||||
::memcpy( m_data, &value, m_size );
|
||||
}
|
||||
|
||||
float Value::getFloat() const {
|
||||
float v;
|
||||
::memcpy( &v, m_data, m_size );
|
||||
return v;
|
||||
}
|
||||
|
||||
void Value::setDouble( double value ) {
|
||||
assert( ddl_double == m_type );
|
||||
::memcpy( m_data, &value, m_size );
|
||||
}
|
||||
|
||||
double Value::getDouble() const {
|
||||
double v;
|
||||
::memcpy( &v, m_data, m_size );
|
||||
return v;
|
||||
}
|
||||
|
||||
void Value::setString( const std::string &str ) {
|
||||
assert( ddl_string == m_type );
|
||||
::memcpy( m_data, str.c_str(), str.size() );
|
||||
m_data[ str.size() ] = '\0';
|
||||
}
|
||||
const char *Value::getString() const {
|
||||
return (const char*) m_data;
|
||||
}
|
||||
|
||||
void Value::dump() {
|
||||
switch( m_type ) {
|
||||
case ddl_none:
|
||||
std::cout << "None" << std::endl;
|
||||
break;
|
||||
case ddl_bool:
|
||||
std::cout << getBool() << std::endl;
|
||||
break;
|
||||
case ddl_int8:
|
||||
std::cout << getInt8() << std::endl;
|
||||
break;
|
||||
case ddl_int16:
|
||||
std::cout << getInt16() << std::endl;
|
||||
break;
|
||||
case ddl_int32:
|
||||
std::cout << getInt32() << std::endl;
|
||||
break;
|
||||
case ddl_int64:
|
||||
std::cout << getInt64() << std::endl;
|
||||
break;
|
||||
case ddl_unsigned_int8:
|
||||
std::cout << "Not supported" << std::endl;
|
||||
break;
|
||||
case ddl_unsigned_int16:
|
||||
std::cout << "Not supported" << std::endl;
|
||||
break;
|
||||
case ddl_unsigned_int32:
|
||||
std::cout << "Not supported" << std::endl;
|
||||
break;
|
||||
case ddl_unsigned_int64:
|
||||
std::cout << "Not supported" << std::endl;
|
||||
break;
|
||||
case ddl_half:
|
||||
std::cout << "Not supported" << std::endl;
|
||||
break;
|
||||
case ddl_float:
|
||||
std::cout << getFloat() << std::endl;
|
||||
break;
|
||||
case ddl_double:
|
||||
std::cout << getDouble() << std::endl;
|
||||
break;
|
||||
case ddl_string:
|
||||
std::cout << "Not supported" << std::endl;
|
||||
break;
|
||||
case ddl_ref:
|
||||
std::cout << "Not supported" << std::endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Value::setNext( Value *next ) {
|
||||
m_next = next;
|
||||
}
|
||||
|
||||
Value *Value::getNext() const {
|
||||
return m_next;
|
||||
}
|
||||
|
||||
Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
|
||||
if( type == Value::ddl_none || Value::ddl_types_max == type ) {
|
||||
return ddl_nullptr;
|
||||
}
|
||||
|
||||
Value *data = new Value;
|
||||
data->m_type = type;
|
||||
switch( type ) {
|
||||
case Value::ddl_bool:
|
||||
data->m_size = sizeof( bool );
|
||||
break;
|
||||
case Value::ddl_int8:
|
||||
data->m_size = sizeof( char );
|
||||
break;
|
||||
case Value::ddl_int16:
|
||||
data->m_size = sizeof( short );
|
||||
break;
|
||||
case Value::ddl_int32:
|
||||
data->m_size = sizeof( int );
|
||||
break;
|
||||
case Value::ddl_int64:
|
||||
data->m_size = sizeof( long );
|
||||
break;
|
||||
case Value::ddl_unsigned_int8:
|
||||
data->m_size = sizeof( unsigned char );
|
||||
break;
|
||||
case Value::ddl_unsigned_int32:
|
||||
data->m_size = sizeof( unsigned int );
|
||||
break;
|
||||
case Value::ddl_unsigned_int64:
|
||||
data->m_size = sizeof( unsigned long );
|
||||
break;
|
||||
case Value::ddl_half:
|
||||
data->m_size = sizeof( short );
|
||||
break;
|
||||
case Value::ddl_float:
|
||||
data->m_size = sizeof( float );
|
||||
break;
|
||||
case Value::ddl_double:
|
||||
data->m_size = sizeof( double );
|
||||
break;
|
||||
case Value::ddl_string:
|
||||
data->m_size = sizeof( char );
|
||||
break;
|
||||
case Value::ddl_ref:
|
||||
data->m_size = sizeof( char );
|
||||
break;
|
||||
case Value::ddl_none:
|
||||
case Value::ddl_types_max:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( data->m_size ) {
|
||||
size_t len1( len );
|
||||
if( Value::ddl_string == type ) {
|
||||
len1++;
|
||||
}
|
||||
data->m_size *= len1;
|
||||
data->m_data = new unsigned char[ data->m_size ];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void ValueAllocator::releasePrimData( Value **data ) {
|
||||
if( !data ) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete *data;
|
||||
*data = ddl_nullptr;
|
||||
}
|
||||
|
||||
END_ODDLPARSER_NS
|
|
@ -0,0 +1,90 @@
|
|||
/*-----------------------------------------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Kim Kulling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
-----------------------------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
#ifndef OPENDDLPARSER_DDLNODE_H_INC
|
||||
#define OPENDDLPARSER_DDLNODE_H_INC
|
||||
|
||||
#include <openddlparser/OpenDDLCommon.h>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
class Value;
|
||||
class OpenDDLParser;
|
||||
|
||||
struct Identifier;
|
||||
struct Reference;
|
||||
struct Property;
|
||||
struct DataArrayList;
|
||||
|
||||
class DLL_ODDLPARSER_EXPORT DDLNode {
|
||||
public:
|
||||
friend class OpenDDLParser;
|
||||
|
||||
typedef std::vector<DDLNode*> DllNodeList;
|
||||
|
||||
public:
|
||||
~DDLNode();
|
||||
void attachParent( DDLNode *parent );
|
||||
void detachParent();
|
||||
DDLNode *getParent() const;
|
||||
const DllNodeList &getChildNodeList() const;
|
||||
void setType( const std::string &name );
|
||||
const std::string &getType() const;
|
||||
void setName( const std::string &name );
|
||||
const std::string &getName() const;
|
||||
void setProperties( Property *prop );
|
||||
Property *getProperties() const;
|
||||
void setValue( Value *val );
|
||||
Value *getValue() const;
|
||||
void setDataArrayList( DataArrayList *dtArrayList );
|
||||
DataArrayList *getDataArrayList() const;
|
||||
void setReferences( Reference *refs );
|
||||
Reference *getReferences() const;
|
||||
static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr );
|
||||
|
||||
private:
|
||||
DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = ddl_nullptr );
|
||||
DDLNode();
|
||||
DDLNode( const DDLNode & );
|
||||
DDLNode &operator = ( const DDLNode & );
|
||||
static void releaseNodes();
|
||||
|
||||
private:
|
||||
std::string m_type;
|
||||
std::string m_name;
|
||||
DDLNode *m_parent;
|
||||
std::vector<DDLNode*> m_children;
|
||||
Property *m_properties;
|
||||
Value *m_value;
|
||||
DataArrayList *m_dtArrayList;
|
||||
Reference *m_references;
|
||||
size_t m_idx;
|
||||
static DllNodeList s_allocatedNodes;
|
||||
};
|
||||
|
||||
END_ODDLPARSER_NS
|
||||
|
||||
#endif // OPENDDLPARSER_DDLNODE_H_INC
|
|
@ -0,0 +1,170 @@
|
|||
/*-----------------------------------------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Kim Kulling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
-----------------------------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
#ifndef OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC
|
||||
#define OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define TAG_DLL_EXPORT __declspec(dllexport)
|
||||
# define TAG_DLL_IMPORT __declspec(dllimport )
|
||||
# ifdef OPENDDLPARSER_BUILD
|
||||
# define DLL_ODDLPARSER_EXPORT TAG_DLL_EXPORT
|
||||
# else
|
||||
# define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT
|
||||
# endif // OPENDDLPARSER_BUILD
|
||||
# pragma warning( disable : 4251 )
|
||||
#else
|
||||
# define DLL_ODDLPARSER_EXPORT
|
||||
#endif // _WIN32
|
||||
|
||||
#define BEGIN_ODDLPARSER_NS namespace ODDLParser {
|
||||
#define END_ODDLPARSER_NS }
|
||||
#define USE_ODDLPARSER_NS using namespace ODDLParser;
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
#ifndef OPENDDL_NO_USE_CPP11
|
||||
# define ddl_nullptr nullptr
|
||||
#else
|
||||
# define ddl_nullptr NULL
|
||||
#endif // OPENDDL_NO_USE_CPP11
|
||||
|
||||
class DDLNode;
|
||||
class Value;
|
||||
|
||||
struct Name;
|
||||
struct Identifier;
|
||||
struct Reference;
|
||||
struct Property;
|
||||
struct DataArrayList;
|
||||
|
||||
typedef char int8;
|
||||
typedef short int16;
|
||||
typedef int int32;
|
||||
typedef long int64;
|
||||
|
||||
enum NameType {
|
||||
GlobalName,
|
||||
LocalName
|
||||
};
|
||||
|
||||
struct Name {
|
||||
NameType m_type;
|
||||
Identifier *m_id;
|
||||
|
||||
Name( NameType type, Identifier *id )
|
||||
: m_type( type )
|
||||
, m_id( id ) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
struct Reference {
|
||||
size_t m_numRefs;
|
||||
Name **m_referencedName;
|
||||
|
||||
Reference()
|
||||
: m_numRefs( 0 )
|
||||
, m_referencedName( ddl_nullptr ) {
|
||||
// empty
|
||||
}
|
||||
|
||||
Reference( size_t numrefs, Name **names )
|
||||
: m_numRefs( numrefs )
|
||||
, m_referencedName( ddl_nullptr ) {
|
||||
m_referencedName = new Name *[ numrefs ];
|
||||
for( size_t i = 0; i < numrefs; i++ ) {
|
||||
Name *name = new Name( names[ i ]->m_type, names[ i ]->m_id );
|
||||
m_referencedName[ i ] = name;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Identifier {
|
||||
size_t m_len;
|
||||
char *m_buffer;
|
||||
|
||||
Identifier( size_t len, char buffer[] )
|
||||
: m_len( len )
|
||||
, m_buffer( buffer ) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
struct Property {
|
||||
Identifier *m_id;
|
||||
Value *m_primData;
|
||||
Reference *m_ref;
|
||||
Property *m_next;
|
||||
|
||||
Property( Identifier *id )
|
||||
: m_id( id )
|
||||
, m_primData( ddl_nullptr )
|
||||
, m_ref( ddl_nullptr )
|
||||
, m_next( ddl_nullptr ) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
struct DataArrayList {
|
||||
size_t m_numItems;
|
||||
Value *m_dataList;
|
||||
DataArrayList *m_next;
|
||||
|
||||
DataArrayList()
|
||||
: m_numItems( 0 )
|
||||
, m_dataList( ddl_nullptr )
|
||||
, m_next( ddl_nullptr ) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
struct Context {
|
||||
DDLNode *m_root;
|
||||
|
||||
Context()
|
||||
: m_root( ddl_nullptr ) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
struct BufferIt {
|
||||
std::vector<char> m_buffer;
|
||||
size_t m_idx;
|
||||
|
||||
BufferIt( const std::vector<char> &buffer )
|
||||
: m_buffer( buffer )
|
||||
, m_idx( 0 ) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
END_ODDLPARSER_NS
|
||||
|
||||
#endif // OPENDDLPARSER_OPENDDLPARSERCOMMON_H_INC
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*-----------------------------------------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Kim Kulling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
-----------------------------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
#ifndef OPENDDLPARSER_OPENDDLPARSER_H_INC
|
||||
#define OPENDDLPARSER_OPENDDLPARSER_H_INC
|
||||
|
||||
#include <openddlparser/OpenDDLCommon.h>
|
||||
#include <openddlparser/DDLNode.h>
|
||||
#include <openddlparser/OpenDDLParserUtils.h>
|
||||
#include <openddlparser/Value.h>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
class DDLNode;
|
||||
class Value;
|
||||
|
||||
struct Identifier;
|
||||
struct Reference;
|
||||
struct Property;
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
T *getNextToken( T *in, T *end ) {
|
||||
while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) {
|
||||
in++;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
/// @brief Defines the log severity.
|
||||
enum LogSeverity {
|
||||
ddl_debug_msg = 0, ///< Debug message, for debugging
|
||||
ddl_info_msg, ///< Info messages, normal mode
|
||||
ddl_warn_msg, ///< Parser warnings
|
||||
ddl_error_msg ///< Parser errors
|
||||
};
|
||||
|
||||
class DLL_ODDLPARSER_EXPORT OpenDDLParser {
|
||||
public:
|
||||
typedef void( *logCallback )( LogSeverity severity, const std::string &msg );
|
||||
|
||||
public:
|
||||
OpenDDLParser();
|
||||
OpenDDLParser( char *buffer, size_t len );
|
||||
~OpenDDLParser();
|
||||
void setLogCallback( logCallback callback );
|
||||
logCallback getLogCallback() const;
|
||||
void setBuffer( char *buffer, size_t len );
|
||||
void setBuffer( const std::vector<char> &buffer );
|
||||
const char *getBuffer() const;
|
||||
size_t getBufferSize() const;
|
||||
void clear();
|
||||
bool parse();
|
||||
char *parseNextNode( char *current, char *end );
|
||||
char *parseHeader( char *in, char *end );
|
||||
char *parseStructure( char *in, char *end );
|
||||
char *parseStructureBody( char *in, char *end, bool &error );
|
||||
void pushNode( DDLNode *node );
|
||||
DDLNode *popNode();
|
||||
DDLNode *top();
|
||||
DDLNode *getRoot() const;
|
||||
Context *getContext() const;
|
||||
|
||||
public: // static parser helpers
|
||||
static void normalizeBuffer( std::vector<char> &buffer );
|
||||
static char *parseName( char *in, char *end, Name **name );
|
||||
static char *parseIdentifier( char *in, char *end, Identifier **id );
|
||||
static char *parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len );
|
||||
static char *parseReference( char *in, char *end, std::vector<Name*> &names );
|
||||
static char *parseBooleanLiteral( char *in, char *end, Value **boolean );
|
||||
static char *parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType = Value::ddl_int32 );
|
||||
static char *parseFloatingLiteral( char *in, char *end, Value **floating );
|
||||
static char *parseStringLiteral( char *in, char *end, Value **stringData );
|
||||
static char *parseHexaLiteral( char *in, char *end, Value **data );
|
||||
static char *parseProperty( char *in, char *end, Property **prop );
|
||||
static char *parseDataList( char *in, char *end, Value **data, Reference **refs );
|
||||
static char *parseDataArrayList( char *in, char *end, DataArrayList **dataList );
|
||||
static const char *getVersion();
|
||||
|
||||
private:
|
||||
OpenDDLParser( const OpenDDLParser & );
|
||||
OpenDDLParser &operator = ( const OpenDDLParser & );
|
||||
|
||||
private:
|
||||
logCallback m_logCallback;
|
||||
std::vector<char> m_buffer;
|
||||
|
||||
typedef std::vector<DDLNode*> DDLNodeStack;
|
||||
DDLNodeStack m_stack;
|
||||
Context *m_context;
|
||||
};
|
||||
|
||||
END_ODDLPARSER_NS
|
||||
|
||||
#endif // OPENDDLPARSER_OPENDDLPARSER_H_INC
|
|
@ -0,0 +1,249 @@
|
|||
/*-----------------------------------------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Kim Kulling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
-----------------------------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
#ifndef OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC
|
||||
#define OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC
|
||||
|
||||
#include <openddlparser/OpenDDLCommon.h>
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isComment( T *in, T *end ) {
|
||||
if( *in == '/' ) {
|
||||
if( in + 1 != end ) {
|
||||
if( *( in + 1 ) == '/' ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isUpperCase( T in ) {
|
||||
return ( in >= 'A' && in <= 'Z' );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isLowerCase( T in ) {
|
||||
return ( in >= 'a' && in <= 'z' );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isSpace( const T in ) {
|
||||
return ( ' ' == in || '\t' == in );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isNewLine( const T in ) {
|
||||
return ( '\n' == in || ( '\r' == in ) );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isSeparator( T in ) {
|
||||
if( isSpace( in ) || ',' == in || '{' == in || '}' == in || '[' == in ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static const unsigned char chartype_table[ 256 ] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 48-63
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64-79
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-95
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 112-127
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // > 127
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isNumeric( const T in ) {
|
||||
return ( in >= '0' && in <= '9' );
|
||||
//return ( chartype_table[in] );
|
||||
/*if (in >= '0' && in <= '9' )
|
||||
return true;
|
||||
|
||||
return false;*/
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isInteger( T *in, T *end ) {
|
||||
if( in != end ) {
|
||||
if( *in == '-' ) {
|
||||
in++;
|
||||
}
|
||||
}
|
||||
|
||||
bool result( false );
|
||||
while( '}' != *in && ',' != *in && !isSpace( *in ) && in != end ) {
|
||||
result = isNumeric( *in );
|
||||
if( !result ) {
|
||||
break;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isFloat( T *in, T *end ) {
|
||||
if( in != end ) {
|
||||
if( *in == '-' ) {
|
||||
in++;
|
||||
}
|
||||
}
|
||||
|
||||
// check for <1>.0f
|
||||
bool result( false );
|
||||
while( !isSpace( *in ) && in != end ) {
|
||||
if( *in == '.' ) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
result = isNumeric( *in );
|
||||
if( !result ) {
|
||||
return false;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
// check for 1<.>0f
|
||||
if( *in == '.' ) {
|
||||
in++;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for 1.<0>f
|
||||
while( !isSpace( *in ) && in != end && *in != ',' ) {
|
||||
result = isNumeric( *in );
|
||||
if( !result ) {
|
||||
return false;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isCharacter( const T in ) {
|
||||
return ( ( in >= 'a' && in <= 'z' ) || ( in >= 'A' && in <= 'Z' ) );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isStringLiteral( const T in ) {
|
||||
return ( in == '\"' );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isHexLiteral( T *in, T *end ) {
|
||||
if( *in == '0' ) {
|
||||
if( in + 1 != end ) {
|
||||
if( *( in + 1 ) == 'x' || *( in + 1 ) == 'X' ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isReference( T *in, T *end ) {
|
||||
if( *in == 'r' ) {
|
||||
if( *(in+1) == 'e' ) {
|
||||
if( *(in+2) == 'f' ) {
|
||||
if( ( in + 2 ) != end ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool isEndofLine( const T in ) {
|
||||
return ( '\n' == in );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
static T *getNextSeparator( T *in, T *end ) {
|
||||
while( !isSeparator( *in ) || in == end ) {
|
||||
in++;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
static const int ErrorHex2Decimal = 9999;
|
||||
|
||||
inline
|
||||
int hex2Decimal( char in ) {
|
||||
if( isNumeric( in ) ) {
|
||||
return (int) in-48;
|
||||
}
|
||||
char hexCodeLower( 'a' ), hexCodeUpper( 'A' );
|
||||
for( int i = 0; i<16; i++ ) {
|
||||
if( in == hexCodeLower + i || in == hexCodeUpper + i ) {
|
||||
return i+10;
|
||||
}
|
||||
}
|
||||
|
||||
return ErrorHex2Decimal;
|
||||
}
|
||||
|
||||
END_ODDLPARSER_NS
|
||||
|
||||
#endif // OPENDDLPARSER_OPENDDLPARSERUTILS_H_INC
|
|
@ -0,0 +1,97 @@
|
|||
/*-----------------------------------------------------------------------------------------------
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Kim Kulling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
-----------------------------------------------------------------------------------------------*/
|
||||
#pragma once
|
||||
#ifndef OPENDDLPARSER_VALUE_H_INC
|
||||
#define OPENDDLPARSER_VALUE_H_INC
|
||||
|
||||
#include <openddlparser/OpenDDLCommon.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
BEGIN_ODDLPARSER_NS
|
||||
|
||||
///------------------------------------------------------------------------------------------------
|
||||
/// @brief This class implements a value.
|
||||
///
|
||||
/// Values are used to store data types like boolean, integer, floats, double and many mode. To get
|
||||
/// an overview please check the enum VylueType ( @see Value::ValueType ).
|
||||
/// Values can be single items or lists of items. They are implemented as linked lists.
|
||||
///------------------------------------------------------------------------------------------------
|
||||
class DLL_ODDLPARSER_EXPORT Value {
|
||||
public:
|
||||
/// @brief This enum describes the data type stored in the value.
|
||||
enum ValueType {
|
||||
ddl_none = -1, ///< Nothing specified
|
||||
ddl_bool = 0, ///< A boolean type
|
||||
ddl_int8, ///< Integer type, 8 bytes
|
||||
ddl_int16, ///< Integer type, 16 bytes
|
||||
ddl_int32, ///< Integer type, 32 bytes
|
||||
ddl_int64, ///< Integer type, 64 bytes
|
||||
ddl_unsigned_int8, ///< Unsigned integer type, 8 bytes
|
||||
ddl_unsigned_int16, ///< Unsigned integer type, 16 bytes
|
||||
ddl_unsigned_int32, ///< Unsigned integer type, 32 bytes
|
||||
ddl_unsigned_int64, ///< Unsigned integer type, 64 bytes
|
||||
ddl_half,
|
||||
ddl_float,
|
||||
ddl_double,
|
||||
ddl_string,
|
||||
ddl_ref,
|
||||
ddl_types_max
|
||||
};
|
||||
|
||||
Value();
|
||||
~Value();
|
||||
void setBool( bool value );
|
||||
bool getBool();
|
||||
void setInt8( int8 value );
|
||||
int8 getInt8();
|
||||
void setInt16( int16 value );
|
||||
int16 getInt16();
|
||||
void setInt32( int32 value );
|
||||
int32 getInt32();
|
||||
void setInt64( int64 value );
|
||||
int64 getInt64();
|
||||
void setFloat( float value );
|
||||
float getFloat() const;
|
||||
void setDouble( double value );
|
||||
double getDouble() const;
|
||||
void setString( const std::string &str );
|
||||
const char *getString() const;
|
||||
void dump();
|
||||
void setNext( Value *next );
|
||||
Value *getNext() const;
|
||||
|
||||
ValueType m_type;
|
||||
size_t m_size;
|
||||
unsigned char *m_data;
|
||||
Value *m_next;
|
||||
};
|
||||
|
||||
struct DLL_ODDLPARSER_EXPORT ValueAllocator {
|
||||
static Value *allocPrimData( Value::ValueType type, size_t len = 1 );
|
||||
static void releasePrimData( Value **data );
|
||||
};
|
||||
|
||||
END_ODDLPARSER_NS
|
||||
|
||||
#endif // OPENDDLPARSER_VALUE_H_INC
|
|
@ -0,0 +1,95 @@
|
|||
Metric (key = "distance") {float {1}}
|
||||
Metric (key = "angle") {float {1}}
|
||||
Metric (key = "time") {float {1}}
|
||||
Metric (key = "up") {string {"z"}}
|
||||
|
||||
GeometryNode $node1
|
||||
{
|
||||
Name {string {"Box001"}}
|
||||
ObjectRef {ref {$geometry1}}
|
||||
MaterialRef {ref {$material1}}
|
||||
|
||||
Transform
|
||||
{
|
||||
float[16]
|
||||
{
|
||||
{0x3F800000, 0x00000000, 0x00000000, 0x00000000, // {1, 0, 0, 0
|
||||
0x00000000, 0x3F800000, 0x00000000, 0x00000000, // 0, 1, 0, 0
|
||||
0x00000000, 0x00000000, 0x3F800000, 0x00000000, // 0, 0, 1, 0
|
||||
0xBEF33B00, 0x411804DE, 0x00000000, 0x3F800000} // -0.47506, 9.50119, 0, 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GeometryNode $node2
|
||||
{
|
||||
Name {string {"Box002"}}
|
||||
ObjectRef {ref {$geometry1}}
|
||||
MaterialRef {ref {$material1}}
|
||||
|
||||
Transform
|
||||
{
|
||||
float[16]
|
||||
{
|
||||
{0x3F800000, 0x00000000, 0x00000000, 0x00000000, // {1, 0, 0, 0
|
||||
0x00000000, 0x3F800000, 0x00000000, 0x00000000, // 0, 1, 0, 0
|
||||
0x00000000, 0x00000000, 0x3F800000, 0x00000000, // 0, 0, 1, 0
|
||||
0x43041438, 0x411804DE, 0x00000000, 0x3F800000} // 132.079, 9.50119, 0, 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GeometryObject $geometry1 // Box001, Box002
|
||||
{
|
||||
Mesh (primitive = "triangles")
|
||||
{
|
||||
VertexArray (attrib = "position")
|
||||
{
|
||||
float[3] // 24
|
||||
{
|
||||
{0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928},
|
||||
{0xC2501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x00000000}, {0x42501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0xC24C468A, 0x42BA3928},
|
||||
{0x42501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0x424C468A, 0x42BA3928}, {0x42501375, 0x424C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x00000000}, {0xC2501375, 0xC24C468A, 0x42BA3928}, {0xC2501375, 0x424C468A, 0x42BA3928}
|
||||
}
|
||||
}
|
||||
|
||||
VertexArray (attrib = "normal")
|
||||
{
|
||||
float[3] // 24
|
||||
{
|
||||
{0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0xBF800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000}, {0x00000000, 0x00000000, 0x3F800000},
|
||||
{0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x00000000, 0xBF800000, 0x00000000}, {0x80000000, 0xBF800000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000}, {0x3F800000, 0x00000000, 0x00000000},
|
||||
{0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x00000000, 0x3F800000, 0x00000000}, {0x80000000, 0x3F800000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}, {0xBF800000, 0x00000000, 0x00000000}
|
||||
}
|
||||
}
|
||||
|
||||
VertexArray (attrib = "texcoord")
|
||||
{
|
||||
float[2] // 24
|
||||
{
|
||||
{0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000},
|
||||
{0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000},
|
||||
{0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}, {0x00000000, 0x00000000}, {0x3F800000, 0x00000000}, {0x3F800000, 0x3F800000}, {0x00000000, 0x3F800000}
|
||||
}
|
||||
}
|
||||
|
||||
IndexArray
|
||||
{
|
||||
unsigned_int32[3] // 12
|
||||
{
|
||||
{0, 1, 2}, {2, 3, 0}, {4, 5, 6}, {6, 7, 4}, {8, 9, 10}, {10, 11, 8}, {12, 13, 14}, {14, 15, 12}, {16, 17, 18}, {18, 19, 16}, {20, 21, 22}, {22, 23, 20}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Material $material1
|
||||
{
|
||||
Name {string {"03 - Default"}}
|
||||
|
||||
Color (attrib = "diffuse") {float[3] {{0.588235, 0.588235, 0.588235}}}
|
||||
Texture (attrib = "diffuse")
|
||||
{
|
||||
string {"texture/Concrete.tga"}
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ IF( WIN32 )
|
|||
MAIN_DEPENDENCY assimp)
|
||||
ENDIF( WIN32 )
|
||||
|
||||
TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES} )
|
||||
SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES
|
||||
OUTPUT_NAME assimp
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue