2
0
Эх сурвалжийг харах

Implemented anims/bones

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@427 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
marksibly 16 жил өмнө
parent
commit
a241829149
2 өөрчлөгдсөн 396 нэмэгдсэн , 147 устгасан
  1. 362 132
      code/B3DImporter.cpp
  2. 34 15
      code/B3DImporter.h

+ 362 - 132
code/B3DImporter.cpp

@@ -54,6 +54,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 using namespace Assimp;
 using namespace std;
 
+//#define DEBUG_B3D
+
 // ------------------------------------------------------------------------------------------------
 bool B3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const{
 
@@ -71,9 +73,20 @@ void B3DImporter::GetExtensionList( std::string& append ){
 	append.append("*.b3d");
 }
 
+#ifdef DEBUG_B3D
+	extern "C"{ void _stdcall AllocConsole(); }
+#endif
 // ------------------------------------------------------------------------------------------------
 void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler){
 
+#ifdef DEBUG_B3D
+	AllocConsole();
+	freopen( "conin$","r",stdin );
+	freopen( "conout$","w",stdout );
+	freopen( "conout$","w",stderr );
+	cout<<"Hello world from the B3DImporter!"<<endl;
+#endif
+
 	boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
 
 	// Check whether we can read from the file
@@ -89,57 +102,27 @@ void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
 	_buf.resize( fileSize );
 	file->Read( &_buf[0],1,fileSize );
 	_stack.clear();
-	_textures.clear();
-	_materials.size();
-	_vertices.clear();
-	_meshes.clear();
 
-	ReadBB3D();
-	
-	//materials
-	if( _materials.size() ){
-		aiMaterial **mats=new aiMaterial*[_materials.size()];
-		for( unsigned i=0;i<_materials.size();++i ){
-			mats[i]=_materials[i];
-		}
-		pScene->mNumMaterials=_materials.size();
-		pScene->mMaterials=mats;
-	}
-	
-	//meshes
-	if( _meshes.size() ){
-		aiMesh **meshes=new aiMesh*[_meshes.size()];
-		for( unsigned i=0;i<_meshes.size();++i ){
-			meshes[i]=_meshes[i];
-		}
-		pScene->mNumMeshes=_meshes.size();
-		pScene->mMeshes=meshes;
-	}else{
-		throw new ImportErrorException( "B3D: No meshes loaded" );
-	}
-
-	//create root node
-	aiNode *node=new aiNode( "root" );
-	
-	node->mNumMeshes=_meshes.size();
-	node->mMeshes=new unsigned[_meshes.size()];
-	for( unsigned i=0;i<_meshes.size();++i ){
-		node->mMeshes[i]=i;
-	}
-	pScene->mRootNode=node;
+	ReadBB3D( pScene );
+}
 
-	// convert to RH
-	MakeLeftHandedProcess monster_maker;
-	monster_maker.Execute(pScene);
+// ------------------------------------------------------------------------------------------------
+void B3DImporter::Oops(){
+	throw new ImportErrorException( "B3D Importer - INTERNAL ERROR" );
+}
 
-	FlipWindingOrderProcess flipper;
-	flipper.Execute(pScene);
+// ------------------------------------------------------------------------------------------------
+void B3DImporter::Fail( string str ){
+#ifdef DEBUG_B3D
+	cout<<"Error in B3D file data: "<<str<<endl;
+#endif
+	throw new ImportErrorException( "B3D Importer - error in B3D file data: "+str );
 }
 
 // ------------------------------------------------------------------------------------------------
 int B3DImporter::ReadByte(){
 	if( _pos<_buf.size() ) return _buf[_pos++];
-	throw new ImportErrorException( "B3D EOF Error" );
+	Fail( "EOF" );
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -149,7 +132,7 @@ int B3DImporter::ReadInt(){
 		_pos+=4;
 		return n;
 	}
-	throw new ImportErrorException( "B3D EOF Error" );
+	Fail( "EOF" );
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -159,34 +142,31 @@ float B3DImporter::ReadFloat(){
 		_pos+=4;
 		return n;
 	}
-	throw new ImportErrorException( "B3D EOF Error" );
+	Fail( "EOF" );
 }
 
 // ------------------------------------------------------------------------------------------------
