/// <summary>
        /// Initializes a new instance of the <see cref="SimpleSmoother" /> class.
        /// </summary>
        /// <param name="factory">Voronoi object factory.</param>
        /// <param name="config">Configuration.</param>
        public SimpleSmoother(IVoronoiFactory factory, Configuration config)
        {
            this.factory = factory;
            this.config = config;

            this.options = new ConstraintOptions() { ConformingDelaunay = true };
        }
Esempio n. 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SimpleSmoother" /> class.
        /// </summary>
        /// <param name="factory">Voronoi object factory.</param>
        /// <param name="predicates">Geometric predicates implementation.</param>
        public SimpleSmoother(IVoronoiFactory factory, IPredicates predicates)
        {
            this.factory = factory;
            this.predicates = predicates;

            this.options = new ConstraintOptions() { ConformingDelaunay = true };
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SimpleSmoother" /> class.
        /// </summary>
        public SimpleSmoother(IVoronoiFactory factory)
        {
            this.factory = factory;
            this.pool = new TrianglePool();

            this.config = new Configuration(
                () => RobustPredicates.Default,
                () => pool.Restart());

            this.options = new ConstraintOptions() { ConformingDelaunay = true };
        }
        /// <summary>
        /// Insert segments into the mesh.
        /// </summary>
        /// <param name="input">The polygon.</param>
        /// <param name="options">Constraint options.</param>
        public void Apply(IPolygon input, ConstraintOptions options)
        {
            behavior.Poly = input.Segments.Count > 0;

            // Copy constraint options
            if (options != null)
            {
                behavior.ConformingDelaunay = options.ConformingDelaunay;
                behavior.Convex = options.Convex;
                behavior.NoBisect = options.SegmentSplitting;

                if (behavior.ConformingDelaunay)
                {
                    behavior.Quality = true;
                }
            }

            //if (input.EdgeMarkers != null)
            //{
            //    behavior.UseBoundaryMarkers = true;
            //}

            behavior.useRegions = input.Regions.Count > 0;

            // Ensure that no vertex can be mistaken for a triangular bounding
            // box vertex in insertvertex().
            mesh.infvertex1 = null;
            mesh.infvertex2 = null;
            mesh.infvertex3 = null;

            if (behavior.useSegments)
            {
                // Segments will be introduced next.
                mesh.checksegments = true;

                // Insert PSLG segments and/or convex hull segments.
                FormSkeleton(input);
            }

            if (behavior.Poly && (mesh.triangles.Count > 0))
            {
                // Copy holes and regions
                mesh.holes.AddRange(input.Holes);
                mesh.regions.AddRange(input.Regions);

                // Carve out holes and concavities.
                CarveHoles();
            }
        }
Esempio n. 5
0
        /// <inheritdoc />
        public IMesh Triangulate(IPolygon polygon, ConstraintOptions options, QualityOptions quality)
        {
            var mesh = (Mesh)triangulator.Triangulate(polygon.Points, config);

            var cmesher = new ConstraintMesher(mesh, config);
            var qmesher = new QualityMesher(mesh, config);

            mesh.SetQualityMesher(qmesher);

            // Insert segments.
            cmesher.Apply(polygon, options);

            // Refine mesh.
            qmesher.Apply(quality);

            return(mesh);
        }
        /// <inheritdoc />
        public IMesh Triangulate(IPolygon polygon, ConstraintOptions options, QualityOptions quality)
        {
            var mesh = (Mesh)triangulator.Triangulate(polygon.Points, config);

            var cmesher = new ConstraintMesher(mesh, config);
            var qmesher = new QualityMesher(mesh, config);

            mesh.SetQualityMesher(qmesher);

            // Insert segments.
            cmesher.Apply(polygon, options);

            // Refine mesh.
            qmesher.Apply(quality);

            return mesh;
        }
Esempio n. 7
0
        public static void ExtrudeText(this MeshBuilder builder, string text, string font, FontStyle fontStyle, FontWeight fontWeight, double fontSize, Vector3D textDirection, Point3D p0, Point3D p1)
        {
            var outlineList = GetTextOutlines(text, font, fontStyle, fontWeight, fontSize);

            // Build the polygon to mesh (using Triangle.NET to triangulate)
            var polygon = new TriangleNet.Geometry.Polygon();
            int marker = 0;

            foreach (var outlines in outlineList)
            {
                var outerOutline = outlines.OrderBy(x => x.AreaOfSegment()).Last();

                for (int i = 0; i < outlines.Count; i++)
                {
                    var outline = outlines[i];
                    var isHole = i != outlines.Count - 1 && IsPointInPolygon(outerOutline, outline[0]);
                    polygon.AddContour(outline.Select(p => new Vertex(p.X, p.Y)), marker++, isHole);
                    builder.AddExtrudedSegments(outline.ToSegments().ToList(), textDirection, p0, p1);
                }
            }

            var mesher = new GenericMesher();
            var options = new ConstraintOptions();
            var mesh = mesher.Triangulate(polygon, options);

            var u = textDirection;
            u.Normalize();
            var z = p1 - p0;
            z.Normalize();
            var v = Vector3D.CrossProduct(z, u);

            // Convert the triangles
            foreach (var t in mesh.Triangles)
            {
                var v0 = t.GetVertex(0);
                var v1 = t.GetVertex(1);
                var v2 = t.GetVertex(2);

                // Add the top triangle.
                // Project the X/Y vertices onto a plane defined by textdirection, p0 and p1.
                builder.AddTriangle(v0.Project(p0, u, v, z, 1), v1.Project(p0, u, v, z, 1), v2.Project(p0, u, v, z, 1));

                // Add the bottom triangle.
                builder.AddTriangle(v2.Project(p0, u, v, z, 0), v1.Project(p0, u, v, z, 0), v0.Project(p0, u, v, z, 0));
            }
        }
Esempio n. 8
0
    public void MakeMesh(Vector3[] _vertices)
    {
        Polygon polygon = new Polygon();

        elevations.Clear();

        for (int i = 0; i < _vertices.Length; i++)
        {
            polygon.Add(new Vertex(_vertices[i].x, _vertices[i].z));
            elevations.Add(_vertices[i].y);
        }

        Debug.Log("Length of polygon vertex-count: " + polygon.Count +
                  "\n Length of elevations:" + elevations.Count);


        int trianglesInChunk = 400;

        TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions()
        {
            ConformingDelaunay = true, Convex = false, SegmentSplitting = 1
        };
        mesh = (TriangleNet.Mesh)polygon.Triangulate(options);

        /*
         *    foreach (Vertex vert in mesh.Vertices)
         *    {
         *        elevations.Add(7);
         *    }
         */
        Debug.Log("Mesh.vertices at breakpoint: " + mesh.Vertices.Count);



        // Instantiate an enumerator to go over the Triangle.Net triangles - they don't
        // provide any array-like interface for indexing
        IEnumerator <Triangle> triangleEnumerator = mesh.Triangles.GetEnumerator();


        // Create more than one chunk, if necessary
        for (int chunkStart = 0; chunkStart < mesh.Triangles.Count; chunkStart += trianglesInChunk)
        {
            // Vertices in the unity mesh
            List <Vector3> vertices = new List <Vector3>();

            // Per-vertex normals
            List <Vector3> normals = new List <Vector3>();

            // Per-vertex UVs - unused here, but Unity still wants them
            List <Vector2> uvs = new List <Vector2>();

            // Triangles - each triangle is made of three indices in the vertices array
            List <int> triangles = new List <int>();

            // Iterate over all the triangles until we hit the maximum chunk size
            int chunkEnd = chunkStart + trianglesInChunk;
            for (int i = chunkStart; i < chunkEnd; i++)
            {
                if (!triangleEnumerator.MoveNext())
                {
                    // If we hit the last triangle before we hit the end of the chunk, stop
                    break;
                }

                // Get the current triangle
                Triangle triangle = triangleEnumerator.Current;

                // For the triangles to be right-side up, they need
                // to be wound in the opposite direction
                Vector3 v0 = GetPoint3D(triangle.vertices[2].id);
                Vector3 v1 = GetPoint3D(triangle.vertices[1].id);
                Vector3 v2 = GetPoint3D(triangle.vertices[0].id);

                // This triangle is made of the next three vertices to be added
                triangles.Add(vertices.Count);
                triangles.Add(vertices.Count + 1);
                triangles.Add(vertices.Count + 2);
                triangles.Add(vertices.Count);
                triangles.Add(vertices.Count + 2);
                triangles.Add(vertices.Count + 1);

                // Add the vertices
                vertices.Add(v0);
                vertices.Add(v1);
                vertices.Add(v2);

                // Compute the normal - flat shaded, so the vertices all have the same normal
                Vector3 normal = Vector3.Cross(v1 - v0, v2 - v0);
                normals.Add(normal);
                normals.Add(normal);
                normals.Add(normal);

                // If you want to texture your terrain, UVs are important,
                // but I just use a flat color so put in dummy coords
                uvs.Add(new Vector2(0.0f, 0.0f));
                uvs.Add(new Vector2(0.0f, 0.0f));
                uvs.Add(new Vector2(0.0f, 0.0f));
            }

            // Create the actual Unity mesh object
            UnityEngine.Mesh chunkMesh = new UnityEngine.Mesh();
            chunkMesh.vertices  = vertices.ToArray();
            chunkMesh.uv        = uvs.ToArray();
            chunkMesh.triangles = triangles.ToArray();
            chunkMesh.normals   = normals.ToArray();

            // Instantiate the GameObject which will display this chunk
            Transform chunk = Instantiate <Transform>(chunkPrefab, transform.position, transform.rotation);
            chunk.GetComponent <MeshFilter>().mesh = chunkMesh;
            //chunk.GetComponent<MeshCollider>().sharedMesh = chunkMesh;
            chunk.transform.parent = transform;
        }
    }
Esempio n. 9
0
 /// <inheritdoc />
 public IMesh Triangulate(IPolygon polygon, ConstraintOptions options)
 {
     return(Triangulate(polygon, options, null));
 }
Esempio n. 10
0
 /// <summary>
 /// Triangulates a polygon, applying quality and constraint options.
 /// </summary>
 /// <param name="options">Constraint options.</param>
 /// <param name="quality">Quality options.</param>
 /// <param name="triangulator">The triangulation algorithm.</param>
 public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality,
     ITriangulator triangulator)
 {
     return (new GenericMesher(triangulator)).Triangulate(polygon, options, quality);
 }
