public static void GenerateOffSet(IslandNetMesh islandNetMesh, float skylandDeclinePrecent, float skylandRadius) { IEnumerator <TriangleNet.Geometry.Vertex> vertexEnum = islandNetMesh.netMesh.Vertices.GetEnumerator(); for (int i = 0; i < islandNetMesh.netMesh.vertices.Count; i++) { if (!vertexEnum.MoveNext()) { break; } TriangleNet.Geometry.Vertex current = vertexEnum.Current; float precentDistanceFromTheEdge = 1 - Mathf.Sqrt(Mathf.Pow((float)current.x, 2) + Mathf.Pow((float)current.y, 2)) / (float)skylandRadius; current.x += (perlinNoise.GetNoise((float)current.x * 10, (float)current.y * 10)) * 5; current.y += (perlinNoise.GetNoise((float)current.x * 10, (float)current.y * 10)) * 5; } }
public static void GenerateHeightVerticies(IslandNetMesh islandNetMesh, AnimationCurve heightCurve, int skylandDeclinePrecent, AnimationCurve skylandDropCurve, float Seed, float skylandRadius, float mapScale, List <float> meshHeights, float heightScale, float cutOut) { IEnumerator <Triangle> triangleEnum = islandNetMesh.netMesh.Triangles.GetEnumerator(); for (int i = 0; i < islandNetMesh.netMesh.Triangles.Count; i++) { if (!triangleEnum.MoveNext()) { break; } Triangle currentTriangle = triangleEnum.Current; for (int j = 0; j < 3; j++) { List <float> heights = new List <float>(); float precentDistanceFromTheEdge = 1 - Mathf.Sqrt(Mathf.Pow((float)currentTriangle.vertices[j].x, 2) + Mathf.Pow((float)currentTriangle.vertices[j].y, 2)) / (float)skylandRadius; if (precentDistanceFromTheEdge > (float)skylandDeclinePrecent / 100) { meshHeights.Add(heightCurve.Evaluate(Noise.GenerateVertexHeightNoise((float)currentTriangle.vertices[j].x, (float)currentTriangle.vertices[j].y, Seed, mapScale, cutOut)) * heightScale); } else if (precentDistanceFromTheEdge < 0.00001) { meshHeights.Add(0); } else { meshHeights.Add(skylandDropCurve.Evaluate(precentDistanceFromTheEdge * 100 / skylandDeclinePrecent) * heightCurve.Evaluate(Noise.GenerateVertexHeightNoise((float)currentTriangle.vertices[j].x, (float)currentTriangle.vertices[j].y, Seed, mapScale, cutOut)) * heightScale); } } } }
public void Initiate() { if (Seed == 0) { Seed = Random.Range(0, 2000000); } Random.seed = (int)Seed; IslandNetMesh topIslandNetMesh = new IslandNetMesh(); IslandNetMesh bottomIslandNetMesh = new IslandNetMesh(); topIslandNetMesh.unityMesh = new UnityEngine.Mesh(); topHeights = new List <float>(); botHeights = new List <float>(); //Make random points to the mesh bottomIslandNetMesh.unityMesh = new UnityEngine.Mesh(); for (int i = 0; i < pointDensity; i++) { float offsetFromCenter = (float)skylandRadius * Mathf.Sqrt(Random.Range(.0f, 1)); float randomAngle = Random.Range(.0f, 1) * 2 * Mathf.PI; var x = offsetFromCenter * Mathf.Cos(randomAngle); var y = offsetFromCenter * Mathf.Sin(randomAngle); topIslandNetMesh.polygon.Add(new TriangleNet.Geometry.Vertex(x, y)); } float angle = 0; for (int i = 0; i < skylandExtraEdgePoints; i++) { angle += 2 * Mathf.PI / skylandExtraEdgePoints; var x = (float)skylandRadius * Mathf.Cos(angle); var y = (float)skylandRadius * Mathf.Sin(angle); topIslandNetMesh.polygon.Add(new TriangleNet.Geometry.Vertex(x, y)); } ConstraintOptions constraints = new ConstraintOptions(); constraints.ConformingDelaunay = true; //Put some triangles to the mesh topIslandNetMesh.netMesh = topIslandNetMesh.polygon.Triangulate(constraints) as TriangleNet.Mesh; Debug.Log("We made some triangles"); GenerateMesh(topIslandNetMesh, topColorGradient, topHeightCurve, topTerrainCollider, topFilter, topHeights); Random.seed = (int)Seed; for (int i = 0; i < pointDensity; i++) { float offsetFromCenter = (float)skylandRadius * Mathf.Sqrt(Random.Range(.0f, 1)); float randomAngle = Random.Range(.0f, 1) * 2 * Mathf.PI; var x = offsetFromCenter * Mathf.Cos(randomAngle); var y = offsetFromCenter * Mathf.Sin(randomAngle); bottomIslandNetMesh.polygon.Add(new TriangleNet.Geometry.Vertex(x, y)); } angle = 0; for (int i = 0; i < skylandExtraEdgePoints; i++) { angle += 2 * Mathf.PI / skylandExtraEdgePoints; var x = (float)skylandRadius * Mathf.Cos(angle); var y = (float)skylandRadius * Mathf.Sin(angle); bottomIslandNetMesh.polygon.Add(new TriangleNet.Geometry.Vertex(-x, -y)); } bottomIslandNetMesh.netMesh = bottomIslandNetMesh.polygon.Triangulate(constraints) as TriangleNet.Mesh; GenerateMesh(bottomIslandNetMesh, bottomColorGradient, bottomHeightCurve, bottomTerrainCollider, bottomFilter, botHeights); if (GetComponent <TerrainObjectGenerator>()) { GetComponent <TerrainObjectGenerator>().GenerateGroundObjects(topIslandNetMesh.unityMesh, pointDensity); } }
public void GenerateMesh(IslandNetMesh islandNetMesh, Gradient colorGradient, AnimationCurve heightCurve, MeshCollider meshCollider, MeshFilter meshFilter, List <float> meshHeights) { Debug.Log("Starting generate mesh function"); List <Vector3> verticies = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <int> triangles = new List <int>(); List <float> heights = new List <float>(); //Generate a height list for the mesh Noise.GenerateHeightVerticies(islandNetMesh, heightCurve, skylandDeclinePrecent, skylandDropCurve, Seed, skylandRadius, mapScale, meshHeights, heightScale, noiseCutOut); Noise.GenerateOffSet(islandNetMesh, skylandDeclinePrecent, skylandRadius); IEnumerator <Triangle> triangleEnum = islandNetMesh.netMesh.Triangles.GetEnumerator(); for (int i = 0; i < islandNetMesh.netMesh.Triangles.Count; i++) { if (!triangleEnum.MoveNext()) { break; } Triangle currentTriangle = triangleEnum.Current; //Debug.Log("Going to noise generation loop"); //if all tris are 0, we skip this triangle if (meshHeights[i * 3] == 0 && meshHeights[i * 3 + 1] == 0 && meshHeights[i * 3 + 2] == 0) { continue; } //This ordering seems counter intuitive to program, but if you do it wrong it will make for a ✨pretty✨ bug with postprosessing. (I have a picture somewhere...) Vector3 v0 = new Vector3((float)currentTriangle.vertices[2].x, (float)meshHeights[i * 3 + 2], (float)currentTriangle.vertices[2].y); Vector3 v1 = new Vector3((float)currentTriangle.vertices[1].x, (float)meshHeights[i * 3 + 1], (float)currentTriangle.vertices[1].y); Vector3 v2 = new Vector3((float)currentTriangle.vertices[0].x, (float)meshHeights[i * 3], (float)currentTriangle.vertices[0].y); triangles.Add(verticies.Count); triangles.Add(verticies.Count + 1); triangles.Add(verticies.Count + 2); verticies.Add(v0); verticies.Add(v1); verticies.Add(v2); var normal = Vector3.Cross(v1 - v0, v2 - v0); for (int x = 0; x < 3; x++) { normals.Add(normal); uvs.Add(Vector3.zero); } } //Colors List <Color> ColorList = new List <Color>(); heights.Clear(); IEnumerator <Triangle> triangleEnum2 = islandNetMesh.netMesh.Triangles.GetEnumerator(); for (int i = 0; i < islandNetMesh.netMesh.Triangles.Count; i++) { if (!triangleEnum2.MoveNext()) { break; } Triangle current = triangleEnum2.Current; float avgHeight = 0; for (int j = 0; j < 3; j++) { avgHeight += meshHeights[i * 3 + j]; } if (avgHeight == 0) { continue; } avgHeight /= 3; if (TrianglesAreMonoColor) { for (int k = 0; k < 3; k++) { ColorList.Add(colorGradient.Evaluate(avgHeight)); } } else { //second counter intuitive loop through a tri for (int j = 2; j >= 0; j--) { float colorHeightVal = meshHeights[i * 3 + j] / (float)heightScale * 4 / heightCurve.Evaluate(1) / 3; colorHeightVal += Random.Range(-0.04f, 0.04f); ColorList.Add(colorGradient.Evaluate(colorHeightVal)); } } } islandNetMesh.unityMesh.vertices = verticies.ToArray(); islandNetMesh.unityMesh.normals = normals.ToArray(); islandNetMesh.unityMesh.triangles = triangles.ToArray(); islandNetMesh.unityMesh.uv = uvs.ToArray(); islandNetMesh.unityMesh.colors = new Color[verticies.Count]; islandNetMesh.unityMesh.colors = ColorList.ToArray(); /* * foreach (Vector3 meshVertex in islandNetMesh.unityMesh.vertices) * { * islandNetMesh.polygon.Add(new TriangleNet.Geometry.Vertex(meshVertex.x, meshVertex.y, (int)meshVertex.z)); * } */ meshFilter.mesh = islandNetMesh.unityMesh; meshCollider.sharedMesh = islandNetMesh.unityMesh; }