-B3DImporter::Vec2 B3DImporter::ReadVec2(){
-	Vec2 t;
-	t.x=ReadFloat();
-	t.y=ReadFloat();
-	return t;
+aiVector2D B3DImporter::ReadVec2(){
+	float x=ReadFloat();
+	float y=ReadFloat();
+	return aiVector2D( x,y );
 }
 
 // ------------------------------------------------------------------------------------------------
-B3DImporter::Vec3 B3DImporter::ReadVec3(){
-	Vec3 t;
-	t.x=ReadFloat();
-	t.y=ReadFloat();
-	t.z=ReadFloat();
-	return t;
+aiVector3D B3DImporter::ReadVec3(){
+	float x=ReadFloat();
+	float y=ReadFloat();
+	float z=ReadFloat();
+	return aiVector3D( x,y,z );
 }
 
 // ------------------------------------------------------------------------------------------------
-B3DImporter::Vec4 B3DImporter::ReadVec4(){
-	Vec4 t;
-	t.x=ReadFloat();
-	t.y=ReadFloat();
-	t.z=ReadFloat();
-	t.w=ReadFloat();
-	return t;
+aiQuaternion B3DImporter::ReadQuat(){
+	float w=ReadFloat();
+	float x=ReadFloat();
+	float y=ReadFloat();
+	float z=ReadFloat();
+	return aiQuaternion( w,x,y,z );
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -197,7 +177,7 @@ string B3DImporter::ReadString(){
 		if( !c ) return str;
 		str+=c;
 	}
-	throw new ImportErrorException( "B3D EOF Error" );
+	Fail( "EOF" );
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -206,7 +186,9 @@ string B3DImporter::ReadChunk(){
 	for( int i=0;i<4;++i ){
 		tag+=char( ReadByte() );
 	}
+#ifdef DEBUG_B3D
 //	cout<<"ReadChunk:"<<tag<<endl;
+#endif
 	unsigned sz=(unsigned)ReadInt();
 	_stack.push_back( _pos+sz );
 	return tag;
@@ -222,6 +204,17 @@ void B3DImporter::ExitChunk(){
 unsigned B3DImporter::ChunkSize(){
 	return _stack.back()-_pos;
 }
+// ------------------------------------------------------------------------------------------------
+
+template<class T>
+T *B3DImporter::to_array( const vector<T> &v ){
+	if( !v.size() ) return 0;
+	T *p=new T[v.size()];
+	for( int i=0;i<v.size();++i ){
+		p[i]=v[i];
+	}
+	return p;
+}
 
 // ------------------------------------------------------------------------------------------------
 void B3DImporter::ReadTEXS(){
@@ -229,22 +222,24 @@ void B3DImporter::ReadTEXS(){
 		string name=ReadString();
 		int flags=ReadInt();
 		int blend=ReadInt();
-		Vec2 pos=ReadVec2();
-		Vec2 scale=ReadVec2();
+		aiVector2D pos=ReadVec2();
+		aiVector2D scale=ReadVec2();
 		float rot=ReadFloat();
 
-		Texture tex;
-		tex.name=name;
-		_textures.push_back( tex );
+		_textures.push_back( name );
 	}
 }
 
 // ------------------------------------------------------------------------------------------------
 void B3DImporter::ReadBRUS(){
 	int n_texs=ReadInt();
+	if( n_texs<0 || n_texs>8 ){
+		Fail( "Bad texture count" );
+	}
 	while( ChunkSize() ){
 		string name=ReadString();
-		Vec4 color=ReadVec4();
+		aiVector3D color=ReadVec3();
+		float alpha=ReadFloat();
 		float shiny=ReadFloat();
 		int blend=ReadInt();
 		int fx=ReadInt();
@@ -257,11 +252,10 @@ void B3DImporter::ReadBRUS(){
 		mat->AddProperty( &ainame,AI_MATKEY_NAME );
 		
 		// Diffuse color 
-		aiColor3D diffcolor( color.x,color.y,color.z ); 
-		mat->AddProperty( &diffcolor,1,AI_MATKEY_COLOR_DIFFUSE );
+		mat->AddProperty( &color,1,AI_MATKEY_COLOR_DIFFUSE );
 
 		// Opacity
-		mat->AddProperty( &color.w,1,AI_MATKEY_OPACITY );
+		mat->AddProperty( &alpha,1,AI_MATKEY_OPACITY );
 
 		// Specular color
 		aiColor3D speccolor( shiny,shiny,shiny );
@@ -280,10 +274,11 @@ void B3DImporter::ReadBRUS(){
 		//Textures
 		for( int i=0;i<n_texs;++i ){
 			int texid=ReadInt();
-			if( !i && texid>=0 && texid<(int)_textures.size() ){
-				//just use tex 0 for now
-				const Texture &tex=_textures[texid];
-				aiString texname( tex.name );
+			if( texid<-1 || (texid>=0 && texid>=_textures.size()) ){
+				Fail( "Bad texture id" );
+			}
+			if( i==0 && texid>=0 ){
+				aiString texname( _textures[texid] );
 				mat->AddProperty( &texname,AI_MATKEY_TEXTURE_DIFFUSE(0) );
 			}
 		}
@@ -292,75 +287,80 @@ void B3DImporter::ReadBRUS(){
 
 // ------------------------------------------------------------------------------------------------
 void B3DImporter::ReadVRTS(){
-	_vertFlags=ReadInt();
-	_tcSets=ReadInt();
-	_tcSize=ReadInt();
+	_vflags=ReadInt();
+	_tcsets=ReadInt();
+	_tcsize=ReadInt();
+	if( _tcsets<0 || _tcsets>4 || _tcsize<0 || _tcsize>4 ){
+		Fail( "Bad texcoord data" );
+	}
 
-	if( _tcSets<0 || _tcSets>4 || _tcSize<0 || _tcSize>4 ) throw new ImportErrorException( "B3D Param Error" );
+	int sz=12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
+	int n_verts=ChunkSize()/sz;
 
-	while( ChunkSize() ){
-		Vertex vert;
+	_vertices.clear();
+	_vertices.resize( n_verts );
 
-		vert.position=ReadVec3();
+	for( int i=0;i<n_verts;++i ){
+		Vertex &v=_vertices[i];
 
-		if( _vertFlags & 1 ){
-			vert.normal=ReadVec3();
-		}
+		memset( v.bones,0,sizeof(v.bones) );
+		memset( v.weights,0,sizeof(v.weights) );
 
-		if( _vertFlags & 2 ){
-			Vec4 color=ReadVec4();
-		}
+		v.vertex=ReadVec3();
 
-		for( int i=0;i<_tcSets;++i ){
-			float texcoords[4]={0,0,0,0};
-			for( int j=0;j<_tcSize;++j ){
-				texcoords[j]=ReadFloat();
+		if( _vflags & 1 ) v.normal=ReadVec3();
+
+		if( _vflags & 2 ) ReadQuat();	//skip v 4bytes...
+
+		for( int i=0;i<_tcsets;++i ){
+			float t[4]={0,0,0,0};
+			for( int j=0;j<_tcsize;++j ){
+				t[j]=ReadFloat();
 			}
-			texcoords[1]=1-texcoords[1];
-			if( !i ) memcpy( &vert.texcoords.x,texcoords,12 );
+			t[1]=1-t[1];
+			if( !i ) v.texcoords=aiVector3D( t[0],t[1],t[2] );
 		}
-		_vertices.push_back( vert );
 	}
 }
 
 // ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadTRIS(){
+void B3DImporter::ReadTRIS( int v0 ){
 	int matid=ReadInt();
+	if( matid==-1 ){
+		matid=0;
+	}else if( matid<0 || matid>=_materials.size() ){
+#ifdef DEBUG_B3D
+		cout<<"material id="<<matid<<endl;
+#endif
+		Fail( "Bad material id" );
+	}
+
+	int n_tris=ChunkSize()/12;
 
-	unsigned n_tris=ChunkSize()/12;
-	unsigned n_verts=n_tris*3;
-	
 	aiMesh *mesh=new aiMesh;
 	_meshes.push_back( mesh );
 
 	mesh->mMaterialIndex=matid;
-	mesh->mNumVertices=n_verts;
 	mesh->mNumFaces=n_tris;
 	mesh->mPrimitiveTypes=aiPrimitiveType_TRIANGLE;
 
-	aiVector3D *mv,*mn=0,*mc=0;
-	
-	mv=mesh->mVertices=new aiVector3D[n_verts];
-	if( _vertFlags & 1 ) mn=mesh->mNormals=new aiVector3D[n_verts];
-	if( _tcSets ) mc=mesh->mTextureCoords[0]=new aiVector3D[n_verts];
-	
 	aiFace *face=mesh->mFaces=new aiFace[n_tris];
 
-	for( unsigned i=0;i<n_verts;i+=3 ){
-		face->mNumIndices=3;
-		unsigned *ip=face->mIndices=new unsigned[3];
-		int v[3];
-		v[0]=ReadInt();
-		v[1]=ReadInt();
-		v[2]=ReadInt();
-		for( unsigned j=0;j<3;++j ){
-			int k=v[j];
-			const Vertex &v=_vertices[k];
-			memcpy( mv++,&v.position.x,12 );
-			if( mn ) memcpy( mn++,&v.normal.x,12 );
-			if( mc ) memcpy( mc++,&v.texcoords.x,12 );
-			*ip++=i+j;
+	for( int i=0;i<n_tris;++i ){
+		int i0=ReadInt()+v0;
+		int i1=ReadInt()+v0;
+		int i2=ReadInt()+v0;
+		if( i0<0 || i0>=_vertices.size() || i1<0 || i1>=_vertices.size() || i2<0 || i2>=_vertices.size() ){
+#ifdef DEBUG_B3D
+			cout<<"i0="<<i0<<", i1="<<i1<<", i2="<<i2<<endl;
+#endif
+			Fail( "Bad triangle index" );
 		}
+		face->mNumIndices=3;
+		face->mIndices=new unsigned[3];
+		face->mIndices[0]=i0;
+		face->mIndices[1]=i1;
+		face->mIndices[2]=i2;
 		++face;
 	}
 }
@@ -369,40 +369,168 @@ void B3DImporter::ReadTRIS(){
 void B3DImporter::ReadMESH(){
 	int matid=ReadInt();
 
-	_vertices.clear();
-	
+	int v0=_vertices.size();
+
 	while( ChunkSize() ){
 		string t=ReadChunk();
 		if( t=="VRTS" ){
 			ReadVRTS();
 		}else if( t=="TRIS" ){
-			ReadTRIS();
+			ReadTRIS( v0 );
 		}
 		ExitChunk();
 	}
+}
 
-	_vertices.clear();
+// ------------------------------------------------------------------------------------------------
+void B3DImporter::ReadBONE( int id ){
+	while( ChunkSize() ){
+		int vertex=ReadInt();
+		float weight=ReadFloat();
+		if( vertex<0 || vertex>=_vertices.size() ){
+			Fail( "Bad vertex index" );
+		}
+
+		Vertex &v=_vertices[vertex];
+		int i;
+		for( i=0;i<4;++i ){
+			if( !v.weights[i] ){
+				v.bones[i]=id;
+				v.weights[i]=weight;
+				break;
+			}
+		}
+#ifdef DEBUG_B3D
+		if( i==4 ){
+			cout<<"Too many bone weights"<<endl;
+		}
+#endif
+	}
+}
+
+// ------------------------------------------------------------------------------------------------
+void B3DImporter::ReadKEYS( aiNodeAnim *nodeAnim ){
+	vector<aiVectorKey> trans,scale;
+	vector<aiQuatKey> rot;
+	int flags=ReadInt();
+	while( ChunkSize() ){
+		int frame=ReadInt();
+		if( flags & 1 ){
+			trans.push_back( aiVectorKey( frame,ReadVec3() ) );
+		}
+		if( flags & 2 ){
+			scale.push_back( aiVectorKey( frame,ReadVec3() ) );
+		}
+		if( flags & 4 ){
+			rot.push_back( aiQuatKey( frame,ReadQuat() ) );
+		}
+	}
+
+	if( flags & 1 ){
+		nodeAnim->mNumPositionKeys=trans.size();
+		nodeAnim->mPositionKeys=to_array( trans );
+	}
+
+	if( flags & 2 ){
+		nodeAnim->mNumScalingKeys=scale.size();
+		nodeAnim->mScalingKeys=to_array( scale );
+	}
+
+	if( flags & 4 ){
+		nodeAnim->mNumRotationKeys=rot.size();
+		nodeAnim->mRotationKeys=to_array( rot );
+	}
+}
+
+// ------------------------------------------------------------------------------------------------
+void B3DImporter::ReadANIM(){
+	int flags=ReadInt();
+	int frames=ReadInt();
+	float fps=ReadFloat();
+
+	aiAnimation *anim=new aiAnimation;
+	_animations.push_back( anim );
+
+	anim->mDuration=frames;
+	anim->mTicksPerSecond=fps;
 }
 
 // ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadNODE(){
+aiNode *B3DImporter::ReadNODE( aiNode *parent ){
 
 	string name=ReadString();
-	Vec3 trans=ReadVec3();
-	Vec3 scale=ReadVec3();
-	Vec4 rot=ReadVec4();
+	aiVector3D t=ReadVec3();
+	aiVector3D s=ReadVec3();
+	aiQuaternion r=ReadQuat();
+
+	aiMatrix4x4 trans,scale,rot;
+
+	aiMatrix4x4::Translation( t,trans );
+	aiMatrix4x4::Scaling( s,scale );
+	rot=aiMatrix4x4( r.GetMatrix() );
+
+	aiMatrix4x4 tform=trans * rot * scale;
+
+	int nodeid=_nodes.size();
+
+	aiNode *node=new aiNode( name );
+	_nodes.push_back( node );
+
+	node->mParent=parent;
+	node->mTransformation=tform;
+
+	aiNodeAnim *nodeAnim=0;
+	vector<unsigned> meshes;
+	vector<aiNode*> children;
 
 	while( ChunkSize() ){
 		string t=ReadChunk();
 		if( t=="MESH" ){
+			int n=_meshes.size();
 			ReadMESH();
+			for( int i=n;i<_meshes.size();++i ){
+				meshes.push_back( i );
+			}
+		}else if( t=="BONE" ){
+			ReadBONE( nodeid );
+		}else if( t=="ANIM" ){
+			ReadANIM();
+		}else if( t=="KEYS" ){
+			if( !nodeAnim ){
+				nodeAnim=new aiNodeAnim;
+				_nodeAnims.push_back( nodeAnim );
+				nodeAnim->mNodeName=node->mName;
+			}
+			ReadKEYS( nodeAnim );
+		}else if( t=="NODE" ){
+			aiNode *child=ReadNODE( node );
+			children.push_back( child );
 		}
 		ExitChunk();
 	}
+
+	node->mNumMeshes=meshes.size();
+	node->mMeshes=to_array( meshes );
+
+	node->mNumChildren=children.size();
+	node->mChildren=to_array( children );
+
+	return node;
 }
 
 // ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadBB3D(){
+void B3DImporter::ReadBB3D( aiScene *scene ){
+
+	_textures.clear();
+	_materials.size();
+
+	_vertices.clear();
+	_meshes.clear();
+
+	_nodes.clear();
+	_nodeAnims.clear();
+	_animations.clear();
+
 	string t=ReadChunk();
 	if( t=="BB3D" ){
 		int version=ReadInt();
@@ -413,12 +541,114 @@ void B3DImporter::ReadBB3D(){
 			}else if( t=="BRUS" ){
 				ReadBRUS();
 			}else if( t=="NODE" ){
-				ReadNODE();
+				ReadNODE( 0 );
 			}
 			ExitChunk();
 		}
 	}
 	ExitChunk();
+
+	if( !_nodes.size() ) Fail( "No nodes" );
+
+	if( !_meshes.size() ) Fail( "No meshes" );
+
+	//Fix nodes/meshes/bones
+	for( int i=0;i<_nodes.size();++i ){
+		aiNode *node=_nodes[i];
+
+		for( int j=0;j<node->mNumMeshes;++j ){
+			aiMesh *mesh=_meshes[node->mMeshes[j]];
+
+			int n_tris=mesh->mNumFaces;
+			int n_verts=mesh->mNumVertices=n_tris * 3;
+
+			aiVector3D *mv=mesh->mVertices=new aiVector3D[ n_verts ],*mn=0,*mc=0;
+			if( _vflags & 1 ) mn=mesh->mNormals=new aiVector3D[ n_verts ];
+			if( _tcsets ) mc=mesh->mTextureCoords[0]=new aiVector3D[ n_verts ];
+
+			aiFace *face=mesh->mFaces;
+
+			vector< vector<aiVertexWeight> > vweights( _nodes.size() );
+
+			for( int i=0;i<n_verts;i+=3 ){
+				for( int j=0;j<3;++j ){
+					Vertex &v=_vertices[face->mIndices[j]];
+
+					*mv++=v.vertex;
+					if( mn ) *mn++=v.normal;
+					if( mc ) *mc++=v.texcoords;
+
+					face->mIndices[j]=i+j;
+
+					for( int k=0;k<4;++k ){
+						if( !v.weights[k] ) break;
+
+						int bone=v.bones[k];
+						float weight=v.weights[k];
+
+						vweights[bone].push_back( aiVertexWeight(i+j,weight) );
+					}
+				}
+				++face;
+			}
+
+			vector<aiBone*> bones;
+			for( int i=0;i<vweights.size();++i ){
+				vector<aiVertexWeight> &weights=vweights[i];
+				if( !weights.size() ) continue;
+
+				aiBone *bone=new aiBone;
+				bones.push_back( bone );
+
+				aiNode *bnode=_nodes[i];
+
+				bone->mName=bnode->mName;
+				bone->mNumWeights=weights.size();
+				bone->mWeights=to_array( weights );
+
+				aiMatrix4x4 mat=bnode->mTransformation;
+				while( bnode->mParent ){
+					bnode=bnode->mParent;
+					mat=bnode->mTransformation * mat;
+				}
+				bone->mOffsetMatrix=mat.Inverse();
+			}
+			mesh->mNumBones=bones.size();
+			mesh->mBones=to_array( bones );
+		}
+	}
+
+	//nodes
+	scene->mRootNode=_nodes[0];
+
+	//materials
+	if( !_materials.size() ){
+		_materials.push_back( new MaterialHelper );
+	}
+	scene->mNumMaterials=_materials.size();
+	scene->mMaterials=to_array( _materials );
+	
+	//meshes
+	scene->mNumMeshes=_meshes.size();
+	scene->mMeshes=to_array( _meshes );
+
+	//animations
+	if( _animations.size()==1 && _nodeAnims.size() ){
+
+		aiAnimation *anim=_animations.back();
+		anim->mNumChannels=_nodeAnims.size();
+		anim->mChannels=to_array( _nodeAnims );
+
+		scene->mNumAnimations=_animations.size();
+		scene->mAnimations=to_array( _animations );
+	}
+
+	// convert to RH
+	MakeLeftHandedProcess makeleft;
+	makeleft.Execute( scene );
+
+	FlipWindingOrderProcess flip;
+	flip.Execute( scene );
 }
 
 #endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER

+ 34 - 15
code/B3DImporter.h

@@ -65,41 +65,60 @@ protected:
 
 private:
 
-	struct Vec2{ float x,y; };
-	struct Vec3{ float x,y,z; };
-	struct Vec4{ float x,y,z,w; };
-	struct Texture{ std::string name; };
-	struct Vertex{ Vec3 position,normal,texcoords; };
-
 	int ReadByte();
 	int ReadInt();
 	float ReadFloat();
-	Vec2 ReadVec2();
-	Vec3 ReadVec3();
-	Vec4 ReadVec4();
+	aiVector2D ReadVec2();
+	aiVector3D ReadVec3();
+	aiQuaternion ReadQuat();
 	std::string ReadString();
 	std::string ReadChunk();
 	void ExitChunk();
 	unsigned ChunkSize();
 
+	template<class T>
+	T *to_array( const std::vector<T> &v );
+
+	struct Vertex{
+		aiVector3D vertex;
+		aiVector3D normal;
+		aiVector3D texcoords;
+		unsigned char bones[4];
+		float weights[4];
+	};
+
+	void Oops();
+	void Fail( std::string str );
+
 	void ReadTEXS();
 	void ReadBRUS();
+
 	void ReadVRTS();
-	void ReadTRIS();
+	void ReadTRIS( int v0 );
 	void ReadMESH();
-	void ReadNODE();
-	void ReadBB3D();
+	void ReadBONE( int id );
+	void ReadKEYS( aiNodeAnim *nodeAnim );
+	void ReadANIM();
+
+	aiNode *ReadNODE( aiNode *parent );
+
+	void ReadBB3D( aiScene *scene );
 
 	unsigned _pos;
 	unsigned _size;
 	std::vector<unsigned char> _buf;
 	std::vector<unsigned> _stack;
 	
-	int _vertFlags,_tcSets,_tcSize;
-	std::vector<Texture> _textures;
-	std::vector<MaterialHelper*> _materials;
+	std::vector<std::string> _textures;
+	std::vector<aiMaterial*> _materials;
+
+	int _vflags,_tcsets,_tcsize;
 	std::vector<Vertex> _vertices;
+
+	std::vector<aiNode*> _nodes;
 	std::vector<aiMesh*> _meshes;
+	std::vector<aiNodeAnim*> _nodeAnims;
+	std::vector<aiAnimation*> _animations;
 };
 
 }