summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/code/OgreImporter.hpp
blob: a24d1fc3f0337262edf4496f4eed8250bf5b619d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include "BaseImporter.h"

#include <vector>

#include "OgreXmlHelper.hpp"
#include "irrXMLWrapper.h"

/// Ogre Importer TODO
/*	- Read Vertex Colors
	- Read multiple TexCoords
*/



namespace Assimp
{
namespace Ogre
{


//Forward declarations:
struct Face;
struct Weight;
struct Bone;
struct Animation;
struct Track;
struct Keyframe;

///A submesh from Ogre
struct SubMesh
{	
	bool SharedData;

	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<std::vector<aiVector3D> > Uvs;//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<Weight> > Weights;//a list(inner) of bones for each vertex(outer)
	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)

	SubMesh(): SharedData(false), HasPositions(false), HasNormals(false), HasTangents(false),
		MaterialIndex(-1), BonesUsed(0) {}//initialize everything
};


///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 const aiImporterDesc* GetInfo () const;
	virtual void SetupProperties(const Importer* pImp);
private:


	//-------------------------------- OgreMesh.cpp -------------------------------
	/// 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);

	/// Reads bone weights are stores them into the given submesh
	static void ReadBoneWeights(SubMesh &theSubMesh, XmlReader *Reader);

	/// After Loading a SubMehs some work needs to be done (make all Vertexes unique, normalize weights)
	static void ProcessSubMesh(SubMesh &theSubMesh, SubMesh &theSharedGeometry);

	/// Uses the bone data to convert a SubMesh into a aiMesh which will be created and returned
	aiMesh* CreateAssimpSubMesh(const SubMesh &theSubMesh, const std::vector<Bone>& Bones) const;
	

	//-------------------------------- 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;

	/// 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
	void CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations);

	/// Recursivly creates a filled aiNode from a given root bone
	static aiNode* CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode);
	

	//-------------------------------- OgreMaterial.cpp -------------------------------
	aiMaterial* LoadMaterial(const std::string MaterialName) const;
	void ReadTechnique(std::stringstream &ss, aiMaterial* NewMaterial) const;
	



	//Now we don't have to give theses parameters to all functions
	std::string m_CurrentFilename;
	std::string m_MaterialLibFilename;
	bool m_TextureTypeFromFilename;
	IOSystem* m_CurrentIOHandler;
	aiScene *m_CurrentScene;
	SubMesh m_SharedGeometry;///< we will just use the vertexbuffers of the submesh
};

///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); }

	// implemented in OgreSkeleton.cpp
	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