Esempio n. 11
0
 /// <summary>
 /// Triangulates a polygon, applying constraint options.
 /// </summary>
 /// <param name="options">Constraint options.</param>
 public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options)
 {
     return (new GenericMesher()).Triangulate(polygon, options, null);
 }
Esempio n. 12
0
 /// <inheritdoc />
 public IMesh Triangulate(IPolygon polygon, ConstraintOptions options)
 {
     return Triangulate(polygon, options, null);
 }
Esempio n. 13
0
        private void Triangulate()
        {
            if (input == null) return;

            var options = new ConstraintOptions();
            var quality = new QualityOptions();

            if (meshControlView.ParamConformDelChecked)
            {
                options.ConformingDelaunay = true;
            }

            if (meshControlView.ParamQualityChecked)
            {
                quality.MinimumAngle = meshControlView.ParamMinAngleValue;

                double maxAngle = meshControlView.ParamMaxAngleValue;

                if (maxAngle < 180)
                {
                    quality.MaximumAngle = maxAngle;
                }

                // Ignore area constraints on initial triangulation.

                //double area = slMaxArea.Value * 0.01;
                //if (area > 0 && area < 1)
                //{
                //    var size = input.Bounds;
                //    double min = Math.Min(size.Width, size.Height);
                //    mesh.SetOption(Options.MaxArea, area * min);
                //}
            }

            if (meshControlView.ParamConvexChecked)
            {
                options.Convex = true;
            }

            try
            {
                if (meshControlView.ParamSweeplineChecked)
                {
                    mesh = (Mesh)input.Triangulate(options, quality, new SweepLine());
                }
                else
                {
                    mesh = (Mesh)input.Triangulate(options, quality);
                }

                statisticView.UpdateStatistic(mesh);

                HandleMeshUpdate();

                if (meshControlView.ParamQualityChecked)
                {
                    settings.RefineMode = true;
                }
            }
            catch (Exception ex)
            {
                LockOnException();
                DarkMessageBox.Show("Exception - Triangulate", ex.Message, MessageBoxButtons.OK);
            }

            UpdateLog();
        }
