- added materials to Collada Export
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1165 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/5/head
parent
fa6039e1cb
commit
82f027b01f
|
@ -94,6 +94,7 @@ void ColladaExporter::WriteFile()
|
|||
|
||||
WriteHeader();
|
||||
|
||||
WriteMaterials();
|
||||
WriteGeometryLibrary();
|
||||
|
||||
WriteSceneLibrary();
|
||||
|
@ -127,6 +128,155 @@ void ColladaExporter::WriteHeader()
|
|||
mOutput << startstr << "</asset>" << endstr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a single surface entry from the given material keys
|
||||
void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex)
|
||||
{
|
||||
if( pSrcMat->GetTextureCount( pTexture) > 0 )
|
||||
{
|
||||
aiString texfile;
|
||||
unsigned int uvChannel = 0;
|
||||
pSrcMat->GetTexture( pTexture, 0, &texfile, nullptr, &uvChannel);
|
||||
poSurface.texture = texfile.C_Str();
|
||||
poSurface.channel = uvChannel;
|
||||
} else
|
||||
{
|
||||
if( pKey )
|
||||
pSrcMat->Get( pKey, pType, pIndex, poSurface.color);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes an image entry for the given surface
|
||||
void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd)
|
||||
{
|
||||
if( !pSurface.texture.empty() )
|
||||
{
|
||||
mOutput << startstr << "<image id=\"" << pNameAdd << "\" name=\"" << pNameAdd << "\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<init_from>" << pSurface.texture << "</init_from>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</image>" << endstr;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes a color-or-texture entry into an effect definition
|
||||
void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName)
|
||||
{
|
||||
mOutput << startstr << "<" << pTypeName << ">" << endstr;
|
||||
PushTag();
|
||||
if( pSurface.texture.empty() )
|
||||
{
|
||||
mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr;
|
||||
} else
|
||||
{
|
||||
mOutput << startstr << "<texture texture=\"" << pImageName << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
|
||||
}
|
||||
PopTag();
|
||||
mOutput << startstr << "</" << pTypeName << ">" << endstr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes the material setup
|
||||
void ColladaExporter::WriteMaterials()
|
||||
{
|
||||
materials.resize( mScene->mNumMaterials);
|
||||
|
||||
/// collect all materials from the scene
|
||||
for( size_t a = 0; a < mScene->mNumMaterials; ++a )
|
||||
{
|
||||
const aiMaterial* mat = mScene->mMaterials[a];
|
||||
|
||||
aiString name;
|
||||
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
|
||||
name = "mat";
|
||||
materials[a].name = boost::lexical_cast<std::string> (a) + name.C_Str();
|
||||
|
||||
ReadMaterialSurface( materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
|
||||
ReadMaterialSurface( materials[a].diffuse, mat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE);
|
||||
ReadMaterialSurface( materials[a].specular, mat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR);
|
||||
ReadMaterialSurface( materials[a].emissive, mat, aiTextureType_EMISSIVE, AI_MATKEY_COLOR_EMISSIVE);
|
||||
ReadMaterialSurface( materials[a].reflective, mat, aiTextureType_REFLECTION, AI_MATKEY_COLOR_REFLECTIVE);
|
||||
ReadMaterialSurface( materials[a].normal, mat, aiTextureType_NORMALS, nullptr, 0, 0);
|
||||
|
||||
mat->Get( AI_MATKEY_SHININESS, materials[a].shininess);
|
||||
}
|
||||
|
||||
// output textures if present
|
||||
mOutput << startstr << "<library_images>" << endstr;
|
||||
PushTag();
|
||||
for( auto it = materials.cbegin(); it != materials.cend(); ++it )
|
||||
{
|
||||
const Material& mat = *it;
|
||||
WriteImageEntry( mat.ambient, mat.name + "_ambient_image");
|
||||
WriteImageEntry( mat.diffuse, mat.name + "_diffuse_image");
|
||||
WriteImageEntry( mat.specular, mat.name + "_specular_image");
|
||||
WriteImageEntry( mat.emissive, mat.name + "_emissive_image");
|
||||
WriteImageEntry( mat.reflective, mat.name + "_reflective_image");
|
||||
WriteImageEntry( mat.normal, mat.name + "_normal_image");
|
||||
}
|
||||
PopTag();
|
||||
mOutput << startstr << "</library_images>" << endstr;
|
||||
|
||||
// output effects - those are the actual carriers of information
|
||||
mOutput << startstr << "<library_effects>" << endstr;
|
||||
PushTag();
|
||||
for( auto it = materials.cbegin(); it != materials.cend(); ++it )
|
||||
{
|
||||
const Material& mat = *it;
|
||||
// this is so ridiculous it must be right
|
||||
mOutput << startstr << "<effect id=\"" << mat.name << "-fx\" name=\"" << mat.name << "\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<profile_COMMON>" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<technique sid=\"standard\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<phong>" << endstr;
|
||||
PushTag();
|
||||
|
||||
WriteTextureColorEntry( mat.ambient, "ambient", mat.name + "_ambient_image");
|
||||
WriteTextureColorEntry( mat.diffuse, "diffuse", mat.name + "_diffuse_image");
|
||||
WriteTextureColorEntry( mat.specular, "specular", mat.name + "_specular_image");
|
||||
WriteTextureColorEntry( mat.emissive, "emission", mat.name + "_emissive_image");
|
||||
WriteTextureColorEntry( mat.reflective, "reflective", mat.name + "_reflective_image");
|
||||
if( !mat.normal.texture.empty() )
|
||||
WriteTextureColorEntry( mat.normal, "bump", mat.name + "_normal_image");
|
||||
|
||||
mOutput << startstr << "<shininess>" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<float sid=\"shininess\">" << mat.shininess << "</float>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</shininess>" << endstr;
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</phong>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</technique>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</profile_COMMON>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</effect>" << endstr;
|
||||
}
|
||||
PopTag();
|
||||
mOutput << startstr << "</library_effects>" << endstr;
|
||||
|
||||
// write materials - they're just effect references
|
||||
mOutput << startstr << "<library_materials>" << endstr;
|
||||
PushTag();
|
||||
for( auto it = materials.cbegin(); it != materials.cend(); ++it )
|
||||
{
|
||||
const Material& mat = *it;
|
||||
mOutput << startstr << "<material id=\"" << mat.name << "\" name=\"" << mat.name << "\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<instance_effect url=\"#" << mat.name << "-fx\"/>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</material>" << endstr;
|
||||
}
|
||||
PopTag();
|
||||
mOutput << startstr << "</library_materials>" << endstr;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes the geometry library
|
||||
void ColladaExporter::WriteGeometryLibrary()
|
||||
|
@ -199,7 +349,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
|
|||
mOutput << startstr << "</vertices>" << endstr;
|
||||
|
||||
// write face setup
|
||||
mOutput << startstr << "<polylist count=\"" << mesh->mNumFaces << "\" material=\"tellme\">" << endstr;
|
||||
mOutput << startstr << "<polylist count=\"" << mesh->mNumFaces << "\" material=\"theresonlyone\">" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstr << "-vertices\" />" << endstr;
|
||||
|
||||
|
@ -356,8 +506,16 @@ void ColladaExporter::WriteNode( const aiNode* pNode)
|
|||
// const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]];
|
||||
mOutput << startstr << "<instance_geometry url=\"#" << GetMeshId( pNode->mMeshes[a]) << "\">" << endstr;
|
||||
PushTag();
|
||||
|
||||
mOutput << startstr << "<bind_material>" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<technique_common>" << endstr;
|
||||
PushTag();
|
||||
mOutput << startstr << "<instance_material symbol=\"theresonlyone\" target=\"" << materials[mScene->mMeshes[pNode->mMeshes[a]]->mMaterialIndex].name << "\" />" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</technique_common>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</bind_material>" << endstr;
|
||||
PopTag();
|
||||
mOutput << startstr << "</instance_geometry>" << endstr;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@ protected:
|
|||
/// Writes the asset header
|
||||
void WriteHeader();
|
||||
|
||||
/// Writes the material setup
|
||||
void WriteMaterials();
|
||||
|
||||
/// Writes the geometry library
|
||||
void WriteGeometryLibrary();
|
||||
|
||||
|
@ -105,6 +108,36 @@ protected:
|
|||
std::string startstr;
|
||||
/// current line end string for simple stream insertion
|
||||
std::string endstr;
|
||||
|
||||
// pair of color and texture - texture precedences color
|
||||
struct Surface
|
||||
{
|
||||
aiColor4D color;
|
||||
std::string texture;
|
||||
size_t channel;
|
||||
Surface() { channel = 0; }
|
||||
};
|
||||
|
||||
// summarize a material in an convinient way.
|
||||
struct Material
|
||||
{
|
||||
std::string name;
|
||||
Surface ambient, diffuse, specular, emissive, reflective, normal;
|
||||
float shininess; /// specular exponent
|
||||
|
||||
Material() { shininess = 16.0f; }
|
||||
};
|
||||
|
||||
std::vector<Material> materials;
|
||||
|
||||
protected:
|
||||
/// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
|
||||
/// Reads a single surface entry from the given material keys
|
||||
void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex);
|
||||
/// Writes an image entry for the given surface
|
||||
void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd);
|
||||
/// Writes a color-or-texture entry into an effect definition
|
||||
void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue