Exemple #1
0
	std::shared_ptr<Mesh> FbxParser::CreateMesh(GameObjectPtr node, FbxNode * fbxNode)
	{
		Mesh::Ptr mesh = Mesh::Create(fbxNode->GetName());

		FbxMesh* fbxMesh = static_cast<FbxMesh*>(fbxNode->GetNodeAttribute());

		int polygonCount = fbxMesh->GetPolygonCount();
		int indicesCount = polygonCount * 3;
			
		mesh->Positions.Data.reserve(indicesCount * 3);
		mesh->Indices.Data.reserve(indicesCount);
		mesh->Colors.Data.reserve(indicesCount * 3);

		for (int i = 0; i < polygonCount; ++i) {
			ASSERT(fbxMesh->GetPolygonSize(i) <= 3,  "Error: triangulate %s", mesh->GetName());

			for (int jj = 0; jj < 3; ++jj) {
				int ctrPointIdx = fbxMesh->GetPolygonVertex(i, jj);
				// TODO 
				// Use Triangle Strip instead of triangle list
				auto position = fbxMesh->GetControlPointAt(ctrPointIdx);

				mesh->Positions.Data.push_back((double*)&position);

				int indices = i * 3 + jj;
				mesh->Indices.Data.push_back(indices);

				auto color = fbxMesh->GetElementVertexColor(ctrPointIdx);
				mesh->Colors.Data.push_back((double*)&color);
			}
		}
		mesh->UpdateBuffer();
		return mesh;
	}
Exemple #2
0
//===============================================================================================================================
void FBXLoader::LoadControlPoints(FbxNode* node)
{
	FbxMesh* mesh = node->GetMesh();
	uint32 controlPointCount = mesh->GetControlPointsCount();
	
	for (uint32 i = 0; i < controlPointCount; ++i)
	{
		ZShadeSandboxMesh::PhysicalPoint* currCtrlPoint = new ZShadeSandboxMesh::PhysicalPoint();
		
		XMFLOAT3 position;
		position.x = static_cast<float>(mesh->GetControlPointAt(i).mData[0]);
		position.y = static_cast<float>(mesh->GetControlPointAt(i).mData[1]);
		position.z = static_cast<float>(mesh->GetControlPointAt(i).mData[2]);
		currCtrlPoint->position = position;
		
		mControlPoints[i] = currCtrlPoint;
	}
}
Exemple #3
0
		void FbxLoader::ProcessControlPoints(FbxNode* node, Node& meshNode)
		{
			FbxMesh* currMesh = node->GetMesh();
			if(!currMesh)
				return;

			const int ctrlPointCount = currMesh->GetControlPointsCount();
			meshNode.controlPoints.resize(ctrlPointCount);

			for(int i = 0; i < ctrlPointCount; i++) {
				FbxVector4 p = currMesh->GetControlPointAt(i);
				auto& cp = meshNode.controlPoints[i];
				cp.position = { (float)p[0], (float)p[1], (float)p[2] };
			}
		}
