#ifndef __C_COLLADA_MESH_FILE_LOADER_H_INCLUDED__
#define __C_COLLADA_MESH_FILE_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "IFileSystem.h"
#include "IVideoDriver.h"
#include "irrString.h"
#include "SMesh.h"
#include "SMeshBuffer.h"
#include "ISceneManager.h"
#include "irrMap.h"
#include "CAttributes.h"
namespace irr
{
namespace scene
{
#ifdef _DEBUG
#endif
class IColladaPrefab;
enum ECOLLADA_PARAM_NAME
{
ECPN_COLOR = 0,
ECPN_AMBIENT,
ECPN_DIFFUSE,
ECPN_SPECULAR,
ECPN_SHININESS,
ECPN_TRANSPARENCY,
ECPN_YFOV,
ECPN_ZNEAR,
ECPN_ZFAR,
ECPN_COUNT
};
enum ECOLLADA_PARAM_TYPE
{
ECPT_FLOAT = 0,
ECPT_FLOAT2,
ECPT_FLOAT3,
ECPT_FLOAT4,
ECPT_COUNT
};
struct SColladaParam
{
SColladaParam()
: Name(ECPN_COUNT), Type(ECPT_COUNT)
{
for (int i=0; i<4; ++i) Floats[i] = 0;
}
ECOLLADA_PARAM_NAME Name;
ECOLLADA_PARAM_TYPE Type;
f32 Floats[4];
};
enum ECOLLADA_INPUT_SEMANTIC
{
ECIS_POSITION = 0,
ECIS_VERTEX,
ECIS_NORMAL,
ECIS_TEXCOORD,
ECIS_UV,
ECIS_TANGENT,
ECIS_IMAGE,
ECIS_TEXTURE,
ECIS_COUNT
};
struct SColladaInput
{
SColladaInput()
: Semantic(ECIS_COUNT), Data(0), Offset(0), Set(0), Stride(1)
{
}
ECOLLADA_INPUT_SEMANTIC Semantic;
core::stringc Source;
f32* Data;
u32 Offset;
u32 Set;
u32 Stride;
};
struct SColladaImage
{
core::stringc Id;
core::stringc Source;
core::dimension2du Dimension;
bool SourceIsFilename;
};
struct SColladaTexture
{
video::ITexture* Texture;
core::stringc Id;
};
struct SColladaMaterial
{
video::SMaterial Mat;
core::stringc Id;
core::stringc InstanceEffectId;
f32 Transparency;
inline bool operator< (const SColladaMaterial & other) const
{
return Id < other.Id;
}
};
struct SColladaEffect
{
core::stringc Id;
f32 Transparency;
core::array<core::stringc> Textures;
video::SMaterial Mat;
inline bool operator< (const SColladaEffect & other) const
{
return Id < other.Id;
}
};
struct SNumberArray
{
core::stringc Name;
core::array<f32> Data;
};
struct SAccessor
{
SAccessor()
: Count(0), Offset(0), Stride(1) {}
int Count;
int Offset;
int Stride;
core::array<SColladaParam> Parameters;
};
struct SSource
{
core::stringc Id;
SNumberArray Array;
core::array<SAccessor> Accessors;
};
class CScenePrefab;
class CColladaFileLoader : public IMeshLoader
{
public:
CColladaFileLoader(scene::ISceneManager* smgr, io::IFileSystem* fs);
virtual ~CColladaFileLoader();
virtual bool isALoadableFileExtension(const io::path& filename) const;
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
private:
void skipSection(io::IXMLReaderUTF8* reader, bool reportSkipping);
void readColladaSection(io::IXMLReaderUTF8* reader);
void readLibrarySection(io::IXMLReaderUTF8* reader);
void readVisualSceneLibrary(io::IXMLReaderUTF8* reader);
void readSceneSection(io::IXMLReaderUTF8* reader);
void readAssetSection(io::IXMLReaderUTF8* reader);
void readNodeSection(io::IXMLReaderUTF8* reader, scene::ISceneNode* parent, CScenePrefab* p=0);
core::matrix4 readLookAtNode(io::IXMLReaderUTF8* reader);
core::matrix4 readMatrixNode(io::IXMLReaderUTF8* reader);
core::matrix4 readPerspectiveNode(io::IXMLReaderUTF8* reader);
core::matrix4 readRotateNode(io::IXMLReaderUTF8* reader);
core::matrix4 readSkewNode(io::IXMLReaderUTF8* reader);
void readBboxNode(io::IXMLReaderUTF8* reader, core::aabbox3df& bbox);
core::matrix4 readScaleNode(io::IXMLReaderUTF8* reader);
core::matrix4 readTranslateNode(io::IXMLReaderUTF8* reader);
video::SColorf readColorNode(io::IXMLReaderUTF8* reader);
f32 readFloatNode(io::IXMLReaderUTF8* reader);
void readInstanceNode(io::IXMLReaderUTF8* reader,
scene::ISceneNode* parent, scene::ISceneNode** outNode,
CScenePrefab* p=0, const core::stringc& type=core::stringc());
void instantiateNode(scene::ISceneNode* parent, scene::ISceneNode** outNode=0,
CScenePrefab* p=0, const core::stringc& url="",
const core::stringc& type=core::stringc());
void readLightPrefab(io::IXMLReaderUTF8* reader);
void readCameraPrefab(io::IXMLReaderUTF8* reader);
void readImage(io::IXMLReaderUTF8* reader);
void readTexture(io::IXMLReaderUTF8* reader);
void readMaterial(io::IXMLReaderUTF8* reader);
void readEffect(io::IXMLReaderUTF8* reader, SColladaEffect * effect = 0);
void readGeometry(io::IXMLReaderUTF8* reader);
inline f32 readFloat(const c8** p);
inline s32 readInt(const c8** p);
void findNextNoneWhiteSpace(const c8** p);
void readFloatsInsideElement(io::IXMLReaderUTF8* reader, f32* floats, u32 count);
void readIntsInsideElement(io::IXMLReaderUTF8* reader, s32* ints, u32 count);
void clearData();
void readColladaParameters(io::IXMLReaderUTF8* reader, const core::stringc& parentName);
SColladaParam* getColladaParameter(ECOLLADA_PARAM_NAME name);
void readColladaInputs(io::IXMLReaderUTF8* reader, const core::stringc& parentName);
void readColladaInput(io::IXMLReaderUTF8* reader, core::array<SColladaInput>& inputs);
SColladaInput* getColladaInput(ECOLLADA_INPUT_SEMANTIC input);
core::stringc readId(io::IXMLReaderUTF8* reader);
void uriToId(core::stringc& str);
void readPolygonSection(io::IXMLReaderUTF8* reader,
core::array<SSource>& sources, scene::SMesh* mesh,
const core::stringc& geometryId);
const SColladaMaterial * findMaterial(const core::stringc & materialName);
void readBindMaterialSection(io::IXMLReaderUTF8* reader, const core::stringc & id);
video::ITexture* getTextureFromImage(core::stringc uri);
void readParameter(io::IXMLReaderUTF8* reader);
scene::ISceneManager* SceneManager;
io::IFileSystem* FileSystem;
scene::IAnimatedMesh* DummyMesh;
core::stringc CurrentlyLoadingMesh;
scene::IAnimatedMesh* FirstLoadedMesh;
io::path FirstLoadedMeshName;
s32 LoadedMeshCount;
u32 Version;
bool FlipAxis;
core::array<IColladaPrefab*> Prefabs;
core::array<SColladaParam> ColladaParameters;
core::array<SColladaImage> Images;
core::array<SColladaTexture> Textures;
core::array<SColladaMaterial> Materials;
core::array<SColladaInput> Inputs;
core::array<SColladaEffect> Effects;
core::map<core::stringc,u32> MaterialsToBind;
core::array< core::array<irr::scene::IMeshBuffer*> > MeshesToBind;
io::CAttributes Parameters;
bool CreateInstances;
};
class IColladaPrefab : public virtual IReferenceCounted
{
public:
virtual scene::ISceneNode* addInstance(scene::ISceneNode* parent,
scene::ISceneManager* mgr) = 0;
virtual const core::stringc& getId() = 0;
};
}
}
#endif