0
\$\begingroup\$

I have a C# Struct with a static method, "Get Shape" which populates a List with the vertices of a polyhedron.

Method Signature:

public static void GetShape(Block b, int x, int y, int z,
                                List<Vector3> vertices, List<int> triangles,
                                List<Vector2> uvs, List<Vector2> uv2s)

Adding directly to the vertices list (via vertices.Add(vector3) ), the code works as expected, and the new polyhedron appears when I trigger the method. However, I want to do some processing on the vertices I'm adding (a rotation), and the most sensible way I can think to do that is by creating a separate list of Vector3s, and then combining the lists when I'm done.

However,

vertices.AddRange(newVerts) does not add the shape to the mesh, nor does a foreach loop with verts.Add(vertices[i]). And this is before I've added in any of the processing!

I have a feeling this might stem from passing the list of vertices in as a parameter, rather than returning a list and then adding to the vertices in the calling object, but since I'm filling 4 lists, I was trying to avoid having to create a data struct to return all four at once.

Any ideas? The working version of the method is reprinted below, in full:

public static void GetShape(Block b, int x, int y, int z,
                            List<Vector3> vertices, List<int> triangles,
                            List<Vector2> uvs, List<Vector2> uv2s)
{
    //List<Vector3> vertices = new List<Vector3>();

    int l_blockShape = b.blockShape;
    int l_blockType  = b.blockType;
    //CheckFace checks if the block is empty
    //if this block is empty, don't draw anything.


    int vertexIndex;

    //only y faces need to be hidden.
    //if((l_blockShape & BlockShape.NegZFace) == BlockShape.NegZFace)
    {
        vertexIndex = vertices.Count;
        //top left, top right, bottom right, bottom left
        vertices.Add(new Vector3(x+.2f, y + 1, z+.2f));
        vertices.Add(new Vector3(x+.8f, y + 1, z+.2f));
        vertices.Add(new Vector3(x+.8f, y , z+.2f));
        vertices.Add(new Vector3(x+.2f, y , z+.2f));

        // first triangle for the face 
        triangles.Add(vertexIndex);
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex+3);

        // second triangle for the face
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex+2);
        triangles.Add(vertexIndex+3);

        //UVs for the face
        uvs.Add( new Vector2(0,1));
        uvs.Add( new Vector2(1,1));
        uvs.Add( new Vector2(1,0));
        uvs.Add( new Vector2(0,0));

        //UV2s (lightmapping?)
        uv2s.Add( new Vector2(0,1));
        uv2s.Add( new Vector2(1,1));
        uv2s.Add( new Vector2(1,0));
        uv2s.Add( new Vector2(0,0));
    }

    //XY Z+1 face
    //if((l_blockShape & BlockShape.PosZFace) == BlockShape.PosZFace)
    {
        vertexIndex = vertices.Count;
        //top left, top right, bottom right, bottom left
        vertices.Add(new Vector3(x+.8f, y + 1, z+.8f));
        vertices.Add(new Vector3(x+.2f, y + 1, z+.8f));
        vertices.Add(new Vector3(x+.2f, y , z+.8f));
        vertices.Add(new Vector3(x+.8f, y , z+.8f));


        // first triangle for the face 
        triangles.Add(vertexIndex);
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex+3);

        // second triangle for the face
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex+2);
        triangles.Add(vertexIndex+3);

        //UVs for the face
        uvs.Add( new Vector2(0,1));
        uvs.Add( new Vector2(1,1));
        uvs.Add( new Vector2(1,0));
        uvs.Add( new Vector2(0,0));

        //UV2s (lightmapping?)
        uv2s.Add( new Vector2(0,1));
        uv2s.Add( new Vector2(1,1));
        uv2s.Add( new Vector2(1,0));
        uv2s.Add( new Vector2(0,0));
    }

    //ZY face
    //if((l_blockShape & BlockShape.NegXFace) == BlockShape.NegXFace)
    {
        vertexIndex = vertices.Count;
        //top left, top right, bottom right, bottom left
        vertices.Add(new Vector3(x+.2f, y + 1, z+.8f));
        vertices.Add(new Vector3(x+.2f, y + 1, z+.2f));
        vertices.Add(new Vector3(x+.2f, y , z+.2f));
        vertices.Add(new Vector3(x+.2f, y , z+.8f));

        // first triangle for the face 
        triangles.Add(vertexIndex);
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex+3);

        // second triangle for the face
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex+2);
        triangles.Add(vertexIndex+3);

        //UVs for the face
        uvs.Add( new Vector2(0,1));
        uvs.Add( new Vector2(1,1));
        uvs.Add( new Vector2(1,0));
        uvs.Add( new Vector2(0,0));

        //UV2s (lightmapping?)
        uv2s.Add( new Vector2(0,1));
        uv2s.Add( new Vector2(1,1));
        uv2s.Add( new Vector2(1,0));
        uv2s.Add( new Vector2(0,0));
    }

    //ZY X+1 face