void MeshImporter::LoadNodeMesh(FbxNode* node, ID3D11Device3* device,
	ID3D11DeviceContext3* context)
{
	unsigned int numPolygons = 0;
	unsigned int numVertices = 0;
	unsigned int numIndices = 0;
	unsigned int numPolygonVert = 0;

	if (node->GetNodeAttribute() != NULL &&
		node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh)
	{
		//PrintNode(node);
		
		// Create meshes
		FbxMesh* fbxMesh = node->GetMesh();
		
		numPolygons = fbxMesh->GetPolygonCount();
		numIndices = fbxMesh->GetPolygonVertexCount();
		numVertices = fbxMesh->GetControlPointsCount();
		
		// Do not use indexed drawing method
		numVertices = numIndices;

		vector<Vertex> vertices(numVertices);
		vector<unsigned int> indices(numIndices);

		numPolygonVert = 3;
		//assert(numPolygonVert == 3);

		FbxVector4* controlPoints = fbxMesh->GetControlPoints();

		int* indices_array = fbxMesh->GetPolygonVertices();

		// Need to be changed for optimization
		for (unsigned int i = 0; i < numIndices; i++)
		{
			indices[i] = indices_array[i];

			vertices[i].pos.x = (float)fbxMesh->GetControlPointAt(indices[i]).mData[0];// / 1000.0f;
			vertices[i].pos.y = (float)fbxMesh->GetControlPointAt(indices[i]).mData[1];// / 1000.0f;
			vertices[i].pos.z = (float)fbxMesh->GetControlPointAt(indices[i]).mData[2];// / 1000.0f;
		}

		// For indexed drawing
		/*for (unsigned int i = 0; i < numVertices; i++)
		{
			vertices[i].pos.x = (float)controlPoints[i].mData[0];
			vertices[i].pos.y = (float)controlPoints[i].mData[1];
			vertices[i].pos.z = (float)controlPoints[i].mData[2];
		}*/

		LoadUV(fbxMesh, &vertices[0], &indices[0]);

		//OutputDebugStringA(("\n number of polygons: " + to_string(numPolygons) + " \n").c_str());
		//OutputDebugStringA(("\n number of indices: " + to_string(numIndices) + " \n").c_str());
		//OutputDebugStringA(("\n number of vertices: " + to_string(vertices.size()) + " \n").c_str());

		// Read mesh base transform matrix
		FbxAMatrix fbxGlobalMeshBaseMatrix = node->EvaluateGlobalTransform().Inverse().Transpose();
		XMFLOAT4X4 globalMeshBaseMatrix;

		for (int r = 0; r < 4; r++)
		{
			//PrintTab("Global mesh base mat: " + to_string(fbxGlobalMeshBaseMatrix.mData[r][0]));

			for (int c = 0; c < 4; c++)
			{
				globalMeshBaseMatrix.m[r][c] = (float)fbxGlobalMeshBaseMatrix.mData[r][c];
			}
		}

		// To be considered when importing Maya fbx model
		//FbxAMatrix geoMatrix = GetTransformMatrix(node);

		//ConvertFbxAMatrixToDXMatrix(&globalMeshBaseMatrix, fbxGlobalMeshBaseMatrix);

		MeshEntry mesh;
		mesh.vertices = vertices;
		mesh.indices = indices;
		mesh.numVertices = numVertices;
		mesh.numIndices = numIndices;
		mesh.fbxNode = node;
		mesh.globalMeshBaseMatrix = globalMeshBaseMatrix;

		// Load materials and textures
		LoadMaterials(node, &mesh, device, context);

		// Load weights
		LoadWeight(fbxMesh, &mesh);

		// Set to be clockwise, must be done after reading uvs, normals, weights and etc
		for (auto it = mesh.vertices.begin(); it != mesh.vertices.end(); it += 3)
		{
			swap(*it, *(it + 2));
		}

		model->entries.push_back(mesh);
	}

	int numChild = node->GetChildCount();

	for (int i = 0; i < numChild; i++)
	{
		LoadNodeMesh(node->GetChild(i), device, context);
	}
}
void MeshImporter::LoadNodeMesh(FbxNode* node, ID3D11Device3* device,
	ID3D11DeviceContext3* context)
{
	unsigned int numPolygons = 0;
	unsigned int numVertices = 0;
	unsigned int numIndices = 0;
	unsigned int numPolygonVert = 0;

	if (node->GetNodeAttribute() != NULL &&
		node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh)
	{
		//PrintNode(node);

		// Create meshes
		FbxMesh* fbxMesh = node->GetMesh();
		numPolygons = fbxMesh->GetPolygonCount();
		numIndices = fbxMesh->GetPolygonVertexCount();
		numVertices = fbxMesh->GetControlPointsCount();

		// Do not use indexed drawing method
		numVertices = numIndices;

		vector<Vertex> vertices(numVertices);
		vector<unsigned int> indices(numIndices);

		numPolygonVert = 3;
		//assert(numPolygonVert == 3);

		FbxVector4* controlPoints = fbxMesh->GetControlPoints();

		int* indices_array = fbxMesh->GetPolygonVertices();

		// Need to be changed for optimization
		for (unsigned int i = 0; i < numIndices; i++)
		{
			indices[i] = indices_array[i];

			vertices[i].pos.x = (float)fbxMesh->GetControlPointAt(indices[i]).mData[0] / 10000.0f;
			vertices[i].pos.y = (float)fbxMesh->GetControlPointAt(indices[i]).mData[1] / 10000.0f;
			vertices[i].pos.z = (float)fbxMesh->GetControlPointAt(indices[i]).mData[2] / 10000.0f;
		}

		// For indexed drawing
		/*for (unsigned int i = 0; i < numVertices; i++)
		{
		vertices[i].pos.x = (float)controlPoints[i].mData[0];// / 25.0f;
		vertices[i].pos.y = (float)controlPoints[i].mData[1];// / 25.0f;
		vertices[i].pos.z = (float)controlPoints[i].mData[2];// / 25.0f;
		}*/

		LoadUV(fbxMesh, &vertices[0], &indices[0]);

		// Set to be clockwise, must be done after reading uvs and normals
		for (auto it = vertices.begin(); it != vertices.end(); it += 3)
		{
			std::swap(*it, *(it + 2));
		}

		//OutputDebugStringA(("\n number of polygons: " + to_string(numPolygons) + " \n").c_str());
		//OutputDebugStringA(("\n number of indices: " + to_string(numIndices) + " \n").c_str());
		//OutputDebugStringA(("\n number of vertices: " + to_string(vertices.size()) + " \n").c_str());

		ModelObj::MeshEntry mesh;
		mesh.vertices = vertices;
		mesh.indices = indices;
		mesh.numVertices = numVertices;
		mesh.numIndices = numIndices;

		LoadMaterials(node, &mesh, device, context);

		model->entries.push_back(mesh);
	}

	for (int i = 0; i < node->GetChildCount(); i++)
	{
		LoadNodeMesh(node->GetChild(i), device, context);
	}
}
	HRESULT FBXLoader::loadFBXFile(char* filePath, VertexBuffer** vBuf, IndexBuffer** iBuf, Renderer* renderer, bool centerShift)
	{
		if (g_pFbxSdkManager == nullptr)
		{
			g_pFbxSdkManager = FbxManager::Create();

			FbxIOSettings* pIOsettings = FbxIOSettings::Create(g_pFbxSdkManager, IOSROOT);
			g_pFbxSdkManager->SetIOSettings(pIOsettings);
		}

		this->shiftCenter = centerShift;

		FbxImporter* pImporter = FbxImporter::Create(g_pFbxSdkManager, "");
		FbxScene* pFbxScene = FbxScene::Create(g_pFbxSdkManager, "");

		bool bSuccess = pImporter->Initialize(filePath, -1, g_pFbxSdkManager->GetIOSettings());
		if (!bSuccess) return E_FAIL;

		bSuccess = pImporter->Import(pFbxScene);
		if (!bSuccess) return E_FAIL;

		FbxAxisSystem sceneAxisSystem = pFbxScene->GetGlobalSettings().GetAxisSystem();
		FbxAxisSystem DirectXAxisSystem(FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eLeftHanded);

		if (sceneAxisSystem != DirectXAxisSystem)
		{
			DirectXAxisSystem.ConvertScene(pFbxScene);
		}

		pImporter->Destroy();

		FbxNode* pFbxRootNode = pFbxScene->GetRootNode();

		if (pFbxRootNode)
		{
			// Check if the getChildCount is > 1  TODO
			int test = pFbxRootNode->GetChildCount();

			for (int i = 0; i < pFbxRootNode->GetChildCount(); i++)
			{
				FbxNode* pFbxChildNode = pFbxRootNode->GetChild(i);

				if (pFbxChildNode->GetNodeAttribute() == NULL)
					continue;

				FbxNodeAttribute::EType AttributeType = pFbxChildNode->GetNodeAttribute()->GetAttributeType();

				if (AttributeType != FbxNodeAttribute::eMesh)
					continue;

				FbxMesh* pMesh = (FbxMesh*)pFbxChildNode->GetNodeAttribute();

				int numControlPoints = pMesh->GetControlPointsCount();
				bool initial = true;
				float xMin, yMin, zMin;
				float xMax, yMax, zMax;
				float xIn, yIn, zIn;

				float xCenter, yCenter, zCenter;

				if (this->shiftCenter){

					for (int c = 0; c < numControlPoints; c++) {
						xIn = (float)pMesh->GetControlPointAt(c).mData[0];
						yIn = (float)pMesh->GetControlPointAt(c).mData[1];
						zIn = (float)pMesh->GetControlPointAt(c).mData[2];

						if (initial) {
							xMin = xIn;
							yMin = yIn;
							zMin = zIn;

							xMax = xIn;
							yMax = yIn;
							zMax = zIn;

							initial = false;
						}
						else {
							if (xIn < xMin) {
								xMin = xIn;
							}

							if (yIn < yMin) {
								yMin = yIn;
							}

							if (zIn < zMin) {
								zMin = zIn;
							}

							if (xIn > xMax) {
								xMax = xIn;
							}

							if (yIn > yMax) {
								yMax = yIn;
							}

							if (zIn > zMax) {
								zMax = zIn;
							}
						}
					}
					xCenter = (xMin + xMax) / 2.0f;
					yCenter = (yMin + yMax) / 2.0f;
					zCenter = (zMin + zMax) / 2.0f;
				}
				else {
					xCenter = 0;
					yCenter = 0;
					zCenter = 0;
				}

				FbxVector4* pVertices = pMesh->GetControlPoints();
				int vertexCount = pMesh->GetPolygonVertexCount();

				//Vertex vertex;
				Vertex* vertexArray = new Vertex[vertexCount];
				//Vertex vertexArray[2592];


				int numIndices = vertexCount;
				unsigned int* indexArray = new unsigned int[numIndices];


				FbxVector4 fbxNorm(0, 0, 0, 0);
				FbxVector2 fbxUV(0, 0);
				bool isMapped;

				int vertexIndex = 0;

				// Loop iterates through the polygons and fills the vertex and index arrays for the buffers
				for (int j = 0; j < pMesh->GetPolygonCount(); j++)
				{
					int iNumVertices = pMesh->GetPolygonSize(j);

					assert(iNumVertices == 3);

					//1st vertex
					int controlIndex = pMesh->GetPolygonVertex(j, 2);
					pMesh->GetPolygonVertexUV(j, 2, "map1", fbxUV, isMapped);
					pMesh->GetPolygonVertexNormal(j, 2, fbxNorm);

					vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter;
					vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter;
					vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter;

					vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0];
					vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1];

					vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0];
					vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1];
					vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2];

					indexArray[vertexIndex] = vertexIndex;
					vertexIndex++;

					//2nd vertex
					controlIndex = pMesh->GetPolygonVertex(j, 1);
					pMesh->GetPolygonVertexUV(j, 1, "map1", fbxUV, isMapped);
					pMesh->GetPolygonVertexNormal(j, 1, fbxNorm);

					vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter;
					vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter;
					vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter;

					vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0];
					vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1];

					vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0];
					vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1];
					vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2];

					indexArray[vertexIndex] = vertexIndex;
					vertexIndex++;

					//3rd vertex
					controlIndex = pMesh->GetPolygonVertex(j, 0);
					pMesh->GetPolygonVertexUV(j, 0, "map1", fbxUV, isMapped);
					pMesh->GetPolygonVertexNormal(j, 0, fbxNorm);

					vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter;
					vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter;
					vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter;

					vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0];
					vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1];

					vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0];
					vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1];
					vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2];

					indexArray[vertexIndex] = vertexIndex;
					vertexIndex++;
				}

				// Generate vertex and index buffers from the vertex and index arrays
				*vBuf = renderer->createVertexBuffer(vertexArray, vertexCount);
				*iBuf = renderer->createIndexBuffer(indexArray, numIndices);

				delete[] vertexArray;
				delete[] indexArray;
			}
		}
		return S_OK;
	}
