irrlicht/source/Irrlicht/CColladaMeshWriter.h
cutealien 0c6385cb92 Replace public header guards to avoid using indentifiers reserved by c++
Usually something like __IRR_SOME_GUARD_INCLUDED__ replaced by IRR_SOME_GUARD_INCLUDED.
Removing underscores at the end wasn't necessary, but more symmetric (probably the reason they got added there as well).
While this touches every header it shouldn't affect users (I hope).

Also a few whitespace changes to unify whitespace usage a bit.
And a bunch of spelling fixes in comments.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6252 dfc29bdd-3216-0410-991c-e03cc46cb475
2021-08-27 15:03:34 +00:00

283 lines
12 KiB
C++

// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef IRR_C_COLLADA_MESH_WRITER_H_INCLUDED
#define IRR_C_COLLADA_MESH_WRITER_H_INCLUDED
#include "IColladaMeshWriter.h"
#include "S3DVertex.h"
#include "irrMap.h"
#include "IVideoDriver.h"
#include "IXMLWriter.h"
namespace irr
{
namespace io
{
class IFileSystem;
}
namespace scene
{
//! Callback interface for properties which can be used to influence collada writing
// (Implementer note: keep namespace labels here to make it easier for users copying this one)
class CColladaMeshWriterProperties : public virtual IColladaMeshWriterProperties
{
public:
//! Which lighting model should be used in the technique (FX) section when exporting effects (materials)
virtual irr::scene::E_COLLADA_TECHNIQUE_FX getTechniqueFx(const irr::video::SMaterial& material) const IRR_OVERRIDE;
//! Which texture index should be used when writing the texture of the given sampler color.
virtual irr::s32 getTextureIdx(const irr::video::SMaterial & material, irr::scene::E_COLLADA_COLOR_SAMPLER cs) const IRR_OVERRIDE;
//! Return which color from Irrlicht should be used for the color requested by collada
virtual irr::scene::E_COLLADA_IRR_COLOR getColorMapping(const irr::video::SMaterial & material, irr::scene::E_COLLADA_COLOR_SAMPLER cs) const IRR_OVERRIDE;
//! Return custom colors for certain color types requested by collada.
virtual irr::video::SColor getCustomColor(const irr::video::SMaterial & material, irr::scene::E_COLLADA_COLOR_SAMPLER cs) const IRR_OVERRIDE;
//! Return the settings for transparence
virtual irr::scene::E_COLLADA_TRANSPARENT_FX getTransparentFx(const irr::video::SMaterial& material) const IRR_OVERRIDE;
//! Transparency value for that material.
virtual irr::f32 getTransparency(const irr::video::SMaterial& material) const IRR_OVERRIDE;
//! Reflectivity value for that material
virtual irr::f32 getReflectivity(const irr::video::SMaterial& material) const IRR_OVERRIDE;
//! Return index of refraction for that material
virtual irr::f32 getIndexOfRefraction(const irr::video::SMaterial& material) const IRR_OVERRIDE;
//! Should node be used in scene export? By default all visible nodes are exported.
virtual bool isExportable(const irr::scene::ISceneNode * node) const IRR_OVERRIDE;
//! Return the mesh for the given nod. If it has no mesh or shouldn't export it's mesh return 0.
virtual irr::scene::IMesh* getMesh(irr::scene::ISceneNode * node) IRR_OVERRIDE;
//! Return if the node has it's own material overwriting the mesh-materials
virtual bool useNodeMaterial(const scene::ISceneNode* node) const IRR_OVERRIDE;
};
class CColladaMeshWriterNames : public virtual IColladaMeshWriterNames
{
public:
CColladaMeshWriterNames(IColladaMeshWriter * writer);
virtual irr::core::stringc nameForMesh(const scene::IMesh* mesh, int instance) IRR_OVERRIDE;
virtual irr::core::stringc nameForNode(const scene::ISceneNode* node) IRR_OVERRIDE;
virtual irr::core::stringc nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node) IRR_OVERRIDE;
protected:
irr::core::stringc nameForPtr(const void* ptr) const;
private:
IColladaMeshWriter * ColladaMeshWriter;
};
//! class to write meshes, implementing a COLLADA (.dae, .xml) writer
/** This writer implementation has been originally developed for irrEdit and then
merged out to the Irrlicht Engine */
class CColladaMeshWriter : public IColladaMeshWriter
{
public:
CColladaMeshWriter(ISceneManager * smgr, video::IVideoDriver* driver, io::IFileSystem* fs);
virtual ~CColladaMeshWriter();
//! Returns the type of the mesh writer
virtual EMESH_WRITER_TYPE getType() const IRR_OVERRIDE;
//! writes a scene starting with the given node
virtual bool writeScene(io::IWriteFile* file, scene::ISceneNode* root, int writeRoot) IRR_OVERRIDE;
//! writes a mesh
virtual bool writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 flags=EMWF_NONE) IRR_OVERRIDE;
// Restrict the characters of oldString a set of allowed characters in xs:NCName and add the prefix.
virtual irr::core::stringc toNCName(const irr::core::stringc& oldString, const irr::core::stringc& prefix=irr::core::stringc("_NC_")) const IRR_OVERRIDE;
//! After export you can find out which name had been used for writing the geometry for this node.
virtual const irr::core::stringc* findGeometryNameForNode(ISceneNode* node) IRR_OVERRIDE;
protected:
void reset();
bool hasSecondTextureCoordinates(video::E_VERTEX_TYPE type) const;
void writeUv(const irr::core::vector2df& vec);
void writeVector(const irr::core::vector3df& vec);
void writeColor(const irr::video::SColorf& colorf, bool writeAlpha=true);
inline irr::core::stringc toString(const irr::video::ECOLOR_FORMAT format) const;
inline irr::core::stringc toString(const irr::video::E_TEXTURE_CLAMP clamp) const;
inline irr::core::stringc toString(const irr::scene::E_COLLADA_TRANSPARENT_FX opaque) const;
inline irr::core::stringc toRef(const irr::core::stringc& source) const;
bool isCamera(const scene::ISceneNode* node) const;
irr::core::stringc nameForMesh(const scene::IMesh* mesh, int instance) const;
irr::core::stringc nameForNode(const scene::ISceneNode* node) const;
irr::core::stringc nameForMaterial(const video::SMaterial & material, int materialId, const scene::IMesh* mesh, const scene::ISceneNode* node);
irr::core::stringc nameForMaterialSymbol(const scene::IMesh* mesh, int materialId) const;
irr::core::stringc findCachedMaterialName(const irr::video::SMaterial& material) const;
irr::core::stringc minTexfilterToString(bool bilinear, bool trilinear) const;
irr::core::stringc magTexfilterToString(bool bilinear, bool trilinear) const;
irr::core::stringc pathToURI(const irr::io::path& path) const;
inline bool isXmlNameStartChar(c8 c) const;
inline bool isXmlNameChar(c8 c) const;
s32 getCheckedTextureIdx(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs);
video::SColor getColorMapping(const video::SMaterial & material, E_COLLADA_COLOR_SAMPLER cs, E_COLLADA_IRR_COLOR colType);
void writeAsset();
void makeMeshNames(irr::scene::ISceneNode * node);
void writeNodeMaterials(irr::scene::ISceneNode * node);
void writeNodeEffects(irr::scene::ISceneNode * node);
void writeNodeLights(irr::scene::ISceneNode * node);
void writeNodeCameras(irr::scene::ISceneNode * node);
void writeAllMeshGeometries();
void writeSceneNode(irr::scene::ISceneNode * node);
void writeMeshMaterials(scene::IMesh* mesh, irr::core::array<irr::core::stringc> * materialNamesOut=0);
void writeMeshEffects(scene::IMesh* mesh);
void writeMaterialEffect(const irr::core::stringc& materialname, const video::SMaterial & material);
void writeMeshGeometry(const irr::core::stringc& meshname, scene::IMesh* mesh);
void writeMeshInstanceGeometry(const irr::core::stringc& meshname, scene::IMesh* mesh, scene::ISceneNode* node=0);
void writeMaterial(const irr::core::stringc& materialname);
void writeLightInstance(const irr::core::stringc& lightName);
void writeCameraInstance(const irr::core::stringc& cameraName);
void writeLibraryImages();
void writeColorFx(const video::SMaterial & material, const c8 * colorname, E_COLLADA_COLOR_SAMPLER cs, const c8* attr1Name=0, const c8* attr1Value=0);
void writeAmbientLightElement(const video::SColorf & col);
void writeColorElement(const video::SColor & col, bool writeAlpha=true);
void writeColorElement(const video::SColorf & col, bool writeAlpha=true);
void writeTextureSampler(s32 textureIdx);
void writeFxElement(const video::SMaterial & material, E_COLLADA_TECHNIQUE_FX techFx);
void writeNode(const c8 * nodeName, const c8 * content);
void writeFloatElement(irr::f32 value);
void writeRotateElement(const irr::core::vector3df& axis, irr::f32 angle);
void writeScaleElement(const irr::core::vector3df& scale);
void writeTranslateElement(const irr::core::vector3df& translate);
void writeLookAtElement(const irr::core::vector3df& eyePos, const irr::core::vector3df& targetPos, const irr::core::vector3df& upVector);
void writeMatrixElement(const irr::core::matrix4& matrix);
struct SComponentGlobalStartPos
{
SComponentGlobalStartPos() : PosStartIndex(0),
NormalStartIndex(0),
TCoord0StartIndex(0),
TCoord1StartIndex(0)
{ }
u32 PosStartIndex;
u32 NormalStartIndex;
u32 TCoord0StartIndex;
u32 TCoord1StartIndex;
};
io::IFileSystem* FileSystem;
video::IVideoDriver* VideoDriver;
io::IXMLWriterUTF8* Writer;
core::array<video::ITexture*> LibraryImages;
io::path Directory;
// Helper struct for creating geometry copies for the ECGI_PER_MESH_AND_MATERIAL settings.
struct SGeometryMeshMaterials
{
bool equals(const core::array<irr::core::stringc>& names) const
{
if ( names.size() != MaterialNames.size() )
return false;
for ( irr::u32 i=0; i<MaterialNames.size(); ++i )
if ( names[i] != MaterialNames[i] )
return false;
return true;
}
irr::core::stringc GeometryName; // replacing the usual ColladaMesh::Name
core::array<irr::core::stringc> MaterialNames; // Material names exported for this instance
core::array<const ISceneNode*> MaterialOwners; // Nodes using this specific mesh-material combination
};
// Check per mesh-ptr if stuff has been written for this mesh already
struct SColladaMesh
{
SColladaMesh() : MaterialsWritten(false), EffectsWritten(false)
{
}
SGeometryMeshMaterials * findGeometryMeshMaterials(const irr::core::array<irr::core::stringc> materialNames)
{
for ( irr::u32 i=0; i<GeometryMeshMaterials.size(); ++i )
{
if ( GeometryMeshMaterials[i].equals(materialNames) )
return &(GeometryMeshMaterials[i]);
}
return NULL;
}
const irr::core::stringc& findGeometryNameForNode(const ISceneNode* node) const
{
if ( GeometryMeshMaterials.size() < 2 )
return Name;
for ( irr::u32 i=0; i<GeometryMeshMaterials.size(); ++i )
{
if ( GeometryMeshMaterials[i].MaterialOwners.linear_search(node) >= 0 )
return GeometryMeshMaterials[i].GeometryName;
}
return Name; // (shouldn't get here usually)
}
irr::core::stringc Name;
bool MaterialsWritten; // just an optimization doing that here in addition to the MaterialsWritten map
bool EffectsWritten; // just an optimization doing that here in addition to the EffectsWritten map
core::array<SGeometryMeshMaterials> GeometryMeshMaterials;
};
typedef core::map<IMesh*, SColladaMesh>::Node MeshNode;
core::map<IMesh*, SColladaMesh> Meshes;
// structure for the lights library
struct SColladaLight
{
SColladaLight() {}
irr::core::stringc Name;
};
typedef core::map<ISceneNode*, SColladaLight>::Node LightNode;
core::map<ISceneNode*, SColladaLight> LightNodes;
// structure for the camera library
typedef core::map<ISceneNode*, irr::core::stringc>::Node CameraNode;
core::map<ISceneNode*, irr::core::stringc> CameraNodes;
// Check per name if stuff has been written already
// TODO: second parameter not needed, we just don't have a core::set class yet in Irrlicht
core::map<irr::core::stringc, bool> MaterialsWritten;
core::map<irr::core::stringc, bool> EffectsWritten;
// Cache material names
struct MaterialName
{
MaterialName(const irr::video::SMaterial & material, const irr::core::stringc& name)
: Material(material), Name(name)
{}
irr::video::SMaterial Material;
irr::core::stringc Name;
};
irr::core::array< MaterialName > MaterialNameCache;
irr::core::stringc WriteBuffer; // use for writing short strings to avoid regular memory allocations
struct EscapeCharacterURL
{
EscapeCharacterURL(irr::c8 c, const irr::c8* e)
: Character(c)
{
Escape = e;
}
irr::c8 Character; // unescaped (like ' ')
irr::core::stringc Escape; // escaped (like '%20')
};
irr::core::array<EscapeCharacterURL> EscapeCharsAnyURI;
};
} // end namespace
} // end namespace
#endif