Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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);
        }