Loading FBX with Directx 11

Started by
14 comments, last by isu diss 6 years, 1 month ago

I tried to build what you described. I couldn't do it. I need help!

Advertisement

@galop1n I managed to write std::map code. But my std::map code doesn't work.

it doesn't generate duplicate vertices. For example, when I load Plane.fbx, it gives me the vertex array of

-5 -5 0

5 -5 0

-5 5 0

5 5 0

0 0 0

0 0 0

the index array is simply, 0, 1, 2, 3, 4, 5 not 0, 1, 2, 2, 1, 3

Can you help me?


bool operator < ( const FBXVTX &lValue,  const FBXVTX &rValue)
{
    if (lValue.Position.x != rValue.Position.x)   return(lValue.Position.x < rValue.Position.x);
    if (lValue.Position.y != rValue.Position.y)   return(lValue.Position.y < rValue.Position.y);
    if (lValue.Position.z != rValue.Position.z)   return(lValue.Position.z < rValue.Position.z);

    if (lValue.TextureCoord.x != rValue.TextureCoord.x)   return(lValue.TextureCoord.x < rValue.TextureCoord.x);
    if (lValue.TextureCoord.y != rValue.TextureCoord.y)   return(lValue.TextureCoord.y < rValue.TextureCoord.y);

    if (lValue.Normal.x != rValue.Normal.x)   return(lValue.Normal.x < rValue.Normal.x);
    if (lValue.Normal.y != rValue.Normal.y)   return(lValue.Normal.y < rValue.Normal.y);
    return(lValue.Normal.z < rValue.Normal.z);
}

struct FBXVTX
{
	XMFLOAT3 Position;
	XMFLOAT2 TextureCoord;
	XMFLOAT3 Normal;
};

std::map< FBXVTX, int > myVertsMap;
std::vector<FBXVTX> myVerts;
std::vector<int> myInds;

HRESULT FBXLoader::Open(HWND hWnd, char* Filename, bool UsePositionOnly)
{
	HRESULT hr = S_OK;
	if (FBXM)
	{
		FBXIOS = FbxIOSettings::Create(FBXM, IOSROOT);
		FBXM->SetIOSettings(FBXIOS);

		FBXI = FbxImporter::Create(FBXM, "");

		if (!(FBXI->Initialize(Filename, -1, FBXIOS)))
		{
			hr = E_FAIL;
			MessageBox(hWnd, (wchar_t*)FBXI->GetStatus().GetErrorString(), TEXT("ALM"), MB_OK);
		}

		FBXS = FbxScene::Create(FBXM, "REALMS"); 
		if (!FBXS)
		{
			hr = E_FAIL;
			MessageBox(hWnd, TEXT("Failed to create the scene"), TEXT("ALM"), MB_OK);
		}

		if (!(FBXI->Import(FBXS)))
		{
			hr = E_FAIL;
			MessageBox(hWnd, TEXT("Failed to import fbx file content into the scene"), TEXT("ALM"), MB_OK);
		}

		FbxAxisSystem OurAxisSystem = FbxAxisSystem::DirectX;

		FbxAxisSystem SceneAxisSystem = FBXS->GetGlobalSettings().GetAxisSystem();
		if(SceneAxisSystem != OurAxisSystem)
		{
			FbxAxisSystem::DirectX.ConvertScene(FBXS);
		}

		FbxSystemUnit SceneSystemUnit = FBXS->GetGlobalSettings().GetSystemUnit();
		if( SceneSystemUnit.GetScaleFactor() != 1.0 )
		{
			FbxSystemUnit::cm.ConvertScene( FBXS );
		}

		if (FBXI)
			FBXI->Destroy();

		FbxNode*	MainNode = FBXS->GetRootNode();
		int			NumKids = MainNode->GetChildCount();
		FbxNode*	ChildNode = NULL;

		for (int i=0; i<NumKids; i++)
		{
			ChildNode = MainNode->GetChild(i);
			FbxNodeAttribute* NodeAttribute = ChildNode->GetNodeAttribute();
			if (NodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
			{
				FbxMesh* Mesh = ChildNode->GetMesh();

				if (UsePositionOnly)
				{
					NumVertices = Mesh->GetControlPointsCount();//number of vertices
					MyV = new XMFLOAT3[NumVertices];
					for (DWORD j = 0; j < NumVertices; j++)
					{
						FbxVector4 Vertex = Mesh->GetControlPointAt(j);//Gets the control point at the specified index. 
						MyV[j] = XMFLOAT3((float)Vertex.mData[0], (float)Vertex.mData[1], (float)Vertex.mData[2]);

					}

					NumIndices = Mesh->GetPolygonVertexCount();//number of indices
					MyI = (DWORD*)Mesh->GetPolygonVertices();//index array
				}
				else
				{
					FbxLayerElementArrayTemplate<FbxVector2>* uvVertices = NULL;
					Mesh->GetTextureUV(&uvVertices);

					int idx = 0;
					for (int i = 0; i < Mesh->GetPolygonCount(); i++)//polygon(=mostly triangle) count
					{
						for (int j = 0; j < Mesh->GetPolygonSize(i); j++)//retrieves number of vertices in a polygon
						{
							FBXVTX myVert;
							int p_index = 3*i+j;
							int t_index = Mesh->GetTextureUVIndex(i, j);

							FbxVector4 Vertex = Mesh->GetControlPointAt(p_index);//Gets the control point at the specified index. 
							myVert.Position = XMFLOAT3((float)Vertex.mData[0], (float)Vertex.mData[1], (float)Vertex.mData[2]);

							FbxVector4 Normal;
							Mesh->GetPolygonVertexNormal(i, j, Normal);
							myVert.Normal = XMFLOAT3((float)Normal.mData[0], (float)Normal.mData[1], (float)Normal.mData[2]);
							
							FbxVector2 uv = uvVertices->GetAt(t_index);
							myVert.TextureCoord = XMFLOAT2((float)uv.mData[0], (float)uv.mData[1]);

							if ( myVertsMap.find( myVert ) != myVertsMap.end() )
								myInds.push_back( myVertsMap[ myVert ]);
							else
							{
								myVertsMap.insert( std::pair<FBXVTX, int> (myVert, idx ) );
								myVerts.push_back(myVert);
								myInds.push_back(idx);
								idx++;
							}
						}
					}
				}
			}
		}
	}
	else
	{
		hr = E_FAIL;
		MessageBox(hWnd, TEXT("Failed to create the FBX Manager"), TEXT("ALM"), MB_OK);
	}
	return hr;
}

 

Now help me, I made my own code and provided it.

@isu diss I think you should work a little bit on your manners here in the forum ;-)

Anyways, when the UV is stored per index you have to resolve this list first and duplicate the vertices if more than one index is using the same vertex. You need a list of homogenous pairs of vertex and texture coordinate.

x y z u v, x y z u v, ....

So everytime you are "reusing" a vertex in the indices you have to copy it and also modify the index in the list to the new copied one.

When you just want  to load the model and don't do this for educational purposes, may have a look at Assimp. This library is doing all the hard stuff of nearly all 3D-formats for you and gives you a simpler data structure which can be just easily.

@AuskennfuchsThanks for your advice on manners. @galop1nThanks for your big help. I finally managed to do it. std::map code works like a charm. All I did is change p_index to its correct index, the value, returned by Mesh->GetPolygonVertex(i, j) and then magic happned. Anyone who wishes to make a fbx loader, can use my code. It works!!!  Thanks everybody for support. Case closed.

This topic is closed to new replies.

Advertisement