2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
# include "BaseImporter.h"
2012-02-20 10:27:27 +00:00
# include "OgreXmlHelper.hpp"
# include "irrXMLWrapper.h"
2014-04-30 02:43:13 +00:00
# include <vector>
2012-03-21 08:49:46 +00:00
2012-02-20 10:27:27 +00:00
namespace Assimp
{
namespace Ogre
{
struct Face ;
2014-04-30 02:43:13 +00:00
struct BoneWeight ;
2012-02-20 10:27:27 +00:00
struct Bone ;
struct Animation ;
2014-04-30 02:43:13 +00:00
/// Ogre SubMesh
2012-03-07 22:42:40 +00:00
struct SubMesh
2014-04-30 02:43:13 +00:00
{
bool UseSharedGeometry ;
bool Use32bitIndexes ;
2012-03-13 16:29:29 +00:00
2012-03-07 22:42:40 +00:00
std : : string Name ;
std : : string MaterialName ;
2014-04-30 02:43:13 +00:00
bool HasGeometry ;
bool HasPositions ;
bool HasNormals ;
bool HasTangents ;
std : : vector < Face > Faces ;
std : : vector < aiVector3D > Positions ;
std : : vector < aiVector3D > Normals ;
std : : vector < aiVector3D > Tangents ;
/// Arbitrary number of texcoords, they are nearly always 2d, but Assimp has always 3d texcoords, n vectors(outer) with texcoords for each vertex(inner).
std : : vector < std : : vector < aiVector3D > > Uvs ;
/// A list(inner) of bones for each vertex(outer).
std : : vector < std : : vector < BoneWeight > > Weights ;
/// The Index in the Assimp material array from the material witch is attached to this submesh.
int MaterialIndex ;
// The highest index of a bone from a bone weight, this is needed to create the Assimp bone struct. Converting from vertex-bones to bone-vertices.
unsigned int BonesUsed ;
SubMesh ( ) :
UseSharedGeometry ( false ) ,
Use32bitIndexes ( false ) ,
HasGeometry ( false ) ,
HasPositions ( false ) ,
HasNormals ( false ) ,
HasTangents ( false ) ,
MaterialIndex ( - 1 ) ,
BonesUsed ( 0 )
{
}
2012-03-07 22:42:40 +00:00
} ;
2014-04-30 02:52:59 +00:00
/** Importer for Ogre mesh, skeleton and material formats.
@ todo Support vertex colors
@ todo Support multiple TexCoords ( this is already done ? ? ) */
2012-02-20 10:27:27 +00:00
class OgreImporter : public BaseImporter
{
public :
2014-04-30 02:43:13 +00:00
/// BaseImporter override.
virtual bool CanRead ( const std : : string & pFile , IOSystem * pIOHandler , bool checkSig ) const ;
/// BaseImporter override.
virtual void InternReadFile ( const std : : string & pFile , aiScene * pScene , IOSystem * pIOHandler ) ;
/// BaseImporter override.
2012-04-22 22:26:26 +00:00
virtual const aiImporterDesc * GetInfo ( ) const ;
2014-04-30 02:43:13 +00:00
/// BaseImporter override.
2012-02-20 10:27:27 +00:00
virtual void SetupProperties ( const Importer * pImp ) ;
2012-03-13 16:29:29 +00:00
2014-04-30 02:43:13 +00:00
private :
2012-03-13 16:29:29 +00:00
//-------------------------------- OgreMesh.cpp -------------------------------
2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
/// Helper Functions to read parts of the XML File.
void ReadSubMesh ( const unsigned int submeshIndex , SubMesh & submesh , XmlReader * reader ) ;
2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
/// Reads a single Vertexbuffer and writes its data in the Submesh.
static void ReadVertexBuffer ( SubMesh & submesh , XmlReader * reader , const unsigned int numVertices ) ;
2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
/// Reads bone weights are stores them into the given submesh.
static void ReadBoneWeights ( SubMesh & submesh , XmlReader * reader ) ;
2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
/// After Loading a SubMehs some work needs to be done (make all Vertexes unique, normalize weights).
static void ProcessSubMesh ( SubMesh & submesh , SubMesh & sharedGeometry ) ;
/// Uses the bone data to convert a SubMesh into a aiMesh which will be created and returned.
2014-05-01 13:33:15 +00:00
aiMesh * CreateAssimpSubMesh ( aiScene * pScene , const SubMesh & submesh , const std : : vector < Bone > & bones ) const ;
2012-03-13 16:29:29 +00:00
//-------------------------------- OgreSkeleton.cpp -------------------------------
2014-04-30 02:43:13 +00:00
2012-03-13 16:29:29 +00:00
/// Writes the results in Bones and Animations, Filename is not const, because its call-by-value and the function will change it!
2014-05-01 13:33:15 +00:00
void ReadSkeleton ( const std : : string & pFile , Assimp : : IOSystem * pIOHandler , const aiScene * pScene ,
const std : : string & skeletonFile , std : : vector < Bone > & Bones , std : : vector < Animation > & Animations ) const ;
2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
/// Converts the animations in aiAnimations and puts them into the scene.
2014-05-01 13:33:15 +00:00
void PutAnimationsInScene ( aiScene * pScene , const std : : vector < Bone > & Bones , const std : : vector < Animation > & Animations ) ;
2012-03-13 16:29:29 +00:00
2014-04-30 02:43:13 +00:00
/// Creates the aiSkeleton in current scene.
2014-05-01 13:33:15 +00:00
void CreateAssimpSkeleton ( aiScene * pScene , const std : : vector < Bone > & Bones , const std : : vector < Animation > & Animations ) ;
2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
/// Recursivly creates a filled aiNode from a given root bone.
2012-03-13 16:29:29 +00:00
static aiNode * CreateAiNodeFromBone ( int BoneId , const std : : vector < Bone > & Bones , aiNode * ParentNode ) ;
//-------------------------------- OgreMaterial.cpp -------------------------------
2014-04-30 02:43:13 +00:00
2014-05-01 13:33:15 +00:00
/// Reads material
aiMaterial * ReadMaterial ( const std : : string & pFile , Assimp : : IOSystem * pIOHandler , const std : : string MaterialName ) ;
// These functions parse blocks from a material file from @c ss. Starting parsing from "{" and ending it to "}".
bool ReadTechnique ( const std : : string & techniqueName , std : : stringstream & ss , aiMaterial * material ) ;
bool ReadPass ( const std : : string & passName , std : : stringstream & ss , aiMaterial * material ) ;
bool ReadTextureUnit ( const std : : string & textureUnitName , std : : stringstream & ss , aiMaterial * material ) ;
2012-03-13 16:29:29 +00:00
2014-04-30 02:43:13 +00:00
// Now we don't have to give theses parameters to all functions
/// @todo Remove this m_Current* bookkeeping.
2014-05-01 13:33:15 +00:00
std : : string m_userDefinedMaterialLibFile ;
bool m_detectTextureTypeFromFilename ;
2012-03-07 22:42:40 +00:00
SubMesh m_SharedGeometry ; ///< we will just use the vertexbuffers of the submesh
2014-05-01 13:33:15 +00:00
std : : map < aiTextureType , unsigned int > m_textures ;
2012-02-20 10:27:27 +00:00
} ;
2014-04-30 02:43:13 +00:00
/// Simplified face.
/** @todo Support other polygon types than just just triangles. Move to using aiFace. */
2012-02-20 10:27:27 +00:00
struct Face
{
unsigned int VertexIndices [ 3 ] ;
} ;
2014-04-30 02:43:13 +00:00
/// Ogre Bone assignment
2012-02-20 10:27:27 +00:00
struct BoneAssignment
{
2014-04-30 02:43:13 +00:00
/// Bone ID from Ogre.
unsigned int BoneId ;
// Bone name for Assimp.
std : : string BoneName ;
2012-02-20 10:27:27 +00:00
} ;
2014-04-30 02:43:13 +00:00
/// Ogre Bone weight
struct BoneWeight
2012-02-20 10:27:27 +00:00
{
2014-04-30 02:43:13 +00:00
/// Bone ID
unsigned int Id ;
/// BoneWeight
2012-02-20 10:27:27 +00:00
float Value ;
} ;
/// Helper Class to describe an ogre-bone for the skeleton:
2014-04-30 02:43:13 +00:00
/** 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!
@ todo Cleanup if possible . Seems like this is overly complex for what we are reading . */
2012-02-20 10:27:27 +00:00
struct Bone
{
2014-04-30 02:43:13 +00:00
std : : string Name ;
2012-02-20 10:27:27 +00:00
int Id ;
int ParentId ;
2014-04-30 02:43:13 +00:00
2012-02-20 10:27:27 +00:00
aiVector3D Position ;
aiVector3D RotationAxis ;
2014-04-30 02:43:13 +00:00
float RotationAngle ;
2012-02-20 10:27:27 +00:00
aiMatrix4x4 BoneToWorldSpace ;
2014-04-30 02:43:13 +00:00
std : : vector < int > Children ;
2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
Bone ( ) :
Id ( - 1 ) ,
ParentId ( - 1 ) ,
RotationAngle ( 0.0f )
{
}
2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
/// This operator is needed to sort the bones after Id's
bool operator < ( const Bone & other ) const { return Id < other . Id ; }
2012-02-20 10:27:27 +00:00
2014-04-30 02:43:13 +00:00
/// This operator is needed to find a bone by its name in a vector<Bone>
bool operator = = ( const std : : string & other ) const { return Name = = other ; }
bool operator = = ( const aiString & other ) const { return Name = = std : : string ( other . data ) ; }
/// @note Implemented in OgreSkeleton.cpp
void CalculateBoneToWorldSpaceMatrix ( std : : vector < Bone > & Bones ) ;
} ;
/// Ogre animation key frame
/** Transformations for a frame. */
struct KeyFrame
2012-02-20 10:27:27 +00:00
{
2014-04-30 02:43:13 +00:00
float Time ;
aiVector3D Position ;
aiQuaternion Rotation ;
aiVector3D Scaling ;
2012-02-20 10:27:27 +00:00
} ;
2014-04-30 02:43:13 +00:00
/// Ogre animation track
/** Keyframes for one bone. */
2012-02-20 10:27:27 +00:00
struct Track
{
std : : string BoneName ;
2014-04-30 02:43:13 +00:00
std : : vector < KeyFrame > Keyframes ;
2012-02-20 10:27:27 +00:00
} ;
2014-04-30 02:43:13 +00:00
/// Ogre animation
struct Animation
2012-02-20 10:27:27 +00:00
{
2014-04-30 02:43:13 +00:00
/// Name
std : : string Name ;
/// Length
float Length ;
/// Tracks
std : : vector < Track > Tracks ;
2012-02-20 10:27:27 +00:00
} ;
} //namespace Ogre
} //namespace Assimp