Esempio n. 14
0
    private static Mesh GetTriangleDotNetMesh(List <Vector2[]> poly_vertices)
    {
        var num_vxs = 0;

        foreach (var ring_vxs in poly_vertices)
        {
            num_vxs += ring_vxs.Length + 1;
        }

        var poly = new TriangleNet.Geometry.Polygon(num_vxs);

        // set vertices
        var ri = 0;

        foreach (var ring_vxs in poly_vertices)
        {
            var vxs_input = new List <TriangleNet.Geometry.Vertex>(ring_vxs.Length + 1);
            foreach (var vx in ring_vxs)
            {
                vxs_input.Add(new TriangleNet.Geometry.Vertex(vx.x, vx.y));
            }

            // add to poly
            bool is_hole = ri != 0;
            var  contour = new TriangleNet.Geometry.Contour(vxs_input);
            poly.Add(contour, is_hole);
            ++ri;
        }

        // triangulate
        var opts = new TriangleNet.Meshing.ConstraintOptions()
        {
            ConformingDelaunay = true
        };
        var tn_mesh = (TriangleNet.Mesh)poly.Triangulate(opts);

        // write
        var tri_vxs = new Vector3[tn_mesh.Triangles.Count * 3];
        var tri_ids = new int[tn_mesh.Triangles.Count * 3];
        int i       = 0;

        foreach (var tri in tn_mesh.Triangles)
        {
            tri_vxs[i + 0] = new Vector3((float)tri.GetVertex(0).x, (float)tri.GetVertex(0).y, 0);
            tri_vxs[i + 1] = new Vector3((float)tri.GetVertex(2).x, (float)tri.GetVertex(2).y, 0);
            tri_vxs[i + 2] = new Vector3((float)tri.GetVertex(1).x, (float)tri.GetVertex(1).y, 0);

            tri_ids[i + 0] = i + 0;
            tri_ids[i + 1] = i + 1;
            tri_ids[i + 2] = i + 2;

            i += 3;
        }

        // create mesh
        var m = new Mesh();

        // assign to mesh
        m.vertices  = tri_vxs;
        m.triangles = tri_ids;

        // recompute geometry
        // QUESTION why do we need bounds?
        m.RecalculateNormals();
        m.RecalculateBounds();

        return(m);
    }
