Monday, November 30, 2009

Continuing seam problems

I'm continuing to have problems with seams.
In this case, Frank is texture baked as a flat red image. I believe that all of the seams should show up as the same color that was used for Frank, ie, the seams should all be red.

In this case, the fragment shader is set up to discover when the resulting color is black and set the seam color to so darker red so that it is obvious what is missing. It is easy to see that a bunch of the information is not transported across to the matching seam.

It looks to me like the tex coords for grabbing the data from the other side of the seam are wrong or are mapping to black spaces.

Here's my code:

//----------------------------------------------------------------------
// Find seams in the object
//----------------------------------------------------------------------
void OBJModel::findSeams(void)
{
// Seams lie along triangle edges. For each triangle, there are
// three possible seams (v0,v1), (v0,v2) and (v1,v2)
//
// Those lines might be seams if each of the vertices has more than
// one texture coordinate.
for(GLuint tri = 0; tri < _triangles.size(); tri++)
{
// Make a convenient copy of the vertex and texcoord indices
GLuint v[3];
GLuint t[3];

for(int i = 0; i < 3; i++)
{
v[i] = _triangles[tri].vertex(i);
t[i] = _triangles[tri].texCoord(i);
}

Seam sm;

// Find any matching seams for line segment (v0, v1)
sm.v0 = v[0]; sm.v1 = v[1]; sm.t0a = t[0]; sm.t1a = t[1];
findMatchingSeams(sm, tri);

// Find any matching seams for line segment (v0, v2)
sm.v0 = v[0]; sm.v1 = v[2]; sm.t0a = t[0]; sm.t1a = t[2];
findMatchingSeams(sm, tri);

// Find any matching seams for line segment (v1, v2)
sm.v0 = v[1]; sm.v1 = v[2]; sm.t0a = t[1]; sm.t1a = t[2];
findMatchingSeams(sm, tri);
}

cout << "Seams: " << _seams.size() << endl;
cout << "Duplicate vertices: " << _duplicateVertices.size() << endl;
}


//----------------------------------------------------------------------
// Find any matching seams for a line segment
//----------------------------------------------------------------------
void OBJModel::findMatchingSeams(Seam sm0, GLuint noTri)
{
// Both of the vertices need to have more than 1 tex coord
// for this to be a seam
if(numTexCoords(sm0.v0) <= 1 || numTexCoords(sm0.v1 <= 1))
return;

// Find triangles with the same vertex indices
for(GLuint tri = 0; tri < _triangles.size(); tri++)
{
// If this triangle contains these two vertices
if(tri != noTri &&
_triangles[tri].hasVertex(sm0.v0) &&
_triangles[tri].hasVertex(sm0.v1))
{
// Make a copy of the potential seam
Seam sm(sm0);
bool found0 = false;
bool found1 = false;

// Find the tex coords in the matching seam
for(int i = 0; i < 3; i++)
{
// If vertex index 0 matches vertex index i,
// get the texture coord on the other side of the seam
if(sm.v0 == _triangles[tri].vertex(i))
{
found0 = true;
sm.t0b = _triangles[tri].texCoord(i);
}

// If vertex index 1 matches vertex index i,
// get the texture coord on the other side of the seam
if(sm.v1 == _triangles[tri].vertex(i))
{
found1 = true;
sm.t1b = _triangles[tri].texCoord(i);
}
}

// This shouldn't happen and in practice I haven't seen it happen, but
// check anyways
if(!found0 && !found1)
{
cout << "Found a seam but no matching texcoords" << endl;
}

// If the tex coords on the other triangle are exactly the same,
// then this isn't a seam. Removing this check results in an image
// that appears exactly the same as the one above
if(!(sm.t0a == sm.t0b && sm.t1a == sm.t1b))
{
// Add the duplicate vertices
_duplicateVertices.insert(sm.v0);
_duplicateVertices.insert(sm.v1);

// Add this seam to the list
_seams.push_back(sm);
}
}
}
}

No comments:

Post a Comment