【问题标题】:Edge Collapse with assimp边缘折叠与 assimp
【发布时间】:2017-04-14 07:14:51
【问题描述】:

我正在尝试在我的游戏引擎中实现边缘崩溃,有一个由 Assimp 引起的问题。从face.mNumIndices 解析的索引始终是递增顺序索引。

当我检查索引列表时,该值应该是 0,1,2,3,4....,999... 。但我知道这是 Assimp 使用的某种mechanism,并且对象被渲染得很好。但是网格简化还有另一个问题,我无法为这个索引生成半边结构。我坚持了几天,没有答案。我应该放弃 Assimp 吗?任何建议表示赞赏。

编辑: 我的顶点在面之间共享,我用来获取数据的代码在这里。

BasicRenderModel* AssimpLoader::ProcessMeshBasicVersion(aiMesh * mesh, const aiScene * scene)
{
    //std::vector<Vertex> vertices;
    float *vertices = new float[mesh->mNumVertices * 3];
    int vertexLength = mesh->mNumVertices * 3;
    float *normals = new float[mesh->mNumVertices * 3];
    int normalLength = mesh->mNumVertices * 3;
    float *texCoords = new float[mesh->mNumVertices * 2];
    int texCoordLength = mesh->mNumVertices * 2;
    std::vector<int> indicesList;
    int *indices;
    int indexLength;

    //std::vector<Texture> textures;
    std::map<TextureType, std::vector<Texture>> textures;
    for (GLuint i = 0; i < mesh->mNumVertices; i++)
    {
        // Process vertex positions, normals and texture coordinates
        vertices[i * 3] = mesh->mVertices[i].x;
        vertices[i * 3 + 1] = mesh->mVertices[i].y;
        vertices[i * 3 + 2] = mesh->mVertices[i].z;
        normals[i * 3] = mesh->mNormals[i].x;
        normals[i * 3 + 1] = mesh->mNormals[i].y;
        normals[i * 3 + 2] = mesh->mNormals[i].z;
        if (mesh->mTextureCoords[0]) // Does the mesh contain texture coordinates?
        {
            texCoords[i * 2] = mesh->mTextureCoords[0][i].x;
            texCoords[i * 2 + 1] = mesh->mTextureCoords[0][i].y;
        }
        else
            texCoords[i * 2] = texCoords[i * 2 + 1] = 0.0f;
        Debug::Log("vertex: " + std::to_string(vertices[i * 3]) + "," + std::to_string(vertices[i * 3 + 1]) + "," + std::to_string(vertices[i * 3 + 2]));
    }
    // Process indices
    for (GLuint i = 0; i < mesh->mNumFaces; i++)
    {
        aiFace face = mesh->mFaces[i];
        for (GLuint j = 0; j < face.mNumIndices; j++)
            indicesList.push_back(face.mIndices[j]);
    }
    indices = new int[indicesList.size()];
    indexLength = indicesList.size();
    for (int i = 0; i < (int)indicesList.size(); i++)
        indices[i] = indicesList[i];

    return this->loader.LoadRenderModel(vertices, vertexLength, indices, indexLength, texCoords, texCoordLength, normals, normalLength);
}

上面代码生成的this object和索引的结果顶点是here

比较结果和 obj 文件。对于树对象,obj 文件有 624 个顶点,而 Assimp 有 927 个顶点,来自 obj 的索引是 310(lines) * 3 = 930,但是从 Assimp 读取的 Indices 是 927 个索引。我以为 Assimp 处理后面的数据,并生成指定的索引和顶点。

如果我需要重新计算索引,这意味着我需要检查每个顶点的所有顶点以找到相同的顶点并构造索引..?无法弄清楚如何解决这个问题..

【问题讨论】:

  • 增加索引很好。问题是什么?您是否认为应该将多个顶点合并为一个,但事实并非如此?如果没有看到数据,那将是有问题的。
  • @keltar ,由于使用了edge collapse,我找不到edge的对立面,因为没有找到相反的索引对,或者我误解了edge collapse?
  • 如果你想合并面之间的顶点,那么是的,这些索引本身是不可合并的。这真的取决于你如何决定你算作“顶点”的东西——一些软件认为它只是位置,而 GL/D3D/assimp/等。将所有属性组装到单个顶点中,如果至少有一个数字不同 - 则存在不同的顶点。所以我会再问一次——你是否 100% 确定你的数据具有在面之间共享的顶点(这包括位置、法线、纹理坐标等)?如果是这样,请添加说明您的问题的数据示例。
  • 也许举个例子会更好 - 硬边立方体没有 8 个“完整”顶点(具有所有属性)而是 24 个,而软边可能有 8 个。如果你不关心其他属性并且只想要位置 - 然后您可以很容易地仅重新计算位置的索引,但之后您必须重新计算其他属性以匹配您的结果模型。
  • 我不知道该怎么说,因为我已经做到了(你链接到的另一个问题也做到了)。您的 obj 是平面阴影/硬边,对于不同方向的每个面顶点法线点,即使顶点位置相同。 Assimp 以 GL/D3D 友好格式加载模型,因此无法将这些位置保持为相同的顶点。至少一个属性(法线)是不同的,因此存在不同的顶点。 Assimp 说你的 obj 有 624 个独特的顶点;当我将此模型导入搅拌机,对其进行平滑并再次导出时 - 它变成了 157,现在可以折叠了。

标签: algorithm opengl computational-geometry mesh assimp


【解决方案1】:

要使算法与 Assimp Importer 一起工作,有两件重要的事情。

  1. 模型应该与面共享顶点,如果模型不是,应该在3D模型软件中使用一些选项来完成。我在问题部分提供的树对象,我需要在搅拌机中删除双精度(删除重复的顶点),法线应该只有一个。

  2. 需要注意的另一件事是带有 assimp 的后处理选项。检查 Assimp 文档,有一个名为 aiProcess_JoinIdenticalVertices 的标志,如果未启用,Assimp 将为唯一顶点生成完全唯一的索引。更多信息请访问here

【讨论】:

    猜你喜欢
    • 2018-10-30
    • 2012-09-11
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-18
    • 2011-12-18
    相关资源
    最近更新 更多