2011-06-15 03:47:42 -07:00
|
|
|
// Copyright (C) 2002-2011 Nikolaus Gebhardt
|
|
|
|
// This file is part of the "Irrlicht Engine".
|
|
|
|
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
|
|
|
|
|
|
|
#ifndef __IRR_I_COLLADA_MESH_WRITER_H_INCLUDED__
|
|
|
|
#define __IRR_I_COLLADA_MESH_WRITER_H_INCLUDED__
|
|
|
|
|
|
|
|
#include "IMeshWriter.h"
|
2011-06-21 10:04:43 -07:00
|
|
|
#include "ISceneNode.h"
|
|
|
|
#include "IAnimatedMesh.h"
|
2011-06-15 03:47:42 -07:00
|
|
|
#include "SMaterial.h"
|
|
|
|
|
|
|
|
namespace irr
|
|
|
|
{
|
|
|
|
namespace io
|
|
|
|
{
|
|
|
|
class IWriteFile;
|
|
|
|
} // end namespace io
|
|
|
|
|
|
|
|
namespace scene
|
|
|
|
{
|
2011-06-15 08:28:02 -07:00
|
|
|
//! Lighting models - more or less the way Collada categorizes materials
|
2011-06-15 03:47:42 -07:00
|
|
|
enum E_COLLADA_TECHNIQUE_FX
|
|
|
|
{
|
|
|
|
//! Blinn-phong which is default for opengl and dx fixed function pipelines.
|
|
|
|
//! But several well-known renderers don't support it and prefer phong.
|
|
|
|
ECTF_BLINN,
|
|
|
|
//! Phong shading, default in many external renderers.
|
|
|
|
ECTF_PHONG,
|
|
|
|
//! diffuse shaded surface that is independent of lighting.
|
|
|
|
ECTF_LAMBERT,
|
|
|
|
// constantly shaded surface that is independent of lighting.
|
|
|
|
ECTF_CONSTANT
|
|
|
|
};
|
|
|
|
|
2011-06-22 12:49:14 -07:00
|
|
|
//! How to interpret the opacity in collada
|
2011-06-15 08:28:02 -07:00
|
|
|
enum E_COLLADA_TRANSPARENT_FX
|
|
|
|
{
|
2011-06-22 12:49:14 -07:00
|
|
|
//! default - only alpha channel of color or texture is used.
|
2011-06-15 08:28:02 -07:00
|
|
|
ECOF_A_ONE = 0,
|
|
|
|
|
2011-06-22 12:49:14 -07:00
|
|
|
//! Alpha values for each RGB channel of color or texture are used.
|
2011-07-01 15:58:38 -07:00
|
|
|
ECOF_RGB_ZERO = 1
|
2011-06-15 08:28:02 -07:00
|
|
|
};
|
|
|
|
|
2011-06-22 12:49:14 -07:00
|
|
|
//! Color names collada uses in it's color samplers
|
2011-06-21 10:04:43 -07:00
|
|
|
enum E_COLLADA_COLOR_SAMPLER
|
|
|
|
{
|
|
|
|
ECCS_DIFFUSE,
|
|
|
|
ECCS_AMBIENT,
|
|
|
|
ECCS_EMISSIVE,
|
|
|
|
ECCS_SPECULAR,
|
2011-06-22 12:49:14 -07:00
|
|
|
ECCS_TRANSPARENT,
|
2011-07-01 15:58:38 -07:00
|
|
|
ECCS_REFLECTIVE
|
2011-06-22 12:49:14 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
//! Irrlicht colors which can be mapped to E_COLLADA_COLOR_SAMPLER values
|
|
|
|
enum E_COLLADA_IRR_COLOR
|
|
|
|
{
|
|
|
|
//! Don't write this element at all
|
|
|
|
ECIC_NONE,
|
|
|
|
|
|
|
|
//! Check IColladaMeshWriterProperties for custom color
|
|
|
|
ECIC_CUSTOM,
|
|
|
|
|
|
|
|
//! Use SMaterial::DiffuseColor
|
|
|
|
ECIC_DIFFUSE,
|
|
|
|
|
|
|
|
//! Use SMaterial::AmbientColor
|
|
|
|
ECIC_AMBIENT,
|
|
|
|
|
|
|
|
//! Use SMaterial::EmissiveColor
|
|
|
|
ECIC_EMISSIVE,
|
|
|
|
|
|
|
|
//! Use SMaterial::SpecularColor
|
|
|
|
ECIC_SPECULAR
|
2011-06-21 10:04:43 -07:00
|
|
|
};
|
|
|
|
|
2011-06-15 03:47:42 -07:00
|
|
|
//! Callback interface for properties which can be used to influence collada writing
|
|
|
|
class IColladaMeshWriterProperties : public virtual IReferenceCounted
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ~IColladaMeshWriterProperties () {}
|
|
|
|
|
|
|
|
//! Which lighting model should be used in the technique (FX) section when exporting effects (materials)
|
|
|
|
virtual E_COLLADA_TECHNIQUE_FX getTechniqueFx(const video::SMaterial& material) const = 0;
|
|
|
|
|
2011-06-21 10:04:43 -07:00
|
|
|
//! Which texture index should be used when writing the texture of the given sampler color.
|
|
|
|
/** \return the index to the texture-layer or -1 if that texture should never be exported
|
|
|
|
Note: for ECCS_TRANSPARENT by default the alpha channel is used, if you want to use RGB you have to set
|
|
|
|
also the ECOF_RGB_ZERO flag in getTransparentFx. */
|
|
|
|
virtual s32 getTextureIdx(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) const = 0;
|
2011-06-15 08:28:02 -07:00
|
|
|
|
2011-06-22 12:49:14 -07:00
|
|
|
//! Return which color from Irrlicht should be used for the color requested by collada
|
|
|
|
/** Note that collada allows exporting either texture or color, not both.
|
|
|
|
So color mapping is only checked if we have no valid texture already.
|
|
|
|
By default we try to return best fits when possible. For example ECCS_DIFFUSE is mapped to ECIC_DIFFUSE.
|
|
|
|
When ECIC_CUSTOM is returned then the result of getCustomColor will be used. */
|
|
|
|
virtual E_COLLADA_IRR_COLOR getColorMapping(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) const = 0;
|
|
|
|
|
|
|
|
//! Return custom colors for certain color types requested by collada.
|
|
|
|
/** Only used when getColorMapping returns ECIC_CUSTOM for the same paramters. */
|
|
|
|
virtual video::SColor getCustomColor(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs) const = 0;
|
|
|
|
|
|
|
|
//! Return the transparence color interpretation.
|
|
|
|
/** Not this is only about ECCS_TRANSPARENT and does not affect getTransparency. */
|
2011-06-15 08:28:02 -07:00
|
|
|
virtual E_COLLADA_TRANSPARENT_FX getTransparentFx(const video::SMaterial& material) const = 0;
|
|
|
|
|
2011-06-22 12:49:14 -07:00
|
|
|
//! Transparency value for that material.
|
2011-06-15 08:28:02 -07:00
|
|
|
/** This value is additional to transparent settings, if both are set they will be multiplicated.
|
|
|
|
\return 1.0 for fully transparent, 0.0 for not transparent and not written at all when < 0.f */
|
|
|
|
virtual f32 getTransparency(const video::SMaterial& material) const = 0;
|
2011-06-21 10:04:43 -07:00
|
|
|
|
2011-06-22 12:49:14 -07:00
|
|
|
//! Reflectivity value for that material
|
|
|
|
/** The amount of perfect mirror reflection to be added to the reflected light
|
|
|
|
\return 0.0 - 1.0 for reflectivity and element is not written at all when < 0.f */
|
|
|
|
virtual f32 getReflectivity(const video::SMaterial& material) const = 0;
|
|
|
|
|
|
|
|
//! Return index of refraction for that material
|
|
|
|
/** By default we don't write that.
|
2011-11-01 01:42:30 -07:00
|
|
|
\return a value greater equal 0.f to write \<index_of_refraction\> when it is lesser than 0 nothing will be written */
|
2011-06-22 12:49:14 -07:00
|
|
|
virtual f32 getIndexOfRefraction(const video::SMaterial& material) const = 0;
|
|
|
|
|
|
|
|
//! Should node be used in scene export? (only needed for scene-writing, ignored in mesh-writing)
|
2011-06-21 10:04:43 -07:00
|
|
|
//! By default all visible nodes are exported.
|
|
|
|
virtual bool isExportable(const irr::scene::ISceneNode * node) const = 0;
|
|
|
|
|
2011-06-22 12:49:14 -07:00
|
|
|
//! Return the mesh for the given node. If it has no mesh or shouldn't export it's mesh
|
|
|
|
//! you can return 0 in which case only the transformation matrix of the node will be used.
|
2011-06-21 10:04:43 -07:00
|
|
|
virtual IMesh* getMesh(irr::scene::ISceneNode * node) = 0;
|
2011-06-15 03:47:42 -07:00
|
|
|
};
|
|
|
|
|
2012-08-08 10:04:26 -07:00
|
|
|
//! Callback interface to use custom names on collada writing.
|
|
|
|
/** Many names and id's have to be unique in collada. By default
|
|
|
|
Irrlicht guarantees for example by using using pointer-values in the name.
|
|
|
|
This works for most tools, but occasionally you might need another naming scheme
|
|
|
|
to make it easier finding names again for further processing.
|
|
|
|
*/
|
|
|
|
class IColladaMeshWriterNames : public virtual IReferenceCounted
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
IColladaMeshWriterNames() : MeshToNC(true), NodeToNC(true), NCNamePrefix(L"_NC_") {}
|
|
|
|
virtual ~IColladaMeshWriterNames () {}
|
|
|
|
|
|
|
|
//! Return a unique name for the given mesh
|
|
|
|
/** Note that names really must be unique here per mesh-pointer, so mostly it's a good idea to return
|
|
|
|
the nameForMesh from IColladaMeshWriter::getDefaultNameGenerator().
|
|
|
|
*/
|
|
|
|
virtual irr::core::stringw nameForMesh(const scene::IMesh* mesh) const = 0;
|
|
|
|
|
|
|
|
//! Return a unique name for the given node
|
|
|
|
/** Note that names really must be unique here per node-pointer, so mostly it's a good idea to return
|
|
|
|
the nameForNode from IColladaMeshWriter::getDefaultNameGenerator().
|
|
|
|
*/
|
|
|
|
virtual irr::core::stringw nameForNode(const scene::ISceneNode* node) const = 0;
|
|
|
|
|
|
|
|
//! Return a name for the material
|
|
|
|
/** There is one material created in the writer for each unique name. So you can use this to control
|
|
|
|
the number of materials which get written. For example Irrlicht does by default write one material for each
|
|
|
|
material instanced by a node. So if you know that in your application material instances per node are identical
|
|
|
|
between different nodes you can reduce the number of exported materials using that knowledge by using identical
|
|
|
|
names for such shared materials. */
|
|
|
|
virtual irr::core::stringw nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node) const = 0;
|
|
|
|
|
|
|
|
//! Ensure meshnames follow the xs::NCName format (so this will change names!)
|
|
|
|
/** Names need to have a certain format in collada, like not starting with numbers,
|
|
|
|
and avoiding certain special characters.
|
|
|
|
*/
|
|
|
|
void SetConvertMeshNameToNC(bool doConvert)
|
|
|
|
{
|
|
|
|
MeshToNC = doConvert;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Check if meshnames are forced to follow the xs::NCName format
|
|
|
|
bool GetConvertMeshNameToNC() const
|
|
|
|
{
|
|
|
|
return MeshToNC;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Ensure nodenames follow the xs::NCName format (so this will change names!)
|
|
|
|
void SetConvertNodeNameToNC(bool doConvert)
|
|
|
|
{
|
|
|
|
NodeToNC = doConvert;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Check if nodenames are forced to follow the xs::NCName format
|
|
|
|
bool GetConvertNodeNameToNC() const
|
|
|
|
{
|
|
|
|
return NodeToNC;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Ensure materialnames follow the xs::NCName format (so this will change names!)
|
|
|
|
void SetConvertMaterialNameToNC(bool doConvert)
|
|
|
|
{
|
|
|
|
MaterialToNC = doConvert;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Check if materialnames are forced to follow the xs::NCName format
|
|
|
|
bool GetConvertMaterialNameToNC() const
|
|
|
|
{
|
|
|
|
return MaterialToNC;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! When conversion to NCName's is enforced resulting names will have this prefix
|
|
|
|
void SetNCNamePrefix(const irr::core::stringw& prefix)
|
|
|
|
{
|
|
|
|
NCNamePrefix = prefix;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Get the NCName prefix
|
|
|
|
const irr::core::stringw& getNCNamePrefix() const
|
|
|
|
{
|
|
|
|
return NCNamePrefix;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
bool MeshToNC;
|
|
|
|
bool NodeToNC;
|
|
|
|
bool MaterialToNC;
|
|
|
|
irr::core::stringw NCNamePrefix;
|
|
|
|
};
|
|
|
|
|
2011-06-15 03:47:42 -07:00
|
|
|
|
|
|
|
//! Interface for writing meshes
|
|
|
|
class IColladaMeshWriter : public IMeshWriter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2012-08-08 10:04:26 -07:00
|
|
|
IColladaMeshWriter()
|
|
|
|
: Properties(0), DefaultProperties(0), NameGenerator(0), DefaultNameGenerator(0)
|
|
|
|
, WriteTextures(true), WriteDefaultScene(false), AmbientLight(0.f, 0.f, 0.f, 1.f)
|
2011-06-15 03:47:42 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Destructor
|
|
|
|
virtual ~IColladaMeshWriter()
|
|
|
|
{
|
|
|
|
if ( Properties )
|
|
|
|
Properties->drop();
|
|
|
|
if ( DefaultProperties )
|
|
|
|
DefaultProperties->drop();
|
2012-08-08 10:04:26 -07:00
|
|
|
if ( NameGenerator )
|
|
|
|
NameGenerator->drop();
|
|
|
|
if ( DefaultNameGenerator )
|
|
|
|
DefaultNameGenerator->drop();
|
2011-06-15 03:47:42 -07:00
|
|
|
}
|
|
|
|
|
2011-06-21 10:04:43 -07:00
|
|
|
//! writes a scene starting with the given node
|
|
|
|
virtual bool writeScene(io::IWriteFile* file, scene::ISceneNode* root) = 0;
|
|
|
|
|
|
|
|
|
2011-06-15 03:47:42 -07:00
|
|
|
//! Set if texture information should be written
|
|
|
|
virtual void setWriteTextures(bool write)
|
|
|
|
{
|
|
|
|
WriteTextures = write;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Get if texture information should be written
|
|
|
|
virtual bool getWriteTextures() const
|
|
|
|
{
|
|
|
|
return WriteTextures;
|
|
|
|
}
|
|
|
|
|
2011-06-21 10:04:43 -07:00
|
|
|
//! Set if a default scene should be written when writing meshes.
|
2011-06-15 03:47:42 -07:00
|
|
|
/** Many collada readers fail to read a mesh if the collada files doesn't contain a scene as well.
|
|
|
|
The scene is doing an instantiation of the mesh.
|
2011-06-21 10:04:43 -07:00
|
|
|
When using writeScene this flag is ignored (as we have scene there already)
|
2011-06-15 03:47:42 -07:00
|
|
|
*/
|
2011-06-21 10:04:43 -07:00
|
|
|
virtual void setWriteDefaultScene(bool write)
|
2011-06-15 03:47:42 -07:00
|
|
|
{
|
2011-06-21 10:04:43 -07:00
|
|
|
WriteDefaultScene = write;
|
2011-06-15 03:47:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//! Get if a default scene should be written
|
2011-06-21 10:04:43 -07:00
|
|
|
virtual bool getWriteDefaultScene() const
|
2011-06-15 03:47:42 -07:00
|
|
|
{
|
2011-06-21 10:04:43 -07:00
|
|
|
return WriteDefaultScene;
|
2011-06-15 03:47:42 -07:00
|
|
|
}
|
|
|
|
|
2011-06-23 10:40:27 -07:00
|
|
|
//! Sets ambient color of the scene to write
|
|
|
|
virtual void setAmbientLight(const video::SColorf &ambientColor)
|
|
|
|
{
|
|
|
|
AmbientLight = ambientColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Return ambient light of the scene which is written
|
|
|
|
virtual video::SColorf getAmbientLight() const
|
|
|
|
{
|
|
|
|
return AmbientLight;
|
|
|
|
}
|
|
|
|
|
2011-06-15 03:47:42 -07:00
|
|
|
//! 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. */
|
|
|
|
virtual void setProperties(IColladaMeshWriterProperties * p)
|
|
|
|
{
|
|
|
|
if ( p == Properties )
|
|
|
|
return;
|
|
|
|
if ( p )
|
|
|
|
p->grab();
|
|
|
|
if ( Properties )
|
|
|
|
Properties->drop();
|
|
|
|
Properties = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Get properties which are currently used.
|
2012-08-08 10:04:26 -07:00
|
|
|
virtual IColladaMeshWriterProperties * getProperties() const
|
2011-06-15 03:47:42 -07:00
|
|
|
{
|
|
|
|
return Properties;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Return the original default properties of the writer.
|
|
|
|
/** You can use this pointer in your own properties to access and return default values. */
|
|
|
|
IColladaMeshWriterProperties * getDefaultProperties() const
|
|
|
|
{
|
|
|
|
return DefaultProperties;
|
|
|
|
}
|
|
|
|
|
2012-08-08 10:04:26 -07:00
|
|
|
//! Install a generator to create custom names on export.
|
|
|
|
virtual void setNameGenerator(IColladaMeshWriterNames * nameGenerator)
|
|
|
|
{
|
|
|
|
if ( nameGenerator == NameGenerator )
|
|
|
|
return;
|
|
|
|
if ( nameGenerator )
|
|
|
|
nameGenerator->grab();
|
|
|
|
if ( NameGenerator )
|
|
|
|
NameGenerator->drop();
|
|
|
|
NameGenerator = nameGenerator;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Get currently used name generator
|
|
|
|
virtual IColladaMeshWriterNames * getNameGenerator() const
|
|
|
|
{
|
|
|
|
return NameGenerator;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Return the original default name generator of the writer.
|
|
|
|
/** You can use this pointer in your own generator to access and return default values. */
|
|
|
|
IColladaMeshWriterNames * getDefaultNameGenerator() const
|
|
|
|
{
|
|
|
|
return DefaultNameGenerator;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-15 03:47:42 -07:00
|
|
|
protected:
|
2012-08-08 10:04:26 -07:00
|
|
|
// NOTE: You usually should also call setProperties with the same paraemter when using setDefaultProperties
|
2011-06-15 03:47:42 -07:00
|
|
|
virtual void setDefaultProperties(IColladaMeshWriterProperties * p)
|
|
|
|
{
|
|
|
|
if ( p == DefaultProperties )
|
|
|
|
return;
|
|
|
|
if ( p )
|
|
|
|
p->grab();
|
|
|
|
if ( DefaultProperties )
|
|
|
|
DefaultProperties->drop();
|
|
|
|
DefaultProperties = p;
|
|
|
|
}
|
|
|
|
|
2012-08-08 10:04:26 -07:00
|
|
|
// NOTE: You usually should also call setNameGenerator with the same paraemter when using setDefaultProperties
|
|
|
|
virtual void setDefaultNameGenerator(IColladaMeshWriterNames * p)
|
|
|
|
{
|
|
|
|
if ( p == DefaultNameGenerator )
|
|
|
|
return;
|
|
|
|
if ( p )
|
|
|
|
p->grab();
|
|
|
|
if ( DefaultNameGenerator )
|
|
|
|
DefaultNameGenerator->drop();
|
|
|
|
DefaultNameGenerator = p;
|
|
|
|
}
|
|
|
|
|
2011-06-15 03:47:42 -07:00
|
|
|
private:
|
|
|
|
IColladaMeshWriterProperties * Properties;
|
|
|
|
IColladaMeshWriterProperties * DefaultProperties;
|
2012-08-08 10:04:26 -07:00
|
|
|
IColladaMeshWriterNames * NameGenerator;
|
|
|
|
IColladaMeshWriterNames * DefaultNameGenerator;
|
2011-06-15 03:47:42 -07:00
|
|
|
bool WriteTextures;
|
2011-06-21 10:04:43 -07:00
|
|
|
bool WriteDefaultScene;
|
2011-06-23 10:40:27 -07:00
|
|
|
video::SColorf AmbientLight;
|
2011-06-15 03:47:42 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // end namespace
|
|
|
|
} // end namespace
|
|
|
|
|
|
|
|
#endif
|