2016-09-09 2 views
0

OpenGL의 삼각형 인접성 기능 (GL_TRIANGLES_ADJACENCY)을 사용하여 로컬 광원에서 메쉬의 실루엣을 결정하는 프로그램을 작성하려고합니다. 나는 ASSIMP를 사용하여 내 메쉬를로드하고 있으며 메쉬를 로딩하고 표시하는 데 모든 것이 올바르게 작동하는 것 같습니다. 불행히도, 인접 삼각형의 인덱스를 저장하기 위해 작성한 코드가 제대로 작동하지 않는 것 같습니다.OpenGL 삼각형 인접성 계산

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가 실제로 인접한 얼굴인지 여부에 따라해야한다)이다 메쉬는 첫 번째와 두 번째 꼭지점 사이의 가장자리를 공유합니다. 그런 다음 원래 전달 된 삼각형의 세 번째 인덱스를 사용하지 않는 삼각형의 세 번째 인덱스를 반환합니다. 이 방법으로 같은 알고리즘을 삼각형의 모든 인덱스에 순서대로 사용할 수 있습니다.

불행하게도 Triangle Adjacency Example

, 내 기능이 작동하지 않습니다 : 내가 쓴 무엇에 대한 이해를 바탕으로

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을 반환하는 것처럼 보입니다. 이는 나에게 거의 의미가 없습니다. 결과는 인접성이 올바르게 업로드되지 않고 개체에서 잘못된 실루엣을 얻게됩니다 ...

여기있는 사람이 어떤 일이 잘못되고 어떤 문제가 해결 될 수 있는지에 대해 밝힐 수 있으면 매우 감사드립니다. 필요한 경우 더 많은 정보를 제공해 드리겠습니다.

답변

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]); 
+0

감사합니다. 귀하의 단순화 된 기능을 사용해 보겠습니다. 그래도 내 예제 코드에는 실수가있었습니다. 실제 코드에서 동일한 함수 호출을 3 번 연속 수행하지 않습니다. 나는 당신의 기능을 총에 줄 것이며, 그것이 효과가 있다면 다시 말해 줄 것이다. –

+0

그냥 시도해 봤어. 약간 수정하면 솔루션이 완벽하게 작동합니다! 어떤 이유로 든 glPrimitiveRestartIndex()가 제대로 작동하지 않았지만 실패 사례에서 index3를 반환하면 나머지 아티팩트가 해결되었습니다. 도와 줘서 고마워, 정말 고마워! –

관련 문제