Esempio n. 15
0
        private void Triangulate_Click(object sender, RoutedEventArgs e)
        {
            var qualityOptions = new TriangleNet.Meshing.QualityOptions();

            qualityOptions.MaximumArea  = double.Parse(hTextBox.Text);
            qualityOptions.MinimumAngle = double.Parse(LTextBox.Text);

            var objct = new TriangleNet.Geometry.Polygon();

            foreach (var item in mycoordinates)
            {
                objct.Add(item);
            }

            for (int i = 0; i < mycoordinates.Count - 1; i++)
            {
                objct.Add(new Segment(mycoordinates[i], mycoordinates[i + 1]));
            }
            objct.Add(new Segment(mycoordinates.LastOrDefault(), mycoordinates.FirstOrDefault()));


            //var test = new TriangleNet.Meshing.Algorithm.SweepLine();
            var constraintOption = new TriangleNet.Meshing.ConstraintOptions();

            meshResult = objct.Triangulate(constraintOption, qualityOptions, new TriangleNet.Meshing.Algorithm.Incremental());
            //Triangulation
            //meshResult = objct.Triangulate(qualityOptions);
            meshResult.Renumber();

            //triangleResult = new List<TriangleNet.Topology.Triangle>(meshResult.Triangles);
            //Triangles
            trianglesResult = GetTrianglesFromMeshTriangles(meshResult.Triangles);
            resultsTriangles.ItemsSource = trianglesResult;
            //Vertices
            verticesResult   = new List <Vertex>(meshResult.Vertices);
            myvertixesResult = meshResult.Vertices.Select(v => new MyVertex {
                Id = v.ID, X = v.X, Y = v.Y
            }).ToList();
            results.ItemsSource = myvertixesResult;

            //Заповнення граничних сегментів
            for (int i = 0; i < boundaries.Count; i++)
            {
                boundaries[i].SetSegments(meshResult.Segments, boundaries.Count);
            }
            //Перетворення орієнтації всіх сегментів проти годинникової стрілки
            for (int i = 0; i < boundaries.Count; i++)
            {
                if (i != boundaries.Count - 1)
                {
                    boundaries[i].SetSegmentsOrientationToCounterclockwise(i, i + 1);
                }
                else
                {
                    boundaries[i].SetSegmentsOrientationToCounterclockwise(i, 0);
                }
            }
            //
            FillGridWithBoundaries(resultsBoundaries, boundaries);
            DrawData(meshResult);

            //Етап 2: Створення матриць Me, Ke, Qe, Re, Pe
            //Підготовка
            //Зчитування параметрів
            double a11 = double.Parse(a11TextBox.Text);
            double a22 = double.Parse(a22TextBox.Text);
            double d   = double.Parse(dTextBox.Text);
            double f   = double.Parse(fTextBox.Text);
            //Створення масиву точок
            var CT = GetPointsArray(myvertixesResult);
            //Створення масиву трикутників
            var NT = GetTrianglesArray(trianglesResult);
            //Створення масиву граничних сегментів
            var NTGR = GetBoundarySegments(boundaries);
            //Створення масиву значень ф-кції f у точках
            var fe = GetFe(CT, f);
            //Етап 3 (ініціалізація A,B)
            //Кількість вузлів
            int nodeNumber = CT.Length;
            var A          = new double[nodeNumber][];

            for (int i = 0; i < nodeNumber; i++)
            {
                A[i] = new double[nodeNumber];
            }

            var b = new double[nodeNumber];

            //Створення Me, Ke, Qe (та їх розсилання)
            double[] function_value = new double[3];
            for (int k = 0; k < trianglesResult.Count; k++)
            {
                //трикутник містить координати вузлів скінченного елемента
                var triangle = NT[k];
                //Підготовка
                double[] i = CT[triangle[0]],
                j = CT[triangle[1]],
                m = CT[triangle[2]];
                double Se = GetArea(i, j, m);
                double ai = GetA(j, m), bi = GetB(j, m), ci = GetC(j, m),
                       aj = GetA(m, i), bj = GetB(m, i), cj = GetC(m, i),
                       am = GetA(i, j), bm = GetB(i, j), cm = GetC(i, j);
                double[] a = new double[] { ai, aj, am },
                B = new double[] { bi, bj, bm },
                c = new double[] { ci, cj, cm };
                function_value[0] = fe[triangle[0]];
                function_value[1] = fe[triangle[1]];
                function_value[2] = fe[triangle[2]];
                //Ke
                var ke = new KE(k, Se, a11, a22, B, c);
                ke.print();
                //Me
                var me = new ME(k, Se, d);
                me.print();
                //Qe
                var qe = new QE(k, Se, fe);
                qe.print();
                //Етап 3
                for (int q = 0; q < 3; q++)
                {
                    //triangle[q] це номер вузла елемента
                    for (int w = 0; w < 3; w++)
                    {
                        A[triangle[q]][triangle[w]] += ke.Ke[q][w] + me.Me[q][w];
                    }

                    b[triangle[q]] += qe.Qe[q][0];
                }
            }
            //Створення Re, Pe (та їх розсилання)
            for (int k = 0; k < boundaries.Count; k++)
            {
                for (int l = 0; l < NTGR[k].Length; l++)
                {
                    //сегмент містить координати вузлів граничного сегмента
                    var segment = NTGR[k][l];
                    //Підготовка
                    double[] i = CT[NTGR[k][l][0]],
                    j = CT[NTGR[k][l][1]];
                    double Length = GetLength(i, j);
                    //Re
                    var re = new RE(k + l, boundaries[k].G, boundaries[k].B,
                                    Length, k + "|" + l + "|" + NTGR[k][l][0] + "-" + NTGR[k][l][1]);
                    re.print();
                    //Pe
                    var pe = new PE(k + l, boundaries[k].G, boundaries[k].B, boundaries[k].Uc,
                                    Length, k + "|" + l + "|" + NTGR[k][l][0] + "-" + NTGR[k][l][1]);
                    pe.print();

                    //Етап 3
                    for (int q = 0; q < 2; q++)
                    {
                        //segment[q] це номер вузла сегмента
                        for (int w = 0; w < 2; w++)
                        {
                            A[segment[q]][segment[w]] += re.Re[q][w];
                        }

                        b[segment[q]] += pe.Pe[q][0];
                    }
                }
            }
            //Запис у файл A,b
            print(A, b);
            //Етап 3-2
            var u = GausseMethod(nodeNumber, A, b);

            printNonFormatted(CT, u, "results.txt");
        }