//  if((l_blockShape & BlockShape.PosXFace) == BlockShape.PosXFace)
    {
        vertexIndex = vertices.Count;
        //top left, top right, bottom right, bottom left
        vertices.Add(new Vector3(x+.8f, y + 1, z+.2f));
        vertices.Add(new Vector3(x+.8f, y + 1, z+.8f));
        vertices.Add(new Vector3(x+.8f, y , z+.8f));
        vertices.Add(new Vector3(x+.8f, y , z+.2f));

        // first triangle for the face 
        triangles.Add(vertexIndex);
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex+3);

        // second triangle for the face
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex+2);
        triangles.Add(vertexIndex+3);

        //UVs for the face
        uvs.Add( new Vector2(0,1));
        uvs.Add( new Vector2(1,1));
        uvs.Add( new Vector2(1,0));
        uvs.Add( new Vector2(0,0));

        //UV2s (lightmapping?)
        uv2s.Add( new Vector2(0,1));
        uv2s.Add( new Vector2(1,1));
        uv2s.Add( new Vector2(1,0));
        uv2s.Add( new Vector2(0,0));
    }

    //ZX face
    if((l_blockShape & BlockShape.NegYFace) == BlockShape.NegYFace)
    {
        vertexIndex = vertices.Count;
        //top left, top right, bottom right, bottom left
        vertices.Add(new Vector3(x+.8f, y , z+.8f));
        vertices.Add(new Vector3(x+.8f, y , z+.2f));
        vertices.Add(new Vector3(x+.2f, y , z+.2f));
        vertices.Add(new Vector3(x+.2f, y , z+.8f));

        // first triangle for the face 
        triangles.Add(vertexIndex+3);
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex);



        // second triangle for the face
        triangles.Add(vertexIndex+3);
        triangles.Add(vertexIndex+2);
        triangles.Add(vertexIndex+1);



        //UVs for the face
        uvs.Add( new Vector2(0,1));
        uvs.Add( new Vector2(1,1));
        uvs.Add( new Vector2(1,0));
        uvs.Add( new Vector2(0,0));

        //UV2s (lightmapping?)
        uv2s.Add( new Vector2(0,1));
        uv2s.Add( new Vector2(1,1));
        uv2s.Add( new Vector2(1,0));
        uv2s.Add( new Vector2(0,0));
    }

    //ZX + 1 face
    if((l_blockShape & BlockShape.PosYFace) == BlockShape.PosYFace)
    {
        vertexIndex = vertices.Count;
        //top left, top right, bottom right, bottom left

        vertices.Add(new Vector3(x+.8f, y+1 , z+.2f));
        vertices.Add(new Vector3(x+.8f, y+1 , z+.8f));
        vertices.Add(new Vector3(x+.2f, y+1 , z+.8f));
        vertices.Add(new Vector3(x+.2f, y+1 , z+.2f));

        // first triangle for the face 
        triangles.Add(vertexIndex+3);
        triangles.Add(vertexIndex+1);
        triangles.Add(vertexIndex);



        // second triangle for the face
        triangles.Add(vertexIndex+3);
        triangles.Add(vertexIndex+2);
        triangles.Add(vertexIndex+1);



        //UVs for the face
        uvs.Add( new Vector2(0,1));
        uvs.Add( new Vector2(1,1));
        uvs.Add( new Vector2(1,0));
        uvs.Add( new Vector2(0,0));

        //UV2s (lightmapping?)
        uv2s.Add( new Vector2(0,1));
        uv2s.Add( new Vector2(1,1));
        uv2s.Add( new Vector2(1,0));
        uv2s.Add( new Vector2(0,0));
    }       
}
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Just checking: you are aware that if you comment out the "if" but not the block the if-condition applies to, the following code block will run every time, right? \$\endgroup\$ Nov 7, 2012 at 5:21
  • \$\begingroup\$ @JonathanHobbs I'm not quite sure I follow. My polyhedron has 6 faces. For this case, I want to always draw 4 of them (where I commented out the ifs). Are you saying I neeed to comment out the {} as well? \$\endgroup\$ Nov 7, 2012 at 11:54
  • \$\begingroup\$ No, having the {} is fine. I'm just checking that you're aware the code within the {} will, in the current code, always run. Putting aside scoping, in this code it will be as if the {} aren't even there, so having them there or not doesn't make a difference and in fact is quite neat. To put it differently: Newbie programmers might think that commenting out the if will mean the block of code that follows will never run, and I want to make sure you're not making that newbie assumption. \$\endgroup\$ Nov 7, 2012 at 13:05
  • 1
    \$\begingroup\$ @JonathanHobbs Okay, then we are on the same page. And yes, the intent is to always run that code. Thanks for the sanity check. \$\endgroup\$ Nov 7, 2012 at 13:54
  • \$\begingroup\$ Excellent! No worries :) \$\endgroup\$ Nov 7, 2012 at 14:07

2 Answers 2

1
\$\begingroup\$

I'm not sure if I got the question correct but is it correct, that you want to edit the vertices you passed as a parameter to the function after calling the function?

Maybe call by reference could help. You could try


public static void GetShape(Block b, int x, int y, int z,
                        ref List<Vector3> vertices, ref List<int> triangles,
                        ref List<Vector2> uvs, ref List<Vector2> uv2s)
\$\endgroup\$
4
  • \$\begingroup\$ Are lists not passed by reference automatically? Is it doing something weird because it's a list of structs (which are pass-by-value)? \$\endgroup\$ Nov 7, 2012 at 22:33
  • 1
    \$\begingroup\$ I also thought that Lists are passed by ref similiar to C++. But I found this and hoped it would help :) \$\endgroup\$
    – TOAOGG
    Nov 7, 2012 at 22:49
  • \$\begingroup\$ That would explain it then. It tries to pass back a reference to the Vertex3, which is a struct, and gets passed by value instead. I will look into this, and accept if it proves the culprit. I will commend you, however, for having better stackexchange search fu than I! \$\endgroup\$ Nov 8, 2012 at 1:27
  • \$\begingroup\$ Well, this seemed like a promising option, but no dice. \$\endgroup\$ Nov 8, 2012 at 2:42
0
\$\begingroup\$

So after more experimentation, I found out what was wrong. TOAOGG is, unfortunately, wrong - the lists were being passed appropriately (else the posted code wouldn't have worked). Instead, the problem is here:

    vertexIndex = vertices.Count;

and also here:

    // first triangle for the face 
    triangles.Add(vertexIndex);
    triangles.Add(vertexIndex+1);
    triangles.Add(vertexIndex+3);

    // second triangle for the face
    triangles.Add(vertexIndex+1);
    triangles.Add(vertexIndex+2);
    triangles.Add(vertexIndex+3);

The vertices were always being added correctly, but their associated triangles were not pointing to them correctly. Here is the correct code (assuming input parameter verts):

int parentIndex = verts.Count;
vertexIndex = vertices.Count;

// first triangle for the face 
   triangles.Add(parentIndex+vertexIndex);
   triangles.Add(parentIndex+vertexIndex+1);
   triangles.Add(parentIndex+vertexIndex+3);

// second triangle for the face
   triangles.Add(parentIndex+vertexIndex+1);
   triangles.Add(parentIndex+vertexIndex+2);
   triangles.Add(parentIndex+vertexIndex+3);

So... lesson learned. Keep your triangles between the proper vertices!

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .