Getting a mirrored mesh from my data structure

Posted by Steve on Game Development See other posts from Game Development or by Steve
Published on 2013-11-08T01:22:53Z Indexed on 2013/11/08 16:18 UTC
Read the original article Hit count: 242

Filed under:
|
|

Here's the background: I'm in the beginning stages of an RTS game in Unity. I have a procedurally generated terrain with a perlin-noise height map, as well as a function to generate a river. The problem is that the graphical creation of the map is taking the data structure of the map and rotating it by 180 degrees.

I noticed this problem when I was creating my rivers. I would set the River's height to flat, and noticed that the actual tiles that were flat in the graphical representation were flipped and mirrored.

Here's 3 screenshots of the map from different angles: http://imgur.com/a/VLHHq

As you can see, if you flipped (graphically) the river by 180 degrees on the z axis, it would fit where the terrain is flattened. I have a suspicion it is being caused by a misunderstanding on my part of how vertices work. Alas, here is a snippet of the code that is used:

This code here creates a new array of Tile objects, which hold the information for each tile, including its type, coordinate, height, and it's 4 vertices

 public DTileMap (int size_x, int size_y)
    {
        this.size_x = size_x;
        this.size_y = size_y;
        //Initialize Map_Data Array of Tile Objects
        map_data = new Tile[size_x, size_y];
        for (int j = 0; j < size_y; j++) {
            for (int i = 0; i < size_x; i++) {
                map_data [i, j] = new Tile ();
                map_data[i,j].coordinate.x = (int)i;
                map_data[i,j].coordinate.y = (int)j;

                map_data[i,j].vertices[0] = new Vector3 (i * GTileMap.TileMap.tileSize, map_data[i,j].Height, -j * GTileMap.TileMap.tileSize);
                map_data[i,j].vertices[1] = new Vector3 ((i+1) * GTileMap.TileMap.tileSize, map_data[i,j].Height, -(j) * GTileMap.TileMap.tileSize);
                map_data[i,j].vertices[2] = new Vector3 (i * GTileMap.TileMap.tileSize, map_data[i,j].Height, -(j-1) * GTileMap.TileMap.tileSize);
                map_data[i,j].vertices[3] = new Vector3 ((i+1) * GTileMap.TileMap.tileSize, map_data[i,j].Height, -(j-1) * GTileMap.TileMap.tileSize);
            }
        }

This code sets the river tiles to height 0

foreach (Tile t in map_data)
        {
            if (t.realType == "Water")
            {
                t.vertices[0].y = 0f;
                t.vertices[1].y = 0f;
                t.vertices[2].y = 0f;
                t.vertices[3].y = 0f;
            }
        }

And below is the code to generate the actual graphics from the data:

public void BuildMesh ()
    {
        DTileMap.DTileMap map = new DTileMap.DTileMap (size_x, size_z);
        int numTiles = size_x * size_z;
        int numTris = numTiles * 2;

        int vsize_x = size_x + 1;
        int vsize_z = size_z + 1;
        int numVerts = vsize_x * vsize_z;

        // Generate the mesh data
        Vector3[] vertices = new Vector3[ numVerts ];
        Vector3[] normals = new Vector3[numVerts];
        Vector2[] uv = new Vector2[numVerts];

        int[] triangles = new int[ numTris * 3 ];

        int x, z;
        for (z=0; z < vsize_z; z++) {
            for (x=0; x < vsize_x; x++) {
                normals [z * vsize_x + x] = Vector3.up;
                uv [z * vsize_x + x] = new Vector2 ((float)x / size_x, 1f - (float)z / size_z);
            }
        }
        for (z=0; z < vsize_z; z+=1) {
            for (x=0; x < vsize_x; x+=1) {
                if (x == vsize_x - 1 && z == vsize_z - 1) {
                    vertices [z * vsize_x + x] = DTileMap.DTileMap.map_data [x - 1, z - 1].vertices [3];
                } else if (z == vsize_z - 1) {
                    vertices [z * vsize_x + x] = DTileMap.DTileMap.map_data [x, z - 1].vertices [2];
                } else if (x == vsize_x - 1) {
                    vertices [z * vsize_x + x] = DTileMap.DTileMap.map_data [x - 1, z].vertices [1];
                } else {
                    vertices [z * vsize_x + x] = DTileMap.DTileMap.map_data [x, z].vertices [0];
                    vertices [z * vsize_x + x+1] = DTileMap.DTileMap.map_data [x, z].vertices [1];
                    vertices [(z+1) * vsize_x + x] = DTileMap.DTileMap.map_data [x, z].vertices [2];
                    vertices [(z+1) * vsize_x + x+1] = DTileMap.DTileMap.map_data [x, z].vertices [3];

                }

            }
        }
}

        for (z=0; z < size_z; z++) {
            for (x=0; x < size_x; x++) {
                int squareIndex = z * size_x + x;
                int triOffset = squareIndex * 6;
                triangles [triOffset + 0] = z * vsize_x + x + 0;
                triangles [triOffset + 2] = z * vsize_x + x + vsize_x + 0;
                triangles [triOffset + 1] = z * vsize_x + x + vsize_x + 1;

                triangles [triOffset + 3] = z * vsize_x + x + 0;
                triangles [triOffset + 5] = z * vsize_x + x + vsize_x + 1;
                triangles [triOffset + 4] = z * vsize_x + x + 1;
            }
        }


        // Create a new Mesh and populate with the data
        Mesh mesh = new Mesh ();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.normals = normals;
        mesh.uv = uv;

        // Assign our mesh to our filter/renderer/collider
        MeshFilter mesh_filter = GetComponent<MeshFilter> ();
        MeshCollider mesh_collider = GetComponent<MeshCollider> ();

        mesh_filter.mesh = mesh;
        mesh_collider.sharedMesh = mesh;

        calculateMeshTangents (mesh);
        BuildTexture (map);
    }

If this looks familiar to you, its because i got most of it from Quill18. I've been slowly adapting it for my uses. And please include any suggestions you have for my code. I'm still in the very early prototyping stage.

© Game Development or respective owner

Related posts about c#

Related posts about unity