- rewrote the XFileLoader material management to handle meshes with dummy material names correctly.
parent
0f781516bf
commit
18f01268e6
|
@ -85,7 +85,9 @@ struct Material
|
||||||
aiColor3D mEmissive;
|
aiColor3D mEmissive;
|
||||||
std::vector<TexEntry> mTextures;
|
std::vector<TexEntry> mTextures;
|
||||||
|
|
||||||
Material() { mIsReference = false; }
|
size_t sceneIndex; ///< the index under which it was stored in the scene's material list
|
||||||
|
|
||||||
|
Material() { mIsReference = false; sceneIndex = SIZE_MAX; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Helper structure to represent a bone weight */
|
/** Helper structure to represent a bone weight */
|
||||||
|
|
|
@ -110,10 +110,6 @@ void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||||
if( fileSize < 16)
|
if( fileSize < 16)
|
||||||
throw DeadlyImportError( "XFile is too small.");
|
throw DeadlyImportError( "XFile is too small.");
|
||||||
|
|
||||||
// need to clear members - this method might be called multiple
|
|
||||||
// times on a single XFileImporter instance.
|
|
||||||
mImportedMats.clear();
|
|
||||||
|
|
||||||
// in the hope that binary files will never start with a BOM ...
|
// in the hope that binary files will never start with a BOM ...
|
||||||
mBuffer.resize( fileSize + 1);
|
mBuffer.resize( fileSize + 1);
|
||||||
file->Read( &mBuffer.front(), 1, fileSize);
|
file->Read( &mBuffer.front(), 1, fileSize);
|
||||||
|
@ -132,7 +128,7 @@ void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructs the return data structure out of the imported data.
|
// Constructs the return data structure out of the imported data.
|
||||||
void XFileImporter::CreateDataRepresentationFromImport( aiScene* pScene, const XFile::Scene* pData)
|
void XFileImporter::CreateDataRepresentationFromImport( aiScene* pScene, XFile::Scene* pData)
|
||||||
{
|
{
|
||||||
// Read the global materials first so that meshes referring to them can find them later
|
// Read the global materials first so that meshes referring to them can find them later
|
||||||
ConvertMaterials( pScene, pData->mGlobalMaterials);
|
ConvertMaterials( pScene, pData->mGlobalMaterials);
|
||||||
|
@ -233,8 +229,8 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
|
||||||
std::vector<aiMesh*> meshes;
|
std::vector<aiMesh*> meshes;
|
||||||
for( unsigned int a = 0; a < pMeshes.size(); a++)
|
for( unsigned int a = 0; a < pMeshes.size(); a++)
|
||||||
{
|
{
|
||||||
const XFile::Mesh* sourceMesh = pMeshes[a];
|
XFile::Mesh* sourceMesh = pMeshes[a];
|
||||||
// first convert its materials so that we can find them when searching by name afterwards
|
// first convert its materials so that we can find them with their index afterwards
|
||||||
ConvertMaterials( pScene, sourceMesh->mMaterials);
|
ConvertMaterials( pScene, sourceMesh->mMaterials);
|
||||||
|
|
||||||
unsigned int numMaterials = std::max( (unsigned int)sourceMesh->mMaterials.size(), 1u);
|
unsigned int numMaterials = std::max( (unsigned int)sourceMesh->mMaterials.size(), 1u);
|
||||||
|
@ -272,15 +268,11 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
|
||||||
aiMesh* mesh = new aiMesh;
|
aiMesh* mesh = new aiMesh;
|
||||||
meshes.push_back( mesh);
|
meshes.push_back( mesh);
|
||||||
|
|
||||||
// find the material by name in the scene's material list. Either own material
|
// find the material in the scene's material list. Either own material
|
||||||
// or referenced material, it should already be found there
|
// or referenced material, it should already have a valid index
|
||||||
if( sourceMesh->mFaceMaterials.size() > 0)
|
if( sourceMesh->mFaceMaterials.size() > 0)
|
||||||
{
|
{
|
||||||
std::map<std::string, unsigned int>::const_iterator matIt = mImportedMats.find( sourceMesh->mMaterials[b].mName);
|
mesh->mMaterialIndex = sourceMesh->mMaterials[b].sceneIndex;
|
||||||
if( matIt == mImportedMats.end())
|
|
||||||
mesh->mMaterialIndex = 0;
|
|
||||||
else
|
|
||||||
mesh->mMaterialIndex = matIt->second;
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
mesh->mMaterialIndex = 0;
|
mesh->mMaterialIndex = 0;
|
||||||
|
@ -554,32 +546,52 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Converts all materials in the given array and stores them in the scene's material list.
|
// Converts all materials in the given array and stores them in the scene's material list.
|
||||||
void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::Material>& pMaterials)
|
void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials)
|
||||||
{
|
{
|
||||||
// count the non-referrer materials in the array
|
// count the non-referrer materials in the array
|
||||||
unsigned int numMaterials = 0;
|
unsigned int numNewMaterials = 0;
|
||||||
for( unsigned int a = 0; a < pMaterials.size(); a++)
|
for( unsigned int a = 0; a < pMaterials.size(); a++)
|
||||||
if( !pMaterials[a].mIsReference)
|
if( !pMaterials[a].mIsReference)
|
||||||
numMaterials++;
|
numNewMaterials++;
|
||||||
|
|
||||||
if( numMaterials == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// resize the scene's material list to offer enough space for the new materials
|
// resize the scene's material list to offer enough space for the new materials
|
||||||
aiMaterial** prevMats = pScene->mMaterials;
|
if( numNewMaterials > 0 )
|
||||||
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials + numMaterials];
|
{
|
||||||
if( prevMats)
|
aiMaterial** prevMats = pScene->mMaterials;
|
||||||
{
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials + numNewMaterials];
|
||||||
memcpy( pScene->mMaterials, prevMats, pScene->mNumMaterials * sizeof( aiMaterial*));
|
if( prevMats)
|
||||||
delete [] prevMats;
|
{
|
||||||
}
|
memcpy( pScene->mMaterials, prevMats, pScene->mNumMaterials * sizeof( aiMaterial*));
|
||||||
|
delete [] prevMats;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// convert all the materials given in the array
|
// convert all the materials given in the array
|
||||||
for( unsigned int a = 0; a < pMaterials.size(); a++)
|
for( unsigned int a = 0; a < pMaterials.size(); a++)
|
||||||
{
|
{
|
||||||
const XFile::Material& oldMat = pMaterials[a];
|
XFile::Material& oldMat = pMaterials[a];
|
||||||
if( oldMat.mIsReference)
|
if( oldMat.mIsReference)
|
||||||
continue;
|
{
|
||||||
|
// find the material it refers to by name, and store its index
|
||||||
|
for( size_t a = 0; a < pScene->mNumMaterials; ++a )
|
||||||
|
{
|
||||||
|
aiString name;
|
||||||
|
pScene->mMaterials[a]->Get( AI_MATKEY_NAME, name);
|
||||||
|
if( strcmp( name.C_Str(), oldMat.mName.data()) == 0 )
|
||||||
|
{
|
||||||
|
oldMat.sceneIndex = a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( oldMat.sceneIndex == SIZE_MAX )
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->warn( boost::str( boost::format( "Could not resolve global material reference \"%s\"") % oldMat.mName));
|
||||||
|
oldMat.sceneIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
aiMaterial* mat = new aiMaterial;
|
aiMaterial* mat = new aiMaterial;
|
||||||
aiString name;
|
aiString name;
|
||||||
|
@ -678,7 +690,7 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
||||||
}
|
}
|
||||||
|
|
||||||
pScene->mMaterials[pScene->mNumMaterials] = mat;
|
pScene->mMaterials[pScene->mNumMaterials] = mat;
|
||||||
mImportedMats[oldMat.mName] = pScene->mNumMaterials;
|
oldMat.sceneIndex = pScene->mNumMaterials;
|
||||||
pScene->mNumMaterials++;
|
pScene->mNumMaterials++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,8 +99,7 @@ protected:
|
||||||
* @param pData The imported data in the internal temporary
|
* @param pData The imported data in the internal temporary
|
||||||
* representation.
|
* representation.
|
||||||
*/
|
*/
|
||||||
void CreateDataRepresentationFromImport( aiScene* pScene,
|
void CreateDataRepresentationFromImport( aiScene* pScene, XFile::Scene* pData);
|
||||||
const XFile::Scene* pData);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Recursively creates scene nodes from the imported hierarchy.
|
/** Recursively creates scene nodes from the imported hierarchy.
|
||||||
|
@ -139,15 +138,11 @@ protected:
|
||||||
* @param pScene The scene to hold the converted materials.
|
* @param pScene The scene to hold the converted materials.
|
||||||
* @param pMaterials The material array to convert.
|
* @param pMaterials The material array to convert.
|
||||||
*/
|
*/
|
||||||
void ConvertMaterials( aiScene* pScene,
|
void ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials);
|
||||||
const std::vector<XFile::Material>& pMaterials);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Buffer to hold the loaded file */
|
/** Buffer to hold the loaded file */
|
||||||
std::vector<char> mBuffer;
|
std::vector<char> mBuffer;
|
||||||
|
|
||||||
/** Imported materials: index in the scene's material list by name */
|
|
||||||
std::map<std::string, unsigned int> mImportedMats;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
~XFileParser();
|
~XFileParser();
|
||||||
|
|
||||||
/** Returns the temporary representation of the imported data */
|
/** Returns the temporary representation of the imported data */
|
||||||
const XFile::Scene* GetImportedData() const { return mScene; }
|
XFile::Scene* GetImportedData() const { return mScene; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ParseFile();
|
void ParseFile();
|
||||||
|
|
Loading…
Reference in New Issue