Exemple #7
0
	void importFBXNode(
		FbxNode *node, 
		vector<Vector3> &vertices, 
		vector<Color> &colors, 
		vector<Vector2> &uvs, 
		vector<Vector3> &normals,
		vector<uint32> &elements) {

		FbxNode *childNode = 0;
		int numKids = node->GetChildCount();
		for ( int i=0 ; i<numKids ; i++)
		{
			childNode = node->GetChild(i);
			FbxMesh *mesh = childNode->GetMesh();

			if ( mesh != NULL )
			{
				auto offset = node->GetGeometricTranslation(FbxNode::eSourcePivot);

				//================= Get Vertices ====================================
				int baseline = vertices.size();
				int numVerts = mesh->GetControlPointsCount();

				for ( int j=0; j<numVerts; j++)
				{
					FbxVector4 vert = mesh->GetControlPointAt(j);
					vertices.push_back(
						Vector3(vert.mData[0], vert.mData[1], vert.mData[2])
						/*+ Vector3(offset.mData[0], offset.mData[1], offset.mData[2])*/);
					colors.push_back(Vector3(1, 1, 1));
					uvs.push_back(Vector2(0, 0));
				}

				//================= Get Indices ====================================
				int numIndices=mesh->GetPolygonVertexCount();
				int *indicesRaw = mesh->GetPolygonVertices();
				for (int j = 0; j < numIndices; j++) {
					elements.push_back(indicesRaw[j] + baseline);
				}

				int cnt = 0;
				int polygonCount = mesh->GetPolygonCount();
				for (int j = 0; j < polygonCount; ++j) {

					FbxLayerElementArrayTemplate<FbxVector2>* uvVertices= 0;
					mesh->GetTextureUV(&uvVertices, FbxLayerElement::eTextureDiffuse);

					for (int k = 0; k < mesh->GetPolygonSize(j); ++k) {

						FbxVector2 uv = (*uvVertices)[mesh->GetTextureUVIndex(j, k)];

						uvs[indicesRaw[cnt] + baseline].x = uv[0];
						uvs[indicesRaw[cnt] + baseline].y = uv[1];
						cnt++;
					}
				}
			}

			importFBXNode(childNode, vertices, colors, uvs, normals, elements);
		}
	}