void FBXModel::loadMeshes(KFbxNode* node, const GraphicsDevice& device, KFbxGeometryConverter& converter)
{
	const char* name = node->GetName();

	if (node->GetNodeAttribute())
	{
		KFbxNodeAttribute::EAttributeType attributeType = node->GetNodeAttribute()->GetAttributeType();

		if (attributeType == KFbxNodeAttribute::eMESH)
		{
			KFbxMesh* kfbxMesh = converter.TriangulateMesh((KFbxMesh*)node->GetNodeAttribute());

			VertexCollection vertices = getVertices(kfbxMesh);
			MaterialCollection materials = getMaterials(device, node);

			unsigned long numFaces = kfbxMesh->GetPolygonCount();
			unsigned long numVertices = kfbxMesh->GetControlPointsCount();
				
			Mesh mesh = Mesh::create(device, numFaces, numVertices, FBXVertex::vertexElements, D3DXMESH_MANAGED | D3DXMESH_32BIT);

			mesh.getVertexBuffer().setData(vertices);
			mesh.getIndexBuffer().setData(kfbxMesh->GetPolygonVertices(), kfbxMesh->GetPolygonVertexCount());

			KFbxLayerElementArrayTemplate<int>* materialIndices;
			kfbxMesh->GetMaterialIndices(&materialIndices);

			unsigned long* buffer = mesh.lockAttributeBuffer();

			for(int i = 0; i < kfbxMesh->GetPolygonCount(); ++i)
				buffer[i] = materialIndices->GetAt(i);
			
			mesh.unlockAttributeBuffer();
				
			Mesh::Adjacency adjacency = mesh.generateAdjacency();

			mesh.clean(D3DXCLEAN_SIMPLIFICATION, adjacency);
			mesh.optimizeInplace(D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, adjacency);
			mesh.computeNormals(adjacency);
			

			meshes[name] = FBXMesh(mesh, materials, name);
		}
	}

	for (int i = 0; i < node->GetChildCount(); i++)
		loadMeshes(node->GetChild(i), device, converter);
}
Ejemplo n.º 2
0
void Model::UpdateVertexBuffer( bool pstatic ) {
	


	int total_verts = 0;

	for( u32 mesh_index = 0; mesh_index < MeshNodes.size(); mesh_index++ ) {
		KFbxMesh *mesh = MeshNodes[mesh_index]->GetMesh();
			
		total_verts += mesh->GetPolygonVertexCount();
	}

	nvertices=total_verts;
	Video::generic_vertex *vertices = new Video::generic_vertex[ total_verts ];
	int vert_write = 0;

	for( u32 mesh_index = 0; mesh_index < MeshNodes.size(); mesh_index++ ) {
		KFbxMesh *mesh = MeshNodes[mesh_index]->GetMesh();
		
		int cp_count = mesh->GetControlPointsCount();
        KFbxVector4 *control_points = new KFbxVector4[cp_count];
        memcpy(control_points, mesh->GetControlPoints(), cp_count * sizeof(KFbxVector4));

		const int skin_count = mesh->GetDeformerCount(KFbxDeformer::eSKIN);
		
		// deform mesh with animation
		if( skin_count ) {
			int cluster_count = 0;
			for( int i = 0; i < skin_count; i++ ) {
				cluster_count += ((KFbxSkin*)(mesh->GetDeformer(i, KFbxDeformer::eSKIN)))->GetClusterCount();
			}

			if( cluster_count){
				ComputeSkinDeformation( mesh, AnimationCurrentTime, control_points, NULL );
			}
		}

		// copy vertex data
		int vcount = mesh->GetPolygonVertexCount();
		int *vertex_index = mesh->GetPolygonVertices();
	

		KStringList lUVNames;
		mesh->GetUVSetNames(lUVNames);
		
		for( int i = 0; i < vcount; i++ ) {
			
			vertices[vert_write].x = control_points[ vertex_index[i] ][0];
			vertices[vert_write].y = control_points[ vertex_index[i] ][2];
			vertices[vert_write].z = control_points[ vertex_index[i] ][1];
			

			KFbxVector2 uv;
			mesh->GetPolygonVertexUV( i/3, i%3, lUVNames[0], uv );
			vertices[vert_write].u = uv[0];
			vertices[vert_write].v = -uv[1];
			vertices[vert_write].r = vertices[vert_write].g = vertices[vert_write].b = 255;
			vertices[vert_write].a = 255;
			vert_write++;
		}

		
	}
	
	// reverse vertex order
	for( int i = 0; i < total_verts; i+= 3 ) {
		Video::generic_vertex a;
		a = vertices[i];
		vertices[i] = vertices[i+2];
		vertices[i+2] = a;
	}

	// update VBO
	buffer.BufferData( vertices, total_verts * sizeof( Video::generic_vertex ), pstatic ? GL_STATIC_DRAW_ARB : GL_STREAM_DRAW_ARB );

		
	delete[] vertices;

}