// 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; }
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); }