FBX 계층 구조
현 수업까지 사용한 FBX의 구조
VertexColor와 TextureCoordinate 읽기
예제
void TFbxLoader::ParseMesh(FbxMesh* pFbxMesh)
{
FbxNode* pNode = pFbxMesh->GetNode();
TFbxObject* pObject = new TFbxObject;
FbxLayer* pFbxLayer = pFbxMesh->GetLayer(0);
FbxLayerElementUV* VertexUVSet=pFbxLayer->GetUVs();
FbxLayerElementVertexColor* VertexColorSet = pFbxLayer->GetVertexColors();
FbxLayerElementMaterial* MaterialSet = pFbxLayer->GetMaterials();
std::string szFileName;
int iNumMtrl = pNode->GetMaterialCount();
std::vector< C_STR> texList;
texList.resize(iNumMtrl);
for (int iMtrl = 0; iMtrl < iNumMtrl; iMtrl++)
{
FbxSurfaceMaterial* pSurface = pNode->GetMaterial(iMtrl);
if (pSurface)
{
auto property = pSurface->FindProperty(FbxSurfaceMaterial::sDiffuse);
if (property.IsValid())
{
const FbxFileTexture* tex = property.GetSrcObject<FbxFileTexture>(0);
szFileName = tex->GetFileName();
texList[iMtrl] = szFileName;
}
}
}
if (iNumMtrl == 1)
{
pObject->m_szTextureName = I_Tex.GetSplitName(szFileName);
}
if (iNumMtrl > 1)
{
pObject->vbDataList.resize(iNumMtrl);
pObject->vbTexList.resize(iNumMtrl);
for (int iTex = 0; iTex < iNumMtrl; iTex++)
{
pObject->vbTexList[iTex] = I_Tex.GetSplitName(
texList[iTex]);
}
}
int iNumPolyCount = pFbxMesh->GetPolygonCount();
int iNumFace = 0;
int iBasePolyIndex = 0;
int iSubMtrl = 0;
FbxVector4* pVertexPositions = pFbxMesh->GetControlPoints();
for (int iPoly = 0; iPoly < iNumPolyCount; iPoly++)
{
int iPolySize = pFbxMesh->GetPolygonSize(iPoly);
iNumFace = iPolySize - 2;
if (MaterialSet)
{
iSubMtrl = GetSubMaterialIndex(iPoly, MaterialSet);
}
for (int iFace = 0; iFace < iNumFace; iFace++)
{
int VertexColor[3] = { 0, iFace + 2, iFace + 1 };
int iCornerIndex[3];
iCornerIndex[0] = pFbxMesh->GetPolygonVertex(iPoly, 0);
iCornerIndex[1] = pFbxMesh->GetPolygonVertex(iPoly, iFace+2);
iCornerIndex[2] = pFbxMesh->GetPolygonVertex(iPoly, iFace+1);
int iUVIndex[3];
iUVIndex[0] = pFbxMesh->GetTextureUVIndex(iPoly, 0);
iUVIndex[1] = pFbxMesh->GetTextureUVIndex(iPoly, iFace + 2);
iUVIndex[2] = pFbxMesh->GetTextureUVIndex(iPoly, iFace + 1);
for (int iIndex = 0; iIndex < 3; iIndex++)
{
int vertexID = iCornerIndex[iIndex];
FbxVector4 v = pVertexPositions[vertexID];
SimpleVertex tVertex;
tVertex.p.x = v.mData[0];
tVertex.p.y = v.mData[2];
tVertex.p.z = v.mData[1];
tVertex.c = TVector4(1,1,1,1);
if (VertexColorSet)
{
FbxColor c = ReadColor(
pFbxMesh,
VertexColorSet,
iCornerIndex[iIndex],
iBasePolyIndex+ VertexColor[iIndex]);
tVertex.c.x = c.mRed;
tVertex.c.y = c.mGreen;
tVertex.c.z = c.mBlue;
tVertex.c.w = 1.0f;
}
if (VertexUVSet)
{
FbxVector2 t = ReadTextureCoord(
pFbxMesh,
VertexUVSet,
iCornerIndex[iIndex],
iUVIndex[iIndex]);
tVertex.t.x = t.mData[0];
tVertex.t.y = 1.0f - t.mData[1];
}
if (iNumMtrl <= 1)
{
pObject->m_VertexList.push_back(tVertex);
}
else
{
pObject->vbDataList[iSubMtrl].push_back(tVertex);
}
}
}
iBasePolyIndex += iPolySize;
}
m_pDrawObjList.push_back(pObject);
}
FbxColor TFbxLoader::ReadColor(FbxMesh* pFbxMesh,
FbxLayerElementVertexColor* VertexColorSet,
int posIndex,
int colorIndex)
{
FbxColor color(1, 1, 1, 1);
FbxLayerElement::EMappingMode mode = VertexColorSet->GetMappingMode();
switch (mode)
{
case FbxLayerElementUV::eByControlPoint:
{
switch (VertexColorSet->GetReferenceMode())
{
case FbxLayerElementUV::eDirect:
{
color = VertexColorSet->GetDirectArray().GetAt(posIndex);
}break;
case FbxLayerElementUV::eIndexToDirect:
{
int index = VertexColorSet->GetIndexArray().GetAt(posIndex);
color = VertexColorSet->GetDirectArray().GetAt(index);
}break;
}break;
} break;
case FbxLayerElementUV::eByPolygonVertex:
{
switch (VertexColorSet->GetReferenceMode())
{
case FbxLayerElementUV::eDirect:
{
color = VertexColorSet->GetDirectArray().GetAt(colorIndex);
}break;
case FbxLayerElementUV::eIndexToDirect:
{
int index = VertexColorSet->GetIndexArray().GetAt(colorIndex);
color = VertexColorSet->GetDirectArray().GetAt(index);
}break;
}break;
}break;
}
return color;
}
FbxVector2 TFbxLoader::ReadTextureCoord(FbxMesh* pFbxMesh,
FbxLayerElementUV* pUVSet,
int vertexIndex,
int uvIndex)
{
FbxVector2 t;
FbxLayerElement::EMappingMode mode = pUVSet->GetMappingMode();
switch(mode)
{
case FbxLayerElementUV::eByControlPoint:
{
switch (pUVSet->GetReferenceMode())
{
case FbxLayerElementUV::eDirect:
{
t = pUVSet->GetDirectArray().GetAt(vertexIndex);
}break;
case FbxLayerElementUV::eIndexToDirect:
{
int index = pUVSet->GetIndexArray().GetAt(vertexIndex);
t = pUVSet->GetDirectArray().GetAt(index);
}break;
}break;
} break;
case FbxLayerElementUV::eByPolygonVertex:
{
switch (pUVSet->GetReferenceMode())
{
case FbxLayerElementUV::eDirect:
case FbxLayerElementUV::eIndexToDirect:
{
t = pUVSet->GetDirectArray().GetAt(uvIndex);
}break;
}break;
}break;
}
return t;
}
int TFbxLoader::GetSubMaterialIndex(int iPoly, FbxLayerElementMaterial* pMaterialSetList)
{
int iSubMtrl = 0;
if (pMaterialSetList != nullptr)
{
switch (pMaterialSetList->GetMappingMode())
{
case FbxLayerElement::eByPolygon:
{
switch (pMaterialSetList->GetReferenceMode())
{
case FbxLayerElement::eIndex:
{
iSubMtrl = iPoly;
}break;
case FbxLayerElement::eIndexToDirect:
{
iSubMtrl = pMaterialSetList->GetIndexArray().GetAt(iPoly);
}break;
}
}
default:
{
break;
}
}
}
return iSubMtrl;
}