- Bugfix: XFileParser handles vertex colors correctly now. Fixes exception in sheep.x import
- Added support for separate normal map filename tag in XFile material list - shortened texture type determination in XFile loader while I was there - Bugfix: ValidateDataStructure wrongly flagged animations with zero duration as error git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@76 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
63596e22c5
commit
b17a5e3b69
|
@ -428,7 +428,9 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else this->ReportError("aiAnimation::mNumBones is 0. At least one bone animation channel must be there.");
|
else this->ReportError("aiAnimation::mNumBones is 0. At least one bone animation channel must be there.");
|
||||||
if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
|
|
||||||
|
// Animation duration is allowed to be zero in cases where the anim contains only a single key frame.
|
||||||
|
// if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial,
|
void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial,
|
||||||
|
|
|
@ -62,6 +62,18 @@ struct Face
|
||||||
std::vector<unsigned int> mIndices;
|
std::vector<unsigned int> mIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Helper structure representing a texture filename inside a material and its potential source */
|
||||||
|
struct TexEntry
|
||||||
|
{
|
||||||
|
std::string mName;
|
||||||
|
bool mIsNormalMap; // true if the texname was specified in a NormalmapFilename tag
|
||||||
|
|
||||||
|
TexEntry() { mIsNormalMap = false; }
|
||||||
|
TexEntry( const std::string& pName, bool pIsNormalMap = false)
|
||||||
|
: mName( pName), mIsNormalMap( pIsNormalMap)
|
||||||
|
{ /* done */ }
|
||||||
|
};
|
||||||
|
|
||||||
/** Helper structure representing a XFile material */
|
/** Helper structure representing a XFile material */
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
|
@ -71,7 +83,7 @@ struct Material
|
||||||
float mSpecularExponent;
|
float mSpecularExponent;
|
||||||
aiColor3D mSpecular;
|
aiColor3D mSpecular;
|
||||||
aiColor3D mEmissive;
|
aiColor3D mEmissive;
|
||||||
std::vector<std::string> mTextures;
|
std::vector<TexEntry> mTextures;
|
||||||
|
|
||||||
Material() { mIsReference = false; }
|
Material() { mIsReference = false; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -580,12 +580,15 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
||||||
// texture, if there is one
|
// texture, if there is one
|
||||||
if (1 == oldMat.mTextures.size())
|
if (1 == oldMat.mTextures.size())
|
||||||
{
|
{
|
||||||
if (oldMat.mTextures[0].length())
|
const XFile::TexEntry& otex = oldMat.mTextures.back();
|
||||||
|
if (otex.mName.length())
|
||||||
{
|
{
|
||||||
// if there is only one texture assume it contains the diffuse color
|
// if there is only one texture assume it contains the diffuse color
|
||||||
aiString tex;
|
aiString tex( otex.mName);
|
||||||
tex.Set( oldMat.mTextures[0]);
|
if( otex.mIsNormalMap)
|
||||||
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(0));
|
||||||
|
else
|
||||||
|
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -595,7 +598,8 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
||||||
unsigned int iHM = 0,iNM = 0,iDM = 0,iSM = 0,iAM = 0,iEM = 0;
|
unsigned int iHM = 0,iNM = 0,iDM = 0,iSM = 0,iAM = 0,iEM = 0;
|
||||||
for( unsigned int b = 0; b < oldMat.mTextures.size(); b++)
|
for( unsigned int b = 0; b < oldMat.mTextures.size(); b++)
|
||||||
{
|
{
|
||||||
std::string sz = oldMat.mTextures[b];
|
const XFile::TexEntry& otex = oldMat.mTextures[b];
|
||||||
|
std::string sz = otex.mName;
|
||||||
if (!sz.length())continue;
|
if (!sz.length())continue;
|
||||||
|
|
||||||
char key[256];
|
char key[256];
|
||||||
|
@ -616,151 +620,67 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
||||||
sz[sExt] = '\0';
|
sz[sExt] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert to lower case for easier comparision
|
||||||
|
for( unsigned int c = 0; c < sz.length(); c++)
|
||||||
|
if( isalpha( sz[c]))
|
||||||
|
sz[c] = tolower( sz[c]);
|
||||||
|
|
||||||
// bump map
|
// bump map
|
||||||
std::string::size_type s2 = sz.find("bump",s);
|
if (std::string::npos != sz.find("bump", s) || std::string::npos != sz.find("height", s))
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("BUMP",s)))
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("Bump",s)))
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("height",s)))
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("HEIGHT",s)))
|
|
||||||
{
|
|
||||||
s2 = sz.find("Height",s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std::string::npos != s2)
|
|
||||||
{
|
{
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
::sprintf_s(key,AI_MATKEY_TEXTURE_HEIGHT_ "[%i]",iHM++);
|
::sprintf_s(key,AI_MATKEY_TEXTURE_HEIGHT_ "[%i]",iHM++);
|
||||||
#else
|
#else
|
||||||
::sprintf(key,AI_MATKEY_TEXTURE_HEIGHT_ "[%i]",iHM++);
|
::sprintf(key,AI_MATKEY_TEXTURE_HEIGHT_ "[%i]",iHM++);
|
||||||
#endif
|
#endif
|
||||||
}
|
} else
|
||||||
else
|
if (otex.mIsNormalMap || std::string::npos != sz.find( "normal", s) || std::string::npos != sz.find("nm", s))
|
||||||
{
|
{
|
||||||
// Normal map
|
|
||||||
std::string::size_type s2 = sz.find("normal",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("NORMAL",s)))
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("nm",s)))
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("Normal",s)))
|
|
||||||
{
|
|
||||||
s2 = sz.find("NM",s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std::string::npos != s2)
|
|
||||||
{
|
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
::sprintf_s(key,AI_MATKEY_TEXTURE_NORMALS_ "[%i]",iNM++);
|
::sprintf_s(key,AI_MATKEY_TEXTURE_NORMALS_ "[%i]",iNM++);
|
||||||
#else
|
#else
|
||||||
::sprintf(key,AI_MATKEY_TEXTURE_NORMALS_ "[%i]",iNM++);
|
::sprintf(key,AI_MATKEY_TEXTURE_NORMALS_ "[%i]",iNM++);
|
||||||
#endif
|
#endif
|
||||||
}
|
} else
|
||||||
else
|
if (std::string::npos != sz.find( "spec", s) || std::string::npos != sz.find( "glanz", s))
|
||||||
{
|
{
|
||||||
|
|
||||||
// specular color texture (not unique, too. Could
|
|
||||||
// also be the material's shininess)
|
|
||||||
std::string::size_type s2 = sz.find("spec",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("Spec",s)))
|
|
||||||
{
|
|
||||||
if (std::string::npos == (sz.find("SPEC",s)))
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("Glanz",s)))
|
|
||||||
{
|
|
||||||
s2 = sz.find("glanz",s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std::string::npos != s2)
|
|
||||||
{
|
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
::sprintf_s(key,AI_MATKEY_TEXTURE_SPECULAR_ "[%i]",iSM++);
|
::sprintf_s(key,AI_MATKEY_TEXTURE_SPECULAR_ "[%i]",iSM++);
|
||||||
#else
|
#else
|
||||||
::sprintf(key,AI_MATKEY_TEXTURE_SPECULAR_ "[%i]",iSM++);
|
::sprintf(key,AI_MATKEY_TEXTURE_SPECULAR_ "[%i]",iSM++);
|
||||||
#endif
|
#endif
|
||||||
}
|
} else
|
||||||
else
|
if (std::string::npos != sz.find( "ambi", s) || std::string::npos != sz.find( "env", s))
|
||||||
{
|
{
|
||||||
// ambient color texture
|
|
||||||
std::string::size_type s2 = sz.find("ambi",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("AMBI",s)))
|
|
||||||
{
|
|
||||||
if (std::string::npos == (s2 = sz.find("env",s)))
|
|
||||||
{
|
|
||||||
s2 = sz.find("Ambi",s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std::string::npos != s2)
|
|
||||||
{
|
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
::sprintf_s(key,AI_MATKEY_TEXTURE_AMBIENT_ "[%i]",iAM++);
|
::sprintf_s(key,AI_MATKEY_TEXTURE_AMBIENT_ "[%i]",iAM++);
|
||||||
#else
|
#else
|
||||||
::sprintf(key,AI_MATKEY_TEXTURE_AMBIENT_ "[%i]",iAM++);
|
::sprintf(key,AI_MATKEY_TEXTURE_AMBIENT_ "[%i]",iAM++);
|
||||||
#endif
|
#endif
|
||||||
}
|
} else
|
||||||
else
|
if (std::string::npos != sz.find( "emissive", s) || std::string::npos != sz.find( "self", s))
|
||||||
{
|
{
|
||||||
// emissive color texture
|
|
||||||
std::string::size_type s2 = sz.find("emissive",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
s2 = sz.find("EMISSIVE",s);
|
|
||||||
if (std::string::npos == s2)
|
|
||||||
{
|
|
||||||
// self illumination
|
|
||||||
if (std::string::npos == (s2 = sz.find("self",s)))
|
|
||||||
{
|
|
||||||
s2 = sz.find("Emissive",s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std::string::npos != s2)
|
|
||||||
{
|
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
::sprintf_s(key,AI_MATKEY_TEXTURE_EMISSIVE_ "[%i]",iEM++);
|
::sprintf_s(key,AI_MATKEY_TEXTURE_EMISSIVE_ "[%i]",iEM++);
|
||||||
#else
|
#else
|
||||||
::sprintf(key,AI_MATKEY_TEXTURE_EMISSIVE_ "[%i]",iEM++);
|
::sprintf(key,AI_MATKEY_TEXTURE_EMISSIVE_ "[%i]",iEM++);
|
||||||
#endif
|
#endif
|
||||||
}
|
} else
|
||||||
else
|
{
|
||||||
{
|
// assume it is a diffuse texture
|
||||||
// assume it is a diffuse texture
|
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
::sprintf_s(key,AI_MATKEY_TEXTURE_DIFFUSE_ "[%i]",iDM++);
|
::sprintf_s(key,AI_MATKEY_TEXTURE_DIFFUSE_ "[%i]",iDM++);
|
||||||
#else
|
#else
|
||||||
::sprintf(key,AI_MATKEY_TEXTURE_DIFFUSE_ "[%i]",iDM++);
|
::sprintf(key,AI_MATKEY_TEXTURE_DIFFUSE_ "[%i]",iDM++);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aiString tex;
|
// place texture filename property under the corresponding name
|
||||||
tex.Set( oldMat.mTextures[b] );
|
aiString tex( oldMat.mTextures[b].mName);
|
||||||
|
|
||||||
mat->AddProperty( &tex, key);
|
mat->AddProperty( &tex, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pScene->mMaterials[pScene->mNumMaterials] = mat;
|
pScene->mMaterials[pScene->mNumMaterials] = mat;
|
||||||
mImportedMats[oldMat.mName] = pScene->mNumMaterials;
|
mImportedMats[oldMat.mName] = pScene->mNumMaterials;
|
||||||
pScene->mNumMaterials++;
|
pScene->mNumMaterials++;
|
||||||
|
|
|
@ -466,9 +466,9 @@ void XFileParser::ParseDataObjectMeshVertexColors( Mesh* pMesh)
|
||||||
ThrowException( "Vertex color index out of bounds");
|
ThrowException( "Vertex color index out of bounds");
|
||||||
|
|
||||||
colors[index] = ReadRGBA();
|
colors[index] = ReadRGBA();
|
||||||
|
CheckForSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckForSemicolon();
|
|
||||||
CheckForClosingBrace();
|
CheckForClosingBrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,7 +569,14 @@ void XFileParser::ParseDataObjectMaterial( Material* pMaterial)
|
||||||
// some exporters write "TextureFileName" instead.
|
// some exporters write "TextureFileName" instead.
|
||||||
std::string texname;
|
std::string texname;
|
||||||
ParseDataObjectTextureFilename( texname);
|
ParseDataObjectTextureFilename( texname);
|
||||||
pMaterial->mTextures.push_back( texname);
|
pMaterial->mTextures.push_back( TexEntry( texname));
|
||||||
|
} else
|
||||||
|
if( objectName == "NormalmapFilename" || objectName == "NormalmapFileName")
|
||||||
|
{
|
||||||
|
// one exporter writes out the normal map in a separate filename tag
|
||||||
|
std::string texname;
|
||||||
|
ParseDataObjectTextureFilename( texname);
|
||||||
|
pMaterial->mTextures.push_back( TexEntry( texname, true));
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->warn("Unknown data object in material in x file");
|
DefaultLogger::get()->warn("Unknown data object in material in x file");
|
||||||
|
@ -755,6 +762,10 @@ void XFileParser::ParseDataObjectTextureFilename( std::string& pName)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->warn("Length of texture file name is zero. Skipping this texture.");
|
DefaultLogger::get()->warn("Length of texture file name is zero. Skipping this texture.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// some exporters write double backslash paths out. We simply replace them if we find them
|
||||||
|
while( pName.find( "\\\\") != std::string::npos)
|
||||||
|
pName.replace( pName.find( "\\\\"), 2, "\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -140,7 +140,7 @@ struct aiString
|
||||||
data[0] = '\0';
|
data[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
//! construction from a given std::string
|
//! Copy constructor
|
||||||
inline aiString(const aiString& rOther) :
|
inline aiString(const aiString& rOther) :
|
||||||
length(rOther.length)
|
length(rOther.length)
|
||||||
{
|
{
|
||||||
|
@ -148,6 +148,14 @@ struct aiString
|
||||||
this->data[this->length] = '\0';
|
this->data[this->length] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Constructor from std::string
|
||||||
|
inline aiString(const std::string& pString) :
|
||||||
|
length(pString.length())
|
||||||
|
{
|
||||||
|
memcpy( data, pString.c_str(), length);
|
||||||
|
data[length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
//! copy a std::string to the aiString
|
//! copy a std::string to the aiString
|
||||||
void Set( const std::string& pString)
|
void Set( const std::string& pString)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue