XNA Creators Club Online
Page 1 of 1 (7 items)
Sort Posts: Previous Next

(Model Processor) Is this an issue with my mesh or my code?

Last post 04-21-2008 10:57 PM by DoppleX. 6 replies.
  • 04-21-2008 2:24 PM

    (Model Processor) Is this an issue with my mesh or my code?

    I'm in the process of trying to write a mesh preprocessor which (should) be identifying all edges in my mesh.  It isn't - it tends to identify roughly half of them, and I'm trying to figure out why.

    (All of this code is from the Content Processor, and is part of the GeometryContent processing, btw)

    The code I'm using for finding the edges (distilled down to the essential method - I know there would be issues trying to run this as written) is:
       for (int i = 0; i + 2 < myGeometry.Indices.Count; i += 3)
    {
    myEdge1 = new myEdge(myGeometry.IndicesIdea, myGeometry.Indices[i+1]);
    myEdge2 = new myEdge(myGeometry.Indices[i+1], myGeometry.Indices[i+2]);
    myEdge3 = new myEdge(myGeometry.Indices[i+2], myGeometry.IndicesIdea);

    myEdgeList.Add(myEdge1);
    myEdgeList.Add(myEdge2);
    myEdgeList.Add(myEdge3);
    }

    On the theory that every triangle we render for the mesh is going to have three edges - and that every edge should therefore be referenced by two triangles.  (in the real code, I check to see if I've already found the edge before adding it - but it's easier to see the basic approach this way)

    And I added an extra function (shown here) in order to do some validation:
            public int EdgeFound(int i1, int i2, IndexCollection Icollection)
    {

    int count = 0;
    for (int i = 0; i + 2 < Icollection.Count; i += 3)
    {
    int vFound = 0;
    if ((IcollectionIdea == i1) || (Icollection[i+1] == i1) || (Icollection[i+2] == i1))
    vFound++;
    if ((IcollectionIdea == i2) || (Icollection[i + 1] == i2) || (Icollection[i + 2] == i2))
    vFound++;
    if (vFound == 2) count++;
    }

    return count;
    }





    Now, in theory, in my mesh any pair of vertices should occur in either 0 or 2 triangles.  At least, I designed the edge processor (and basically everything else) to operate under that assumption.  When I run the validator on the edges in a sample GeometryContent though, I get very weird results:

    Example (This is the tank.fbx mesh from the CustomModel sample, for reference)
    First GeometryContent:
    # of Edges which only occur once:  3814
    # of Edges which occur twice:  8900  (or 4450)

    Second GeometryContent:
    # of Edges which only occur once:  1868
    # of Edges which occur twice:  3688(or 1844)

    Third GeometryContent:
    # of Edges which only occur once:  910
    # of Edges which occur twice:  1526(or 763)

    Fourth GeometryContent:
    # of Edges which only occur once:  1580
    # of Edges which occur twice:  3604(or 1802)

    ... etc

    Now, some of these I can explain due to boundaries between model parts (ie, the triangle on the other half of the edge was in a different GeometryContent, assuming that there's no requirement for an individual GeometryContent to be a closed mesh) but I don't understand how 50% of the edges I'm finding (in what looks like a closed mesh to me) are being flagged as only occuring once.   Add this to the fact that when I render the edge points I'm finding, half of them are obviously not being detected, it's clear that something's going wrong somewhere in here.

    I'm just not sure if it's the mesh, the code, or something else entirely.  I half suspect that I'm missing something blindingly obvious - or am making a stupid API mistake.

    Anyone have any ideas?

    (Edit:  Note, these are the results from the tank.fbx model, but I'm getting similar behavior from everything I try, so it's probable that I'm doing something stupid here...)
  • 04-21-2008 3:56 PM In reply to

    Re: (Model Processor) Is this an issue with my mesh or my code?

    Your code for pulling out the list of edges looks fine (although this will of course find duplicates if the same edge is used by more than one triangle).

    I don't understand what your EdgeFound method is attempting to do, though: this looks wrong for me but I might be misunderstanding the intent here.

    It's very common in most 3D content for edges not to be shared by multiple triangles. Of course this depends on how the model was constructed, but your assumption of two triangles per edge will only hold true if the mesh is entirely closed. In my experience most game artwork is very far from that so there will typically be many open edges.
    XNA Framework Developer - blog - homepage
  • 04-21-2008 4:19 PM In reply to

    Re: (Model Processor) Is this an issue with my mesh or my code?

    Hmmm....

    Thanks for the info, though it wasn't what I really wanted to hear!  This is obviously going to be more complicated than I thought.

    (I  left my duplicate checking out of the above code in an effort to keep things short.  The EdgeFound function is just a debugging function which is *intended* to go through the index buffer and count the number of triangles which use the edge between vertices i1 and i2.  I think it works, but it's just behind the debugging output.  Anyway, it's pointless if I'm going to encounter a fair amount of legitimate edges with only 1 triangle attached)

    I think this means I need to reexamine my approach for constructing edge data.  Since any game that uses Shadow Volumes is necessarily managing this, there must be a way to manage this - although I suppose that its possible that those games simply impose a "closed mesh" requirement on their assets.

    From a very high level perspective, almost all of these meshes at least *appear* to have two polygons attached at every edge.

    I think perhaps the problem I'm having is with the distinction between vertices and positions.

    Is this what's happening when I run into an edge with only one triangle (but which looks normal when rendered):

    We have two positions - P1 and P2.

    We have four vertices, V1, V2, V3, and V4.   V1 and V2 both have the position P1, and V3 and V4 both have the position P2.

    Theres a triangle on the V1 and V3 edge, and another on the V2 and V4 edge - so the edge defined by P1-P2 actually has two adjacent triangles - even though if I just look for V1-V3, I'll only find one adjacent triangle.

    If this isn't actually the case, I'm a bit confused about how there are so many edges with only one bordering triangle (aside from the discontinuities that are not in visible portions of the geometry - just because I'd think that it would be visible to the viewer.
  • 04-21-2008 4:27 PM In reply to

    Re: (Model Processor) Is this an issue with my mesh or my code?

    DoppleX:

    Since any game that uses Shadow Volumes is necessarily managing this, there must be a way to manage this - although I suppose that its possible that those games simply impose a "closed mesh" requirement on their assets.


    Shadow volumes require a closed mesh to work correctly, yes.

    This is in fact one of the biggest disadvantages of shadow volumes as a technique. It is a considerable pain to construct models that meet this requirement. It's a safe bet that anything you download from the net or find in a sample will not be fully closed.

    I used shadow volumes for the bike and rider in MotoGP, and it took several days of bouncing the model back to the artists for corrections before they managed to make one that was fully closed! Admittedly we didn't have any good tools for diagnosing the problem edges, but still, it wasn't a fun process :-)

    DoppleX:

    We have four vertices, V1, V2, V3, and V4.   V1 and V2 both have the position P1, and V3 and V4 both have the position P2.

    Theres a triangle on the V1 and V3 edge, and another on the V2 and V4 edge - so the edge defined by P1-P2 actually has two adjacent triangles - even though if I just look for V1-V3, I'll only find one adjacent triangle.


    That's very possible, and common.

    For instance if the model contains a hard edge (one with non-smoothed normals) then there will be two vertices with the same position but different normals.

    Also every time the texture mapping is not contiguous from one triangle to another (which depends on how the texture maps were applied, but is usually quite common) there will be multiple vertices with the same position but different texture coordinates.
    XNA Framework Developer - blog - homepage
  • 04-21-2008 4:59 PM In reply to

    Re: (Model Processor) Is this an issue with my mesh or my code?

    Thanks again.

    In that case, it might be possible to create a closed mesh if I meld vertices with Positions in common when evaluating my adjacencies.  Of course, this approach will prove problematic once I want to start getting things to animate - but if I can manage to keep doing this on a per mesh part basis, I should be able to cope with that.

    It's a start though - and I feel like I'm going to have an easier time forcing animation onto my artificial closed mesh structure than I will trying to get these approaches to work on a non-closed mesh.


    (The sad thing is that I wasn't even trying to implement shadow volumes - although at this point I'm feeling like I'm going to be more or less obligated to do that, given how much work I'm putting into the setup here!  I'm working on silhouette rendering for my toon-shader - and simply wasn't satisfied by any of the image processing approaches I tried)
  • 04-21-2008 6:02 PM In reply to

    Re: (Model Processor) Is this an issue with my mesh or my code?

    Answer
    Yeah, unfortunately shadow volumes and silhouette rendering are both equally fussy in requiring a nice clean closed mesh to work properly. The side effects of getting this wrong will be less extreme for silhouettes (you'll just have a missing silhouette edge where there should be one, or a bogus edge on the interior of your model, wheras for shadow volumes even a tiny crack in the source data can show up as a giant black piece of shadow stretching over half the screen) but the fundamental requirement for well-formed data is the same.

    This is one of those irritating places in graphics where the algorithm requires clean well formed data, but most actual model data created by artists is not so clean or well formed :-)

    If your model is full closed and your code is just being thrown off by the difference between vertices-the-same and vertices-different-due-to-normal-or-texcoord-but-underlying-position-the-same, doing your own welding based on the position value should take care of things. Once you have that in place, counting the edges and making sure each one has exactly two triangles will confirm whether the underlying model data is properly closed.

    I know the tank model in our sample is not, though.


    XNA Framework Developer - blog - homepage
  • 04-21-2008 10:57 PM In reply to

    Re: (Model Processor) Is this an issue with my mesh or my code?

    It may not be - but it still comes out pretty well...





    There are definitely some artifacts I need to clean up, and it desperately needs optimization - but it works!  Plus it gives me some degree of freedom in terms of how I want to render the lines - I could embed vertex data altering line widths at various points in the model, for instance.

    (Of course, one of the optimization problems no doubt has to do with the fact that I've been working on this on an integrated GPU with software Vertex processing - and the entire point of the thing is to shift load onto the GPU)

    Now just to put it together with the cel shading...



    Edit:  My god this forum's width is tiny!
Page 1 of 1 (7 items) Previous Next