Commit 86bd1032 authored by cutealien's avatar cutealien

ColladaExporter does now cache material-names on export by default which leads...

ColladaExporter does now cache material-names on export by default which leads to smaller .dae files.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4279 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 9459acf1
......@@ -82,7 +82,9 @@ namespace scene
//! Default - write each mesh exactly once to collada. Optimal but will not work with many tools.
ECGI_PER_MESH,
//! Write each mesh as often as it's used with different materials in the scene.
//! Write each mesh as often as it's used with different materials-names in the scene.
//! Material names which are used here are created on export, so using the IColladaMeshWriterNames
//! interface you have some control over how many geometries are written.
ECGI_PER_MESH_AND_MATERIAL,
// not yet supported, but might be useful as well
......@@ -205,7 +207,8 @@ namespace scene
IColladaMeshWriter()
: Properties(0), DefaultProperties(0), NameGenerator(0), DefaultNameGenerator(0)
, WriteTextures(true), WriteDefaultScene(true), AmbientLight(0.f, 0.f, 0.f, 1.f)
, WriteTextures(true), WriteDefaultScene(true), ExportSMaterialOnce(true)
, AmbientLight(0.f, 0.f, 0.f, 1.f)
{
}
......@@ -285,6 +288,24 @@ namespace scene
return GeometryWriting;
}
//! Make certain there is only one collada material generated per Irrlicht material
/** Checks before creating a collada material-name if an identical
irr:::video::SMaterial has been exported already. If so don't export it with
another name. This is set by default and leads to way smaller .dae files.
Note that if you need to disable this flag for some reason you can still
get a similar effect using the IColladaMeshWriterNames::nameForMaterial
by returning identical names for identical materials there.
*/
virtual void setExportSMaterialsOnlyOnce(bool exportOnce)
{
ExportSMaterialOnce = exportOnce;
}
virtual bool getExportSMaterialsOnlyOnce() const
{
return ExportSMaterialOnce;
}
//! Set properties to use by the meshwriter instead of it's default properties.
/** Overloading properties with an own class allows modifying the writing process in certain ways.
By default properties are set to the DefaultProperties. */
......@@ -374,6 +395,7 @@ namespace scene
IColladaMeshWriterNames * DefaultNameGenerator;
bool WriteTextures;
bool WriteDefaultScene;
bool ExportSMaterialOnce;
video::SColorf AmbientLight;
E_COLLADA_GEOMETRY_WRITING GeometryWriting;
};
......
......@@ -263,6 +263,7 @@ void CColladaMeshWriter::reset()
LightNodes.clear();
MaterialsWritten.clear();
EffectsWritten.clear();
MaterialNameCache.clear();
}
//! Returns the type of the mesh writer
......@@ -996,14 +997,27 @@ irr::core::stringw CColladaMeshWriter::nameForNode(const scene::ISceneNode* node
return irr::core::stringw(L"missing_name_generator");
}
irr::core::stringw CColladaMeshWriter::nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node) const
irr::core::stringw CColladaMeshWriter::nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node)
{
irr::core::stringw matName;
if ( getExportSMaterialsOnlyOnce() )
{
matName = findCachedMaterialName(material);
if ( !matName.empty() )
return matName;
}
IColladaMeshWriterNames * nameGenerator = getNameGenerator();
if ( nameGenerator )
{
return nameGenerator->nameForMaterial(material, materialId, mesh, node);
matName = nameGenerator->nameForMaterial(material, materialId, mesh, node);
}
return irr::core::stringw(L"missing_name_generator");
else
matName = irr::core::stringw(L"missing_name_generator");
if ( getExportSMaterialsOnlyOnce() )
MaterialNameCache.push_back (MaterialName(material, matName));
return matName;
}
// Each mesh-material has one symbol which is replaced on instantiation
......@@ -1014,6 +1028,16 @@ irr::core::stringw CColladaMeshWriter::nameForMaterialSymbol(const scene::IMesh*
return irr::core::stringw(buf);
}
irr::core::stringw CColladaMeshWriter::findCachedMaterialName(const irr::video::SMaterial& material) const
{
for ( u32 i=0; i<MaterialNameCache.size(); ++i )
{
if ( MaterialNameCache[i].Material == material )
return MaterialNameCache[i].Name;
}
return irr::core::stringw();
}
irr::core::stringw CColladaMeshWriter::minTexfilterToString(bool bilinear, bool trilinear) const
{
if ( trilinear )
......
......@@ -109,9 +109,9 @@ protected:
inline irr::core::stringw toRef(const irr::core::stringw& source) const;
irr::core::stringw nameForMesh(const scene::IMesh* mesh, int instance) const;
irr::core::stringw nameForNode(const scene::ISceneNode* node) const;
irr::core::stringw nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node) const;
irr::core::stringw nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node);
irr::core::stringw nameForMaterialSymbol(const scene::IMesh* mesh, int materialId) const;
irr::core::stringw nameForPtr(const void* ptr) const;
irr::core::stringw findCachedMaterialName(const irr::video::SMaterial& material) const;
irr::core::stringw minTexfilterToString(bool bilinear, bool trilinear) const;
irr::core::stringw magTexfilterToString(bool bilinear, bool trilinear) const;
irr::core::stringw pathToURI(const irr::io::path& path) const;
......@@ -241,6 +241,17 @@ protected:
// TODO: second parameter not needed, we just don't have a core::set class yet in Irrlicht
core::map<irr::core::stringw, bool> MaterialsWritten;
core::map<irr::core::stringw, bool> EffectsWritten;
// Cache material names
struct MaterialName
{
MaterialName(const irr::video::SMaterial & material, const irr::core::stringw& name)
: Material(material), Name(name)
{}
irr::video::SMaterial Material;
irr::core::stringw Name;
};
irr::core::array< MaterialName > MaterialNameCache;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment