From 7d4ee98350f05ec428ec5be4384da18572f33ab9 Mon Sep 17 00:00:00 2001 From: Albert Wang Date: Mon, 12 Nov 2012 12:33:51 -0600 Subject: [PATCH 1/3] Adjusting the Collada Color Parser The collada parser parses the RGB descriptor out of the xml file, but does not use this information when constructing the actual mColors array. If you export a collada file with RGB colors, and then import it, it used to create color values in the form RGBR, taking the R component from the next color tuple instead of filling in sensible defaults for the alpha channel. This patch uses the information to fill each color. --- code/ColladaParser.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index 195d0d7ca..d8d9e5f10 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -2231,7 +2231,12 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(), pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1)); - pMesh->mColors[pInput.mIndex].push_back( aiColor4D( obj[0], obj[1], obj[2], obj[3])); + aiColor4D result(0, 0, 0, 1); + for (size_t i = 0; i < pInput.mResolved->mSize; ++i) + { + result[i] = obj[pInput.mResolved->mSubOffset[i]]; + } + pMesh->mColors[pInput.mIndex].push_back(result); } else { DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping."); From 0ea6ec4e848c0eefce01fb30dbdb73aaf1b52a04 Mon Sep 17 00:00:00 2001 From: Albert Wang Date: Mon, 12 Nov 2012 12:39:11 -0600 Subject: [PATCH 2/3] Fixing some whitespace issues in ColladaParser --- code/ColladaParser.cpp | 82 +++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index d8d9e5f10..bfe6a2b1e 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -2156,7 +2156,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si // get a pointer to the start of the data object referred to by the accessor and the local index const float* dataObject = &(acc.mData->mValues[0]) + acc.mOffset + pLocalIndex* acc.mStride; - + // assemble according to the accessors component sub-offset list. We don't care, yet, // what kind of object exactly we're extracting here float obj[4]; @@ -2173,79 +2173,79 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si DefaultLogger::get()->error("Collada: just one vertex position stream supported"); break; case IT_Normal: - // pad to current vertex count if necessary - if( pMesh->mNormals.size() < pMesh->mPositions.size()-1) - pMesh->mNormals.insert( pMesh->mNormals.end(), pMesh->mPositions.size() - pMesh->mNormals.size() - 1, aiVector3D( 0, 1, 0)); + // pad to current vertex count if necessary + if( pMesh->mNormals.size() < pMesh->mPositions.size()-1) + pMesh->mNormals.insert( pMesh->mNormals.end(), pMesh->mPositions.size() - pMesh->mNormals.size() - 1, aiVector3D( 0, 1, 0)); - // ignore all normal streams except 0 - there can be only one normal - if( pInput.mIndex == 0) + // ignore all normal streams except 0 - there can be only one normal + if( pInput.mIndex == 0) pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2])); else DefaultLogger::get()->error("Collada: just one vertex normal stream supported"); break; case IT_Tangent: - // pad to current vertex count if necessary - if( pMesh->mTangents.size() < pMesh->mPositions.size()-1) - pMesh->mTangents.insert( pMesh->mTangents.end(), pMesh->mPositions.size() - pMesh->mTangents.size() - 1, aiVector3D( 1, 0, 0)); + // pad to current vertex count if necessary + if( pMesh->mTangents.size() < pMesh->mPositions.size()-1) + pMesh->mTangents.insert( pMesh->mTangents.end(), pMesh->mPositions.size() - pMesh->mTangents.size() - 1, aiVector3D( 1, 0, 0)); - // ignore all tangent streams except 0 - there can be only one tangent - if( pInput.mIndex == 0) + // ignore all tangent streams except 0 - there can be only one tangent + if( pInput.mIndex == 0) pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); else DefaultLogger::get()->error("Collada: just one vertex tangent stream supported"); break; case IT_Bitangent: - // pad to current vertex count if necessary - if( pMesh->mBitangents.size() < pMesh->mPositions.size()-1) - pMesh->mBitangents.insert( pMesh->mBitangents.end(), pMesh->mPositions.size() - pMesh->mBitangents.size() - 1, aiVector3D( 0, 0, 1)); + // pad to current vertex count if necessary + if( pMesh->mBitangents.size() < pMesh->mPositions.size()-1) + pMesh->mBitangents.insert( pMesh->mBitangents.end(), pMesh->mPositions.size() - pMesh->mBitangents.size() - 1, aiVector3D( 0, 0, 1)); - // ignore all bitangent streams except 0 - there can be only one bitangent - if( pInput.mIndex == 0) + // ignore all bitangent streams except 0 - there can be only one bitangent + if( pInput.mIndex == 0) pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2])); else DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported"); break; case IT_Texcoord: - // up to 4 texture coord sets are fine, ignore the others + // up to 4 texture coord sets are fine, ignore the others if( pInput.mIndex < AI_MAX_NUMBER_OF_TEXTURECOORDS) - { - // pad to current vertex count if necessary - if( pMesh->mTexCoords[pInput.mIndex].size() < pMesh->mPositions.size()-1) - pMesh->mTexCoords[pInput.mIndex].insert( pMesh->mTexCoords[pInput.mIndex].end(), - pMesh->mPositions.size() - pMesh->mTexCoords[pInput.mIndex].size() - 1, aiVector3D( 0, 0, 0)); + { + // pad to current vertex count if necessary + if( pMesh->mTexCoords[pInput.mIndex].size() < pMesh->mPositions.size()-1) + pMesh->mTexCoords[pInput.mIndex].insert( pMesh->mTexCoords[pInput.mIndex].end(), + pMesh->mPositions.size() - pMesh->mTexCoords[pInput.mIndex].size() - 1, aiVector3D( 0, 0, 0)); pMesh->mTexCoords[pInput.mIndex].push_back( aiVector3D( obj[0], obj[1], obj[2])); if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */ pMesh->mNumUVComponents[pInput.mIndex]=3; } else - { + { DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping."); - } + } break; case IT_Color: - // up to 4 color sets are fine, ignore the others + // up to 4 color sets are fine, ignore the others if( pInput.mIndex < AI_MAX_NUMBER_OF_COLOR_SETS) - { - // pad to current vertex count if necessary - if( pMesh->mColors[pInput.mIndex].size() < pMesh->mPositions.size()-1) - pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(), - pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1)); + { + // pad to current vertex count if necessary + if( pMesh->mColors[pInput.mIndex].size() < pMesh->mPositions.size()-1) + pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(), + pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1)); - aiColor4D result(0, 0, 0, 1); - for (size_t i = 0; i < pInput.mResolved->mSize; ++i) - { - result[i] = obj[pInput.mResolved->mSubOffset[i]]; - } + aiColor4D result(0, 0, 0, 1); + for (size_t i = 0; i < pInput.mResolved->mSize; ++i) + { + result[i] = obj[pInput.mResolved->mSubOffset[i]]; + } pMesh->mColors[pInput.mIndex].push_back(result); - } else - { + } else + { DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping."); - } + } break; - default: - // IT_Invalid and IT_Vertex - ai_assert(false && "shouldn't ever get here"); + default: + // IT_Invalid and IT_Vertex + ai_assert(false && "shouldn't ever get here"); } } From fbe408dd2e6b46daeab63d8f00a07b7948cbdb91 Mon Sep 17 00:00:00 2001 From: Kim Date: Sat, 26 Jan 2013 14:11:57 +0100 Subject: [PATCH 3/3] update : implement obj-support for normal maps. refactoring : some improvements for more readable code. Signed-off-by: Kim --- code/ObjFileData.h | 1 + code/ObjFileImporter.cpp | 3 ++ code/ObjFileMtlImporter.cpp | 68 ++++++++++++++++++++----------------- 3 files changed, 41 insertions(+), 31 deletions(-) diff --git a/code/ObjFileData.h b/code/ObjFileData.h index 59c39d48c..905f69346 100644 --- a/code/ObjFileData.h +++ b/code/ObjFileData.h @@ -157,6 +157,7 @@ struct Material aiString textureSpecular; aiString textureAmbient; aiString textureBump; + aiString textureNormal; aiString textureSpecularity; aiString textureOpacity; aiString textureDisp; diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 84b8df5b2..bb12785e1 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -556,6 +556,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc if ( 0 != pCurrentMaterial->textureBump.length ) mat->AddProperty( &pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0)); + if ( 0 != pCurrentMaterial->textureNormal.length ) + mat->AddProperty( &pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0)); + if ( 0 != pCurrentMaterial->textureDisp.length ) mat->AddProperty( &pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0) ); diff --git a/code/ObjFileMtlImporter.cpp b/code/ObjFileMtlImporter.cpp index 2c63592a0..c6816577d 100644 --- a/code/ObjFileMtlImporter.cpp +++ b/code/ObjFileMtlImporter.cpp @@ -49,6 +49,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { +// Material specific token +static const std::string DiffuseTexture = "map_kd"; +static const std::string AmbientTexture = "map_ka"; +static const std::string SpecularTexture = "map_ks"; +static const std::string OpacityTexture = "map_d"; +static const std::string BumpTexture1 = "map_bump"; +static const std::string BumpTexture2 = "map_Bump"; +static const std::string BumpTexture3 = "bump"; +static const std::string NormalTexture = "map_Kn"; +static const std::string DisplacementTexture = "disp"; +static const std::string SpecularityTexture = "map_ns"; + // ------------------------------------------------------------------- // Constructor ObjFileMtlImporter::ObjFileMtlImporter( std::vector &buffer, @@ -249,46 +261,40 @@ void ObjFileMtlImporter::createMaterial() // ------------------------------------------------------------------- // Gets a texture name from data. -void ObjFileMtlImporter::getTexture() -{ - aiString *out = NULL; +void ObjFileMtlImporter::getTexture() { + aiString *out( NULL ); - // FIXME: just a quick'n'dirty hack, consider cleanup later - - // Diffuse texture - if (!ASSIMP_strincmp(&(*m_DataIt),"map_kd",6)) + const char *pPtr( &(*m_DataIt) ); + if ( !ASSIMP_strincmp( pPtr, DiffuseTexture.c_str(), DiffuseTexture.size() ) ) { + // Diffuse texture out = & m_pModel->m_pCurrentMaterial->texture; - - // Ambient texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ka",6)) + } else if ( !ASSIMP_strincmp( pPtr,AmbientTexture.c_str(),AmbientTexture.size() ) ) { + // Ambient texture out = & m_pModel->m_pCurrentMaterial->textureAmbient; - - // Specular texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ks",6)) + } else if (!ASSIMP_strincmp( pPtr, SpecularTexture.c_str(), SpecularTexture.size())) { + // Specular texture out = & m_pModel->m_pCurrentMaterial->textureSpecular; - - // Opacity texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_d",5)) + } else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), OpacityTexture.size() ) ) { + // Opacity texture out = & m_pModel->m_pCurrentMaterial->textureOpacity; - - // Ambient texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ka",6)) + } else if (!ASSIMP_strincmp( pPtr,"map_ka",6)) { + // Ambient texture out = & m_pModel->m_pCurrentMaterial->textureAmbient; - - // Bump texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_bump",8) || !ASSIMP_strincmp(&(*m_DataIt),"bump",4)) + } else if ( !ASSIMP_strincmp( pPtr, BumpTexture1.c_str(), BumpTexture1.size() ) || + !ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), BumpTexture2.size() ) || + !ASSIMP_strincmp( pPtr, BumpTexture3.c_str(), BumpTexture3.size() ) ) { + // Bump texture out = & m_pModel->m_pCurrentMaterial->textureBump; - - // Displacement texture - else if (!ASSIMP_strincmp(&(*m_DataIt),"disp",4)) + } else if (!ASSIMP_strincmp( pPtr,NormalTexture.c_str(), NormalTexture.size())) { + // Normal map + out = & m_pModel->m_pCurrentMaterial->textureNormal; + } else if (!ASSIMP_strincmp( pPtr, DisplacementTexture.c_str(), DisplacementTexture.size() ) ) { + // Displacement texture out = &m_pModel->m_pCurrentMaterial->textureDisp; - - // Specularity scaling (glossiness) - else if (!ASSIMP_strincmp(&(*m_DataIt),"map_ns",6)) + } else if (!ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(),SpecularityTexture.size() ) ) { + // Specularity scaling (glossiness) out = & m_pModel->m_pCurrentMaterial->textureSpecularity; - - else - { + } else { DefaultLogger::get()->error("OBJ/MTL: Encountered unknown texture type"); return; }