示例#1
0
//data loading
bool ModelData::LoadIn(QString filepath)
{	
    unsigned int m;
    unsigned int t;
    unsigned int i;

    Triangle3D newtri;
    const struct aiFace* face;

	
	this->filepath = filepath;
	
	if(filepath.isEmpty())
		return false;
	
	//extract filename from path!
	filename = QFileInfo(filepath).baseName();

	//AI_CONFIG_PP_FD_REMOVE = aiPrimitiveType_POINTS | aiPrimitiveType_LINES;
    pScene = aiImportFile(filepath.toAscii(), aiProcess_Triangulate);// | aiProcess_JoinIdenticalVertices); //trian
	
    if(pScene == NULL)//assimp cant handle the file - lets try our own reader.
	{
		//display Assimp Error
		QMessageBox msgBox;
		msgBox.setText("Assimp Error:  " + QString().fromAscii(aiGetErrorString()));
		msgBox.exec();

        aiReleaseImport(pScene);

		return false;
	}

    qDebug() << "Model imported with " << pScene->mMeshes[0]->mNumFaces << " faces.";
	

	for (m = 0; m < pScene->mNumMeshes; m++) 
	{
		const aiMesh* mesh = pScene->mMeshes[m];
		
	    for (t = 0; t < mesh->mNumFaces; t++)
		{
            face = &mesh->mFaces[t];
			
			if(face->mNumIndices == 3)
			{
				for(i = 0; i < face->mNumIndices; i++) 
				{
					int index = face->mIndices[i];
				
                    newtri.normal.setX(mesh->mNormals[index].x);
                    newtri.normal.setY(mesh->mNormals[index].y);
                    newtri.normal.setZ(mesh->mNormals[index].z);
			
                    newtri.vertex[i].setX(mesh->mVertices[index].x);
                    newtri.vertex[i].setY(mesh->mVertices[index].y);
                    newtri.vertex[i].setZ(mesh->mVertices[index].z);
				}
                newtri.UpdateBounds();
                triList.push_back(newtri);

			}
		}
	}

    aiReleaseImport(pScene);

    qDebug() << "Loaded triangles: " << triList.size();
	//now center it!
	CenterModel();

	//generate a displaylist
    int displayerror = FormDisplayList();

    //check for errors in display list creation (if its a large model the card may run out of memory.

    if(displayerror){
    while(displayerror)//loop and see if there are additional errors as well.
    {
        //display Assimp Error
        qDebug() << "Display List Error: " << displayerror; //write to log as well.
        QMessageBox msgBox;

        switch(displayerror)
        {
        case GL_OUT_OF_MEMORY:
            msgBox.setText("OpenGL Error:  GL_OUT_OF_MEMORY\nModel is too large to render on your graphics card.");
            break;
        case GL_INVALID_ENUM:
            msgBox.setText("OpenGL Error:  GL_INVALID_ENUM");
            break;
        case GL_INVALID_VALUE:
            msgBox.setText("OpenGL Error:  GL_INVALID_VALUE");
            break;
        case GL_INVALID_FRAMEBUFFER_OPERATION:
            msgBox.setText("OpenGL Error:  GL_INVALID_FRAMEBUFFER_OPERATION");
            break;
        case GL_STACK_UNDERFLOW:
            msgBox.setText("OpenGL Error:  GL_STACK_UNDERFLOW");
            break;
        case GL_STACK_OVERFLOW:
            msgBox.setText("OpenGL Error:  GL_STACK_OVERFLOW");
            break;
        default:
            break;
        }

        msgBox.exec();
        displayerror = glGetError();
    }
    return false;
    }




	return true;
}
示例#2
0
文件: assiqe.c 项目: r-lyeh/eve
int main(int argc, char **argv)
{
	FILE *file;
	const struct aiScene *scene;
	char *p;
	int c;

	char *output = NULL;
	char *input = NULL;
	int onlyanim = 0;
	int onlymesh = 0;

	while ((c = getopt(argc, argv, "AHMPSabflmn:o:rvxsu:")) != -1) {
		switch (c) {
		case 'A': save_all_bones++; break;
		case 'H': dohips = 1; break;
		case 'M': list_all_meshes = 1; break;
		case 'P': list_all_positions = 1; break;
		case 'S': dostatic = 1; break;
		case 'a': onlyanim = 1; break;
		case 'm': onlymesh = 1; break;
		case 'n': only_one_node = optarg++; break;
		case 'b': need_to_bake_skin = 1; break;
		case 'o': output = optarg++; break;
		case 'f': doflip = 0; break;
		case 'r': dorigid = 1; break;
		case 'l': dolowprec = 1; break;
		case 'v': verbose++; break;
		case 'x': doaxis = 1; break;
		case 's': dounscale = 1; break;
		case 'u': untaglist[numuntags++] = optarg++; break;
		default: usage(); break;
		}
	}

	if (optind == argc)
		usage();

	input = argv[optind++];

	p = strrchr(input, '/');
	if (!p) p = strrchr(input, '\\');
	if (!p) p = input; else p++;
	strcpy(basename, p);
	p = strrchr(basename, '.');
	if (p) *p = 0;

	numtags = argc - optind;
	taglist = argv + optind;

	/* Read input file and post process */

	int flags = 0;
	flags |= aiProcess_JoinIdenticalVertices;
	flags |= aiProcess_GenSmoothNormals;
	flags |= aiProcess_GenUVCoords;
	flags |= aiProcess_TransformUVCoords;
	flags |= aiProcess_LimitBoneWeights;
	//flags |= aiProcess_FindInvalidData;
	flags |= aiProcess_ImproveCacheLocality;
	//flags |= aiProcess_RemoveRedundantMaterials;
	//flags |= aiProcess_OptimizeMeshes;

	fprintf(stderr, "loading %s\n", input);
	scene = aiImportFile(input, flags);
	if (!scene) {
		fprintf(stderr, "cannot import '%s': %s\n", input, aiGetErrorString());
		exit(1);
	}

	if (scene->mNumAnimations > 0) doanim = 1;
	if (onlymesh) { domesh = 1; doanim = 0; }
	if (onlyanim) { domesh = 0; doanim = 1; }

	if (getenv("DOANIM")) doanim = 1;

	// Convert to Z-UP coordinate system
	aiMultiplyMatrix4(&scene->mRootNode->mTransformation, &yup_to_zup);

	// Build a list of bones and compute the bind pose matrices.
	if (build_bone_list(scene) > 0)
		dobone = 1;

	if (dostatic) {
		dobone = 0;
		need_to_bake_skin = 0;
	}

	if (list_all_meshes) {
		export_mesh_list(scene);
		return 0;
	}

	if (list_all_positions) {
		export_position_list(scene);
		return 0;
	}

	// Mesh is split with incompatible bind matrices, so pick a new
	// bind pose and deform the mesh to fit.
	if (need_to_bake_skin && !onlyanim) {
		apply_initial_frame(); // ditch original bind pose
		bake_scene_skin(scene);
	}

	/*
	 * Export scene as mesh/skeleton/animation
	 */

	if (output) {
		fprintf(stderr, "saving %s\n", output);
		file = fopen(output, "w");
		if (!file) {
			fprintf(stderr, "cannot open output file: '%s'\n", output);
			exit(1);
		}
	} else {
		file = stdout;
	}

	fprintf(file, "# Inter-Quake Export\n");

	if (dobone) {
		export_bone_list(file);
	}

	if (domesh) {
		struct aiMatrix4x4 identity;
		aiIdentityMatrix4(&identity);
		export_custom_vertexarrays(file, scene);
		export_node(file, scene, scene->mRootNode, identity, "SCENE");
	}

	if (dobone) {
		if (doanim) {
			export_animations(file, scene);
		}
	}

	if (output)
		fclose(file);

	aiReleaseImport(scene);

	return 0;
}
示例#3
0
ModelAndTextureLoader::ModelAndTextureLoader(const char* TextureDirectory,const char* fullPathToModel)
{
	m_nbTotalMesh = 0;
	m_allMeshes = NULL;

	//force to recompute normal tangent and bitangent
	//Assimp::Importer::SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_NORMALS);
	//aiSetImportPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_NORMALS);
	//aiSetImportPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_TANGENTS_AND_BITANGENTS);


	m_assimpScene = aiImportFile(fullPathToModel,  aiProcessPreset_TargetRealtime_MaxQuality|aiProcess_PreTransformVertices);
//		 | aiProcess_RemoveComponent | aiProcess_CalcTangentSpace | aiProcess_GenSmoothNormals //force to recompute normal tangent and bitangent
//		 );


	if ( m_assimpScene )
	{
		struct aiVector3D scene_min, scene_max, scene_center;
		get_bounding_box(&scene_min,&scene_max);
		m_vCenter.x = (scene_min.x + scene_max.x) / 2.0f;
		m_vCenter.y = (scene_min.y + scene_max.y) / 2.0f;
		m_vCenter.z = (scene_min.z + scene_max.z) / 2.0f;

		m_fSize = scene_max.x-scene_min.x;
		m_fSize = aisgl_max(scene_max.y - scene_min.y,m_fSize);
		m_fSize = aisgl_max(scene_max.z - scene_min.z,m_fSize);

		RecursiveMesh_CountTotalMesh(m_assimpScene,m_assimpScene->mRootNode);

		m_allMeshes = (MESH*)malloc(sizeof(MESH) * m_nbTotalMesh);

		unsigned int iMesh = 0;
		RecursiveMesh_Loading(m_assimpScene,m_assimpScene->mRootNode,&iMesh);
	



		//load textures

		m_textureOfEachMaterial = new MATERIAL_TEXTUREID[m_assimpScene->mNumMaterials];

		for (unsigned int m=0; m<m_assimpScene->mNumMaterials; m++)
		{
			int texIndex;
		
			texIndex = 0;
			while (true)
			{
				aiString path;	
				aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
				if ( texFound ==  AI_SUCCESS ) { m_textureIdMap[path.data] = NULL;  texIndex++; }
				else{break;}
			}

			texIndex = 0;
			texIndex = 0;
			while (true)
			{
				aiString path;	
				aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_SPECULAR, texIndex, &path);
				if ( texFound ==  AI_SUCCESS ) { m_textureIdMap[path.data] = NULL;  texIndex++; }
				else{break;}
			}

			texIndex = 0;
			while (true)
			{
				aiString path;	
				aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_AMBIENT, texIndex, &path);
				if ( texFound ==  AI_SUCCESS ) { m_textureIdMap[path.data] = NULL;  texIndex++; }
				else{break;}
			}

			texIndex = 0;
			while (true)
			{
				aiString path;	
				aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_EMISSIVE, texIndex, &path);
				if ( texFound ==  AI_SUCCESS ) { m_textureIdMap[path.data] = NULL;  texIndex++; }
				else{break;}
			}

			texIndex = 0;
			while (true)
			{
				aiString path;	
				aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_NORMALS, texIndex, &path);
				if ( texFound ==  AI_SUCCESS ) { m_textureIdMap[path.data] = NULL;  texIndex++; }
				else{break;}
			}

			texIndex = 0;
			while (true)
			{
				aiString path;	
				aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_HEIGHT, texIndex, &path);
				if ( texFound ==  AI_SUCCESS ) { m_textureIdMap[path.data] = NULL;  texIndex++; }
				else{break;}
			}
		}

		int numTextures = int(m_textureIdMap.size());

		std::map<std::string, GLuint*>::iterator itr = m_textureIdMap.begin();

		m_textureIds = new GLuint[numTextures];
		glGenTextures(numTextures, m_textureIds);

		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		for (int i=0; i<numTextures; i++)
		{
			std::string filename = (*itr).first;
			(*itr).second = &m_textureIds[i];

			gli::texture2D textureFileLoaded = gli::load(std::string(TextureDirectory) + filename);
			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			gli::texture2D::format_type formatImage = textureFileLoaded.format();
			if ( formatImage == gli::RGB8U )
			{
				glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,textureFileLoaded[0].dimensions().x,textureFileLoaded[0].dimensions().y,0,GL_RGB,GL_UNSIGNED_BYTE,textureFileLoaded[0].data());
			}
			else if ( formatImage == gli::RGBA8U )
			{
				glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,textureFileLoaded[0].dimensions().x,textureFileLoaded[0].dimensions().y,0,GL_RGBA,GL_UNSIGNED_BYTE,textureFileLoaded[0].data());
			}
			glBindTexture(GL_TEXTURE_2D, 0);


			itr++;
		}
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
		for (unsigned int m=0; m<m_assimpScene->mNumMaterials; m++)
		{

			aiString path;	
			aiReturn texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, 0, &path);
			if ( texFound ==  AI_SUCCESS ) 
			{ 
				m_textureOfEachMaterial[m].idDiffuse = *m_textureIdMap[path.data] ;  
			}
			else{ m_textureOfEachMaterial[m].idDiffuse = 0;}


			texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_SPECULAR, 0, &path);
			if ( texFound ==  AI_SUCCESS ) 
			{ 
				m_textureOfEachMaterial[m].idSpecular = *m_textureIdMap[path.data] ;  
			}
			else{ m_textureOfEachMaterial[m].idSpecular = 0;}

	
			texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_AMBIENT, 0, &path);
			if ( texFound ==  AI_SUCCESS ) 
			{ 
				m_textureOfEachMaterial[m].idAmbiant = *m_textureIdMap[path.data] ;  
			}
			else{ m_textureOfEachMaterial[m].idAmbiant = 0;}


			texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_EMISSIVE, 0, &path);
			if ( texFound ==  AI_SUCCESS ) 
			{ 
				m_textureOfEachMaterial[m].idEmissive = *m_textureIdMap[path.data] ;  
			}
			else{ m_textureOfEachMaterial[m].idEmissive = 0;}

				
			texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_NORMALS, 0, &path);
			if ( texFound ==  AI_SUCCESS ) 
			{ 
				m_textureOfEachMaterial[m].idNormal = *m_textureIdMap[path.data] ;  
			}
			else
			{ 
				//height could be considered as normals
				texFound = m_assimpScene->mMaterials[m]->GetTexture(aiTextureType_HEIGHT, 0, &path);
				if ( texFound ==  AI_SUCCESS ) 
				{ 
					m_textureOfEachMaterial[m].idNormal = *m_textureIdMap[path.data] ;  
				}
				else
				{ 
					m_textureOfEachMaterial[m].idNormal = 0;
				}
			}

			

		}

	}	
}
bool Animated_Mesh::Load_Assimp(const std::string& file){
	const aiScene* load =aiImportFile(file.c_str(), aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_ConvertToLeftHanded );
	if(load==NULL) {
		OUTPUT_DEBUG_MSG("Could not load the Model in Animated_Mesh::Load_MyFormat file: '" + file+"'");
		return false;
	}
	size_t numverts(0), currentvertex(0), currentindex(0), numindices(0);
	bool hasbones=false;
	// go through the mesh counting all the verts and indices that I will need
	for (unsigned int i = 0; i < load->mNumMeshes;++i) {
		numverts+=load->mMeshes[i]->mNumVertices;
		numindices+=load->mMeshes[i]->mNumFaces*3;
		if(load->mMeshes[i]->HasBones()) hasbones=true;
	}
	if(!hasbones) {
		aiReleaseImport(load);// free the resrouces
		OUTPUT_DEBUG_MSG("Could not load the Model in Animated_Mesh::Load_MyFormat file: '" + file+"', there were no bones deteected.");
		return false;
	}
	IB.Stride=2;
	if(numverts >= 65536) IB.Stride=4;

	Vertices.resize(numverts);
	Indices.resize((IB.Stride/2)*numindices);
	std::vector<Vertex_Types::Pos_Tex_Norm_Tang_Bone_Weight> tempverts(numverts);
	std::vector<std::string> bonenames;

	for (unsigned int i = 0; i < load->mNumMeshes;++i){
		Graphics::Texture diffuse, normal;
		const aiMesh* mesh = load->mMeshes[i];
		if(mesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) {
			OUTPUT_DEBUG_MSG("There are errors with this submesh, named: "<<mesh->mName.data<<"   Please, fix it");
			if(mesh->mPrimitiveTypes == aiPrimitiveType_LINE){
				OUTPUT_DEBUG_MSG("Problem: The mesh containes lines when it should only contain triangles");
			}else {
				OUTPUT_DEBUG_MSG("Problem: The mesh containes points when it should only contain triangles");
			}
			continue;
		}

		if (!mesh->HasTextureCoords(0))	{
			OUTPUT_DEBUG_MSG("There are errors with this submesh, named: "<<mesh->mName.data<<"   Please, fix it");
			OUTPUT_DEBUG_MSG("Problem: The mesh containes no texcoords, which means there will just be color displayed. This engine does not support color mesh displays, only textured mesh!");
			continue;
		} 
		if(!mesh->HasTangentsAndBitangents()) {
			OUTPUT_DEBUG_MSG("There are errors with this submesh, named: "<<mesh->mName.data<<"   Please, fix it");
			OUTPUT_DEBUG_MSG("Problem: Tangents were not created. No known fix");
			continue;
		}
		OUTPUT_DEBUG_MSG("Loading "<<mesh->mNumBones<<" bones . . .");
		for( unsigned int a = 0; a < mesh->mNumBones; a++)	{
			const aiBone* bone = mesh->mBones[a];
			size_t bonein(-1);
			for(size_t ib(0); ib< bonenames.size(); ib++){
				std::string tname = bone->mName.data;
				if(tname == bonenames[ib]){// found the bone.. break
					bonein=ib;
					break;
				}
			}
			if(bonein ==-1){//  did not find the bone, this is a new one push back
				bonein = bonenames.size();// get the index before insertion
				bonenames.push_back(bone->mName.data);
			}
			// there should only be 4 per vertex here because assimp guaranteees it, but if there are more, we are ok
			for( unsigned int b = 0; b < bone->mNumWeights; b++){
				if(			tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.x <= 0.f) {
							tempverts[bone->mWeights[b].mVertexId+ currentvertex].Bones[0] = static_cast<float>(bonein);
							tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.x = bone->mWeights[b].mWeight;
				} else if(	tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.y <= 0.f){
							tempverts[bone->mWeights[b].mVertexId+ currentvertex].Bones[1] = static_cast<float>(bonein);
							tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.y = bone->mWeights[b].mWeight;
				} else if(	tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.z <= 0.f){
							tempverts[bone->mWeights[b].mVertexId+ currentvertex].Bones[2] = static_cast<float>(bonein);
							tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.z = bone->mWeights[b].mWeight;
				} else if(	tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.w <= 0.f){
							tempverts[bone->mWeights[b].mVertexId+ currentvertex].Bones[3] = static_cast<float>(bonein);
							tempverts[bone->mWeights[b].mVertexId+ currentvertex].Weights.w = bone->mWeights[b].mWeight;
				}
			}
			
		}
		for (unsigned int x = 0; x < mesh->mNumVertices;++x){
			Vertices[x + currentvertex] = tempverts[x + currentvertex].Pos = *reinterpret_cast<vec3*>(&mesh->mVertices[x]);
			tempverts[x + currentvertex].Tex =  *reinterpret_cast<vec2*>(&mesh->mTextureCoords[0][x]);
			tempverts[x + currentvertex].Norm = *reinterpret_cast<vec3*>(&mesh->mNormals[x]);
			tempverts[x + currentvertex].Tang = *reinterpret_cast<vec3*>(&mesh->mTangents[x]);
		}
		// check whether we can use 16 bit indices for our format... the ASSIMPOBLARBLA uses 32 bit indices for all theirs..
		if (IB.Stride == 4){
			uint32_t* pbData = reinterpret_cast<uint32_t*>(&Indices[currentindex]);
			for (unsigned int x = 0; x < mesh->mNumFaces;++x){
				for (unsigned int a = 0; a < 3 ;++a) {
					*pbData++ = static_cast<uint32_t>(mesh->mFaces[x].mIndices[a]+ currentvertex);
				}
			}
		} else {
			uint16_t* pbData = reinterpret_cast<uint16_t*>(&Indices[currentindex]);
			for (unsigned int x = 0; x < mesh->mNumFaces;++x){
				for (unsigned int a = 0; a < 3 ;++a) {
					*pbData++ = static_cast<uint16_t>(mesh->mFaces[x].mIndices[a]+ currentvertex);
				}
			}
		}
		//load the textures
		std::string pathtomodel(GetPath(file));
		Batch *batch = new Batch();

		LoadMaterials(mesh, load->mMaterials, batch, pathtomodel, Asset_Dir);
		batch->NumIndices=mesh->mNumFaces*3;
		batch->StartIndex = static_cast<uint32_t>(currentindex);
		batch->NumVerts= mesh->mNumVertices;
		// make sure to increment the ref count for thesse so they are properly destroyed

		currentvertex+=mesh->mNumVertices;
		currentindex+=mesh->mNumFaces*3;

		//For now, there will be a new shader for each material. I will create a shader cache where the graphics lib will cache the shaders and issue out already created shaders like it does with textures.
		Graphics::Shader_Macro macro1[] = {
			{"NORMALMAP", "1" }, 
			{"MATRIX_PALETTE_SIZE_DEFAULT", "60" }, 
			{NULL, NULL}
		};
		Graphics::Shader_Macro macro0[] = {
			{"NORMALMAP", "0" }, 
			{"MATRIX_PALETTE_SIZE_DEFAULT", "60" }, 
			{NULL, NULL}
		};

		Graphics::Shader_Macro* ptr = nullptr;
		if(batch->Has_NormalMap()) ptr = macro1;
		else ptr = macro0;

		batch->GetVS()->CompileShaderFromFile("Animated_Mesh.fx", "VS", "vs_4_0", ptr);

		FormatDesc lay[] = {
			FormatDesc(),
			FormatDesc(TYPE_TEXCOORD, FORMAT_FLOAT, 2),
			FormatDesc(TYPE_NORMAL, FORMAT_FLOAT, 3),
			FormatDesc(TYPE_TANGENT, FORMAT_FLOAT, 3),
			FormatDesc(TYPE_BONE, FORMAT_FLOAT, 4),
			FormatDesc(TYPE_WEIGHT, FORMAT_FLOAT, 4)
		};
		batch->GetVS()->CreateInputLayout(lay, sizeof(lay)/sizeof(FormatDesc));
		batch->GetPS()->CompileShaderFromFile("Animated_Mesh.fx", "PS", "ps_4_0", ptr);

		Batches.push_back(batch);
	}
	Animatior.Init(load);
	aiReleaseImport(load);// free the resrouces
	if(currentvertex==0) {// this could happen, if so GET OUTOF HERE
		OUTPUT_DEBUG_MSG("Problem loading the mesh, there were no vertices loaded. Failed to load the mesh");
		return false;
	}
	VB[0].Create(currentvertex, sizeof(Vertex_Types::Pos_Tex_Norm_Tang_Bone_Weight), VERTEX_BUFFER, IMMUTABLE, CPU_NONE, &tempverts[0] );
	IB.Create(currentindex, IB.Stride, INDEX_BUFFER, IMMUTABLE, CPU_NONE, &Indices[0]); // create index buffer!
	OUTPUT_DEBUG_MSG("Finished Loading the Mesh");
	Name=FileName =file;
	return true;
}