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