2016-09-09 7 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であるべきです)第1の頂点と第2の頂点との間のエッジを共有するメッシュである。次に、渡された元の三角形の3番目のインデックスを使用しない三角形の3番目のインデックスを返します。このようにして、同じアルゴリズムを三角形のすべてのインデックスに対して順番に使用することができます。

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の仕様から取られたこの例の画像で完璧に動作するはずです:残念ながら

Triangle Adjacency Example

、私の機能は動作しません。私の実際の世界のメッシュのいずれかに、なぜ私は考えがありません。たとえば、単純なボックスメッシュを関数に渡すと、通常、各頂点の隣接するインデックスとして0が返されるように見えますが、これはほとんど意味がありません。その結果、隣接関係は正しくアップロードされず、私のオブジェクトから正しくないシルエットが得られます。

ここに誰もが何が問題になっているのか、私がそれを修正するために何ができるかについて、非常に感謝しています。もし必要があれば、私はさらに多くの情報を提供してくれるでしょう。

答えて

1

あなたは、必要以上に複雑になっています。特定のエッジを共有し、3番目の頂点を返す三角形を検索したいとします。それからちょうどそうする。

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; 

また、通話を変更する必要があります。関数を同じ引数で3回呼び出すと、もちろん同じ結果が得られます。

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を返すと残りの成果物が解決されました。あなたの助けをありがとう、私は大いに感謝します! –