Esempio n. 16
0
    void Start()
    {
        //UnityEngine.Random.InitState(0);

        elevations = new List <float>();

        //float[] seed = new float[octaves];

        //for (int i = 0; i < octaves; i++)
        //{
        //    seed[i] = Random.Range(0.0f, 100.0f);
        //}

        Polygon polygon = new Polygon();

        ShapeFile shapeFile = new ShapeFile();

        shapeFile.Read(path);

        List <double> MinMax  = shapeFile.FileHeader.GetMinMax();
        double        xMin    = MinMax[0];
        double        xMax    = MinMax[1];
        double        yMin    = MinMax[2];
        double        yMax    = MinMax[3];
        int           intxMin = (int)Math.Floor(xMin);
        int           intxMax = (int)Math.Ceiling(xMax);
        int           intyMin = (int)Math.Floor(yMin);
        int           intyMax = (int)Math.Ceiling(yMax);

        Debug.Log(xMin);
        Debug.Log(intxMin);
        Debug.Log(yMin);
        Debug.Log(intyMin);

        xsize = 0;
        ysize = 0;


        Debug.Log(shapeFile.ToString());

        //PoissonDiscSampler sampler = new PoissonDiscSampler(xsize, ysize, minPointRadius);

        //// Add uniformly-spaced points
        //foreach (Vector2 sample in sampler.Samples()) {
        //    polygon.Add(new Vertex((double)sample.x, (double)sample.y));
        //}

        //Add some randomly sampled points

        //for (int i = 0; i < randomPoints; i++)
        //{
        //    polygon.Add(new Vertex(Random.Range(0.0f, xsize), Random.Range(0.0f, ysize)));
        //    xpoint = Random.Range(0.0f, xsize);
        //    ypoint = Random.Range(0.0f, ysize);
        //    Debug.Log(xpoint);
        //    Debug.Log(ypoint);

        //}
        foreach (ShapeFileRecord record in shapeFile.Records)
        {
            foreach (Vector3 point in record.Points)
            {
                polygon.Add(new Vertex((double)point.x, (double)point.y));
                xpoint = point.x;
                ypoint = point.y;
                xsize += 1;
                ysize += 1;
                elevations.Add(point.z);
            }
        }

        TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions()
        {
            ConformingDelaunay = true
        };
        mesh = (TriangleNet.Mesh)polygon.Triangulate(options); //

        //bin = new TriangleBin(mesh, xsize, ysize, minPointRadius);

        // Sample perlin noise to get elevations
        //foreach (Vertex vert in mesh.Vertices)
        //{
        //    float elevation = 0.0f;
        //    float amplitude = Mathf.Pow(persistence, octaves);
        //    float frequency = 1.0f;
        //    float maxVal = 0.0f;

        //    for (int o = 0; o < octaves; o++)
        //    {
        //        float sample = (Mathf.PerlinNoise(seed[o] + (float)vert.x * sampleSize / (float)xsize * frequency,
        //                                          seed[o] + (float)vert.y * sampleSize / (float)ysize * frequency) - 0.5f) * amplitude;
        //        elevation += sample;
        //        maxVal += amplitude;
        //        amplitude /= persistence;
        //        frequency *= frequencyBase;
        //    }

        //    elevation = elevation / maxVal;
        //    Debug.Log(elevation);
        //    Debug.Log(elevation * elevationScale);
        //    elevations.Add(elevation * elevationScale);
        //}

        //foreach (ShapeFileRecord record in shapeFile.Records)
        //{
        //    foreach (Vector3 point in record.Points)
        //    {
        //        foreach (Vertex vert in mesh.Vertices)
        //        {
        //            elevations.Add(point.z);
        //            zpoint = point.z;
        //            Debug.Log(zpoint);
        //        }
        //    }
        // }


        MakeMesh();

        //ScatterDetailMeshes();
    }
