예제 #1
0
    // Use this for initialization
    void Start()
    {
        Random.InitState((int)System.DateTime.Now.Ticks);

        mountObjects = new GameObject[2];

        mountObjects [0] = new GameObject("Left Facade");
        mountObjects [0].AddComponent <MeshFilter>();
        mountObjects [0].AddComponent <MeshRenderer>();
        mountObjects [0].GetComponent <MeshRenderer> ().material = gameObject.GetComponent <MeshRenderer>().material;
        mountObjects [0].transform.SetParent(gameObject.transform);

        mountObjects [1] = new GameObject("Right Facade");
        mountObjects [1].AddComponent <MeshFilter>();
        mountObjects [1].AddComponent <MeshRenderer>();
        mountObjects [1].GetComponent <MeshRenderer> ().material = gameObject.GetComponent <MeshRenderer>().material;
        mountObjects [1].transform.SetParent(gameObject.transform);

        // the extreme vertices of the mountain
        Vector3 topRight    = new Vector3(1, -4 + height, 0);
        Vector3 bottomRight = new Vector3(width, -4, 0);
        Vector3 topLeft     = new Vector3(-1, -4 + height, 0);
        Vector3 bottomLeft  = new Vector3(-width, -4, 0);

        // get the sides of the mountain
        rightMount = GenerateMountainside(topRight, bottomRight, "right");
        leftMount  = GenerateMountainside(topLeft, bottomLeft, "left");

        // save the mesh so that it may be displayed
        mountObjects [0].GetComponent <MeshFilter> ().mesh = rightMount.mesh;
        mountObjects [1].GetComponent <MeshFilter> ().mesh = leftMount.mesh;
    }
