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); }
bool Fbx::addPolygonObjectToScene( std::vector<KFbxVector4> &vertex_list ) { assert(vertex_list.size()>=3); if(!_output_scene) { //std::cout << " Not scene has been created!! " << std::endl; return false; } KFbxNode *root = _output_scene->GetRootNode(); if(!root) { //std::cout<<"Don't have root!"<< std::endl; return false; } KFbxMesh *mesh = KFbxMesh::Create(_sdk_manager, ""); if(!mesh) return false; mesh->BeginPolygon(); std::vector<KFbxVector4>::iterator it; int index = 0; for (it = vertex_list.begin(); it != vertex_list.end(); it++, index++) { mesh->SetControlPointAt((*it), index); mesh->AddPolygon(index); } mesh->EndPolygon(); mesh->BuildMeshEdgeArray(); _mesh_list.push_back(mesh); KFbxNode *polygon_node = KFbxNode::Create(_sdk_manager, ""); assert(polygon_node->AddNodeAttribute(mesh)); assert(root->AddChild(polygon_node)); return true; }
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; }
SceneObject* parseNode(KFbxNode *node, int level = 0) { KString s = node->GetName(); KFbxNodeAttribute::EAttributeType attributeType; stringstream ss; for (int i=0;i<level;i++){ ss<<" "; } SceneObject* sceneObject = NULL; MeshComponent* ga = NULL; if (node->GetNodeAttribute() == NULL){ ss<<"No node attribute"<<endl; } else { attributeType = node->GetNodeAttribute()->GetAttributeType(); switch (attributeType) { case KFbxNodeAttribute::eMARKER: ss<<"eMarker"<<endl; break; case KFbxNodeAttribute::eSKELETON: ss<<"eSkeleton"<<endl; break; case KFbxNodeAttribute::eMESH: { KFbxMesh *fbxMesh = node->GetMesh(); KFbxVector4 *controlPoints = fbxMesh->GetControlPoints(); int polygonCount = fbxMesh->GetPolygonCount(); vector<glm::vec3> vertices; vector<glm::vec3> normals; vector<glm::vec2> texCords; vector<int> polycount; assert(fbxMesh->GetLayerCount(KFbxLayerElement::eNORMAL)==1); // assume only one normal layer KFbxLayer *normalLayer = fbxMesh->GetLayer(0, KFbxLayerElement::eNORMAL); KFbxLayerElementNormal *normalElement = normalLayer->GetNormals(); KFbxLayerElementArrayTemplate<KFbxVector4> *normalArray = &(normalElement->GetDirectArray()); int normalCount = normalArray->GetCount(); vector<int> indices; assert(fbxMesh->GetControlPointsCount() <= USHRT_MAX); for (int i=0;i<fbxMesh->GetControlPointsCount();i++){ glm::vec3 v = toVector(controlPoints[i]); vertices.push_back(v); v = toVector(normalArray->GetAt(i)); normals.push_back(v); } for (int i=0;i<polygonCount;i++){ int polygonSize = fbxMesh->GetPolygonSize(i); polycount.push_back(polygonSize); for (int j=0;j<polygonSize;j++){ if (j>2){ // if polygon size > 2 then add first and last index // this triangulates the mesh int first = fbxMesh->GetPolygonVertex(i,0); int last = fbxMesh->GetPolygonVertex(i,j-1); indices.push_back(first); indices.push_back(last); } int polygonIndex = fbxMesh->GetPolygonVertex(i,j); indices.push_back(polygonIndex); /*KFbxVector4 vectorSrc = controlPoints[polygonIndex]; Vector3 vectorDst = toVector(vectorSrc); vertices.push_back(vectorDst); texCords.push_back(Vector2(0,0)); KFbxVector4 normalSrc = normalArray->GetAt(polygonIndex); Vector3 normalDst = toVector(normalSrc); normals.push_back(normalDst);*/ } } Mesh mesh; ss<<"Creating mesh: vertices "<<vertices.size()<<" normals "<<normals.size()<<" indices "<<indices.size()<<endl; mesh.SetVertices(vertices); mesh.SetNormals(normals); mesh.SetIndices(indices); sceneObject = new SceneObject(); ga = new MeshComponent(); ga->SetMesh(&mesh); sceneObject->AddCompnent(ga); // Set translate fbxDouble3 v3 = node->LclTranslation.Get(); glm::vec3 translate = toVector(v3); sceneObject->GetTransform()->SetPosition(translate); // Set rotation v3 = node->LclRotation.Get(); glm::vec3 rotation = toVector(v3)*Mathf::DEGREE_TO_RADIAN; sceneObject->GetTransform()->SetRotation(rotation); // Set scale v3 = node->LclScaling.Get(); glm::vec3 scale = toVector(v3); sceneObject->GetTransform()->SetScale(scale); } break; case KFbxNodeAttribute::eCAMERA: ss<<"eCAMERA"<<endl; break; case KFbxNodeAttribute::eLIGHT: ss<<"eLIGHT"<<endl; break; case KFbxNodeAttribute::eBOUNDARY: ss<<"eBOUNDARY"<<endl; break; default: ss<<s<<endl; } } if (node->GetChildCount()>0){ for (int i=0;i<node->GetChildCount();i++){ SceneObject *res = parseNode(node->GetChild(i),level+1); if (res!=NULL){ if (sceneObject == NULL){ sceneObject = new SceneObject(); } sceneObject->AddChild(res); } } } DEBUG(ss.str()); return sceneObject; }
void FBXJSONSerializer::recurse_over_model(fbxsdk_2012_1::KFbxNode *fbx_node, json::Array& meshes_array) { KFbxMesh* old_mesh = fbx_node->GetMesh(); if (old_mesh) { KFbxGeometryConverter converter(fbx_node->GetFbxSdkManager()); KFbxMesh* mesh = converter.TriangulateMesh(old_mesh); mesh->ComputeBBox(); mesh->ComputeVertexNormals(); Object json_mesh; { KFbxLayerElementUV* uvs = mesh->GetLayer(0)->GetUVs(); KFbxLayerElementNormal* normals = mesh->GetLayer(0, KFbxLayerElement::eNORMAL)->GetNormals(); Array json_mesh_normals; Array json_mesh_uvs; Array json_mesh_vertices; int polygon_count = mesh->GetPolygonCount(); for (int poly_index = 0; poly_index < polygon_count; poly_index++) { for (int vertex_index = 0; vertex_index < mesh->GetPolygonSize(poly_index); vertex_index++) { int vertex_position = mesh->GetPolygonVertex(poly_index, vertex_index); KFbxVector4 vertex = mesh->GetControlPoints()[vertex_position]; Number vertex_x = vertex.GetAt(0); json_mesh_vertices.Insert(vertex_x); Number vertex_y = vertex.GetAt(1); json_mesh_vertices.Insert(vertex_y); Number vertex_z = vertex.GetAt(2); json_mesh_vertices.Insert(vertex_z); KFbxVector4 normal = normals->GetDirectArray()[vertex_position]; Number normal_x = normal.GetAt(0); json_mesh_normals.Insert(normal_x); Number normal_y = normal.GetAt(1); json_mesh_normals.Insert(normal_y); Number normal_z = normal.GetAt(2); json_mesh_normals.Insert(normal_z); if (uvs) { int mesh_index = mesh->GetTextureUVIndex(poly_index, vertex_index); KFbxVector2 uv = uvs->GetDirectArray().GetAt(mesh_index); Number uv_x = 1.0f-uv[0]; json_mesh_uvs.Insert(uv_x); // these are flipped Number uv_y = 1.0f-uv[1]; json_mesh_uvs.Insert(uv_y); } } } json_mesh["vertices"] = json_mesh_vertices; json_mesh["normals"] = json_mesh_normals; json_mesh["uvs"] = json_mesh_uvs; } { fbxDouble3 scale = fbx_node->LclScaling.Get(); Object json_mesh_scale; json_mesh_scale["x"] = Number(scale[0]); json_mesh_scale["y"] = Number(scale[1]); json_mesh_scale["z"] = Number(scale[2]); json_mesh["scale"] = json_mesh_scale; } { fbxDouble3 translation = fbx_node->LclTranslation.Get(); Object json_mesh_translation; json_mesh_translation["x"] = Number(translation[0]); json_mesh_translation["y"] = Number(translation[1]); json_mesh_translation["z"] = Number(translation[2]); json_mesh["translation"] = json_mesh_translation; } { fbxDouble3 rotation = fbx_node->LclRotation.Get(); Object json_mesh_rotation; json_mesh_rotation["x"] = Number(rotation[0]); json_mesh_rotation["y"] = Number(rotation[1]); json_mesh_rotation["z"] = Number(rotation[2]); json_mesh["rotation"] = json_mesh_rotation; } { int material_count = fbx_node->GetMaterialCount(); Array json_mesh_materials; for (int material_index = 0; material_index < material_count; material_index++) { KFbxSurfaceMaterial* surface_material = fbx_node->GetMaterial(material_index); Object json_material; Array json_textures; int textureIndex = 0; FOR_EACH_TEXTURE(textureIndex) { KFbxProperty property = surface_material->FindProperty(KFbxLayerElement::TEXTURE_CHANNEL_NAMES[textureIndex]); int layered_texture_count = property.GetSrcObjectCount(KFbxTexture::ClassId); for (int layered_texture_index = 0; layered_texture_index < layered_texture_count; ++layered_texture_index) { KFbxTexture* texture = KFbxCast <KFbxTexture> (property.GetSrcObject(KFbxTexture::ClassId, layered_texture_index)); if(texture) { KFbxFileTexture *file_texture = KFbxCast<KFbxFileTexture>(texture); if (file_texture) { Object json_texture; json_texture["filename"] = String(file_texture->GetFileName()); json_textures.Insert(json_texture); } } } } json_material["textures"] = json_textures; KFbxSurfaceLambert* lambert_material = KFbxCast<KFbxSurfaceLambert>(surface_material); if (lambert_material) { Object diffuse; double diffuse_r = lambert_material->Diffuse.Get()[0]; diffuse["r"] = Number(diffuse_r); double diffuse_g = lambert_material->Diffuse.Get()[1]; diffuse["g"] = Number(diffuse_g); double diffuse_b = lambert_material->Diffuse.Get()[2]; diffuse["b"] = Number(diffuse_b); json_material["diffuse"] = diffuse; Object ambient; double ambient_r = lambert_material->Ambient.Get()[0]; ambient["r"] = Number(ambient_r); double ambient_g = lambert_material->Ambient.Get()[1]; ambient["g"] = Number(ambient_g); double ambient_b = lambert_material->Ambient.Get()[2]; ambient["b"] = Number(ambient_b); json_material["ambient"] = ambient; KFbxProperty specular_property = lambert_material->FindProperty("SpecularColor"); fbxDouble3 specular_data; specular_property.Get(&specular_data, eDOUBLE3); Object specular; float specular_r = specular_data[0]; specular["r"] = Number(specular_r); float specular_g = specular_data[1]; specular["g"] = Number(specular_g); float specular_b = specular_data[2]; specular["b"] = Number(specular_b); json_material["specular"] = specular; } json_mesh_materials.Insert(json_material); } json_mesh["materials"] = json_mesh_materials; } json_mesh["uv_stride"] = Number(2); json_mesh["vertex_stride"] = Number(3); json_mesh["normal_stride"] = Number(3); meshes_array.Insert(json_mesh); } for(int j = 0; j < fbx_node->GetChildCount(); j++) { recurse_over_model(fbx_node->GetChild(j), meshes_array); } }