2012-02-20 10:27:27 +00:00
# include "BaseImporter.h"
# include <vector>
# include "OgreXmlHelper.hpp"
# include "irrXMLWrapper.h"
namespace Assimp
{
namespace Ogre
{
//Forward declarations:
struct Face ;
struct Weight ;
struct Bone ;
struct Animation ;
struct Track ;
struct Keyframe ;
2012-03-07 22:42:40 +00:00
///A submesh from Ogre
struct SubMesh
{
2012-03-13 16:29:29 +00:00
bool SharedData ;
2012-03-07 22:42:40 +00:00
std : : string Name ;
std : : string MaterialName ;
std : : vector < Face > FaceList ;
std : : vector < aiVector3D > Positions ; bool HasPositions ;
std : : vector < aiVector3D > Normals ; bool HasNormals ;
std : : vector < aiVector3D > Tangents ; bool HasTangents ;
std : : vector < aiVector3D > Uvs ; unsigned int NumUvs ; //nearly always 2d, but assimp has always 3d texcoords
std : : vector < std : : vector < Weight > > Weights ; //a list of bones for each vertex
int MaterialIndex ; ///< The Index in the Assimp Materialarray from the material witch is attached to this submesh
unsigned int BonesUsed ; //the highest index of a bone from a bone weight, this is needed to create the assimp bone structur (converting from Vertex-Bones to Bone-Vertices)
2012-03-13 16:29:29 +00:00
SubMesh ( ) : SharedData ( false ) , HasPositions ( false ) , HasNormals ( false ) , HasTangents ( false ) ,
2012-03-07 22:42:40 +00:00
NumUvs ( 0 ) , MaterialIndex ( - 1 ) , BonesUsed ( 0 ) { } //initialize everything
} ;
2012-02-20 10:27:27 +00:00
///The Main Ogre Importer Class
class OgreImporter : public BaseImporter
{
public :
virtual bool CanRead ( const std : : string & pFile , IOSystem * pIOHandler , bool checkSig ) const ;
virtual void InternReadFile ( const std : : string & pFile , aiScene * pScene , IOSystem * pIOHandler ) ;
virtual void GetExtensionList ( std : : set < std : : string > & extensions ) ;
virtual void SetupProperties ( const Importer * pImp ) ;
private :
2012-03-13 16:29:29 +00:00
//-------------------------------- OgreMesh.cpp -------------------------------
2012-02-20 10:27:27 +00:00
/// Helper Functions to read parts of the XML File
void ReadSubMesh ( SubMesh & theSubMesh , XmlReader * Reader ) ; //the submesh reference is the result value
/// Reads a single Vertexbuffer and writes its data in the Submesh
static void ReadVertexBuffer ( SubMesh & theSubMesh , XmlReader * Reader , unsigned int NumVertices ) ;
2012-03-13 16:29:29 +00:00
/// Reads bone weights are stores them into the given submesh
static void ReadBoneWeights ( SubMesh & theSubMesh , XmlReader * Reader ) ;
2012-02-20 10:27:27 +00:00
2012-03-13 16:29:29 +00:00
/// After Loading a SubMehs some work needs to be done (make all Vertexes unique, normalize weights)
2012-03-18 03:22:05 +00:00
static void ProcessSubMesh ( SubMesh & theSubMesh , SubMesh & theSharedGeometry ) ;
2012-02-20 10:27:27 +00:00
2012-03-13 16:29:29 +00:00
/// Uses the bone data to convert a SubMesh into a aiMesh which will be created and returned
2012-02-20 10:27:27 +00:00
aiMesh * CreateAssimpSubMesh ( const SubMesh & theSubMesh , const std : : vector < Bone > & Bones ) const ;
2012-03-13 16:29:29 +00:00
//-------------------------------- OgreSkeleton.cpp -------------------------------
/// Writes the results in Bones and Animations, Filename is not const, because its call-by-value and the function will change it!
void LoadSkeleton ( std : : string FileName , std : : vector < Bone > & Bones , std : : vector < Animation > & Animations ) const ;
2012-02-20 10:27:27 +00:00
2012-03-13 16:29:29 +00:00
/// Converts the animations in aiAnimations and puts them into the scene
void PutAnimationsInScene ( const std : : vector < Bone > & Bones , const std : : vector < Animation > & Animations ) ;
/// Creates the aiskeleton in current scene
2012-02-20 10:27:27 +00:00
void CreateAssimpSkeleton ( const std : : vector < Bone > & Bones , const std : : vector < Animation > & Animations ) ;
2012-03-13 16:29:29 +00:00
/// Recursivly creates a filled aiNode from a given root bone
static aiNode * CreateAiNodeFromBone ( int BoneId , const std : : vector < Bone > & Bones , aiNode * ParentNode ) ;
//-------------------------------- OgreMaterial.cpp -------------------------------
2012-02-20 10:27:27 +00:00
aiMaterial * LoadMaterial ( const std : : string MaterialName ) const ;
static void ReadTechnique ( std : : stringstream & ss , aiMaterial * NewMaterial ) ;
2012-03-13 16:29:29 +00:00
2012-02-20 10:27:27 +00:00
//Now we don't have to give theses parameters to all functions
std : : string m_CurrentFilename ;
std : : string m_MaterialLibFilename ;
IOSystem * m_CurrentIOHandler ;
aiScene * m_CurrentScene ;
2012-03-07 22:42:40 +00:00
SubMesh m_SharedGeometry ; ///< we will just use the vertexbuffers of the submesh
2012-02-20 10:27:27 +00:00
} ;
///For the moment just triangles, no other polygon types!
struct Face
{
unsigned int VertexIndices [ 3 ] ;
} ;
struct BoneAssignment
{
unsigned int BoneId ; //this is, what we get from ogre
std : : string BoneName ; //this is, what we need for assimp
} ;
///for a vertex->bone structur
struct Weight
{
unsigned int BoneId ;
float Value ;
} ;
/// Helper Class to describe an ogre-bone for the skeleton:
/** All Id's are signed ints, because than we have -1 as a simple INVALID_ID Value (we start from 0 so 0 is a valid bone ID!*/
struct Bone
{
int Id ;
int ParentId ;
std : : string Name ;
aiVector3D Position ;
float RotationAngle ;
aiVector3D RotationAxis ;
std : : vector < int > Children ;
aiMatrix4x4 BoneToWorldSpace ;
///ctor
Bone ( ) : Id ( - 1 ) , ParentId ( - 1 ) , RotationAngle ( 0.0f ) { }
///this operator is needed to sort the bones after Id's
bool operator < ( const Bone & rval ) const
{ return Id < rval . Id ; }
///this operator is needed to find a bone by its name in a vector<Bone>
bool operator = = ( const std : : string & rval ) const
{ return Name = = rval ; }
bool operator = = ( const aiString & rval ) const
{ return Name = = std : : string ( rval . data ) ; }
2012-03-13 16:29:29 +00:00
// implemented in OgreSkeleton.cpp
2012-02-20 10:27:27 +00:00
void CalculateBoneToWorldSpaceMatrix ( std : : vector < Bone > & Bones ) ;
} ;
///Describes an Ogre Animation
struct Animation
{
std : : string Name ;
float Length ;
std : : vector < Track > Tracks ;
} ;
///a track (keyframes for one bone) from an animation
struct Track
{
std : : string BoneName ;
std : : vector < Keyframe > Keyframes ;
} ;
/// keyframe (bone transformation) from a track from a animation
struct Keyframe
{
float Time ;
aiVector3D Position ;
aiQuaternion Rotation ;
aiVector3D Scaling ;
} ;
} //namespace Ogre
} //namespace Assimp