Esempio n. 17
0
    public virtual void Generate()
    {
        UnityEngine.Random.InitState(0);

        elevations = new List <float>();

        float[] seed = new float[octaves];

        for (int i = 0; i < octaves; i++)
        {
            seed[i] = Random.Range(0.0f, 100.0f);
        }

        PoissonDiscSampler sampler = new PoissonDiscSampler(xsize, ysize, minPointRadius);

        Polygon polygon = new Polygon();

        // Add uniformly-spaced points
        foreach (Vector2 sample in sampler.Samples())
        {
            polygon.Add(new Vertex((double)sample.x, (double)sample.y));
        }

        // Add some randomly sampled points
        for (int i = 0; i < randomPoints; i++)
        {
            polygon.Add(new Vertex(Random.Range(0.0f, xsize), Random.Range(0.0f, ysize)));
        }

        TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions()
        {
            ConformingDelaunay = true
        };
        mesh = (TriangleNet.Mesh)polygon.Triangulate(options);

        bin = new TriangleBin(mesh, xsize, ysize, minPointRadius * 2.0f);

        // Sample perlin noise to get elevations
        foreach (Vertex vert in mesh.Vertices)
        {
            float elevation = 0.0f;
            float amplitude = Mathf.Pow(persistence, octaves);
            float frequency = 1.0f;
            float maxVal    = 0.0f;

            for (int o = 0; o < octaves; o++)
            {
                float sample = (Mathf.PerlinNoise(seed[o] + (float)vert.x * sampleSize / (float)xsize * frequency,
                                                  seed[o] + (float)vert.y * sampleSize / (float)ysize * frequency) - 0.5f) * amplitude;
                elevation += sample;
                maxVal    += amplitude;
                amplitude /= persistence;
                frequency *= frequencyBase;
            }

            elevation = elevation / maxVal;
            elevations.Add(elevation * elevationScale);
        }

        MakeMesh();

        ScatterDetailMeshes();
    }
