/// <summary> /// Generate the data for the meshes and the population locations. /// </summary> public void GenerateMesh() { List <Vector3> t_vertices = new List <Vector3>(); List <int> t_triangles = new List <int>(); List <Color> t_colors = new List <Color>(); // If the chunck don't need to be divided. if (planet.GetChunkSubdivisions() == 0) { // Only asssign the original triangle. List <Vector3> v = planet.GetVertices(); t_vertices = new List <Vector3>() { v[vertices[0]], v[vertices[1]], v[vertices[2]] }; t_triangles = new List <int>() { 0, 1, 2 }; meshData = new MeshData(t_vertices, t_triangles, t_colors); Planet.AddPolygonToQueue(this); return; } List <List <Vector3> > sub_vertices = Subdivide(vertices); List <Mesh> meshes = new List <Mesh>(); int size = (int)Mathf.Pow(2, planet.GetChunkSubdivisions()); int iv = 0; PopulateData[] population = planet.GetPopulation(); pop = new List <Vector3> [population.Length]; for (int i = 0; i < pop.Length; i++) { pop[i] = new List <Vector3>(); } // Create the mesh data. for (int x = 0; x < size; x++) { for (int y = 0; y < size - x; y++) { if (Planet.ThreadNeedToQuit()) { return; } Vector3 v1, v2, v3, v4 = Vector3.zero; v1 = sub_vertices[x][y]; v2 = sub_vertices[x][y + 1]; v3 = sub_vertices[x + 1][y]; // Variables for the height of each vertex of the triangle. float h1 = 0.0f, h2 = 0.0f, h3 = 0.0f, h4 = 0.0f; h1 = getHeight(v1); h2 = getHeight(v2); h3 = getHeight(v3); v1 = v1 + (v1).normalized * h1; v2 = v2 + (v2).normalized * h2; v3 = v3 + (v3).normalized * h3; if (planet.GetStyle() == Style.LowPoly) { t_vertices.Add(v1 + planet.GetPosition()); t_vertices.Add(v2 + planet.GetPosition()); t_vertices.Add(v3 + planet.GetPosition()); t_triangles.Add(iv + 0); t_triangles.Add(iv + 1); t_triangles.Add(iv + 2); if (h1 > 19 && h2 > 19 && h3 > 19) { t_colors.Add(new Color(0.6415094f, 0.5063629f, 0.1845852f, 1)); t_colors.Add(new Color(0.6415094f, 0.5063629f, 0.1845852f, 1)); t_colors.Add(new Color(0.6415094f, 0.5063629f, 0.1845852f, 1)); } else if (h1 > 16 && h2 > 16 && h3 > 16) { t_colors.Add(new Color(0.4470589f, 0.6392157f, 0.145098f, 1)); t_colors.Add(new Color(0.4470589f, 0.6392157f, 0.145098f, 1)); t_colors.Add(new Color(0.4470589f, 0.6392157f, 0.145098f, 1)); } else if (h1 > 14 && h2 > 14 && h3 > 14) { t_colors.Add(new Color(0.6196079f, 0.6431373f, 0.1568628f, 1)); t_colors.Add(new Color(0.6196079f, 0.6431373f, 0.1568628f, 1)); t_colors.Add(new Color(0.6196079f, 0.6431373f, 0.1568628f, 1)); } else { t_colors.Add(new Color(0.9450981f, 0.8392158f, 0.4980392f, 1)); t_colors.Add(new Color(0.9450981f, 0.8392158f, 0.4980392f, 1)); t_colors.Add(new Color(0.9450981f, 0.8392158f, 0.4980392f, 1)); } iv += 3; } else { Vector3[] triangle = new Vector3[3] { v1, v2, v3 }; MeshData mesh_data = TriangleToStair(triangle); foreach (var item in mesh_data.vertices) { t_vertices.Add(item); } foreach (var item in mesh_data.triangles) { t_triangles.Add(iv + item); } foreach (var item in mesh_data.colors) { t_colors.Add(item); } iv += mesh_data.vertices.Count; } if (x != 0) { v4 = sub_vertices[x - 1][y + 1]; h4 = getHeight(v4); v4 = v4 + v4.normalized * h4; if (planet.GetStyle() == Style.LowPoly) { t_vertices.Add(v1 + planet.GetPosition()); t_vertices.Add(v2 + planet.GetPosition()); t_vertices.Add(v4 + planet.GetPosition()); t_triangles.Add(iv + 0); t_triangles.Add(iv + 2); t_triangles.Add(iv + 1); if (h1 > 19 && h2 > 19 && h4 > 19) { t_colors.Add(new Color(0.6415094f, 0.5063629f, 0.1845852f, 1)); t_colors.Add(new Color(0.6415094f, 0.5063629f, 0.1845852f, 1)); t_colors.Add(new Color(0.6415094f, 0.5063629f, 0.1845852f, 1)); } else if (h1 > 16 && h2 > 16 && h4 > 16) { t_colors.Add(new Color(0.4470589f, 0.6392157f, 0.145098f, 1)); t_colors.Add(new Color(0.4470589f, 0.6392157f, 0.145098f, 1)); t_colors.Add(new Color(0.4470589f, 0.6392157f, 0.145098f, 1)); } else if (h1 > 14 && h2 > 14 && h4 > 14) { t_colors.Add(new Color(0.6196079f, 0.6431373f, 0.1568628f, 1)); t_colors.Add(new Color(0.6196079f, 0.6431373f, 0.1568628f, 1)); t_colors.Add(new Color(0.6196079f, 0.6431373f, 0.1568628f, 1)); } else { t_colors.Add(new Color(0.9450981f, 0.8392158f, 0.4980392f, 1)); t_colors.Add(new Color(0.9450981f, 0.8392158f, 0.4980392f, 1)); t_colors.Add(new Color(0.9450981f, 0.8392158f, 0.4980392f, 1)); } iv += 3; } else { Vector3[] triangle2 = new Vector3[3] { v1, v2, v4 }; MeshData mesh_data2 = TriangleToStair(triangle2); foreach (var item in mesh_data2.vertices) { t_vertices.Add(item); } foreach (var item in mesh_data2.triangles) { t_triangles.Add(iv + item); } foreach (var item in mesh_data2.colors) { t_colors.Add(item); } iv += mesh_data2.vertices.Count; } } if (Vector3.Magnitude(v1) < planet.GetSeaLevel() || Vector3.Magnitude(v2) < planet.GetSeaLevel() || Vector3.Magnitude(v3) < planet.GetSeaLevel()) { // Only asssign the original triangle. List <Vector3> v = planet.GetVertices(); List <Vector3> sea_t_vertices = new List <Vector3>() { (v[vertices[0]] - planet.GetPosition()).normalized * planet.GetSeaLevel() + planet.GetPosition(), (v[vertices[1]] - planet.GetPosition()).normalized * planet.GetSeaLevel() + planet.GetPosition(), (v[vertices[2]] - planet.GetPosition()).normalized * planet.GetSeaLevel() + planet.GetPosition() }; List <int> sea_t_triangles = new List <int>() { 0, 1, 2 }; List <Color> sea_t_colors = new List <Color>(); seaMeshData = new MeshData(sea_t_vertices, sea_t_triangles, sea_t_colors); } Vector3 a = v1; Vector3 b = v2; Vector3 c = v3; Vector3 d = v4; for (int i = 0; i < pop.Length; i++) { float rand1 = (float)rng.NextDouble(); float rand2 = (float)rng.NextDouble(); Vector3 ac = Vector3.Lerp(a, c, rand1); Vector3 bc = Vector3.Lerp(b, c, rand1); Vector3 point = Vector3.Lerp(ac, bc, rand2); float height = Vector3.Magnitude(point); if (Style.Terrace == planet.GetStyle()) { height = Mathf.Floor(height); point = point.normalized * height; } if (height >= population[i].minHeight && height <= population[i].maxHeight && population[i].GetHeightAtPosition(point) > 0 && population[i].probability > (float)rng.NextDouble()) { pop[i].Add(point + planet.GetPosition()); } if (x != 0) { rand1 = (float)rng.NextDouble(); rand2 = (float)rng.NextDouble(); Vector3 ab = Vector3.Lerp(a, b, rand1); Vector3 db = Vector3.Lerp(d, b, rand1); point = Vector3.Lerp(ab, db, rand2); height = Vector3.Distance(planet.GetPosition(), point); if (Style.Terrace == planet.GetStyle()) { height = Mathf.Floor(height); point = point.normalized * height; } if (height >= population[i].minHeight && height <= population[i].maxHeight && population[i].GetHeightAtPosition(point) > 0 && population[i].probability > (float)rng.NextDouble()) { pop[i].Add(point + planet.GetPosition()); } } } } } // Assign the mesh data. meshData = new MeshData(t_vertices, t_triangles, t_colors); Planet.AddPolygonToQueue(this); }
/// <summary> /// From a triangle generate a stair. /// </summary> /// <param name="triangle">Triangle to use.</param> /// <returns>Return the mesh of the stair.</returns> private MeshData TriangleToStair(Vector3[] triangle) { Vector3 middle = planet.GetPosition(); MeshData mesh_data = new MeshData(); Vector3 v1, v2, v3; v1 = triangle[0]; v2 = triangle[1]; v3 = triangle[2]; Organize(ref v1, ref v2, ref v3); float h1, h2, h3; h1 = Vector3.Magnitude(v1); h2 = Vector3.Magnitude(v2); h3 = Vector3.Magnitude(v3); int h_min, h_max; h_min = Mathf.FloorToInt(Mathf.Min(h1, h2, h3)); h_max = Mathf.FloorToInt(Mathf.Max(h1, h2, h3)); int iv = 0; for (int h = h_min; h <= h_max; h++) { int points_above = 0; if (h3 == h2 && h3 == h1) { points_above = 3; } else if (h3 > h) { points_above = 3; } else if (h2 > h) { points_above = 2; } else { points_above = 1; } // Current Plane. Vector3 v1_c, v2_c, v3_c; v1_c = v1.normalized * h; v2_c = v2.normalized * h; v3_c = v3.normalized * h; // Previous Plane. Vector3 v1_p, v2_p, v3_p; v1_p = v1.normalized * (h - 1); v2_p = v2.normalized * (h - 1); v3_p = v3.normalized * (h - 1); Vector3 normal = Vector3.Cross(v1_p - v2_p, v3_p - v2_p).normalized; float d = -Vector3.Dot(normal, v1_p); float sign1 = d; float distance = Mathf.Abs(normal.x * v1_c.x + normal.y * v1_c.y + normal.z * v1_c.z + d); Color color = Color.white; ColorHeight[] colorHeight = planet.GetColorHeight(); foreach (var item in colorHeight) { if (h > item.layer) { color = item.color; break; } } if (points_above == 3) { // Floor. mesh_data.vertices.Add(v1_c + middle); mesh_data.vertices.Add(v2_c + middle); mesh_data.vertices.Add(v3_c + middle); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); if (sign1 < 0) { // Floor. mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 1); } else { mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 2); } iv += 3; } else if (points_above == 2) { float t1 = (h1 - h) / (h1 - h3); Vector3 v1_v3_c = Vector3.Lerp(v1, v3, t1); Vector3 v1_v3_p = v1_v3_c + Vector3.Cross(v1_c - v2_c, v3_c - v2_c).normalized *distance *Mathf.Sign(sign1); float t2 = (h2 - h) / (h2 - h3); Vector3 v2_v3_c = Vector3.Lerp(v2, v3, t2); Vector3 v2_v3_p = v2_v3_c + Vector3.Cross(v1_c - v2_c, v3_c - v2_c).normalized *distance *Mathf.Sign(sign1); if (sign1 < 0) { // Floor. mesh_data.vertices.Add(v1_v3_c + middle); mesh_data.vertices.Add(v2_v3_c + middle); mesh_data.vertices.Add(v1_c + middle); mesh_data.vertices.Add(v2_c + middle); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 3); mesh_data.triangles.Add(iv + 2); iv += 4; // Wall. mesh_data.vertices.Add(v1_v3_c + middle); mesh_data.vertices.Add(v1_v3_p + middle); mesh_data.vertices.Add(v2_v3_c + middle); mesh_data.vertices.Add(v2_v3_p + middle); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 3); mesh_data.triangles.Add(iv + 2); iv += 4; } else { // Floor. mesh_data.vertices.Add(v1_v3_c + middle); mesh_data.vertices.Add(v2_v3_c + middle); mesh_data.vertices.Add(v1_c + middle); mesh_data.vertices.Add(v2_c + middle); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 3); iv += 4; // Wall. mesh_data.vertices.Add(v1_v3_c + middle); mesh_data.vertices.Add(v1_v3_p + middle); mesh_data.vertices.Add(v2_v3_c + middle); mesh_data.vertices.Add(v2_v3_p + middle); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 3); iv += 4; } } else if (points_above == 1) { float t1 = (h1 - h) / (h1 - h3); Vector3 v1_v3_c = Vector3.Lerp(v1, v3, t1); Vector3 v1_v3_p = v1_v3_c + Vector3.Cross(v1_c - v2_c, v3_c - v2_c).normalized *distance *Mathf.Sign(sign1); float t2 = (h1 - h) / (h1 - h2); Vector3 v2_v3_c = Vector3.Lerp(v1, v2, t2); Vector3 v2_v3_p = v2_v3_c + Vector3.Cross(v1_c - v2_c, v3_c - v2_c).normalized *distance *Mathf.Sign(sign1); if (sign1 < 0) { // Floor. mesh_data.vertices.Add(v1_v3_c + middle); mesh_data.vertices.Add(v2_v3_c + middle); mesh_data.vertices.Add(v1_c + middle); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 2); iv += 3; // Wall. mesh_data.vertices.Add(v1_v3_c + middle); mesh_data.vertices.Add(v1_v3_p + middle); mesh_data.vertices.Add(v2_v3_c + middle); mesh_data.vertices.Add(v2_v3_p + middle); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 3); mesh_data.triangles.Add(iv + 2); iv += 4; } else { // Floor. mesh_data.vertices.Add(v1_v3_c + middle); mesh_data.vertices.Add(v2_v3_c + middle); mesh_data.vertices.Add(v1_c + middle); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 1); iv += 3; // Wall. mesh_data.vertices.Add(v1_v3_c + middle); mesh_data.vertices.Add(v1_v3_p + middle); mesh_data.vertices.Add(v2_v3_c + middle); mesh_data.vertices.Add(v2_v3_p + middle); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.colors.Add(color); mesh_data.triangles.Add(iv); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 1); mesh_data.triangles.Add(iv + 2); mesh_data.triangles.Add(iv + 3); iv += 4; } } } MeshData data = new MeshData(); data.vertices = new List <Vector3>(triangle); int[] i = new int[3] { 0, 1, 2 }; data.triangles = new List <int>(i); return(mesh_data); }