Beispiel #1
0
void FBXImporter::ProcessMesh(FbxNodeAttribute* nodeAttribute)
{
	FbxMesh* mesh = (FbxMesh*)nodeAttribute;
	
	// 网格是否三角化的?如果不是先将其转为三角化的。
	// 注意:一步其实应该在建模软件导出的时候进行。
	if (!mesh->IsTriangleMesh())
	{
		FbxGeometryConverter converter(mSDKManager);

		// #1
		// For FBX SDK 2015.1
		nodeAttribute = converter.Triangulate(nodeAttribute, true, false);
		// For FBX SDK 2013.3
		//converter.TriangulateInPlace(nodeAttribute->GetNode());

		mesh = (FbxMesh*)nodeAttribute;
	}

	FBXMeshData* fbxMeshData = new FBXMeshData();
	fbxMeshData->mMesh = mesh;
	mFBXMeshDatas.push_back(fbxMeshData);

	Log("TriangleCount:%d\n", mesh->GetPolygonCount());
	Log("VertexCount:%d\n", mesh->GetControlPointsCount());
	Log("IndexCount:%d\n", mesh->GetPolygonVertexCount());
	Log("Layer:%d\n", mesh->GetLayerCount());
	Log("DeformerCount:%d\n", mesh->GetDeformerCount());
	Log("MaterialCount%d\n", mesh->GetNode()->GetMaterialCount());
	Log("\n");
}
// Load Fbx File
void GenerateLOD::LoadFbx()
{
	FbxManager *fbxManager = FbxManager::Create();

	//Create an IOSetting
	FbxIOSettings *ios = FbxIOSettings::Create(fbxManager, IOSROOT);
	fbxManager->SetIOSettings(ios);

	//Create an impoter
	FbxImporter *lImporter = FbxImporter::Create(fbxManager, "myImporter");
	std::string tmp = std::string(".\\LODs\\") + srcFbxName;
	bool lImporterStatus = lImporter->Initialize(tmp.c_str(), -1, fbxManager->GetIOSettings());
	if (!lImporterStatus) {
		MessageBox(NULL, "No Scuh File in .\\LODs\\ directory !", "Warning", 0);
		return;
	}

	FbxScene *fbxScene = FbxScene::Create(fbxManager, "myScene");
	lImporter->Import(fbxScene);

	FbxNode *rootNode = fbxScene->GetRootNode();
	if (rootNode != NULL) {
		for (int i = 0; i < rootNode->GetChildCount(); ++i) {
			FbxNode *node = rootNode->GetChild(i);
			FbxNodeAttribute *Att = node->GetNodeAttribute();
			if (Att != NULL && Att->GetAttributeType() == FbxNodeAttribute::eMesh) {
				FbxMesh *lMesh = (FbxMesh *)(Att);
				//FbxMesh *lMesh = dynamic_cast<FbxMesh *>(Att);
				if (!lMesh->IsTriangleMesh()) {
					FbxGeometryConverter converter = FbxGeometryConverter(fbxManager);
					FbxNodeAttribute *Attr = converter.Triangulate(lMesh, true);
					lMesh = (FbxMesh *)(Attr);
				}

				//Following is the SImplification
				Reduction_EdgesCollapse_UV(node, lMesh, fbxManager, fbxScene);

			}
		}
	}

	//MessageBox(NULL, "Export Succeed!", "Export", 0);
	fbxManager->Destroy();
}
void FBXSceneEncoder::loadModel(FbxNode* fbxNode, Node* node)
{
    FbxMesh* fbxMesh = fbxNode->GetMesh();
    if (!fbxMesh)
    {
        return;
    }
    if (fbxMesh->IsTriangleMesh())
    {
        Mesh* mesh = loadMesh(fbxMesh);
        Model* model = new Model();
        model->setMesh(mesh);
        node->setModel(model);
        loadSkin(fbxMesh, model);
        if (model->getSkin())
        {
            node->resetTransformMatrix();
        }
    }
}
Beispiel #4
0
int main(int argc, char **argv)
{
#ifndef _DEBUG
	if (argc != 2)
	{
		printf("invalid arg");
		return 0;
	}
	const char* filename = argv[1];
#else
	const char* filename = "*****@*****.**";
#endif
	
	output.open("output.txt", ios::out | ios::trunc);
	output2.open("output2.txt", ios::out | ios::trunc);
	output3.open("output3.txt", ios::out | ios::trunc);
	if (!output.is_open())
	{
		exit(1);
	}
	FbxManager* fm = FbxManager::Create();
	FbxIOSettings *ios = FbxIOSettings::Create(fm, IOSROOT);
	//ios->SetBoolProp(EXP_FBX_ANIMATION, false);
	ios->SetIntProp(EXP_FBX_COMPRESS_LEVEL, 9);
	
	ios->SetAllObjectFlags(true);
	fm->SetIOSettings(ios);

	FbxImporter* importer = FbxImporter::Create(fm, "");
	if (!importer->Initialize(filename, -1, fm->GetIOSettings()))
	{
		printf("error returned : %s\n", importer->GetStatus().GetErrorString());
		exit(-1);
	}

	FbxScene* scene = FbxScene::Create(fm, "myscene");

	importer->Import(scene);
	importer->Destroy();
	output << "some\n";
	output << "charcnt : " << scene->GetCharacterCount() << endl << "node cnt : " << scene->GetNodeCount() << endl;
	int animstackcnt = scene->GetSrcObjectCount<FbxAnimStack>();
	output << "animstackcnt : " << animstackcnt << endl;

	output << "------------" << endl;
	vector<FbxNode*> removableNodes;

	for (int i = 0; i < scene->GetNodeCount(); i++)
	{
		FbxNode* node = scene->GetNode(i);
		output << "scene's node " << i << " : " << node->GetName() << ", childcnt : " << node->GetChildCount();
		if (node->GetNodeAttribute())
		{
			output <<", att type : " << node->GetNodeAttribute()->GetAttributeType();
			if (node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::EType::eMesh)
			{
				FbxMesh* mesh = node->GetMesh();

				output << ", mem usage : " << mesh->MemoryUsage() << ", deformer cnt : " << mesh->GetDeformerCount(FbxDeformer::EDeformerType::eSkin) << endl;
				collapseMesh(mesh);
				FbxSkin* skin = (FbxSkin*) (mesh->GetDeformer(0, FbxDeformer::EDeformerType::eSkin));
				if (skin)
				{
					
					for (int cli = 0; cli < skin->GetClusterCount(); cli++)
					{
						FbxCluster* cluster = skin->GetCluster(cli);
						output << "\tcluster no." << cli << " has " << cluster->GetControlPointIndicesCount() << " connected verts" << endl;
						if (cluster->GetControlPointIndicesCount() == 0)
							removableNodes.push_back( cluster->GetLink() );
						
						//cluster->
						//skin->RemoveCluster(cluster);효과없음
					}

					
					
				}
				if (mesh->IsTriangleMesh())
				{
					output << "\tit's triangle mesh" << endl;
					
				}
				//mesh->RemoveDeformer(0);효과없음
			}
			else
				output << endl;
		}
		else
		{
			output << ", att type : none" << endl;
		}
	}

	for (int rni = 0; rni < removableNodes.size(); rni++)
	{
		FbxNode* rnd = removableNodes[rni];
		if (rnd && rnd->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::EType::eSkeleton)
		{
			output3 << rnd->GetName() << " node with no vert attached's curve : " << rnd->GetSrcObjectCount<FbxAnimCurve>() << "," << rnd->GetSrcObjectCount<FbxAnimCurveNode>() << endl;
		}
	}

	output << "-----------animinfo" << endl;
	int cubic = 0, linear = 0, cons = 0;
	for (int si = 0; si < animstackcnt; si++)
	{
		FbxAnimStack* stack = scene->GetSrcObject<FbxAnimStack>(si);
		for (int i = 0; i < stack->GetMemberCount<FbxAnimLayer>(); i++)
		{
			FbxAnimLayer* layer = stack->GetMember<FbxAnimLayer>(i);
			int curvenodecnt = layer->GetMemberCount<FbxAnimCurveNode>();
			int compositcnt = 0;
			for (int j = 0; j < curvenodecnt; j++)
			{
				FbxAnimCurveNode* cnode = layer->GetMember<FbxAnimCurveNode>(j);
				compositcnt += (cnode->IsComposite() ? 1 : 0);
			}
			output << "\tanimstack's layer " << i << " : " << layer->GetName() << ", curve node cnt : " << curvenodecnt << ", composit node cnt : " << compositcnt << endl;
			vector<FbxAnimCurveNode*> nodes2del;
			
			for (int j = 0; j < curvenodecnt; j++)
			{
				FbxAnimCurveNode* cnode = layer->GetMember<FbxAnimCurveNode>(j);
				output << "\t\tcurvenode " << j << " channel cnt : " << cnode->GetChannelsCount() << ", dst obj cnt " << cnode->GetDstObjectCount() << "(";
				for (int dsti = 0; dsti < cnode->GetDstObjectCount(); dsti++)
				{
					output << "," << cnode->GetDstObject(dsti)->GetName();
					if (cnode->GetDstObject(dsti)->GetSrcObjectCount() > 0)
						output << "<" << cnode->GetDstObject(dsti)->GetSrcObjectCount<FbxSkeleton>() << ">";
				}
				output << ")";
				FbxTimeSpan interval;
				if (cnode->GetAnimationInterval(interval))
				{
					output << ", start : " << interval.GetStart().GetTimeString() << ", end : " << interval.GetStop().GetTimeString() << endl;
				}
				else
				{
					nodes2del.push_back(cnode);
					output << ", no interval" << endl;
				}

				for (int chi = 0; chi < cnode->GetChannelsCount(); chi++)
				{
					
					int curvecnt = cnode->GetCurveCount(chi);
					output << "\t\t\tchannel." << chi << " curvecnt : " << curvecnt << endl;
					for (int ci = 0; ci < curvecnt; ci++)
					{
						FbxAnimCurve* curve = cnode->GetCurve(chi, ci);
						int keycnt = curve->KeyGetCount();
						output << "\t\t\t\tcurve no." << ci << " : key count : " << keycnt;
						output2 << "curve  " << ci << endl;
						
						vector<int> keys2Remove;
						for (int cki = 0; cki < keycnt; cki++)
						{
							FbxAnimCurveKey prevkey, currkey, nextkey;

							if (cki == 0 || cki == keycnt - 1)
								continue;
							
							currkey = curve->KeyGet(cki);
							prevkey = curve->KeyGet(cki-1);
							nextkey = curve->KeyGet(cki + 1);
							
							bool keepit = true;

							output2 << ci << "-" << cki;

//							keepit = keepTestHorizon(curve, prevkey, currkey, nextkey);
	//						if (keepit)
	//							keepit = slopkeepTest(curve, prevkey, currkey, nextkey);

							if (!keepit)
							{
								if (!(currkey.GetInterpolation() == FbxAnimCurveDef::EInterpolationType::eInterpolationConstant && nextkey.GetInterpolation() != FbxAnimCurveDef::EInterpolationType::eInterpolationConstant))
									keys2Remove.push_back(cki);
							}
						}
						for (int kri = keys2Remove.size() - 1; kri >= 0; kri--)
						{
							
							//curve->KeyRemove(keys2Remove[kri]);
						}
						output2 << endl;
						//output << ", cubic:linear:const : " << cubic << ":" << linear << ":" << cons << endl;
						if (keys2Remove.size() > 0)
							output << ", " << keys2Remove.size() << " keys removed";

						keycnt = curve->KeyGetCount();
						
					}

				}
			}
			//이부분은 별로 효과없음
			/*
			for (int di = 0; di < nodes2del.size(); di++)
			{
				layer->RemoveMember(nodes2del[di]);
			}
			*/
			
		}
	}
	output << "cubic:linear:const  " << cubic << ":" << linear << ":" << cons << endl;
	FbxExporter* exporter = FbxExporter::Create(fm, "");
	const char* outFBXName = "after.fbx";

	bool exportstatus = exporter->Initialize(outFBXName, -1, fm->GetIOSettings());
	if (exportstatus == false)
	{
		puts("err export fail");
	}
	exporter->Export(scene);
	exporter->Destroy();
	scene->Destroy();
	
	ios->Destroy();
	fm->Destroy();
	output.close();
	output2.close();
	output3.close();
	return 0;
}
void fbxLoader2::processMesh(FbxNode* node)
{
	FbxMesh* mesh = node->GetMesh();

	this->readAnimationWeigths(mesh);

	if(mesh!=NULL && mesh->IsTriangleMesh())
	{
		for (int i = 0; i<mesh->GetControlPointsCount(); i++)
		{
			readVertex(mesh, i, &vertex[i]);
			vertexArray[i].position = D3DXVECTOR3(vertex[i]);
		}

		int a = mesh->GetPolygonVertexCount();

		for (int i = 0; i<mesh->GetPolygonVertexCount(); i++)
		{
			readUV(mesh, i, 0, &uv[i]);
			readNormal(mesh, i, &normal[i]);
			indices[i].indice = mesh->GetPolygonVertices()[i];
			indices[i].normal1 = normal[i];
			indices[i].uv1 = uv[i];
			indicesMeshCount++;
		}
	}

	//vertexLists.push_back(vertexArray);
	indiceLists.push_back(indices);

	FbxAnimStack* pAnimStack = FbxCast<FbxAnimStack>(scene->GetSrcObject(FBX_TYPE(FbxAnimStack)));
	int numAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(FbxAnimLayer));

	this->setBindPoseCluster(node);

	for (int i = 0; i < numAnimLayers; i++)
	{
		FbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(FbxAnimLayer), i);
		FbxAnimCurve* animCv = this->findSkeletonRootBone(scene->GetRootNode())->GetChild(0)->LclTranslation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);

		if (animCv)
		{
			FbxTimeSpan animationLength;
			int p = animCv->KeyGetCount();
			animCv->GetTimeInterval(animationLength);

			for(int j = 0; j<animationStructure->GetFramesNumber();j++)
			{
				FbxTime timeKey = animCv->KeyGet(j).mTime;
				//FbxTime interval = (duration/p)*j + animationLength.GetStart();

				//int intervalVal = (duration.GetSecondCount()/p)*j + animationLength.GetStart().GetSecondCount();
				const FbxTime pTime = animCv->KeyGet(j).mTime;


				FbxAMatrix pGlobalPos = GetGlobalPosition(node, pTime, scene->GetPose(j));

				ComputeSkinDeformation(pGlobalPos, mesh, timeKey, scene->GetPose(j), j);
			}
		}
	}

	for(int i = 0; i<node->GetChildCount(); i++)
	{
		processMesh(node->GetChild(i));
	}
}
Beispiel #6
0
Model* FbxModelLoader::LoadModel(const char* fileName)
{
	Model* model = nullptr;

	if (!m_importer->Initialize(fileName, -1, m_manager->GetIOSettings()))
	{
		return nullptr;
	}

	FbxScene* lScene = FbxScene::Create(m_manager, "myscene");
	m_importer->Import(lScene);


	FbxNode* lRootNode = lScene->GetRootNode();

	if (lRootNode)
	{
		if (lRootNode->GetChildCount() > 0)
		{
			FbxNode* lNode = lRootNode->GetChild(0);

			FbxMesh* lMesh = lNode->GetMesh();

			

			if (!lMesh)
				return nullptr;

			
			std::ofstream file;

			file.open("DataFromFbxVector.txt");
			char* buffer = new char[1024];

			sprintf_s(buffer, 1024, "Number of children in Root: %d\n\n\n\n", lRootNode->GetChildCount());

			file << buffer;

			if (lMesh->IsTriangleMesh())
				file << "It's a triangle mesh!";
			else
				file << "It's NOT a triangle mesh!";

			


			FbxVector4* vertexArray = lMesh->GetControlPoints();

			for (int i = 0; i < lMesh->GetControlPointsCount(); i++)
			{
				sprintf(buffer, "(%f, %f, %f)\n", vertexArray[i].mData[0], vertexArray[i].mData[1], vertexArray[i].mData[2]);
				file << buffer;
			}

			delete buffer;

			file.close();

			Polygon* polygons = new Polygon[lMesh->GetPolygonCount()];

			int polygonCount = lMesh->GetPolygonCount();

			int index = 0;

			buffer = new char[1024];
			file.open("DataFromPolygons.txt");

			for (int i = 0; i < lMesh->GetPolygonCount(); i++)
			{
				

				index = lMesh->GetPolygonVertex(i, 0);

				sprintf(buffer, "\n\nPolygon #%d\nPolygon Vertex Index #%d: ", i, index);
				file << buffer;

				polygons[i].vertex1.x = (float)vertexArray[index].mData[0];
				polygons[i].vertex1.y = (float)vertexArray[index].mData[1];
				polygons[i].vertex1.z = (float)vertexArray[index].mData[2];

				sprintf(buffer, "(%f, %f, %f)\n", polygons[i].vertex1.x, polygons[i].vertex1.y, polygons[i].vertex1.z);
				file << buffer;


				
				index = lMesh->GetPolygonVertex(i, 1);
				sprintf(buffer, "Polygon Vertex Index #%d: ", index);
				file << buffer;

				polygons[i].vertex2.x = (float)vertexArray[index].mData[0];
				polygons[i].vertex2.y = (float)vertexArray[index].mData[1];
				polygons[i].vertex2.z = (float)vertexArray[index].mData[2];
				sprintf(buffer, "(%f, %f, %f)\n", polygons[i].vertex2.x, polygons[i].vertex2.y, polygons[i].vertex2.z);
				file << buffer;
				
				index = lMesh->GetPolygonVertex(i, 2);
				sprintf(buffer, "Polygon Vertex Index #%d: ", index);
				file << buffer;

				polygons[i].vertex3.x = (float)vertexArray[index].mData[0];
				polygons[i].vertex3.y = (float)vertexArray[index].mData[1];
				polygons[i].vertex3.z = (float)vertexArray[index].mData[2];
				sprintf(buffer, "(%f, %f, %f)\n", polygons[i].vertex3.x, polygons[i].vertex3.y, polygons[i].vertex3.z);
				file << buffer;
			}

			file.close();
			delete buffer;


			model = new Model();
			model->Vertices = new DirectX::XMFLOAT3[polygonCount * 3];
			model->NumVertices = polygonCount * 3;

			file.open("DataFromPolygonToModelTransfer.txt");
			buffer = new char[1024];

			for (int i = 0; i < lMesh->GetPolygonCount() * 3; i += 3)
			{
				model->Vertices[i] = polygons[i/3].vertex1;
				model->Vertices[i+1] = polygons[i/3].vertex2;
				model->Vertices[i+2] = polygons[i/3].vertex3;
			
				sprintf_s(buffer, 1024, "Polygon #%d:\n(%f, %f, %f)\n(%f, %f, %f)\n(%f, %f, %f)\n\n"
					, i / 3
					, model->Vertices[i].x, model->Vertices[i].y, model->Vertices[i].z
					, model->Vertices[i+1].x, model->Vertices[i+1].y, model->Vertices[i+1].z
					, model->Vertices[i+2].x, model->Vertices[i+2].y, model->Vertices[i+2].z);
			
				file << buffer;
			}

			delete buffer;
			file.close();


			// delete [] polygons;
		}
		else
			return nullptr;
	}
	else
		return nullptr;



	return model;
}
	std::shared_ptr<Node> FBXConverter::LoadHierarchy(std::shared_ptr<Node> parent, FbxNode* fbxNode, FbxManager* fbxManager)
	{
		FbxMesh* mesh = nullptr;
		std::shared_ptr<Node> node = std::make_shared<Node>();

		node->Name = fbxNode->GetName();

		auto attribute_ = fbxNode->GetNodeAttribute();

		if (attribute_ != nullptr)
		{
			auto attributeType = attribute_->GetAttributeType();
			switch (attributeType)
			{
			case FbxNodeAttribute::eMesh:
				mesh = fbxNode->GetMesh();

				if (!mesh->IsTriangleMesh())
				{
					FbxGeometryConverter converter(fbxManager);
					auto mesh_tri = (FbxMesh*) converter.Triangulate(mesh, false);
				
					if (mesh_tri != nullptr)
					{
						mesh = mesh_tri;
					}
				}

				node->MeshData = LoadMesh(mesh);
				break;
			case FbxNodeAttribute::eSkeleton:
				break;
			default:
				break;
			}
		}
		else
		{
			// This is root.
		}

		// load transforms
		EFbxRotationOrder fbxRotationOrder;
		fbxNode->GetRotationOrder(FbxNode::eDestinationPivot, fbxRotationOrder);
		node->RotationOrder = fbxRotationOrder;

		// default transform
		auto lclT = fbxNode->LclTranslation.Get();
		auto lclR = fbxNode->LclRotation.Get();
		auto lclS = fbxNode->LclScaling.Get();

		node->Translation[0] = lclT[0];
		node->Translation[1] = lclT[1];
		node->Translation[2] = lclT[2];

		node->Rotation[0] = lclR[0];
		node->Rotation[1] = lclR[1];
		node->Rotation[2] = lclR[2];

		node->Scaling[0] = lclS[0];
		node->Scaling[1] = lclS[1];
		node->Scaling[2] = lclS[2];

		for (auto i = 0; i < fbxNode->GetChildCount(); i++)
		{
			auto childNode = LoadHierarchy(node, fbxNode->GetChild(i), fbxManager);
			if (childNode != nullptr)
			{
				node->Children.push_back(childNode);
			}
		}

		return node;
	}