From a052251bcff0fbd690edd119371468990cf41465 Mon Sep 17 00:00:00 2001 From: kimmi Date: Fri, 16 May 2008 17:57:48 +0000 Subject: [PATCH] FEATURE: First prototype for ObjFile material-importer, the assimp data structure will not be created yet. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@17 67173fc5-114c-0410-ac8e-9d2fd5bffc1f --- code/ObjFileData.h | 2 +- code/ObjFileImporter.cpp | 10 +-- code/ObjFileMtlImporter.cpp | 152 ++++++++++++++++++++++++++++++++++-- code/ObjFileMtlImporter.h | 41 ++++++++-- code/ObjFileParser.cpp | 57 ++++++-------- code/ObjTools.h | 61 ++++++++++++++- include/ObjFileParser.h | 1 - workspaces/vc8/assimp.sln | 28 +++---- 8 files changed, 281 insertions(+), 71 deletions(-) diff --git a/code/ObjFileData.h b/code/ObjFileData.h index c97428559..91e3ad02e 100644 --- a/code/ObjFileData.h +++ b/code/ObjFileData.h @@ -38,7 +38,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ - #ifndef OBJ_FILEDATA_H_INC #define OBJ_FILEDATA_H_INC @@ -174,6 +173,7 @@ struct Model std::vector m_Normals; //! Groupmap GroupMap m_Groups; + //! Group to face id assignment std::vector *m_pGroupFaceIDs; //! Active group std::string m_strActiveGroup; diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 2c1c6d99f..e7bc4ee18 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -1,13 +1,14 @@ #include "ObjFileImporter.h" #include "ObjFileParser.h" #include "ObjFileData.h" -#include "../include/IOStream.h" -#include "../include/IOSystem.h" -#include "../include/aiMesh.h" -#include "../include/aiScene.h" +#include "IOStream.h" +#include "IOSystem.h" +#include "aiMesh.h" +#include "aiScene.h" #include "aiAssert.h" #include "MaterialSystem.h" #include "DefaultLogger.h" + #include #include @@ -47,7 +48,6 @@ bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) c if (pFile.empty()) return false; - DefaultLogger::get()->info("ObjFileImporter::CanRead"); string::size_type pos = pFile.find_last_of("."); if (string::npos == pos) return false; diff --git a/code/ObjFileMtlImporter.cpp b/code/ObjFileMtlImporter.cpp index a335cf33f..ddee09f90 100644 --- a/code/ObjFileMtlImporter.cpp +++ b/code/ObjFileMtlImporter.cpp @@ -1,12 +1,31 @@ #include "ObjFileMtlImporter.h" +#include "aiTypes.h" +#include "ObjTools.h" +#include "ObjFileData.h" +#include "aiAssert.h" +#include "fast_atof.h" + namespace Assimp { // ------------------------------------------------------------------- -ObjFileMtlImporter::ObjFileMtlImporter() +ObjFileMtlImporter::ObjFileMtlImporter( std::vector &buffer, + const std::string &strAbsPath, + ObjFile::Model *pModel ) : + m_DataIt( buffer.begin() ), + m_DataItEnd( buffer.end() ), + m_uiLine( 0 ), + m_pModel( NULL ) { - // TODO: Inplement this + ai_assert ( NULL != m_pModel ); + if ( NULL == m_pModel->m_pDefaultMaterial ) + { + m_pModel->m_pDefaultMaterial = new ObjFile::Material(); + + //m_pModel->m_pDefaultMaterial-> + } + load(); } // ------------------------------------------------------------------- @@ -22,33 +41,154 @@ ObjFileMtlImporter::ObjFileMtlImporter(const ObjFileMtlImporter &rOther) } // ------------------------------------------------------------------- -ObjFileMtlImporter &ObjFileMtlImporter::operator = (const ObjFileMtlImporter &rOther) +ObjFileMtlImporter &ObjFileMtlImporter::operator = ( + const ObjFileMtlImporter &rOther) { return *this; } + // ------------------------------------------------------------------- -void ObjFileMtlImporter::getColorRGBA() +void ObjFileMtlImporter::load() { + if ( m_DataIt == m_DataItEnd ) + return; + + while ( m_DataIt != m_DataItEnd ) + { + switch (*m_DataIt) + { + case 'K': + { + ++m_DataIt; + if (*m_DataIt == 'a') // Ambient color + { + getColorRGBA( &m_pModel->m_pCurrentMaterial->ambient ); + } + else if (*m_DataIt == 'd') // Diffuse color + { + getColorRGBA( &m_pModel->m_pCurrentMaterial->diffuse ); + } + else if (*m_DataIt == 's') + { + getColorRGBA( &m_pModel->m_pCurrentMaterial->specular ); + } + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + break; + + case 'd': // Alpha value + { + getFloatValue( m_pModel->m_pCurrentMaterial->alpha ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + break; + + case 'N': // Shineness + { + getIlluminationModel( m_pModel->m_pCurrentMaterial->illumination_model ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + break; + + case 'm': // Texture + { + getTexture(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + break; + + case 'n': // New material name + { + createMaterial(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + break; + + case 'i': // Illumination model + { + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + break; + + default: + { + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + break; + } + } } // ------------------------------------------------------------------- -void ObjFileMtlImporter::getIlluminationModel() +void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor ) { + ai_assert( NULL != pColor ); + + float r, g, b; + m_DataIt = CopyNextWord( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE ); + r = (float) fast_atof(m_buffer); + + m_DataIt = CopyNextWord( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE ); + g = (float) fast_atof(m_buffer); + + m_DataIt = CopyNextWord( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE ); + b = (float) fast_atof(m_buffer); + + pColor->r = r; + pColor->g = g; + pColor->b = b; } // ------------------------------------------------------------------- -void ObjFileMtlImporter::getFloatValue() +void ObjFileMtlImporter::getIlluminationModel( int &illum_model ) { + m_DataIt = CopyNextWord( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE ); + illum_model = atoi(m_buffer); +} + +// ------------------------------------------------------------------- +void ObjFileMtlImporter::getFloatValue( float &value ) +{ + m_DataIt = CopyNextWord( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE ); + value = (float) fast_atof(m_buffer); } // ------------------------------------------------------------------- void ObjFileMtlImporter::createMaterial() { + m_pModel->m_pCurrentMaterial = new ObjFile::Material(); + + /*m_DataIt = getNextToken( m_DataIt, m_DataItEnd ); + if (m_DataIt == m_DataItEnd) + return; + + char *pStart = &(*m_DataIt); + while ( !isSpace(*m_DataIt) && m_DataIt != m_DataItEnd ) + ++m_DataIt; + + // Get name + std::string strName(pStart, &(*m_DataIt)); + if ( strName.empty() ) + return;*/ + std::string strName; + m_DataIt = getName( m_DataIt, m_DataItEnd, strName ); + if ( m_DataItEnd == m_DataIt ) + return; + + m_pModel->m_pCurrentMaterial->MaterialName.Set( strName ); + m_pModel->m_MaterialLib.push_back( strName ); + m_pModel->m_MaterialMap[ strName ] = m_pModel->m_pCurrentMaterial; } // ------------------------------------------------------------------- void ObjFileMtlImporter::getTexture() { + std::string strTexture; + m_DataIt = getName( m_DataIt, m_DataItEnd, strTexture ); + if ( m_DataItEnd == m_DataIt ) + return; + + m_pModel->m_pCurrentMaterial->texture.Set( strTexture ); } // ------------------------------------------------------------------- diff --git a/code/ObjFileMtlImporter.h b/code/ObjFileMtlImporter.h index e831b994f..ea0357a7c 100644 --- a/code/ObjFileMtlImporter.h +++ b/code/ObjFileMtlImporter.h @@ -35,25 +35,41 @@ 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 OBJFILEMTLIMPORTER_H_INC #define OBJFILEMTLIMPORTER_H_INC +#include + +struct aiColor3D; + namespace Assimp { +namespace ObjFile +{ +struct Model; +struct Material; + +} + + /** * @class ObjFileMtlImporter * @brief Loads the material description from a mtl file. */ class ObjFileMtlImporter { +public: + static const size_t BUFFERSIZE = 1024; + typedef std::vector DataArray; + typedef std::vector::iterator DataArrayIt; + typedef std::vector::const_iterator ConstDataArrayIt; + public: //! \brief Default constructor - ObjFileMtlImporter(); + ObjFileMtlImporter( std::vector &buffer, const std::string &strAbsPath, + ObjFile::Model *pModel ); //! \brief DEstructor ~ObjFileMtlImporter(); @@ -65,11 +81,20 @@ private: //! \brief Assignment operator, returns only a reference of this instance. ObjFileMtlImporter &operator = (const ObjFileMtlImporter &rOther); - void getColorRGBA(); - void getIlluminationModel(); - void getFloatValue(); + void load(); + void getColorRGBA( aiColor3D *pColor); + void getIlluminationModel( int &illum_model ); + void getFloatValue( float &value ); void createMaterial(); void getTexture(); + +private: + std::string m_strAbsPath; + DataArrayIt m_DataIt; + DataArrayIt m_DataItEnd; + ObjFile::Model *m_pModel; + unsigned int m_uiLine; + char m_buffer[BUFFERSIZE]; }; } // Namespace Assimp diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index b533846b9..8820e9997 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -118,7 +118,7 @@ void ObjFileParser::parseFile() default: { - skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } break; } @@ -174,12 +174,13 @@ void ObjFileParser::getVector3(std::vector &point3d_array) z = (float) fast_atof(m_buffer); point3d_array.push_back(new aiVector3D(x,y,z)); - skipLine(); + //skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get values for a new 2D vector instance -void ObjFileParser::getVector2(std::vector &point2d_array) +void ObjFileParser::getVector2( std::vector &point2d_array ) { float x, y; copyNextWord(m_buffer, BUFFERSIZE); @@ -189,20 +190,8 @@ void ObjFileParser::getVector2(std::vector &point2d_array) y = (float) fast_atof(m_buffer); point2d_array.push_back(new aiVector2D(x, y)); - skipLine(); -} -// ------------------------------------------------------------------- -// Skips a line -void ObjFileParser::skipLine() -{ - while (m_DataIt != m_DataItEnd && *m_DataIt != '\n') - ++m_DataIt; - if (m_DataIt != m_DataItEnd) - { - ++m_DataIt; - ++m_uiLine; - } + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- @@ -212,6 +201,7 @@ void ObjFileParser::getFace() copyNextLine(m_buffer, BUFFERSIZE); if (m_DataIt == m_DataItEnd) return; + char *pPtr = m_buffer; char *pEnd = &pPtr[BUFFERSIZE]; pPtr = getNextToken(pPtr, pEnd); @@ -296,7 +286,7 @@ void ObjFileParser::getFace() m_pModel->m_pCurrent->m_Faces.push_back(face); // Skip the rest of the line - skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- @@ -319,14 +309,14 @@ void ObjFileParser::getMaterialDesc() // Search for material std::string strFile; - std::map::iterator it = m_pModel->m_MaterialMap.find(strName); + std::map::iterator it = m_pModel->m_MaterialMap.find( strName ); if (it == m_pModel->m_MaterialMap.end()) { m_pModel->m_pCurrentMaterial = new ObjFile::Material(); - m_pModel->m_MaterialMap[strName] = m_pModel->m_pCurrentMaterial; + m_pModel->m_MaterialMap[ strName ] = m_pModel->m_pCurrentMaterial; } - skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- @@ -366,7 +356,7 @@ void ObjFileParser::getMaterialLib() std::string absName = m_strAbsPath + IOSystem.getOsSeparator() + strMatName; if (!IOSystem.Exists(absName)) { - skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); return; } @@ -379,20 +369,20 @@ void ObjFileParser::getMaterialLib() if (0L != pFile) { size_t size = pFile->FileSize(); - char *pBuffer = new char[size]; - size_t read_size = pFile->Read(pBuffer, sizeof(char), size); - FileSystem.Close(pFile); + std::vector buffer; + buffer.resize( size ); + + size_t read_size = pFile->Read( &buffer[ 0 ], sizeof(char), size ); + FileSystem.Close( pFile ); // TODO: Load mtl file - delete [] pBuffer; - } // Load material library (all materials will be created) m_pModel->m_MaterialLib.push_back(strMatName); - skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- @@ -421,7 +411,7 @@ void ObjFileParser::getNewMaterial() m_pModel->m_pCurrentMaterial = (*it).second; } - skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- @@ -458,16 +448,16 @@ void ObjFileParser::getGroupName() } m_pModel->m_strActiveGroup = strGroupName; } - skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Not supported void ObjFileParser::getGroupNumber() { - // TODO: Implement this + // Not used - skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- @@ -509,7 +499,7 @@ void ObjFileParser::getObjectName() m_pModel->m_Objects.push_back(m_pModel->m_pCurrent);*/ } } - skipLine(); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Creates a new object instance @@ -528,7 +518,8 @@ void ObjFileParser::createObject(const std::string &strObjectName) void ObjFileParser::reportErrorTokenInFace() { std::string strErr(""); - skipLine(); + + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); std::cerr << "Not supported token in face desc. detected : " << strErr << std::endl; } diff --git a/code/ObjTools.h b/code/ObjTools.h index d12886a95..1f3a72c01 100644 --- a/code/ObjTools.h +++ b/code/ObjTools.h @@ -78,7 +78,7 @@ inline Char_T getNextWord(Char_T pBuffer, Char_T pEnd) * @param pBuffer Pointer to data buffer * @param pEnd Pointer to end of buffer * @return Pointer to next token -*/ + */ template inline Char_T getNextToken(Char_T pBuffer, Char_T pEnd) { @@ -91,6 +91,65 @@ inline Char_T getNextToken(Char_T pBuffer, Char_T pEnd) return getNextWord(pBuffer, pEnd); } +/** @brief Skips a line + * @param Iterator set to current position + * @param Iterator set to end of scratch buffer for readout + * @param Current linenumber in format + * @return Current-iterator with new position + */ +template +inline char_t skipLine(char_t it, char_t end, unsigned int &uiLine) +{ + while ( it != end && *it != '\n' ) + ++it; + if ( it != end ) + { + ++it; + ++uiLine; + } + return it; +} + +template +inline char_t getName( char_t it, char_t end, std::string &name ) +{ + name = ""; + it = getNextToken( it, end ); + if ( it == end ) + return end; + + char *pStart = &(*it); + while ( !isSpace(*it) && it != end ) + ++it; + + // Get name + std::string strName(pStart, &(*it)); + if ( strName.empty() ) + return it; + else + name = strName; + + return it; +} + +template +inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length ) +{ + size_t index = 0; + it = getNextWord( it, end ); + while (!isSpace( *it ) && it != end ) + { + pBuffer[index] = *it ; + index++; + if (index == length-1) + break; + ++it; + } + pBuffer[index] = '\0'; + return it; +} + + } // Namespace Assimp #endif diff --git a/include/ObjFileParser.h b/include/ObjFileParser.h index 8c9850cbe..2184ee47a 100644 --- a/include/ObjFileParser.h +++ b/include/ObjFileParser.h @@ -81,7 +81,6 @@ private: void copyNextLine(char *pBuffer, size_t length); void getVector3(std::vector &point3d_array); void getVector2(std::vector &point2d_array); - void skipLine(); void getFace(); void getMaterialDesc(); void getComment(); diff --git a/workspaces/vc8/assimp.sln b/workspaces/vc8/assimp.sln index 162cedb1e..6c00864fc 100644 --- a/workspaces/vc8/assimp.sln +++ b/workspaces/vc8/assimp.sln @@ -1,20 +1,16 @@  Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assimp", "assimp.vcproj", "{5691E159-2D9B-407F-971F-EA5C592DC524}" +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assimp_view", "assimp_view.vcproj", "{B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}" + ProjectSection(ProjectDependencies) = postProject + {5691E159-2D9B-407F-971F-EA5C592DC524} = {5691E159-2D9B-407F-971F-EA5C592DC524} + EndProjectSection ProjectSection(WebsiteProperties) = preProject Debug.AspNetCompiler.Debug = "True" Release.AspNetCompiler.Debug = "False" EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assimp_view", "assimp_view.vcproj", "{B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}" - ProjectSection(WebsiteProperties) = preProject - Debug.AspNetCompiler.Debug = "True" - Release.AspNetCompiler.Debug = "False" - EndProjectSection - ProjectSection(ProjectDependencies) = postProject - {5691E159-2D9B-407F-971F-EA5C592DC524} = {5691E159-2D9B-407F-971F-EA5C592DC524} - EndProjectSection +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "assimp", "assimp.vcproj", "{5691E159-2D9B-407F-971F-EA5C592DC524}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -24,6 +20,12 @@ Global Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Debug_DLL|Win32.ActiveCfg = Debug|Win32 + {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Debug|Win32.ActiveCfg = Debug|Win32 + {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Debug|Win32.Build.0 = Debug|Win32 + {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Release_DLL|Win32.ActiveCfg = Release|Win32 + {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Release|Win32.ActiveCfg = Release|Win32 + {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Release|Win32.Build.0 = Release|Win32 {5691E159-2D9B-407F-971F-EA5C592DC524}.Debug_DLL|Win32.ActiveCfg = Debug_DLL|Win32 {5691E159-2D9B-407F-971F-EA5C592DC524}.Debug_DLL|Win32.Build.0 = Debug_DLL|Win32 {5691E159-2D9B-407F-971F-EA5C592DC524}.Debug|Win32.ActiveCfg = Debug|Win32 @@ -32,12 +34,6 @@ Global {5691E159-2D9B-407F-971F-EA5C592DC524}.Release_DLL|Win32.Build.0 = Release_DLL|Win32 {5691E159-2D9B-407F-971F-EA5C592DC524}.Release|Win32.ActiveCfg = Release|Win32 {5691E159-2D9B-407F-971F-EA5C592DC524}.Release|Win32.Build.0 = Release|Win32 - {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Debug_DLL|Win32.ActiveCfg = Debug|Win32 - {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Debug|Win32.ActiveCfg = Debug|Win32 - {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Debug|Win32.Build.0 = Debug|Win32 - {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Release_DLL|Win32.ActiveCfg = Release|Win32 - {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Release|Win32.ActiveCfg = Release|Win32 - {B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE