我正在尝试编写一个程序,该程序使用OpenGL的三角形邻接功能(GL_TRIANGLES_ADJACENCY)来确定来自本地光源的网格轮廓。我正在使用ASSIMP来加载我的网格,就加载和显示网格而言,一切似乎都正常工作。不幸的是,我编写的用于存储相邻三角形索引的代码似乎没有正常工作。
index[0] = mesh.mFaces[i].mIndices[0];
index[2] = mesh.mFaces[i].mIndices[1];
index[4] = mesh.mFaces[i].mIndices[2];
index[1] = findAdjacentIndex( mesh, index[0], index[2], index[4] );
index[3] = findAdjacentIndex( mesh, index[0], index[2], index[4] );
index[5] = findAdjacentIndex( mesh, index[0], index[2], index[4] );
我的算法背后的基本思想是,给定网格和来自该网格的三个索引,找到共享网格的网格的所有面(应该是1或2,具体取决于是否存在相邻的面)第一个和第二个顶点之间的边缘。然后,返回不使用原始传递三角形的第三个索引的三角形的第三个索引。这样,相同的算法可以按顺序用于三角形的所有索引。
unsigned int Mesh::findAdjacentIndex(const aiMesh& mesh, const unsigned int index1, const unsigned int index2, const unsigned int index3) {
std::vector<unsigned int> indexMap[2];
// first pass: find all faces that use the first index
for( unsigned int i=0; i<mesh.mNumFaces; ++i ) {
unsigned int*& indices = mesh.mFaces[i].mIndices;
if( indices[0] == index1 || indices[1] == index1 || indices[2] == index1 ) {
indexMap[0].push_back(i);
}
}
// second pass: find the two faces that share the second index
for( unsigned int i=0; i<indexMap[0].size(); ++i ) {
unsigned int*& indices = mesh.mFaces[indexMap[0][i]].mIndices;
if( indices[0] == index2 || indices[1] == index2 || indices[2] == index2 ) {
indexMap[1].push_back(i);
}
}
// third pass: find the face that does NOT use the third index and return its third index
for( unsigned int i=0; i<indexMap[1].size(); ++i ) {
unsigned int*& indices = mesh.mFaces[indexMap[1][i]].mIndices;
if( indices[0] != index3 && indices[1] != index3 && indices[2] != index3 ) {
if( indices[0] != index1 && indices[0] != index2 ) {
return indices[0];
}
if( indices[1] != index1 && indices[1] != index2 ) {
return indices[1];
}
if( indices[2] != index1 && indices[2] != index2 ) {
return indices[2];
}
}
}
// no third index was found, this means there is no face adjacent to this one.
// return primitive restart index
return restartIndex;
}
基于我对我所写内容的理解,上述函数应该完全适用于从OpenGL规范中获取的示例图像:
不幸的是,我的功能不适用于我的任何现实世界网格,我不知道为什么。例如,通过函数传递一个简单的框网格通常会返回0作为每个顶点的相邻索引,这对我来说没什么意义。结果是邻接没有正确上传,我的对象得到了不正确的轮廓......
如果这里的任何人能够解决出错的问题以及我能做些什么来解决它,我将非常感激。如果需要,我也很乐意提供更多信息。
答案 0 :(得分:1)
你正在变得比它需要的更复杂。您想要搜索共享特定边的三角形并返回第三个顶点。然后就这样做。
for(unsigned int i=0; i<mesh.mNumFaces; ++i ) {
unsigned int*& indices = mesh.mFaces[i].mIndices;
for(int edge = 0; edge < 3; ++edge) { //iterate all edges of the face
unsigned int v1 = indices[edge]; //first edge index
unsigned int v2 = indices[(edge + 1) % 3]; //second edge index
unsigned int vOpp = indices[(edge + 2) % 3]; //index of opposite vertex
//if the edge matches the search edge and the opposite vertex does not match
if(((v1 == index1 && v2 == index2) || (v2 == index1 && v1 == index2)) && vOpp != index3)
return vOpp; //we have found the adjacent vertex
}
}
return -1;
此外,您需要更改通话。如果使用相同的参数调用该函数三次,则会得到相同的结果:
index[1] = findAdjacentIndex( mesh, index[0], index[2], index[4] );
index[3] = findAdjacentIndex( mesh, index[2], index[4], index[0] );
index[5] = findAdjacentIndex( mesh, index[4], index[0], index[2] );