Esempio n. 18
0
    public void MakeMesh()
    {
        float elevationScale = Random.Range(elevationScaleLow, elevationScaleHigh);

        Debug.Log(elevationScale);
        int   octaves     = Random.Range(octavesLow, octavesHigh);
        float persistence = Random.Range(persistenceLow, persistenceHigh);



        // Vertex is TriangleNet.Geometry.Vertex
        Polygon polygon = new Polygon();

        for (int i = 0; i < vertexNumber; i++)
        {
            var newVer = new Vertex(Random.Range(0, xsize / 2f), Random.Range(0, ysize / 2f));
            polygon.Add(newVer);
        }

        // ConformingDelaunay is false by default; this leads to ugly long polygons at the edges
        // because the algorithm will try to keep the mesh convex
        TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions()
        {
            ConformingDelaunay = true
        };
        mesh = (TriangleNet.Mesh)polygon.Triangulate(options);

        float[] seed = new float[octaves];
        for (int i = 0; i < octaves; i++)
        {
            seed[i] = Random.Range(0.0f, 100.0f);
        }
        // Sample perlin noise at each generated point to get elevation and store it in
        // the elevations array
        foreach (Vertex vert in mesh.Vertices)
        {
            float elevation = 0.0f;
            float amplitude = Mathf.Pow(persistence, octaves);
            float frequency = 1.0f;
            float maxVal    = 0.0f;

            for (int o = 0; o < octaves; o++)
            {
                float sample = (Mathf.PerlinNoise(seed[o] + (float)vert.x * sampleSize / (float)xsize * frequency,
                                                  seed[o] + (float)vert.y * sampleSize / (float)ysize * frequency) - 0.5f) * amplitude;
                elevation += sample;
                maxVal    += amplitude;
                amplitude /= persistence;
                frequency *= frequencyBase;
            }

            elevation = elevation / maxVal;
            elevations.Add(elevation * elevationScale);
        }

        // Instantiate an enumerator to go over the Triangle.Net triangles - they don't
        // provide any array-like interface for indexing
        IEnumerator <Triangle> triangleEnumerator = mesh.Triangles.GetEnumerator();

        // Create more than one chunk, if necessary
        for (int chunkStart = 0; chunkStart < mesh.Triangles.Count; chunkStart += trianglesInChunk)
        {
            // Vertices in the unity mesh
            List <Vector3> vertices = new List <Vector3>();
            // Per-vertex normals
            List <Vector3> normals = new List <Vector3>();
            // Per-vertex UVs - unused here, but Unity still wants them
            List <Vector2> uvs = new List <Vector2>();
            // Triangles - each triangle is made of three indices in the vertices array
            List <int> triangles = new List <int>();

            // Iterate over all the triangles until we hit the maximum chunk size
            int chunkEnd = chunkStart + trianglesInChunk;
            for (int i = chunkStart; i < chunkEnd; i++)
            {
                if (!triangleEnumerator.MoveNext())
                {
                    // If we hit the last triangle before we hit the end of the chunk, stop
                    break;
                }

                // Get the current triangle
                Triangle triangle = triangleEnumerator.Current;

                // For the triangles to be right-side up, they need
                // to be wound in the opposite direction
                Vector3 v0 = GetPoint3D(triangle.vertices[2].id);
                Vector3 v1 = GetPoint3D(triangle.vertices[1].id);
                Vector3 v2 = GetPoint3D(triangle.vertices[0].id);

                // This triangle is made of the next three vertices to be added
                triangles.Add(vertices.Count);
                triangles.Add(vertices.Count + 1);
                triangles.Add(vertices.Count + 2);

                // Add the vertices
                vertices.Add(v0);
                vertices.Add(v1);
                vertices.Add(v2);

                // Compute the normal - flat shaded, so the vertices all have the same normal
                Vector3 normal = Vector3.Cross(v1 - v0, v2 - v0);
                normals.Add(normal);
                normals.Add(normal);
                normals.Add(normal);

                // If you want to texture your terrain, UVs are important,
                // but I just use a flat color so put in dummy coords
                uvs.Add(new Vector2(0.0f, 0.0f));
                uvs.Add(new Vector2(0.0f, 0.0f));
                uvs.Add(new Vector2(0.0f, 0.0f));
            }

            // Create the actual Unity mesh object
            Mesh chunkMesh = new Mesh();
            chunkMesh.vertices  = vertices.ToArray();
            chunkMesh.uv        = uvs.ToArray();
            chunkMesh.triangles = triangles.ToArray();
            chunkMesh.normals   = normals.ToArray();
            chunkMesh.RecalculateNormals();
            chunkMesh.RecalculateTangents();
            chunkMesh.RecalculateBounds();

            // Instantiate the GameObject which will display this chunk
            Transform chunk = new GameObject("terrain patch").GetComponent <Transform>();
            chunk.gameObject.AddComponent <MeshFilter>().mesh         = chunkMesh;
            chunk.gameObject.AddComponent <MeshCollider>().sharedMesh = chunkMesh;
            var rend = chunk.gameObject.AddComponent <MeshRenderer>();
            rend.sharedMaterial = material;
            // rend.material = ColorManager.instance.GetMaterial(1f, false,false);
            chunk.gameObject.AddComponent <MeshCollider>();
            chunk.transform.parent   = transform;
            chunk.transform.position = new Vector3(-xsize / 4f, transform.position.y, -ysize / 4f);
            // chunk.transform.Translate(Random.Range(-10f, 10f), 0, Random.Range(-10f, 10f));
        }
    }
    void generateMesh(int xOffSet, int yOffSet)
    {
        #region Triangle.Net mesh Generation and trianglation
        elevations.Clear();
        polygon = new Polygon();
        mesh    = null;
        for (int i = 0; i < randomPoints; i++)
        {
            polygon.Add(new Vertex(Random.Range(0.0f, xsize), Random.Range(0.0f, ysize)));
        }
        TriangleNet.Meshing.ConstraintOptions options =
            new TriangleNet.Meshing.ConstraintOptions()
        {
            ConformingDelaunay = true
        };
        mesh           = (TriangleNet.Mesh)polygon.Triangulate(options);
        boundedVoronoi = new TriangleNet.Voronoi.BoundedVoronoi(mesh);
        #endregion

        //setting up bounds to be used for generatating UVs
        meshBounds = new Bounds(new Vector3((float)mesh.Bounds.Left - (float)mesh.Bounds.Right,
                                            (float)mesh.Bounds.Top - (float)mesh.Bounds.Bottom), new Vector3((float)mesh.Bounds.Width, (float)mesh.Bounds.Height));

        #region defining and sampling data from images or noise
        int randomMap = Random.Range(0, typesOfImages[selectedImagePoolIndex].Count);
        int min       = 0;
        int maxW;
        int maxH;
        int maxX = 0;
        int maxY = 0;

        // setting width and height to be used for normalising the values to select the appropriate portion of the image
        if (useCustomImage)
        {
            circleGradient = customImage;
            maxW           = circleGradient.width;
            maxH           = circleGradient.height;
        }
        else
        {
            if (useImagePool)
            {
                circleGradient = typesOfImages[selectedImagePoolIndex][randomMap];
                maxW           = typesOfImages[selectedImagePoolIndex][randomMap].width;
                maxH           = typesOfImages[selectedImagePoolIndex][randomMap].height;
            }
            else
            {
                maxW = circleGradient.width;
                maxH = circleGradient.height;
            }
        }
        //sampling image/noise and defining heights
        for (int i = 0; i < mesh.vertices.Count; i++)
        {
            float sample;
            if (usePerlinNoise)
            {
                sample = Mathf.PerlinNoise((float)mesh.vertices[i].x + xOffSet, (float)mesh.vertices[i].y + yOffSet);
            }
            else
            {
                int x = Mathf.FloorToInt(HelperFunctions.normalise((float)mesh.vertices[i].x, min, xsize, min, maxW));
                int y = Mathf.FloorToInt(HelperFunctions.normalise((float)mesh.vertices[i].y, min, ysize, min, maxH));
                maxX = Mathf.Max(x, maxX);
                maxY = Mathf.Max(y, maxY);

                sample = circleGradient.GetPixel(x, y).grayscale;
            }
            sample = defineIsland(sample, mesh.vertices[i]);

            elevations.Add(sample);
        }
        #endregion

        MakeMesh(xOffSet, yOffSet);
    }