Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用FBX SDK获取索引_C++_Graphics_3d_Fbx - Fatal编程技术网

C++ 使用FBX SDK获取索引

C++ 使用FBX SDK获取索引,c++,graphics,3d,fbx,C++,Graphics,3d,Fbx,我在计算如何从FBX文件中获取索引时遇到了问题。恢复数据是非常好的(至少对于位置来说是这样),但我似乎找不到如何获取索引 免责声明:很抱歉代码太长,如果您认为某些部分确实不必要,请随意编辑 我目前得到的数据如下: // Recovering geometry for (int meshIndex = 0; meshIndex < scene->GetGeometryCount(); ++meshIndex) { const auto mesh = static_cast<F

我在计算如何从FBX文件中获取索引时遇到了问题。恢复数据是非常好的(至少对于位置来说是这样),但我似乎找不到如何获取索引

免责声明:很抱歉代码太长,如果您认为某些部分确实不必要,请随意编辑

我目前得到的数据如下:

// Recovering geometry
for (int meshIndex = 0; meshIndex < scene->GetGeometryCount(); ++meshIndex)
{
  const auto mesh = static_cast<FbxMesh*>(scene->GetGeometry(meshIndex));

  // Recovering positions
  int currentVertIndex = points_coords.size();
  points_coords.resize(currentVertIndex + mesh->GetControlPointsCount(), std::vector<coord_type>(3));

  for (int vertIndex = 0; vertIndex < mesh->GetControlPointsCount(); ++vertIndex, ++currentVertIndex)
  {
    const auto& vertPos = mesh->GetControlPointAt(vertIndex);

    points_coords[currentVertIndex][0] = vertPos[0]; // X position
    points_coords[currentVertIndex][1] = vertPos[1]; // Y position
    points_coords[currentVertIndex][2] = vertPos[2]; // Z position
  }

  // Iterate over normals with mesh->GetElementNormal()->GetDirectArray().GetCount()

  // Iterate over texcoords with mesh->GetElementUV()->GetDirectArray().GetCount()
//恢复几何体
对于(int-meshdex=0;meshdexGetGeometryCount();++meshdex)
{
const auto mesh=static_cast(场景->获取几何体(网格索引));
//恢复阵地
int currentVertIndex=points_coords.size();
调整点的大小(currentVertIndex+mesh->GetControlPointScont(),std::vector(3));
对于(int vertIndex=0;vertIndexGetControlPointScont();++vertIndex,++currentVertIndex)
{
const auto&vertPos=mesh->GetControlPointAt(vertIndex);
点坐标[currentVertIndex][0]=vertPos[0];//X位置
点坐标[currentVertIndex][1]=顶点位置[1];//Y位置
点坐标[currentVertIndex][2]=顶点位置[2];//Z位置
}
//使用mesh->GetElementNormal()->GetDirectArray().GetCount()在法线上迭代
//使用mesh->GetElementUV()->GetDirectArray().GetCount()在texcoords上迭代
至于索引,我在面(多边形)上迭代,得到它们的顶点索引如下:

// Fetching positions' indices
int currentPosPolyIndex = face_indices.size();
face_indices.resize(currentPosPolyIndex + mesh->GetPolygonCount());

for (int polyIndex = 0; polyIndex < mesh->GetPolygonCount(); ++polyIndex, ++currentPosPolyIndex)
{
  const auto polySize = mesh->GetPolygonSize(polyIndex);
  face_indices[currentPosPolyIndex].resize(polySize);

  for (int polyVertIndex = 0; polyVertIndex < polySize; ++polyVertIndex)
    face_indices[currentPosPolyIndex][polyVertIndex] = mesh->GetPolygonVertex(polyIndex, polyVertIndex);
}
//获取位置的索引
int currentPosPolyIndex=face_index.size();
面索引。调整大小(currentPosPolyIndex+mesh->GetPolygoCount());
对于(int polyIndex=0;polyIndexGetPolyOnCount();++polyIndex,++currentPosPolyIndex)
{
const auto polySize=mesh->GetPolygonSize(polyIndex);
面索引[currentPosPolyIndex]。调整大小(多边形大小);
对于(int polyVertIndex=0;polyVertIndexGetPolygonVertex(polyIndex,polyVertIndex);
}
对于只包含一个网格的FBX,这样做很好,但是当有几个网格时,它似乎无法缝合面。我将进一步彻底调查这是否来自我使用的数据结构,但是如果有人发现这方面的问题,请让我知道

问题出在normals&texcoords的索引中,我不知道如何获取。目前我正在检查两者的映射模式,并尝试相应地填充数据:

  const auto texMapping = mesh->GetElementUV()->GetMappingMode();

  if (texMapping == FbxLayerElement::EMappingMode::eByControlPoint)
  {
    std::cout << "[FbxFileReader] Mapping mesh's texture coordinates by vertex." << std::endl;

    texture_face_indices.resize(texture_face_indices.size() + mesh->GetPolygonCount());

    std::copy(face_indices.cend() - mesh->GetPolygonCount(), face_indices.cend(), texture_face_indices.end() - mesh->GetPolygonCount());
  }
  else if (texMapping == FbxLayerElement::EMappingMode::eByEdge)
  {
    std::cout << "[FbxFileReader] Mapping mesh's texture coordinates by halfedge." << std::endl;
  }
  else if (texMapping == FbxLayerElement::EMappingMode::eByPolygon || texMapping == FbxLayerElement::EMappingMode::eByPolygonVertex)
  {
    std::cout << "[FbxFileReader] Mapping mesh's texture coordinates by face" << (texMapping == FbxLayerElement::EMappingMode::eByPolygonVertex ? " vertices" : "") << '.' << std::endl;

    int currentTexPolyIndex = texture_face_indices.size();
    texture_face_indices.resize(currentTexPolyIndex + mesh->GetPolygonCount());

    for (int polyIndex = 0; polyIndex < mesh->GetPolygonCount(); ++polyIndex, ++currentTexPolyIndex)
    {
      if (texMapping == FbxLayerElement::EMappingMode::eByPolygonVertex)
      {
        const auto polySize = mesh->GetPolygonSize(polyIndex);
        texture_face_indices[currentTexPolyIndex].resize(polySize);

        for (int polyVertIndex = 0; polyVertIndex < polySize; ++polyVertIndex)
          texture_face_indices[currentTexPolyIndex][polyVertIndex] = mesh->GetTextureUVIndex(polyIndex, polyVertIndex);
      }
      else
      {
        // Fetch face's texcoords & add it
        //texture_face_indices[currentTexPolyIndex].emplace_back(...);
      }
    }
  }
  else if (texMapping == FbxLayerElement::EMappingMode::eAllSame)
  {
    std::cout << "[FbxFileReader] Mapping mesh's texture coordinates by mesh." << std::endl;
  }
  else
  {
    std::cerr << "[FbxFileReader] Couldn't handle mesh's texture coordinates' mapping mode." << std::endl;
  }
const auto texMapping=mesh->GetElementUV()->GetMappingMode();
if(texMapping==fbxlayerement::EMappingMode::eByControlPoint)
{
std::cout GetPolygonCount(),face_index.cend(),texture_face_index.end()-mesh->GetPolygonCount();
}
else if(texMapping==fbxlayerement::EMappingMode::eByEdge)
{

std::cout首先,不应将所有网格的数据放在同一数组中。每个网格可以有不同的材质,因此应使用单独的drawcall绘制。但如果不是您的选择,则错误在该行:

face_indices[currentPosPolyIndex][polyVertIndex] = mesh->GetPolygonVertex(polyIndex, polyVertIndex);
将顶点放在单个数组中,如下所示

[(1-st mesh) V1, V2, V3, ..., (2-nd mesh) V52, V53, V54, ...]
但是
mesh->GetPolygonVertex(polyIndex,polyVertIndex)
返回相对当前网格的索引,所以第二个网格将不是从
V52
开始,而是从
V1
开始。所以您应该计算一些偏移量

int currentVertIndex = points_coords.size();
int meshVertIndexStart = currentVertIndex;
...
for (int polyVertIndex = 0; polyVertIndex < polySize; ++polyVertIndex)
    face_indices[currentPosPolyIndex][polyVertIndex] = meshVertIndexStart + mesh->GetPolygonVertex(polyIndex, polyVertIndex);
int currentVertIndex=points_coords.size();
int meshVertIndexStart=currentVertIndex;
...
对于(int polyVertIndex=0;polyVertIndexGetPolygonVertex(polyIndex,polyVertIndex);
法线和UV最好在同一个循环中得到索引

FbxVector4 getNormal(FbxGeometryElementNormal* normalElement, int polyIndex, int posIndex) {
    if (normalElement->GetMappingMode() == FbxGeometryElement::eByControlPoint) {
        if (normalElement->GetReferenceMode() == FbxGeometryElement::eDirect)
            return normalElement->GetDirectArray().GetAt(posIndex);
        int i = normalElement->GetIndexArray().GetAt(posIndex);
        return normalElement->GetDirectArray().GetAt(i);
    }
    else if (normalElement->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) {
        if (normalElement->GetReferenceMode() == FbxGeometryElement::eDirect)
            return normalElement->GetDirectArray().GetAt(polyIndex);
        int i = normalElement->GetIndexArray().GetAt(polyIndex);
        return normalElement->GetDirectArray().GetAt(i);
    }
    return FbxVector4();
}

FbxVector2 getUV(FbxGeometryElementUV* uvElement, int polyIndex, int posIndex) {
    if (uvElement->GetMappingMode() == FbxGeometryElement::eByControlPoint) {
        if (uvElement->GetReferenceMode() == FbxGeometryElement::eDirect)
            return uvElement->GetDirectArray().GetAt(posIndex);
        int i = uvElement->GetIndexArray().GetAt(posIndex);
        return uvElement->GetDirectArray().GetAt(i);
    }
    else if (uvElement->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) {
        if (uvElement->GetReferenceMode() == FbxGeometryElement::eDirect)
            return uvElement->GetDirectArray().GetAt(polyIndex);
        int i = uvElement->GetIndexArray().GetAt(polyIndex);
        return uvElement->GetDirectArray().GetAt(i);
    }
    return FbxVector2();
}

...

int vertNum = 0;

for (int polyIndex = 0; polyIndex < mesh->GetPolygonCount(); ++polyIndex, ++currentPosPolyIndex) {
    const auto polySize = mesh->GetPolygonSize(polyIndex);
    face_indices[currentPosPolyIndex].resize(polySize);

    for (int polyVertIndex = 0; polyVertIndex < polySize; ++polyVertIndex) {
        int vertIndex = mesh->GetPolygonVertex(polyIndex, polyVertIndex);
        face_indices[currentPosPolyIndex][polyVertIndex] = meshVertIndexStart + vertIndex;

        FbxVector4 normal = getNormal(mesh->GetElementNormal(), vertNum, vertIndex);
        FbxVector2 uv = getUV(mesh->GetElementUV(), vertNum, vertIndex);
        vertNum++;
    }
}
FbxVector4 getNormal(FbxGeometryElementNormal*normalElement,int polyIndex,int posIndex){
如果(normalElement->GetMappingMode()==FbxGeometryElement::eByControlPoint){
如果(normalElement->GetReferenceMode()==FbxGeometryElement::eDirect)
返回normalElement->GetDirectArray().GetAt(posIndex);
int i=normalElement->GetIndexArray().GetAt(posIndex);
返回normalElement->GetDirectArray().GetAt(i);
}
else if(normalElement->GetMappingMode()==FbxGeometryElement::eByPolygonVertex){
如果(normalElement->GetReferenceMode()==FbxGeometryElement::eDirect)
返回normalElement->GetDirectArray().GetAt(polyIndex);
int i=normalElement->GetIndexArray().GetAt(polyIndex);
返回normalElement->GetDirectArray().GetAt(i);
}
返回FbxVector4();
}
FbxVector2 getUV(FbxGeometryElementUV*uvElement,int polyIndex,int posIndex){
如果(uvElement->GetMappingMode()==FbxGeometryElement::eByControlPoint){
如果(uvElement->GetReferenceMode()==FbxGeometryElement::eDirect)
返回uvElement->GetDirectArray().GetAt(posIndex);
int i=uvElement->GetIndexArray().GetAt(posIndex);
返回uvElement->GetDirectArray().GetAt(i);
}
else if(uvElement->GetMappingMode()==FbxGeometryElement::eByPolygonVertex){
如果(uvElement->GetReferenceMode()==FbxGeometryElement::eDirect)
返回uvElement->GetDirectArray().GetAt(polyIndex);
int i=uvElement->GetIndexArray().GetAt(polyIndex);
返回uvElement->GetDirectArray().GetAt(i);
}
返回FbxVector2();
}
...
int vertNum=0;
对于(int polyIndex=0;polyIndexGetPolyOnCount();++polyIndex,++currentPosPolyIndex){
const auto polySize=mesh->GetPolygonSize(polyIndex);
面索引[currentPosPolyIndex]。调整大小(多边形大小);
对于(int polyVertIndex=0;polyVertIndex获取多边形顶点(多边形索引,多边形vertIndex);
面索引[currentPosPolyIndex][polyVertIndex]=meshVertIndexStart+vertIndex;
FbxVector4 normal=getNormal(网格->GetElementNormal(),vertNum,vertIndex);
FbxVector2 uv=getUV(网格->GetElementUV(),vertNum,vertIndex);
vertNum++;
}
}
FbxVector4 getNormal(FbxGeometryElementNormal* normalElement, int polyIndex, int posIndex) {
    if (normalElement->GetMappingMode() == FbxGeometryElement::eByControlPoint) {
        if (normalElement->GetReferenceMode() == FbxGeometryElement::eDirect)
            return normalElement->GetDirectArray().GetAt(posIndex);
        int i = normalElement->GetIndexArray().GetAt(posIndex);
        return normalElement->GetDirectArray().GetAt(i);
    }
    else if (normalElement->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) {
        if (normalElement->GetReferenceMode() == FbxGeometryElement::eDirect)
            return normalElement->GetDirectArray().GetAt(polyIndex);
        int i = normalElement->GetIndexArray().GetAt(polyIndex);
        return normalElement->GetDirectArray().GetAt(i);
    }
    return FbxVector4();
}

FbxVector2 getUV(FbxGeometryElementUV* uvElement, int polyIndex, int posIndex) {
    if (uvElement->GetMappingMode() == FbxGeometryElement::eByControlPoint) {
        if (uvElement->GetReferenceMode() == FbxGeometryElement::eDirect)
            return uvElement->GetDirectArray().GetAt(posIndex);
        int i = uvElement->GetIndexArray().GetAt(posIndex);
        return uvElement->GetDirectArray().GetAt(i);
    }
    else if (uvElement->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) {
        if (uvElement->GetReferenceMode() == FbxGeometryElement::eDirect)
            return uvElement->GetDirectArray().GetAt(polyIndex);
        int i = uvElement->GetIndexArray().GetAt(polyIndex);
        return uvElement->GetDirectArray().GetAt(i);
    }
    return FbxVector2();
}

...

int vertNum = 0;

for (int polyIndex = 0; polyIndex < mesh->GetPolygonCount(); ++polyIndex, ++currentPosPolyIndex) {
    const auto polySize = mesh->GetPolygonSize(polyIndex);
    face_indices[currentPosPolyIndex].resize(polySize);

    for (int polyVertIndex = 0; polyVertIndex < polySize; ++polyVertIndex) {
        int vertIndex = mesh->GetPolygonVertex(polyIndex, polyVertIndex);
        face_indices[currentPosPolyIndex][polyVertIndex] = meshVertIndexStart + vertIndex;

        FbxVector4 normal = getNormal(mesh->GetElementNormal(), vertNum, vertIndex);
        FbxVector2 uv = getUV(mesh->GetElementUV(), vertNum, vertIndex);
        vertNum++;
    }
}