예제 #2
0
    private MountainSide GenerateMountainside(Vector3 vertex1, Vector3 vertex2, string side = "right")
    {
        /*
         * inputs are the start and end verices to describe the facade of a mountain and the
         * keyword side to state which side of the mountain it is. Because triangles are shown to the
         * camera based on the clockwise/counterclockwise listing of vertices, it is imperative to know
         * which side of the mountian is being generated
         *
         * output is a list of the vertices that describe the surface of the mountainside, will be used
         * for collision detection
         *
         * the process here is to find and add the exterior vertices then the vertices that can be used
         * to complete the triangles on the surface. Following this, the vertices that can be used to
         * complete the triangles to fill out the interior of the mountain are added. Once all the vertices
         * are found, the triangles are added to a mesh in a method that looks at the orientation of the
         * mountainside as well as the relationship between edge, surface-completing and interior-completing
         * vertices
         */


        MountainSide mount = new MountainSide();

        // get the vertices from midpoint bisection
        List <Vector3> vertexList = MidpointBisect(vertex1, vertex2, bisectionDepth);

        // add the original vertices to the list
        vertexList.Add(vertex1);
        vertexList.Add(vertex2);

        // sort the vertices in order of descending height
        vertexList.Sort((a, b) => b.y.CompareTo(a.y));

        // these are the vertices that will define the shape of the mountain
        mount.surfaceVertices = vertexList.GetRange(0, vertexList.Count);

        // this value helps in determining the number of triangles that will be used
        int length = vertexList.Count;

        // this covers the triangles on the surface and the triangles that make up the squares to fill in the half mountain
        int numberOfTriangles        = (length - 1) * 3;
        int numberOfSurfaceTriangles = (length - 1);

        // add the vertices that will complete the triangles that make up the surface
        for (int i = 1; i < length; i++)
        {
            if (side.Equals("right"))
            {
                if (vertexList [i].x < vertexList [i - 1].x)
                {
                    // this line is actually pointing inwards toward the mountain's centre, so the completing vertex will be level
                    // with the top vertex of this line
                    vertexList.Add(new Vector3(vertexList [i].x, vertexList [i - 1].y, 0));
                }
                else
                {
                    // this line is pointing away from the mountain's centre, so the completing vertex is level with the
                    // bottom vertex of this line
                    vertexList.Add(new Vector3(vertexList [i - 1].x, vertexList [i].y, 0));
                }
            }
            else
            {
                if (vertexList [i].x < vertexList [i - 1].x)
                {
                    // this line is actually pointing inwards toward the mountain's centre, so the completing vertex will be level
                    // with the top vertex of this line
                    vertexList.Add(new Vector3(vertexList [i - 1].x, vertexList [i].y, 0));
                }
                else
                {
                    // this line is pointing away from the mountain's centre, so the completing vertex is level with the
                    // bottom vertex of this line
                    vertexList.Add(new Vector3(vertexList [i].x, vertexList [i - 1].y, 0));
                }
            }
        }

        // use this value to keep track of which vertex to start with when filling the interior triangles
        int firstInteriorVertex = vertexList.Count;

        // add the final vertices that account for the middle line of the mountain
        for (int i = 0; i < length; i++)
        {
            vertexList.Add(new Vector3(0, vertexList [i].y, 0));
        }

        Vector3[] vertices = vertexList.ToArray();
        mount.mesh.vertices = vertices;


        int[] triangles = new int[numberOfTriangles * 3];
        int   j         = 0;

        // create the triangles that make up the exterior of the mountain (one third of the triangles)
        for (int i = 0; i < numberOfSurfaceTriangles; i++)
        {
//			print (j.ToString ());
            if (side.Equals("right"))
            {
                triangles [j]     = i;
                triangles [j + 1] = i + 1;
                triangles [j + 2] = i + numberOfSurfaceTriangles + 1;
            }
            else
            {
                triangles [j]     = i;
                triangles [j + 1] = i + numberOfSurfaceTriangles + 1;
                triangles [j + 2] = i + 1;
            }

//			print (triangles [j].ToString() + "," + triangles [j + 1].ToString () + "," + triangles [j + 2].ToString ());
            j += 3;
        }

        // create the triangles that make up the interior of the mountain (one third * 2 of the triangles)
        for (int i = firstInteriorVertex; i < vertexList.Count - 1; i++)
        {
            //			print (j.ToString ());
            if (vertices [i].y.Equals(vertices [i - (firstInteriorVertex - 1) / 2].y))
            {
                // this is a layer for an inward facing edge triangle
                if (side.Equals("right"))
                {
                    // this is on the right side, so use this specific order to add triangle vertices
                    triangles [j]     = i;
                    triangles [j + 1] = i - (firstInteriorVertex - 1) / 2;
                    triangles [j + 2] = i - (firstInteriorVertex - 1);

                    triangles [j + 3] = i;
                    triangles [j + 4] = i - (firstInteriorVertex - 1);
                    triangles [j + 5] = i + 1;
                }
                else
                {
                    // this is on the left side, so reverse the order of the second and third vertex in each triangle to maintain
                    // a clockwise rotation
                    triangles [j]     = i;
                    triangles [j + 1] = i - (firstInteriorVertex - 1);
                    triangles [j + 2] = i - (firstInteriorVertex - 1) / 2;

                    triangles [j + 3] = i;
                    triangles [j + 4] = i + 1;
                    triangles [j + 5] = i - (firstInteriorVertex - 1);
                }
            }
            else
            {
                // this is a layer for an outward facing edge triangle
                if (side.Equals("right"))
                {
                    // this is on the right side, so use this specific order to add triangle vertices
                    triangles [j]     = i;
                    triangles [j + 1] = i - firstInteriorVertex;
                    triangles [j + 2] = i - (firstInteriorVertex - 1) / 2;

                    triangles [j + 3] = i;
                    triangles [j + 4] = i - (firstInteriorVertex - 1) / 2;
                    triangles [j + 5] = i + 1;
                }
                else
                {
                    // this is on the left side, so reverse the order of the second and third vertex in each triangle to maintain
                    // a clockwise rotation
                    triangles [j]     = i;
                    triangles [j + 1] = i - (firstInteriorVertex - 1) / 2;
                    triangles [j + 2] = i - firstInteriorVertex;

                    triangles [j + 3] = i;
                    triangles [j + 4] = i + 1;
                    triangles [j + 5] = i - (firstInteriorVertex - 1) / 2;
                }
            }

            j += 6;
        }

        mount.mesh.triangles = triangles;

        return(mount);
    }