#ifndef __C_OGRE_MESH_FILE_LOADER_H_INCLUDED__
#define __C_OGRE_MESH_FILE_LOADER_H_INCLUDED__
#include "IMeshLoader.h"
#include "IFileSystem.h"
#include "IVideoDriver.h"
#include "irrString.h"
#include "SMesh.h"
#include "SMeshBuffer.h"
#include "SMeshBufferLightMap.h"
#include "IMeshManipulator.h"
#include "matrix4.h"
#include "quaternion.h"
#include "CSkinnedMesh.h"
namespace irr
{
namespace scene
{
class COgreMeshFileLoader : public IMeshLoader
{
public:
COgreMeshFileLoader(io::IFileSystem* fs, video::IVideoDriver* driver);
virtual ~COgreMeshFileLoader();
virtual bool isALoadableFileExtension(const io::path& filename) const;
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
private:
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
#elif defined( __GNUC__ )
# define PACK_STRUCT __attribute__((packed))
#else
# error compiler not supported
#endif
struct ChunkHeader
{
u16 id;
u32 length;
} PACK_STRUCT;
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
struct ChunkData
{
ChunkData() : read(0) {}
ChunkHeader header;
u32 read;
};
struct OgreTexture
{
OgreTexture() : Filename("") {}
core::stringc Filename;
core::stringc Alias;
core::stringc CoordsType;
core::stringc MipMaps;
core::stringc Alpha;
};
struct OgrePass
{
OgrePass() : AmbientTokenColor(false),
DiffuseTokenColor(false), SpecularTokenColor(false),
EmissiveTokenColor(false),
MaxLights(8), PointSize(1.0f), PointSprites(false),
PointSizeMin(0), PointSizeMax(0) {}
video::SMaterial Material;
OgreTexture Texture;
bool AmbientTokenColor;
bool DiffuseTokenColor;
bool SpecularTokenColor;
bool EmissiveTokenColor;
u32 MaxLights;
f32 PointSize;
bool PointSprites;
u32 PointSizeMin;
u32 PointSizeMax;
};
struct OgreTechnique
{
OgreTechnique() : Name(""), LODIndex(0) {}
core::stringc Name;
core::stringc Scheme;
u16 LODIndex;
core::array<OgrePass> Passes;
};
struct OgreMaterial
{
OgreMaterial() : Name(""), ReceiveShadows(true),
TransparencyCastsShadows(false) {}
core::stringc Name;
bool ReceiveShadows;
bool TransparencyCastsShadows;
core::array<f32> LODDistances;
core::array<OgreTechnique> Techniques;
};
struct OgreVertexBuffer
{
OgreVertexBuffer() : BindIndex(0), VertexSize(0), Data(0) {}
u16 BindIndex;
u16 VertexSize;
core::array<f32> Data;
};
struct OgreVertexElement
{
u16 Source,
Type,
Semantic,
Offset,
Index;
};
struct OgreGeometry
{
s32 NumVertex;
core::array<OgreVertexElement> Elements;
core::array<OgreVertexBuffer> Buffers;
core::array<core::vector3df> Vertices;
core::array<core::vector3df> Normals;
core::array<s32> Colors;
core::array<core::vector2df> TexCoords;
};
struct OgreTextureAlias
{
OgreTextureAlias() {};
OgreTextureAlias(const core::stringc& a, const core::stringc& b) : Texture(a), Alias(b) {};
core::stringc Texture;
core::stringc Alias;
};
struct OgreBoneAssignment
{
s32 VertexID;
u16 BoneID;
f32 Weight;
};
struct OgreSubMesh
{
core::stringc Material;
bool SharedVertices;
core::array<s32> Indices;
OgreGeometry Geometry;
u16 Operation;
core::array<OgreTextureAlias> TextureAliases;
core::array<OgreBoneAssignment> BoneAssignments;
bool Indices32Bit;
};
struct OgreMesh
{
bool SkeletalAnimation;
OgreGeometry Geometry;
core::array<OgreSubMesh> SubMeshes;
core::array<OgreBoneAssignment> BoneAssignments;
core::vector3df BBoxMinEdge;
core::vector3df BBoxMaxEdge;
f32 BBoxRadius;
};
struct OgreBone
{
core::stringc Name;
core::vector3df Position;
core::quaternion Orientation;
core::vector3df Scale;
u16 Handle;
u16 Parent;
};
struct OgreKeyframe
{
u16 BoneID;
f32 Time;
core::vector3df Position;
core::quaternion Orientation;
core::vector3df Scale;
};
struct OgreAnimation
{
core::stringc Name;
f32 Length;
core::array<OgreKeyframe> Keyframes;
};
struct OgreSkeleton
{
core::array<OgreBone> Bones;
core::array<OgreAnimation> Animations;
};
bool readChunk(io::IReadFile* file);
bool readObjectChunk(io::IReadFile* file, ChunkData& parent, OgreMesh& mesh);
bool readGeometry(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry);
bool readVertexDeclaration(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry);
bool readVertexBuffer(io::IReadFile* file, ChunkData& parent, OgreGeometry& geometry);
bool readSubMesh(io::IReadFile* file, ChunkData& parent, OgreSubMesh& subMesh);
void readChunkData(io::IReadFile* file, ChunkData& data);
void readString(io::IReadFile* file, ChunkData& data, core::stringc& out);
void readBool(io::IReadFile* file, ChunkData& data, bool& out);
void readInt(io::IReadFile* file, ChunkData& data, s32* out, u32 num=1);
void readShort(io::IReadFile* file, ChunkData& data, u16* out, u32 num=1);
void readFloat(io::IReadFile* file, ChunkData& data, f32* out, u32 num=1);
void readVector(io::IReadFile* file, ChunkData& data, core::vector3df& out);
void readQuaternion(io::IReadFile* file, ChunkData& data, core::quaternion& out);
void composeMeshBufferMaterial(scene::IMeshBuffer* mb, const core::stringc& materialName);
scene::SMeshBuffer* composeMeshBuffer(const core::array<s32>& indices, const OgreGeometry& geom);
scene::SMeshBufferLightMap* composeMeshBufferLightMap(const core::array<s32>& indices, const OgreGeometry& geom);
scene::IMeshBuffer* composeMeshBufferSkinned(scene::CSkinnedMesh& mesh, const core::array<s32>& indices, const OgreGeometry& geom);
void composeObject(void);
bool readColor(io::IReadFile* meshFile, video::SColor& col);
void getMaterialToken(io::IReadFile* file, core::stringc& token, bool noNewLine=false);
void readTechnique(io::IReadFile* meshFile, OgreMaterial& mat);
void readPass(io::IReadFile* file, OgreTechnique& technique);
void loadMaterials(io::IReadFile* file);
bool loadSkeleton(io::IReadFile* meshFile, const core::stringc& name);
void clearMeshes();
io::IFileSystem* FileSystem;
video::IVideoDriver* Driver;
core::stringc Version;
bool SwapEndian;
core::array<OgreMesh> Meshes;
io::path CurrentlyLoadingFromPath;
core::array<OgreMaterial> Materials;
OgreSkeleton Skeleton;
IMesh* Mesh;
u32 NumUV;
};
}
}
#endif