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);
}
Beispiel #2
0
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;

}
Beispiel #4
0
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);
  }
}