Triangulate() public method

Triangulate given input data.
public Triangulate ( InputGeometry input ) : void
input TriangleNet.Geometry.InputGeometry
return void
Ejemplo n.º 1
1
    public Mesh CreateMeshFromPoints(bool combine)
    {
        if (spriteRenderer != null && points.Length > 2) {

            int pointNum = points.Length;
            if (combine && combineMesh != null) {
                pointNum = points.Length + combineMesh.vertices.Length;
            }

            //Create triangle.NET geometry
            TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(pointNum);

            geometry.AddPolygon(points);

            if (combine && combineMesh != null) {
                geometry.AddPolygon(combineMesh.vertices.Select(x => (Vector2)x).ToArray());
            }

            //Triangulate
            TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();

            triangleMesh.Triangulate(geometry);

            //transform vertices
            points = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] vertices = new Vector3[triangleMesh.Vertices.Count];
            Vector3[] normals = new Vector3[triangleMesh.Vertices.Count];

            int n = 0;
            foreach(TriangleNet.Data.Vertex v in triangleMesh.Vertices)
            {

                points[n] = new Vector2((float)v.X, (float)v.Y);
                vertices[n] = new Vector3((float)v.X, (float)v.Y, 0);
                normals[n]=new Vector3(0,0,-1);

                n++;
            }

            //transform triangles
            int[] triangles = triangleMesh.Triangles.ToUnityMeshTriangleIndices();

            mesh.Clear();
            mesh = new Mesh();
            mesh.vertices = vertices;
            mesh.triangles = triangles;
            mesh.uv = genUV(mesh.vertices);
            mesh.normals = normals;

            return mesh;
        }
        else {
            return null;
        }
    }
    public void BuildMeshFromGeometry()
    {
        triMesh = new TriangleNet.Mesh();

        triMesh.behavior.Quality  = true;
        triMesh.behavior.MinAngle = 1f;


        triMesh.Triangulate(Geometry);

        //         var statistic = new Statistic();
        //         statistic.Update(triMesh, 1);

        // Refine by setting a custom maximum area constraint.
        //triMesh.Refine(statistic.LargestArea / 4);
        //triMesh.Smooth();

        triMesh.Renumber();

        UniMesh.vertices = TriangleConverter.ConverteVertices(triMesh.Vertices);
        UniMesh.RecalculateNormals();
        UniMesh.triangles = TriangleConverter.ConverteTriangles(triMesh.Triangles);
        UniMesh.uv        = TriangleConverter.ConverteUVs(triMesh);


        Debug.Log(string.Format("width {0:0.00}, height {1:0.00}; min {2:0.00}, {3:0.00}; max {4:0.00}, {5:0.00}",
                                triMesh.Bounds.Width, triMesh.Bounds.Height,
                                triMesh.Bounds.Xmin, triMesh.Bounds.Ymin,
                                triMesh.Bounds.Xmax, triMesh.Bounds.Ymax));
    }
Ejemplo n.º 3
0
        private int CreateRoofTriangulation(List <Vector3> corners, float height, MeshData data)
        {
            _mesh = new TriangleNet.Mesh();
            var inp = new InputGeometry(corners.Count);

            for (int i = 0; i < corners.Count; i++)
            {
                var v = corners[i];
                inp.AddPoint(v.x, v.z);
                inp.AddSegment(i, (i + 1) % corners.Count);
            }
            _mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            _mesh.Behavior.Quality   = true;
            _mesh.Triangulate(inp);

            var vertsStartCount = data.Vertices.Count;

            data.Vertices.AddRange(corners.Select(x => new Vector3(x.x, height, x.z)).ToList());

            foreach (var tri in _mesh.Triangles)
            {
                data.Indices.Add(vertsStartCount + tri.P1);
                data.Indices.Add(vertsStartCount + tri.P0);
                data.Indices.Add(vertsStartCount + tri.P2);
            }
            return(vertsStartCount);
        }
Ejemplo n.º 4
0
 private static ICollection <Triangle> Triangulate(InputGeometry input)
 {
     TriangleNet.Mesh mesh = new TriangleNet.Mesh();
     mesh.Behavior.ConformingDelaunay = true;
     mesh.Behavior.Algorithm          = TriangulationAlgorithm.SweepLine;
     mesh.Behavior.Convex             = false;
     mesh.Triangulate(input);
     return(mesh.Triangles);
 }
        private static Mesh buildMesh(Dictionary<Point, Color> pointIndex)
        {
            InputGeometry g = new InputGeometry();
            foreach (var value in pointIndex)
            {
                g.AddPoint(value.Key.X, value.Key.Y);
            }

            Mesh m = new Mesh();
            m.Triangulate(g);
            return m;
        }
Ejemplo n.º 6
0
        private void CreateMesh(InputGeometry corners, MeshData meshdata)
        {
            var mesh = new TriangleNet.Mesh();
            mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            mesh.Behavior.Quality = true;
            mesh.Triangulate(corners);

            var vertsStartCount = meshdata.Vertices.Count;
            meshdata.Vertices.AddRange(corners.Points.Select(x => new Vector3((float)x.X, 0, (float)x.Y)).ToList());

            foreach (var tri in mesh.Triangles)
            {
                meshdata.Indices.Add(vertsStartCount + tri.P1);
                meshdata.Indices.Add(vertsStartCount + tri.P0);
                meshdata.Indices.Add(vertsStartCount + tri.P2);
            }
        }
        public override void Run(VectorFeatureUnity feature, MeshData md)
        {
            if (md.Vertices.Distinct().Count() < 3)
            {
                return;
            }

            var data  = new List <int>();
            var _mesh = new TriangleNet.Mesh();
            var inp   = new InputGeometry(md.Vertices.Count);

            for (int i = 0; i < md.Vertices.Count; i++)
            {
                var v = md.Vertices[i];
                inp.AddPoint(v.x, v.z);
                inp.AddSegment(i, (i + 1) % md.Vertices.Count);
            }
            _mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            _mesh.Behavior.Quality   = true;
            _mesh.Triangulate(inp);

            foreach (var tri in _mesh.Triangles)
            {
                data.Add(tri.P1);
                data.Add(tri.P0);
                data.Add(tri.P2);
            }

            if (_mesh.Vertices.Count != md.Vertices.Count)
            {
                md.Vertices.Clear();
                using (var sequenceEnum = _mesh.Vertices.GetEnumerator())
                {
                    while (sequenceEnum.MoveNext())
                    {
                        md.Vertices.Add(new Vector3((float)sequenceEnum.Current.x, 0, (float)sequenceEnum.Current.y));
                    }
                }
            }
            md.Triangles.Add(data);
        }
Ejemplo n.º 8
0
        private List <int> CreateRoofTriangulation(List <Vector3> corners)
        {
            var data  = new List <int>();
            var _mesh = new TriangleNet.Mesh();
            var inp   = new InputGeometry(corners.Count);

            for (int i = 0; i < corners.Count; i++)
            {
                var v = corners[i];
                inp.AddPoint(v.x, v.z);
                inp.AddSegment(i, (i + 1) % corners.Count);
            }
            _mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            _mesh.Behavior.Quality   = true;
            _mesh.Triangulate(inp);

            foreach (var tri in _mesh.Triangles)
            {
                data.Add(tri.P1);
                data.Add(tri.P0);
                data.Add(tri.P2);
            }
            return(data);
        }
Ejemplo n.º 9
0
        private void CreateMesh(List <Vector3> corners, float height, BuildingSettings typeSettings, MeshData data, Vector2 min, Vector2 size)
        {
            _mesh = new TriangleNet.Mesh();

            var inp = new InputGeometry(corners.Count);

            for (int i = 0; i < corners.Count; i++)
            {
                var v = corners[i];
                inp.AddPoint(v.x, v.z);
                inp.AddSegment(i, (i + 1) % corners.Count);
            }
            _mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            _mesh.Behavior.Quality   = true;
            _mesh.Triangulate(inp);

            var vertsStartCount = data.Vertices.Count;

            data.Vertices.AddRange(corners.Select(x => new Vector3(x.x, height, x.z)).ToList());

            foreach (var tri in _mesh.Triangles)
            {
                data.Indices.Add(vertsStartCount + tri.P1);
                data.Indices.Add(vertsStartCount + tri.P0);
                data.Indices.Add(vertsStartCount + tri.P2);
            }

            foreach (var c in corners)
            {
                data.UV.Add(new Vector2((c.x - min.x), (c.z - min.y)));
            }

            if (typeSettings.IsVolumetric)
            {
                float   d = 0f;
                Vector3 v1;
                Vector3 v2;
                int     ind = 0;
                for (int i = 1; i < corners.Count; i++)
                {
                    v1  = data.Vertices[vertsStartCount + i - 1];
                    v2  = data.Vertices[vertsStartCount + i];
                    ind = data.Vertices.Count;
                    data.Vertices.Add(v1);
                    data.Vertices.Add(v2);
                    data.Vertices.Add(new Vector3(v1.x, 0, v1.z));
                    data.Vertices.Add(new Vector3(v2.x, 0, v2.z));

                    d = (v2 - v1).magnitude;

                    data.UV.Add(new Vector2(0, 0));
                    data.UV.Add(new Vector2(d, 0));
                    data.UV.Add(new Vector2(0, height));
                    data.UV.Add(new Vector2(d, height));

                    data.Indices.Add(ind);
                    data.Indices.Add(ind + 2);
                    data.Indices.Add(ind + 1);

                    data.Indices.Add(ind + 1);
                    data.Indices.Add(ind + 2);
                    data.Indices.Add(ind + 3);
                }

                v1  = data.Vertices[vertsStartCount];
                v2  = data.Vertices[vertsStartCount + corners.Count - 1];
                ind = data.Vertices.Count;
                data.Vertices.Add(v1);
                data.Vertices.Add(v2);
                data.Vertices.Add(new Vector3(v1.x, 0, v1.z));
                data.Vertices.Add(new Vector3(v2.x, 0, v2.z));

                d = (v2 - v1).magnitude;

                data.UV.Add(new Vector2(0, 0));
                data.UV.Add(new Vector2(d, 0));
                data.UV.Add(new Vector2(0, height));
                data.UV.Add(new Vector2(d, height));

                data.Indices.Add(ind);
                data.Indices.Add(ind + 1);
                data.Indices.Add(ind + 2);

                data.Indices.Add(ind + 1);
                data.Indices.Add(ind + 3);
                data.Indices.Add(ind + 2);
            }
        }
Ejemplo n.º 10
0
    private void CreateMesh()
    {
        Sprite sprite = spriteRenderer.sprite;

        Rect bounds = GetBounds(polygon);

        TriangleNet.Mesh tnMesh = new TriangleNet.Mesh();
        TriangleNet.Geometry.InputGeometry input = new TriangleNet.Geometry.InputGeometry();

        input.AddPolygon(polygon);

        tnMesh.Triangulate(input);

        Mesh mesh = new Mesh();
        mesh.vertices = tnMesh.Vertices.Select(p => new Vector3((float)p.X, (float)p.Y, 0)).ToArray();

        // Not sure about winding
        // If there is an interesting error, It is probably because of cw/ccw windings
        int[] tris = tnMesh.Triangles.ToUnityMeshTriangleIndices();
        mesh.triangles = tris;

        List<Vector2> uv = new List<Vector2>();

        Vector3 lower = new Vector3(bounds.x, bounds.y);
        Vector3 size = new Vector3(bounds.xMax, bounds.yMax) - lower;

        Rect uv_bounds = new Rect(sprite.rect.x / sprite.texture.width, sprite.rect.y / sprite.texture.height, sprite.rect.width / sprite.texture.width, sprite.rect.height / sprite.texture.height);

        float scalex = sprite.bounds.size.x / bounds.width;
        float scaley = sprite.bounds.size.y / bounds.height;

        Vector3[] scaled = mesh.vertices;

        for (int i = 0; i < mesh.vertices.Length; i++) {
            Vector3 v = scaled[i];
            Vector3 rel = v - lower;
            uv.Add(new Vector2(rel.x / size.x * uv_bounds.width, rel.y / size.y * uv_bounds.height) + new Vector2(uv_bounds.x, uv_bounds.y));

            scaled[i] = new Vector3(v.x * scalex, v.y * scaley, v.z) - ((Vector3)bounds.center * scalex) + sprite.bounds.center;
        }

        mesh.MarkDynamic();
            mesh.vertices = scaled;
        mesh.uv = uv.ToArray();
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();

        //GameObject go = new GameObject();
        //MeshFilter mf = go.AddComponent<MeshFilter>();
        //mf.sharedMesh = mesh;
        //MeshRenderer mr = go.AddComponent<MeshRenderer>();
        //mr.sharedMaterial = spriteRenderer.sharedMaterial;

        // Check if the Meshes directory exists, if not, create it.
        DirectoryInfo meshDir = new DirectoryInfo("Assets/Meshes");
        if (Directory.Exists(meshDir.FullName) == false)
        {
            Directory.CreateDirectory(meshDir.FullName);
        }
        ScriptableObjectUtility.CreateAsset(mesh, "Meshes/" + spriteRenderer.gameObject.name + ".Mesh");
    }
Ejemplo n.º 11
0
    public void SubdivideMesh(int divisions)
    {
        if (spriteRenderer != null && points.Length > 2) {
            // Unparent the skin temporarily before adding the mesh
            Transform polygonParent = spriteRenderer.transform.parent;
            spriteRenderer.transform.parent = null;

            // Reset the rotation before creating the mesh so the UV's will align properly
            Quaternion localRotation = spriteRenderer.transform.localRotation;
            spriteRenderer.transform.localRotation = Quaternion.identity;

            // Reset the scale before creating the mesh so the UV's will align properly
            Vector3 localScale = spriteRenderer.transform.localScale;
            spriteRenderer.transform.localScale = Vector3.one;

            //Create triangle.NET geometry
            TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(points.Length);

            //Add vertices
            foreach (Vector2 point in points) {
                geometry.AddPoint(point.x,point.y);
            }

            int N = geometry.Count;
            int end = 0;
            //Add vertices
            foreach (Vector2 point in points) {
                geometry.AddPoint(point.x,point.y);
                end++;
            }

            for (int i = 0; i < end; i++) {
                geometry.AddSegment(N + i, N + ((i + 1) % end));
            }

            //Triangulate and subdivide the mesh
            TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh();

            if (divisions > 0) {
                triangleMesh.behavior.MinAngle = 10;
            }

            triangleMesh.Triangulate(geometry);
            if (divisions > 0) {
                if (divisions > 1) triangleMesh.Refine(true);
                TriangleNet.Tools.Statistic stat = new TriangleNet.Tools.Statistic();
                stat.Update(triangleMesh, 1);
                // Refine by area
                if (divisions > 2) triangleMesh.Refine (stat.LargestArea / 8);

                try {
                    triangleMesh.Smooth();
                } catch {
                    //Debug.Log("Cannot subdivide");
                }
                triangleMesh.Renumber();
            }

            //transform vertices
            points = new Vector2[triangleMesh.Vertices.Count];
            Vector3[] vertices = new Vector3[triangleMesh.Vertices.Count];
            Vector3[] normals = new Vector3[triangleMesh.Vertices.Count];

            int n = 0;
            foreach(TriangleNet.Data.Vertex v in triangleMesh.Vertices) {

                points[n] = new Vector2((float)v.X, (float)v.Y);
                vertices[n] = new Vector3((float)v.X, (float)v.Y, 0);
                normals[n] = new Vector3(0, 0, -1);
                n++;
            }

            //transform triangles
            int[] triangles = new int[triangleMesh.Triangles.Count*3];
            n = 0;
            foreach (TriangleNet.Data.Triangle t in triangleMesh.Triangles) {
                triangles[n++] = t.P1;
                triangles[n++] = t.P0;
                triangles[n++] = t.P2;
            }

            mesh.Clear();
            mesh = new Mesh();
            mesh.vertices = vertices;
            mesh.triangles = triangles;
            mesh.uv = genUV(mesh.vertices);
            mesh.normals = normals;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();

            // Reset the rotations of the object
            spriteRenderer.transform.localRotation = localRotation;
            spriteRenderer.transform.localScale = localScale;
            spriteRenderer.transform.parent = polygonParent;

            meshCreated = true;
        }
    }
Ejemplo n.º 12
0
        public static List<SampleTri> BuildMesh(Dictionary<Point, Pixel> pointIndex)
        {
            InputGeometry g = new InputGeometry();
            foreach (var value in pointIndex)
            {
                g.AddPoint(value.Key.X, value.Key.Y);
            }

            Mesh m = new Mesh();
            m.Triangulate(g);

            List<SampleTri> sampleMesh = new List<SampleTri>();

            Dictionary<ITriangle, SampleTri> table = new Dictionary<ITriangle, SampleTri>();

            Dictionary<Point, Sample> sampleTable = new Dictionary<Point, Sample>();

            foreach (var mTri in m.Triangles)
            {
                SampleTri tri = new SampleTri(mTri);

                for (int i = 0; i < 3; i++)
                    tri.TriangleNeighbours.Add(mTri.GetNeighbor(i));

                sampleMesh.Add(tri);
                table.Add(mTri, tri);

                if (sampleTable.ContainsKey(tri.U.Point))
                    tri.U = sampleTable[tri.U.Point];
                else
                    sampleTable[tri.U.Point] = tri.U;

                if (sampleTable.ContainsKey(tri.V.Point))
                    tri.V = sampleTable[tri.V.Point];
                else
                    sampleTable[tri.V.Point] = tri.V;

                if (sampleTable.ContainsKey(tri.W.Point))
                    tri.W = sampleTable[tri.W.Point];
                else
                    sampleTable[tri.W.Point] = tri.W;
            }

            foreach (var tri in sampleMesh)
            {
                foreach (var triangleNeighbour in tri.TriangleNeighbours)
                {
                    if (triangleNeighbour != null)
                        tri.SampleTriNeighbours.Add(table[triangleNeighbour]);
                }
                tri.U.Triangles.Add(tri);
                tri.V.Triangles.Add(tri);
                tri.W.Triangles.Add(tri);

                tri.U.Color = pointIndex[tri.U.Point];
                tri.V.Color = pointIndex[tri.V.Point];
                tri.W.Color = pointIndex[tri.W.Point];

                tri.CenterColor = tri.U.Color;
            }

            return sampleMesh;
        }
Ejemplo n.º 13
0
		public static PolyGisLayer CreateFromContour(Game engine, DVector2[] lonLatRad, Color color)
		{
			var triangulator = new TriangleNet.Mesh();
			triangulator.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
			
			InputGeometry ig = new InputGeometry();

			ig.AddPoint(lonLatRad[0].X, lonLatRad[0].Y);
			for (int v = 1; v < lonLatRad.Length; v++) {
				ig.AddPoint(lonLatRad[v].X, lonLatRad[v].Y);
				ig.AddSegment(v-1, v);
			}
			ig.AddSegment(lonLatRad.Length - 1, 0);
			
			triangulator.Triangulate(ig);

			if (triangulator.Vertices.Count != lonLatRad.Length) {
				Log.Warning("Vertices count not match");
				return null;
			}


			var points = new List<Gis.GeoPoint>();
			foreach (var pp in triangulator.Vertices) {
				points.Add(new Gis.GeoPoint {
					Lon		= pp.X,
					Lat		= pp.Y,
					Color	= color
				});
			}


			var indeces = new List<int>();
			foreach (var tr in triangulator.Triangles) {
				indeces.Add(tr.P0);
				indeces.Add(tr.P1);
				indeces.Add(tr.P2);
			}


			return new PolyGisLayer(engine, points.ToArray(), indeces.ToArray(), true) {
				Flags = (int)(PolyFlags.NO_DEPTH | PolyFlags.DRAW_TEXTURED | PolyFlags.CULL_NONE | PolyFlags.VERTEX_SHADER | PolyFlags.PIXEL_SHADER | PolyFlags.USE_PALETTE_COLOR) 
			};
		}
Ejemplo n.º 14
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="contour"></param>
        void AddMunicipalDivision(string name, List<DVector2> contour)
        {
            if (municipalDivisions.ContainsKey(name)) return;

            var mesh = new TriangleNet.Mesh();
            mesh.Behavior.Quality = true;
            mesh.Behavior.MinAngle = 25;
            mesh.Behavior.Convex = false;

            var ig = new InputGeometry();

            ig.AddPoint(contour[0].X, contour[0].Y);
            for (int v = 1; v < contour.Count; v++) {
                ig.AddPoint(contour[v].X, contour[v].Y);
                ig.AddSegment(v - 1, v);
            }
            ig.AddSegment(contour.Count - 1, 0);

            mesh.Triangulate(ig);

            int n = mesh.Vertices.Count;

            mesh.Renumber();

            // Vertices
            var moVerts = new GeoVert[n];
            int i = 0;
            foreach (var pt in mesh.Vertices) {
                moVerts[i] = new GeoVert {
                    Lon			= pt.X * Math.PI / 180.0,
                    Lat			= pt.Y * Math.PI / 180.0,
                    Position	= Vector3.Zero,
                    Tex			= Vector4.Zero,
                    Color		= Color.White
                };

                i++;
            }

            // Triangles
            var triangles = new int[3 * mesh.Triangles.Count];
            i = 0;
            foreach (var tri in mesh.Triangles) {
                triangles[i * 3 + 0] = tri.P0;
                triangles[i * 3 + 1] = tri.P1;
                triangles[i * 3 + 2] = tri.P2;
                i++;
            }

            // Contour vertices
            var contourVerts = new GeoVert[contour.Count*2];

            contourVerts[1] = new GeoVert {
                Lon			= contour[0].X * Math.PI / 180.0,
                Lat			= contour[0].Y * Math.PI / 180.0,
                Position	= Vector3.Zero,
                Tex			= Vector4.Zero,
                Color		= Color.Red
            };

            for (int j = 1; j < contour.Count; j++) {
                contourVerts[2*j+1] = new GeoVert {
                    Lon			= contour[j].X * Math.PI / 180.0,
                    Lat			= contour[j].Y * Math.PI / 180.0,
                    Position	= Vector3.Zero,
                    Tex			= Vector4.Zero,
                    Color		= Color.Red
                };
                contourVerts[2*j] = contourVerts[2*(j - 1) + 1];
            }

            contourVerts[0] = contourVerts[contourVerts.Length-1];

            // Create buffers
            var vb		= new VertexBuffer(Game.GraphicsDevice, typeof (GeoVert), moVerts.Length);
            var inds	= new IndexBuffer(Game.GraphicsDevice, triangles.Length);
            var cont	= new VertexBuffer(Game.GraphicsDevice, typeof (GeoVert), contourVerts.Length);

            vb.SetData(moVerts, 0, moVerts.Length);
            inds.SetData(triangles, 0, triangles.Length);
            cont.SetData(contourVerts, 0, contourVerts.Length);

            municipalDivisions.Add(name, new MD {
                    Contour		= cont,
                    Indeces		= inds,
                    Vertices	= vb,
                    Value		= r.NextFloat(0.0f, 1.0f)
                });
        }
    public void CreateSubdividedMesh(Vector2[] vertsToCopy, Transform transform, int smoothLevel)
    {
        Sprite spr = transform.GetComponent<SpriteRenderer>().sprite;
        Rect rec = spr.rect;
        Vector3 bound = transform.GetComponent<Renderer>().bounds.max- transform.GetComponent<Renderer>().bounds.min ;
        TextureImporter textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spr)) as TextureImporter;

        //Create triangle.NET geometry
        TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(vertsToCopy.Length);

        //Add vertices
        foreach (Vector2 p in vertsToCopy)
        {
            geometry.AddPoint(p.x,p.y);
        }
        //Add segments
        for (int i=0;i<vertsToCopy.Length-1;i++) {
            geometry.AddSegment(i,i+1);
        }
        geometry.AddSegment(vertsToCopy.Length-1,0);

        //Triangulate, refine and smooth
        TriangleNet.Mesh triangleNetMesh = new TriangleNet.Mesh();
        if(smoothLevel>0)
            triangleNetMesh.behavior.MinAngle = 10;

        triangleNetMesh.Triangulate(geometry);
        if (smoothLevel > 0)
        {
            if (smoothLevel > 1)
                triangleNetMesh.Refine (true);
            TriangleNet.Tools.Statistic statistic = new TriangleNet.Tools.Statistic ();
            statistic.Update (triangleNetMesh, 1);
            // Refine by setting a custom maximum area constraint.
            if (smoothLevel > 2)
                triangleNetMesh.Refine (statistic.LargestArea / 8);

            try {
                triangleNetMesh.Smooth ();
            } catch {
                //Debug.LogWarning("unable to smooth");
            }
            triangleNetMesh.Renumber ();
        }

        //transform vertices
        Vector3[] vertices = new Vector3[triangleNetMesh.Vertices.Count];
        Vector2[] uvs = new Vector2[triangleNetMesh.Vertices.Count];
        Vector3[] normals = new Vector3[triangleNetMesh.Vertices.Count];

        int idx = 0;
        foreach(TriangleNet.Data.Vertex v in triangleNetMesh.Vertices)
        {

            vertices[idx] = new Vector3(	(float)v.X,	(float)v.Y,	0	);
            normals[idx]=new Vector3(0,0,-1);

            Vector2 newUv = new Vector2(((float)v.X /bound.x) + 0.5f,  ((float)v.Y /bound.y)  + 0.5f);

            newUv.x *= rec.width/ spr.texture.width;
            newUv.y *= rec.height/ spr.texture.height;
            //Debug.Log(spr.textureRectOffset);
            newUv.x += (rec.x)/ spr.texture.width;
            newUv.y += (rec.y) / spr.texture.height;

            SpriteMetaData[] smdArray = textureImporter.spritesheet;
            Vector2 pivot = new Vector2(.0f,.0f);;

            for (int i = 0; i < smdArray.Length; i++)
            {
                if (smdArray[i].name == spr.name)
                {
                    switch(smdArray[i].alignment)
                    {
                        case(0):
                        smdArray[i].pivot = Vector2.zero;
                        break;
                        case(1):
                        smdArray[i].pivot = new Vector2(0f,1f) -new Vector2(.5f,.5f);
                        break;
                        case(2):
                        smdArray[i].pivot = new Vector2(0.5f,1f) -new Vector2(.5f,.5f);
                        break;
                        case(3):
                        smdArray[i].pivot = new Vector2(1f,1f) -new Vector2(.5f,.5f);
                        break;
                        case(4):
                        smdArray[i].pivot = new Vector2(0f,.5f) -new Vector2(.5f,.5f);
                        break;
                        case(5):
                        smdArray[i].pivot = new Vector2(1f,.5f) -new Vector2(.5f,.5f);
                        break;
                        case(6):
                        smdArray[i].pivot = new Vector2(0f,0f) -new Vector2(.5f,.5f);
                        break;
                        case(7):
                        smdArray[i].pivot = new Vector2(0.5f,0f) -new Vector2(.5f,.5f);
                        break;
                        case(8):
                        smdArray[i].pivot = new Vector2(1f,0f) -new Vector2(.5f,.5f);
                        break;
                        case(9):
                        smdArray[i].pivot -= new Vector2(.5f,.5f);
                        break;
                    }
                    pivot = smdArray[i].pivot ;
                }
            }
            if(textureImporter.spriteImportMode == SpriteImportMode.Single)
                pivot = textureImporter.spritePivot-new Vector2(.5f,.5f);
            newUv.x += ((pivot.x)*rec.width)/ spr.texture.width;
            newUv.y += ((pivot.y)*rec.height)/ spr.texture.height;

            uvs[idx] = newUv;
            idx++;
        }

        //transform triangles
        int[] triangles = new int[triangleNetMesh.Triangles.Count*3];
        idx = 0;
        foreach (TriangleNet.Data.Triangle t in triangleNetMesh.Triangles)
        {
            triangles[idx++] = t.P1;
            triangles[idx++] = t.P0;
            triangles[idx++] = t.P2;
        }

        finalVertices = vertices;
        finalTriangles = triangles;
        finalUvs = uvs;
        finalNormals = normals;
    }
Ejemplo n.º 16
0
        void InitBuildingsOSM()
        {
            var osm = Game.GetService<LayerService>().OpenStreetMapSource;

            List<GeoVert> lines = new List<GeoVert>();
            List<GeoVert> simple = new List<GeoVert>();

            var nodes = osm.allNodes;
            int k = 0;
            foreach (var way in osm.allWays) {
                if (!way.Value.isBuilding) continue;

                var centerMerc = way.Value.BBox.Center();
                float width		= (way.Value.BBox.Maximum - way.Value.BBox.Minimum).X * 10000.0f;
                float length	= (way.Value.BBox.Maximum - way.Value.BBox.Minimum).Y * 10000.0f;
                double lon, lat;
                GeoHelper.TileToWorldPos(centerMerc.X, centerMerc.Y, 0, out lon, out lat);

                simple.Add(new GeoVert {
                        Lon			= DMathUtil.DegreesToRadians(lon),
                        Lat			= DMathUtil.DegreesToRadians(lat),
                        Color		= Color.White,
                        Position	= Vector3.Zero,
                        Tex			= new Vector4(width, length, 0, 0)
                    });

                List<DVector2> buildingVertices = new List<DVector2>();
                for (int i = 0; i < way.Value.nodeRef.Length - 1; i++) {
                    var nInds = way.Value.nodeRef;

                    lines.Add(new GeoVert {
                            Lon			= DMathUtil.DegreesToRadians(nodes[nInds[i]].Longitude),
                            Lat			= DMathUtil.DegreesToRadians(nodes[nInds[i]].Latitude),
                            Position	= new Vector3(1.0f, 0.0f, 0.0f),
                            Color		= Color.Yellow,
                            Tex			= Vector4.Zero
                        });

                    lines.Add(new GeoVert {
                            Lon			= DMathUtil.DegreesToRadians(nodes[nInds[i+1]].Longitude),
                            Lat			= DMathUtil.DegreesToRadians(nodes[nInds[i+1]].Latitude),
                            Position	= new Vector3(1.0f, 0.0f, 0.0f),
                            Color		= Color.Yellow,
                            Tex			= Vector4.Zero
                        });

                    buildingVertices.Add(new DVector2(nodes[nInds[i]].Longitude, nodes[nInds[i]].Latitude));
                }
                buildingVertices.Add(new DVector2(nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Longitude, nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Latitude));

                /////////////////////////////////////////

                var mesh = new Mesh();
                mesh.Behavior.Quality	= false;
                mesh.Behavior.MinAngle	= 25;
                mesh.Behavior.Convex	= false;

                var ig = new InputGeometry();

                ig.AddPoint(buildingVertices[0].X, buildingVertices[0].Y);
                for (int v = 1; v < buildingVertices.Count; v++) {
                    ig.AddPoint(buildingVertices[v].X, buildingVertices[v].Y);
                    ig.AddSegment(v - 1, v);
                }
                ig.AddSegment(buildingVertices.Count - 1, 0);

                mesh.Triangulate(ig);

                int n = mesh.Vertices.Count;

                mesh.Renumber();

                buildings = new GeoVert[mesh.Triangles.Count*3];

                int ind = 0;
                foreach (var triangle in mesh.Triangles) {
                    buildings[ind++] = new GeoVert {
                        Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).X),
                        Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).Y),
                        Position = new Vector3(0.1f, 0.0f, 0.0f),
                        Color = Color.Green,
                        Tex = Vector4.Zero
                    };
                    buildings[ind++] = new GeoVert {
                        Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).X),
                        Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).Y),
                        Position = new Vector3(0.1f, 0.0f, 0.0f),
                        Color = Color.Green,
                        Tex = Vector4.Zero
                    };
                    buildings[ind++] = new GeoVert {
                        Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).X),
                        Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).Y),
                        Position = new Vector3(0.1f, 0.0f, 0.0f),
                        Color = Color.Green,
                        Tex = Vector4.Zero
                    };
                }

                /////////////////////////////////////////

                k++;
                if (k >= 1) break;
            }

            simpleBuildings		= simple.ToArray();
            contourBuildings	= lines.ToArray();

            contourBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof (GeoVert), contourBuildings.Length);
            contourBuildingsVB.SetData(contourBuildings, 0, contourBuildings.Length);

            simpleBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), simpleBuildings.Length);
            simpleBuildingsVB.SetData(simpleBuildings, 0, simpleBuildings.Length);

            buildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), buildings.Length);
            buildingsVB.SetData(buildings, 0, buildings.Length);
        }
Ejemplo n.º 17
0
        private void RecalculateVertices()
        {
            if (points.Count < 2)
            {
                return;
            }

            vertexPositionColorArray = null;

            var lineColor = Color.Red;

            #region clipper
            List<IntPoint> clipperPath = new List<IntPoint>(points.Count);
            foreach (var point in points)
            {
                clipperPath.Add(new IntPoint(point.X * ClipperScale, point.Y * ClipperScale));
            }

            List<List<IntPoint>> clipperSolution = new List<List<IntPoint>>();
            ClipperOffset clipperOffset = new ClipperOffset();

            clipperOffset.AddPath(clipperPath, JoinType.jtRound, EndType.etOpenRound);
            clipperOffset.Execute(ref clipperSolution, lineThickness / 2.0f * ClipperScale);
            #endregion

            #region triangle.net
            InputGeometry InputGeometry = new InputGeometry();
            Mesh TriangleMesh = new Mesh();

            for (int iii = 0; iii < clipperSolution.Count; iii++)
            {
                var trianglePath = clipperSolution[iii].Select(p => new TrianglePoint(p.X / (float)ClipperScale, p.Y / (float)ClipperScale)).ToList();

                if (iii == 0)
                {
                    InputGeometry.AddRing(trianglePath);
                }
                else
                {
                    InputGeometry.AddRingAsHole(trianglePath);
                }
            }
            #endregion

            if (InputGeometry.Count > 0)
            {
                TriangleMesh.Triangulate(InputGeometry);

                vertexPositionColorArray = TriangleMesh.GetTriangleList().Select(v => new VertexPositionColor(new Vector3((float)v.X, (float)v.Y, 0.0f), lineColor)).ToArray();

                vertexBuffer = new VertexBuffer(GraphicsDevice, VertexPositionColor.VertexDeclaration, vertexPositionColorArray.Length, BufferUsage.WriteOnly);
                vertexBuffer.SetData<VertexPositionColor>(vertexPositionColorArray);
            }
        }
        private void endBtn_Click(object sender, RoutedEventArgs e)
        {
            this._host.CommandReset.Click  -= endBtn_Click;
            this._host.Menues.IsEnabled     = true;
            this._host.UIMessage.Visibility = Visibility.Hidden;
            //this.JGraphMode = false;
            this._host.Cursor = Cursors.Arrow;
            this._host.FloorScene.MouseLeftButtonDown -= FloorScene_MouseLeftButtonDown;
            try
            {
                #region Create Graph
                HashSet <UV>         pnts               = new HashSet <UV>();
                TriangleNet.Behavior behavior           = new Behavior();
                TriangleNet.Mesh     t_mesh             = new TriangleNet.Mesh();
                TriangleNet.Geometry.InputGeometry geom = new TriangleNet.Geometry.InputGeometry();
                foreach (Node node in JGNodes)
                {
                    TriangleNet.Data.Vertex vertex = new TriangleNet.Data.Vertex(node.Coordinates.U, node.Coordinates.V, 0);
                    geom.AddPoint(vertex);
                    pnts.Add(node.Coordinates);
                }
                t_mesh.Triangulate(geom);

                var graph = new JGGraph(pnts);
                foreach (var item in t_mesh.Triangles)
                {
                    UV  a    = null;
                    var vrtx = t_mesh.GetVertex(item.P0);
                    if (vrtx != null)
                    {
                        a = new UV(vrtx.X, vrtx.Y);
                    }
                    UV b = null;
                    vrtx = t_mesh.GetVertex(item.P1);
                    if (vrtx != null)
                    {
                        b = new UV(vrtx.X, vrtx.Y);
                    }
                    UV c = null;
                    vrtx = t_mesh.GetVertex(item.P2);
                    if (vrtx != null)
                    {
                        c = new UV(vrtx.X, vrtx.Y);
                    }
                    if (a != null && b != null)
                    {
                        graph.AddConnection(a, b);
                    }
                    if (a != null && c != null)
                    {
                        graph.AddConnection(a, c);
                    }
                    if (c != null && b != null)
                    {
                        graph.AddConnection(c, b);
                    }
                }
                #endregion
                #region Remove Edges with isovists at the ends that do not overlap
                this.edges = graph.ToEdges();
                Dictionary <int, Isovist> IsovistGuid = new Dictionary <int, Isovist>();
                foreach (JGVertex item in graph.Vertices)
                {
                    double x = double.NegativeInfinity;
                    foreach (JGVertex vertex in item.Connections)
                    {
                        var y = item.Point.DistanceTo(vertex.Point);
                        if (y > x)
                        {
                            x = y;
                        }
                    }
                    var isovist = CellularIsovistCalculator.GetIsovist(item.Point, x, BarrierType.Visual, this._host.cellularFloor);
                    IsovistGuid.Add(item.Point.GetHashCode(), isovist);
                }
                HashSet <JGEdge> visibleVertexes = new HashSet <JGEdge>();
                foreach (JGEdge item in this.edges)
                {
                    Isovist v1 = null;
                    IsovistGuid.TryGetValue(item.P1.GetHashCode(), out v1);
                    Isovist v2 = null;
                    IsovistGuid.TryGetValue(item.P2.GetHashCode(), out v2);
                    if (v1 != null && v2 != null)
                    {
                        if (v2.VisibleCells.Overlaps(v1.VisibleCells))
                        {
                            visibleVertexes.Add(item);
                        }
                    }
                }
                #endregion
                #region setting the edges
                JGEdge.LineToEdgeGuide.Clear();
                foreach (JGEdge edge in this.edges)
                {
                    edge.Clear();
                }
                this.edges = visibleVertexes.ToList <JGEdge>();
                foreach (JGEdge item in this.edges)
                {
                    item.Draw();
                }
                #endregion
                //cleaning up the used data
                t_mesh = null;
                graph  = null;
                geom.Clear();
                geom            = null;
                visibleVertexes = null;
                IsovistGuid     = null;
                //enabling edit mode
                this.EditGraph.IsEnabled      = true;
                this.DrawJG.IsEnabled         = true;
                this.Hide_show_Menu.IsEnabled = true;
                this.CreateCovexGraph.Header  = "Reset Convex Graph";
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Report());
            }
        }
Ejemplo n.º 19
0
	// Use this for initialization
	void Start () 
    {
        Map = new GameMap();
        Map.TerrainData = LowPolyTerrainData.GetRandomMap();

        var building = new Building();
        building.Positions.Add(new Vector2Int(6, 1));
        building.Positions.Add(new Vector2Int(7, 1));
        building.Positions.Add(new Vector2Int(8, 1));
        building.Positions.Add(new Vector2Int(9, 1));
        building.Positions.Add(new Vector2Int(10, 1));
        building.Positions.Add(new Vector2Int(11, 1));
        building.Positions.Add(new Vector2Int(12, 1));
        building.Positions.Add(new Vector2Int(13, 1));
        building.Positions.Add(new Vector2Int(14, 1));
        building.Positions.Add(new Vector2Int(11, 2));
        building.Positions.Add(new Vector2Int(12, 2));
        building.Positions.Add(new Vector2Int(12, 3));
        building.Positions.Add(new Vector2Int(13, 3));
        building.Positions.Add(new Vector2Int(13, 4));
        building.Positions.Add(new Vector2Int(14, 4));
        building.Positions.Add(new Vector2Int(14, 5));
        building.Positions.Add(new Vector2Int(15, 5));
        building.RemoveTrees(Map.TerrainData);
        //Map.Buildings.Add(building);
        
        building = new Building();
        //building.Positions.Add(new Vector2Int(6, 2));
        building.Positions.Add(new Vector2Int(7, 2));
        building.Positions.Add(new Vector2Int(8, 2));
        building.Positions.Add(new Vector2Int(9, 2));
        building.Positions.Add(new Vector2Int(10, 2));
        building.Positions.Add(new Vector2Int(5, 3));
        building.Positions.Add(new Vector2Int(6, 3));
        building.Positions.Add(new Vector2Int(7, 3));
        building.Positions.Add(new Vector2Int(8, 3));
        building.Positions.Add(new Vector2Int(9, 3));
        building.Positions.Add(new Vector2Int(10, 3));
        building.Positions.Add(new Vector2Int(11, 3));
        //building.Positions.Add(new Vector2Int(5, 4));
        building.Positions.Add(new Vector2Int(6, 4));
        building.Positions.Add(new Vector2Int(7, 4));
        building.Positions.Add(new Vector2Int(8, 4));
        building.Positions.Add(new Vector2Int(9, 4));
        building.Positions.Add(new Vector2Int(10, 4));
        building.Positions.Add(new Vector2Int(11, 4));
        building.Positions.Add(new Vector2Int(10, 6));
        building.Positions.Add(new Vector2Int(11, 6));
        building.Positions.Add(new Vector2Int(12, 6));
        building.Type = "house";
        building.RemoveTrees(Map.TerrainData);
        //Map.Buildings.Add(building);
        
        building = new Building();
        
        var floor = new BuildingFloor();
        floor.Positions.Add(new Vector2Int(13, 2));
        floor.Positions.Add(new Vector2Int(14, 2));
        floor.Positions.Add(new Vector2Int(15, 2));
        floor.Positions.Add(new Vector2Int(16, 2));
        floor.Positions.Add(new Vector2Int(14, 3));
        floor.Positions.Add(new Vector2Int(15, 3));
        floor.Positions.Add(new Vector2Int(16, 3));

		floor.WallEdges.Add(new WallEdge(new Vector2Int(13, 2), 2));
		floor.WallEdges.Add(new WallEdge(new Vector2Int(13, 2), 0));

        floor.BaseHeight = 20.0f;
        floor.FloorHeight = 0.2f;
        floor.Height = 10.0f;
        floor.Map = Map;

        building.Floors.Add(floor);
        
        floor = new BuildingFloor();
        floor.Positions.Add(new Vector2Int(14, 2));
        floor.Positions.Add(new Vector2Int(15, 2));
        floor.Positions.Add(new Vector2Int(16, 2));
        floor.Positions.Add(new Vector2Int(14, 3));
        floor.Positions.Add(new Vector2Int(15, 3));
        floor.Positions.Add(new Vector2Int(16, 3));

		floor.WallEdges.Add(new WallEdge(new Vector2Int(14, 2), 2));
		floor.WallEdges.Add(new WallEdge(new Vector2Int(15, 2), 2));

        floor.BaseHeight = 30.0f;
        floor.FloorHeight = 0.2f;
        floor.Height = 10.0f;
        floor.Map = Map;
        building.Floors.Add(floor);

        floor = new BuildingFloor();
        floor.Positions.Add(new Vector2Int(15, 4));
        floor.Positions.Add(new Vector2Int(16, 4));
        floor.Positions.Add(new Vector2Int(17, 4));
        floor.Positions.Add(new Vector2Int(17, 3));
        floor.Positions.Add(new Vector2Int(18, 3));

		floor.WallEdges.Add(new WallEdge(new Vector2Int(15, 4), 0));
		floor.WallEdges.Add(new WallEdge(new Vector2Int(16, 4), 0));
		floor.WallEdges.Add(new WallEdge(new Vector2Int(17, 4), 1, 2));

        floor.BaseHeight = 22.0f;
        floor.FloorHeight = 0.2f;
        floor.Height = 10.0f;
        floor.Map = Map;
        building.Floors.Add(floor);

        building.Type = "generic";

        building.RemoveTrees(Map.TerrainData);
        Map.Buildings.Add(building);

        Init(Map);

        var geometry = new InputGeometry();

        //it is necessary to put a border around all the points in order to get triangulation to work correctly when holes are used
        var border = new List<Point>();
        border.Add(new Point(10, 6));
        border.Add(new Point(10, -6));
        border.Add(new Point(-10, -6));
        border.Add(new Point(-10, 6));
        geometry.AddRing(border);

        border = new List<Point>();
        border.Add(new Point(7, 4));
        border.Add(new Point(7, 2));
        border.Add(new Point(5, 2));
        border.Add(new Point(5, 4));
        geometry.AddRingAsHole(border);
        
        border = new List<Point>();
        border.Add(new Point(3, 2));
        border.Add(new Point(3, -6));
        border.Add(new Point(-3, -6));
        border.Add(new Point(-3, 2));
        geometry.AddRingAsHole(border);

        var meshRepresentation = new TriangleNet.Mesh();
        meshRepresentation.Triangulate(geometry);

        var triangleIndex = 0;
        var vertices = new List<Vector3>(meshRepresentation.triangles.Count * 3);
        var triangleIndices = new List<int>(meshRepresentation.triangles.Count * 3);

        foreach(var pair in meshRepresentation.triangles)
        {
            var triangle = pair.Value;

            var vertex0 = triangle.GetVertex(0);
            var vertex1 = triangle.GetVertex(1);
            var vertex2 = triangle.GetVertex(2);

			var p0 = new Vector3( vertex0.x, vertex0.y, 0 );
			var p1 = new Vector3( vertex1.x, vertex1.y, 0 );
			var p2 = new Vector3( vertex2.x, vertex2.y, 0 );

            vertices.Add(p0);
            vertices.Add(p1);
            vertices.Add(p2);

            triangleIndices.Add(triangleIndex + 2);
            triangleIndices.Add(triangleIndex + 1);
            triangleIndices.Add(triangleIndex);

            triangleIndex += 3;
        }
        
        var mesh = new Mesh();
        mesh.vertices = vertices.ToArray();
        mesh.triangles = triangleIndices.ToArray();
        mesh.RecalculateNormals();

        var newObj = new GameObject();
        newObj.name = "Test";
        newObj.transform.parent = transform;
        newObj.AddComponent<MeshFilter>();
        newObj.AddComponent<MeshRenderer>();
        newObj.GetComponent<MeshFilter>().mesh = mesh;

        /*
        var path = new List<ClipperLib.IntPoint>();
        path.Add(new ClipperLib.IntPoint(-3000, 0));
        path.Add(new ClipperLib.IntPoint(1000, 0));
        path.Add(new ClipperLib.IntPoint(6000, 3000));
        path.Add(new ClipperLib.IntPoint(6000, -3000));
        path.Add(new ClipperLib.IntPoint(1000, 0));
        //path.Add(new ClipperLib.IntPoint(5000, 0));
        //path.Add(new ClipperLib.IntPoint(1000, -3500));
        //path.Add(new ClipperLib.IntPoint(-3000, 0));
        
        var co = new ClipperLib.ClipperOffset();
        co.AddPath(path, ClipperLib.JoinType.jtSquare, ClipperLib.EndType.etClosedLine);

        var result = new List<List<ClipperLib.IntPoint>>();
        co.Execute(ref result, 500);
        foreach (var intpoint in path)
        {
            var point = new Vector3((float)intpoint.X / 1000.0f, 0, (float)intpoint.Y / 1000.0f);
            Debug.DrawLine(point, point + Vector3.up * 3, Color.cyan, 100);
        }

        foreach (var intpath in result)
        {
            foreach (var intpoint in intpath)
            {
                var point = new Vector3((float)intpoint.X / 1000.0f, 0, (float)intpoint.Y / 1000.0f);
                Debug.DrawLine(point, point + Vector3.up * 3, Color.red, 100);
            }
        }
        */
    }
Ejemplo n.º 20
0
    public WaterSurfacePolygon(List<Point> points)
    {
        mesh = new TriangleNet.Mesh();
        mesh.Behavior.Quality = true;

        this.points = points;

        triangleNormals = new List<Point>();
        trianglePlaneEquationDs = new List<double>();

        InputGeometry geomtery = new InputGeometry();

        for (int i = 0; i < points.Count; i++)
        {
            Point p = points[i];

            if (i == 0)
            {
                minX = maxX = p.X;
                minY = maxY = p.Y;
                minZ = maxZ = p.Z;
            }
            else
            {
                minX = Math.Min(p.X, minX);
                maxX = Math.Max(p.X, maxX);
                minY = Math.Min(p.Y, minY);
                maxY = Math.Max(p.Y, maxY);
                minZ = Math.Min(p.Z, minZ);
                maxZ = Math.Max(p.Z, maxZ);
            }

            geomtery.AddPoint(p.X, p.Y, 0, p.Z);

            //add segments
            if (i > 0)
            {
                geomtery.AddSegment(i - 1, i, 0);
            }

            if (i == points.Count - 1)
            {
                geomtery.AddSegment(i, 0, 0);
            }
        }

        mesh.Triangulate(geomtery);
        triangles = new List<TriangleNet.Data.Triangle>();

        foreach (TriangleNet.Data.Triangle tr in mesh.Triangles)
        {
            if (tr.P0 < points.Count && tr.P1 < points.Count && tr.P2 < points.Count)
            {
                triangles.Add(tr);
            }
        }

        calculateNormalsAndDs();
    }
Ejemplo n.º 21
0
        public TriangulatedGlyph(Glyph glyphData, TrueTypeFile.HorizontalMetric horizontalMetric)
        {
            indices = new List<int>();
            vertices = new List<Vertex>();
            advanceWidth = horizontalMetric.AdvanceWidth;
            leftSideBearing = horizontalMetric.LeftSideBearing;

            if (glyphData.IsCompound)
            {
                
            }
            else
            {
                if (glyphData.Contours.Length == 0)
                    return;

                List<Triangle> triangles;
                List<LinkedList<ControlPoint>> contours = CreateContours(glyphData, out triangles);

                int count = 0;
                bool split;
                do
                {
                    split = SplitTriangles(ref triangles);
                    count++;
                } while (split && count < 4);

                foreach (var triangle in triangles)
                {
                    ControlPoint p = (triangle.B + triangle.C) / 2;
                    int windingNumber = GetWindingNumber(p, glyphData);
                    triangle.IsInside = windingNumber == 0;

                    if (triangle.IsInside) triangle.Contour.AddAfter(triangle.BNode, triangle.A);
                }

                PolyTree tree = ClipperHelper.Combine(contours.Select(contour => contour.ToList()).ToList());

                int pointIndex = 0;
                var inputGeometry = new InputGeometry();
                SearchTree(inputGeometry, ref pointIndex, tree);

                if (inputGeometry.Count > 0)
                {
                    var mesh = new Mesh();
                    mesh.Triangulate(inputGeometry);

                    int highestIndex = 0;
                    var indexDict = new Dictionary<int, int>();
                    foreach (TriangleNet.Data.Triangle triangle in mesh.Triangles)
                    {
                        int[] newIndices;
                        List<Vertex> newVertices = IndexVertices(triangle, indexDict, ref highestIndex, out newIndices);

                        indices.AddRange(newIndices);
                        vertices.AddRange(newVertices);
                    }

                    foreach (var triangle in triangles)
                    {
                        indices.Add(vertices.Count);
                        vertices.Add(new Vertex((float)triangle.B.X, (float)triangle.B.Y, 0, 0, triangle.IsInside));
                        indices.Add(vertices.Count);
                        vertices.Add(new Vertex((float)triangle.A.X, (float)triangle.A.Y, 0.5f, 0, triangle.IsInside));
                        indices.Add(vertices.Count);
                        vertices.Add(new Vertex((float)triangle.C.X, (float)triangle.C.Y, 1, 1, triangle.IsInside));
                    }
                }
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="name"></param>
        /// <param name="contour"></param>
        void AddMunicipalDivision(string name, List <DVector2> contour)
        {
            if (municipalDivisions.ContainsKey(name))
            {
                return;
            }

            var mesh = new TriangleNet.Mesh();

            mesh.Behavior.Quality  = true;
            mesh.Behavior.MinAngle = 25;
            mesh.Behavior.Convex   = false;

            var ig = new InputGeometry();

            ig.AddPoint(contour[0].X, contour[0].Y);
            for (int v = 1; v < contour.Count; v++)
            {
                ig.AddPoint(contour[v].X, contour[v].Y);
                ig.AddSegment(v - 1, v);
            }
            ig.AddSegment(contour.Count - 1, 0);

            mesh.Triangulate(ig);

            int n = mesh.Vertices.Count;

            mesh.Renumber();

            // Vertices
            var moVerts = new GeoVert[n];
            int i       = 0;

            foreach (var pt in mesh.Vertices)
            {
                moVerts[i] = new GeoVert {
                    Lon      = pt.X * Math.PI / 180.0,
                    Lat      = pt.Y * Math.PI / 180.0,
                    Position = Vector3.Zero,
                    Tex      = Vector4.Zero,
                    Color    = Color.White
                };

                i++;
            }

            // Triangles
            var triangles = new int[3 * mesh.Triangles.Count];

            i = 0;
            foreach (var tri in mesh.Triangles)
            {
                triangles[i * 3 + 0] = tri.P0;
                triangles[i * 3 + 1] = tri.P1;
                triangles[i * 3 + 2] = tri.P2;
                i++;
            }


            // Contour vertices
            var contourVerts = new GeoVert[contour.Count * 2];

            contourVerts[1] = new GeoVert {
                Lon      = contour[0].X * Math.PI / 180.0,
                Lat      = contour[0].Y * Math.PI / 180.0,
                Position = Vector3.Zero,
                Tex      = Vector4.Zero,
                Color    = Color.Red
            };

            for (int j = 1; j < contour.Count; j++)
            {
                contourVerts[2 * j + 1] = new GeoVert {
                    Lon      = contour[j].X * Math.PI / 180.0,
                    Lat      = contour[j].Y * Math.PI / 180.0,
                    Position = Vector3.Zero,
                    Tex      = Vector4.Zero,
                    Color    = Color.Red
                };
                contourVerts[2 * j] = contourVerts[2 * (j - 1) + 1];
            }

            contourVerts[0] = contourVerts[contourVerts.Length - 1];


            // Create buffers
            var vb   = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), moVerts.Length);
            var inds = new IndexBuffer(Game.GraphicsDevice, triangles.Length);
            var cont = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), contourVerts.Length);

            vb.SetData(moVerts, 0, moVerts.Length);
            inds.SetData(triangles, 0, triangles.Length);
            cont.SetData(contourVerts, 0, contourVerts.Length);

            municipalDivisions.Add(name, new MD {
                Contour  = cont,
                Indeces  = inds,
                Vertices = vb,
                Value    = r.NextFloat(0.0f, 1.0f)
            });
        }
Ejemplo n.º 23
0
        void Triangulate(out List<int[]> indices, out List<Vertex[]> vertices)
        {
            indices = new List<int[]>();
            vertices = new List<Vertex[]>();
            if (polygons == null) return;

            int pointIndex = 0;
            var inputGeometry = new InputGeometry();
            SearchTree(inputGeometry, ref pointIndex, tree);

            var mesh = new Mesh();
            mesh.Triangulate(inputGeometry);

            int highestIndex = 0;
            var currentIndices = new List<int>();
            var currentVertices = new List<Vertex>();
            var indexDict = new Dictionary<int, int>();
            foreach (Triangle triangle in mesh.Triangles)
            {
                bool indexOverflow = currentIndices.Count + 3 > Renderer.IndexBufferSize;
                if (indexOverflow)
                {
                    indices.Add(currentIndices.ToArray());
                    vertices.Add(currentVertices.ToArray());

                    currentIndices.Clear();
                    currentVertices.Clear();
                    indexDict.Clear();
                    highestIndex = 0;
                }

                int[] newIndices;
                List<Vertex> newVertices = IndexVertices(triangle, indexDict, ref highestIndex, out newIndices);
                if (currentVertices.Count + newVertices.Count > Renderer.VertexBufferSize)
                {
                    indices.Add(currentIndices.ToArray());
                    vertices.Add(currentVertices.ToArray());

                    currentIndices.Clear();
                    currentVertices.Clear();
                    indexDict.Clear();

                    highestIndex = 3;
                    newIndices[0] = 0;
                    newIndices[1] = 1;
                    newIndices[2] = 2;

                    indexDict.Add(triangle.P0, 0);
                    indexDict.Add(triangle.P1, 1);
                    indexDict.Add(triangle.P2, 2);

                    newVertices.Clear();
                    TriangleNet.Data.Vertex vertex0 = triangle.GetVertex(0);
                    TriangleNet.Data.Vertex vertex1 = triangle.GetVertex(1);
                    TriangleNet.Data.Vertex vertex2 = triangle.GetVertex(2);
                    newVertices.Add(new Vertex((float)vertex0.X, (float)vertex0.Y));
                    newVertices.Add(new Vertex((float)vertex1.X, (float)vertex1.Y));
                    newVertices.Add(new Vertex((float)vertex2.X, (float)vertex2.Y));
                }

                currentIndices.AddRange(newIndices);
                currentVertices.AddRange(newVertices);
            }
            indices.Add(currentIndices.ToArray());
            vertices.Add(currentVertices.ToArray());
        }
Ejemplo n.º 24
0
    private Mesh TriangulateMesh() {
		if (verts.Count > 2) {
			var tnMesh = new TriangleNet.Mesh();
			var input = new TriangleNet.Geometry.InputGeometry();

			var localVertices = verts.Select(v => spriteRenderer.transform.InverseTransformPoint(v.position)).ToArray();

			for(int i = 0; i < verts.Count; i++) {
				verts[i].index = i;
				input.AddPoint(verts[i].position.x, verts[i].position.y);
			}

			foreach(var seg in segments) {
				if(!seg.IsDeleted())
					input.AddSegment(seg.first.index, seg.second.index);
			}

			foreach(var hole in holes) {
				input.AddHole(hole.x, hole.y);
			}

			tnMesh.Triangulate(input);

			try {
				Mesh mesh = new Mesh();
				mesh.vertices = localVertices;
				mesh.triangles = tnMesh.Triangles.ToUnityMeshTriangleIndices();
				mesh.uv = genUV(mesh.vertices);
				mesh.RecalculateBounds();
				mesh.RecalculateNormals();
				return mesh;
			}
			catch {
				Debug.LogError("Mesh topology was wrong. Make sure you dont have intersecting edges.");
				throw;
			}
		} else {
			return null;
		}
    }
    public Mesh CreateMeshFromVerts(Vector3[] vertsToCopy, Mesh mesh, List<int> pathSplitIds, Transform SpriteGO = null)
    {
        Sprite spr = new Sprite();
        Rect rec = new Rect();
        Vector3 bound = Vector3.zero;
        TextureImporter textureImporter = new TextureImporter();

        if(SpriteGO !=null && SpriteGO.GetComponent<SpriteRenderer>() && SpriteGO.GetComponent<SpriteRenderer>().sprite)
        {

            spr = SpriteGO.GetComponent<SpriteRenderer>().sprite;
            rec = spr.rect;
            bound = SpriteGO.GetComponent<Renderer>().bounds.max- SpriteGO.GetComponent<Renderer>().bounds.min ;
            textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spr)) as TextureImporter;

        }

        //Create triangle.NET geometry
        TriangleNet.Geometry.InputGeometry geometry = new TriangleNet.Geometry.InputGeometry(vertsToCopy.Length);

        //Add vertices
        foreach (Vector3 p in vertsToCopy)
        {
            geometry.AddPoint(p.x,p.y);
        }
        //Add segments
        int prevEnd = 0;
        for (int i=0;i<vertsToCopy.Length-1;i++)
        {
            if (!pathSplitIds.Contains (i+1))
            {
                geometry.AddSegment (i, i + 1);
                //Debug.Log ("joining " + i + " to " + (i + 1));
            }
            else
            {
                geometry.AddSegment (i, prevEnd);
                prevEnd = i + 1;
            }

        }
        if (pathSplitIds.Count <= 1)
        {
            //Debug.Log ("joining " + (vertsToCopy.Length - 1) + " to 0");
            geometry.AddSegment(vertsToCopy.Length - 1, 0);
        }

        //Triangulate, refine and smooth
        TriangleNet.Mesh triangleNetMesh = new TriangleNet.Mesh();

        triangleNetMesh.Triangulate(geometry);

        //transform vertices
        Vector3[] vertices = new Vector3[triangleNetMesh.Vertices.Count];
        Vector2[] uvs = new Vector2[triangleNetMesh.Vertices.Count];
        Vector3[] normals = new Vector3[triangleNetMesh.Vertices.Count];

        int idx = 0;
        foreach(TriangleNet.Data.Vertex v in triangleNetMesh.Vertices)
        {

            vertices[idx] = new Vector3(    (float)v.X, (float)v.Y, 0   );
            normals[idx]=new Vector3(0,0,-1);

            if (SpriteGO != null && SpriteGO.GetComponent<SpriteRenderer>() )
            {
                Vector2 newUv = new Vector2 (((float)v.X / bound.x) + 0.5f , ((float)v.Y / bound.y) + 0.5f);

                newUv.x *= rec.width / spr.texture.width;
                newUv.y *= rec.height / spr.texture.height;
                //Debug.Log(spr.textureRectOffset);
                newUv.x += (rec.x) / spr.texture.width;
                newUv.y += (rec.y) / spr.texture.height;

                SpriteMetaData[] smdArray = textureImporter.spritesheet;
                Vector2 pivot = new Vector2 (.0f, .0f);
                ;

                for (int i = 0; i < smdArray.Length; i++) {
                    if (smdArray [i].name == spr.name) {
                        switch (smdArray [i].alignment) {
                        case(0):
                            smdArray [i].pivot = Vector2.zero;
                            break;
                        case(1):
                            smdArray [i].pivot = new Vector2 (0f, 1f) - new Vector2 (.5f, .5f);
                            break;
                        case(2):
                            smdArray [i].pivot = new Vector2 (0.5f, 1f) - new Vector2 (.5f, .5f);
                            break;
                        case(3):
                            smdArray [i].pivot = new Vector2 (1f, 1f) - new Vector2 (.5f, .5f);
                            break;
                        case(4):
                            smdArray [i].pivot = new Vector2 (0f, .5f) - new Vector2 (.5f, .5f);
                            break;
                        case(5):
                            smdArray [i].pivot = new Vector2 (1f, .5f) - new Vector2 (.5f, .5f);
                            break;
                        case(6):
                            smdArray [i].pivot = new Vector2 (0f, 0f) - new Vector2 (.5f, .5f);
                            break;
                        case(7):
                            smdArray [i].pivot = new Vector2 (0.5f, 0f) - new Vector2 (.5f, .5f);
                            break;
                        case(8):
                            smdArray [i].pivot = new Vector2 (1f, 0f) - new Vector2 (.5f, .5f);
                            break;
                        case(9):
                            smdArray [i].pivot -= new Vector2 (.5f, .5f);
                            break;
                        }
                        pivot = smdArray [i].pivot;
                    }
                }
                if (textureImporter.spriteImportMode == SpriteImportMode.Single)
                    pivot = textureImporter.spritePivot - new Vector2 (.5f, .5f);
                newUv.x += ((pivot.x) * rec.width) / spr.texture.width;
                newUv.y += ((pivot.y) * rec.height) / spr.texture.height;

                uvs [idx] = newUv;
            }

            idx++;
        }

        //transform triangles
        int[] triangles = new int[triangleNetMesh.Triangles.Count*3];
        idx = 0;
        foreach (TriangleNet.Data.Triangle t in triangleNetMesh.Triangles)
        {
            triangles[idx++] = t.P1;
            triangles[idx++] = t.P0;
            triangles[idx++] = t.P2;
        }

        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uvs;
        mesh.normals = normals;

        return mesh;
    }
Ejemplo n.º 26
0
        private void Triangulate()
        {
            if (input == null) return;

            //Stopwatch sw = new Stopwatch();

            mesh = new Mesh();

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

            if (meshControlView.ParamSweeplineChecked)
            {
                mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
            }

            if (meshControlView.ParamQualityChecked)
            {
                mesh.Behavior.Quality = true;

                mesh.Behavior.MinAngle = meshControlView.ParamMinAngleValue;

                double maxAngle = meshControlView.ParamMaxAngleValue;

                if (maxAngle < 180)
                {
                    mesh.Behavior.MaxAngle = 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.Behavior.MaxArea, area * min);
                //}
            }

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

            try
            {
                //sw.Start();
                mesh.Triangulate(input);
                //sw.Stop();

                statisticView.UpdateStatistic(mesh);

                HandleMeshUpdate();

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

            UpdateLog();
        }
Ejemplo n.º 27
0
        void InitBuildingsOSM()
        {
            var osm = Game.GetService <LayerService>().OpenStreetMapSource;

            List <GeoVert> lines  = new List <GeoVert>();
            List <GeoVert> simple = new List <GeoVert>();

            var nodes = osm.allNodes;
            int k     = 0;

            foreach (var way in osm.allWays)
            {
                if (!way.Value.isBuilding)
                {
                    continue;
                }

                var    centerMerc = way.Value.BBox.Center();
                float  width = (way.Value.BBox.Maximum - way.Value.BBox.Minimum).X * 10000.0f;
                float  length = (way.Value.BBox.Maximum - way.Value.BBox.Minimum).Y * 10000.0f;
                double lon, lat;
                GeoHelper.TileToWorldPos(centerMerc.X, centerMerc.Y, 0, out lon, out lat);

                simple.Add(new GeoVert {
                    Lon      = DMathUtil.DegreesToRadians(lon),
                    Lat      = DMathUtil.DegreesToRadians(lat),
                    Color    = Color.White,
                    Position = Vector3.Zero,
                    Tex      = new Vector4(width, length, 0, 0)
                });

                List <DVector2> buildingVertices = new List <DVector2>();
                for (int i = 0; i < way.Value.nodeRef.Length - 1; i++)
                {
                    var nInds = way.Value.nodeRef;

                    lines.Add(new GeoVert {
                        Lon      = DMathUtil.DegreesToRadians(nodes[nInds[i]].Longitude),
                        Lat      = DMathUtil.DegreesToRadians(nodes[nInds[i]].Latitude),
                        Position = new Vector3(1.0f, 0.0f, 0.0f),
                        Color    = Color.Yellow,
                        Tex      = Vector4.Zero
                    });

                    lines.Add(new GeoVert {
                        Lon      = DMathUtil.DegreesToRadians(nodes[nInds[i + 1]].Longitude),
                        Lat      = DMathUtil.DegreesToRadians(nodes[nInds[i + 1]].Latitude),
                        Position = new Vector3(1.0f, 0.0f, 0.0f),
                        Color    = Color.Yellow,
                        Tex      = Vector4.Zero
                    });

                    buildingVertices.Add(new DVector2(nodes[nInds[i]].Longitude, nodes[nInds[i]].Latitude));
                }
                buildingVertices.Add(new DVector2(nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Longitude, nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Latitude));

                /////////////////////////////////////////

                var mesh = new Mesh();
                mesh.Behavior.Quality  = false;
                mesh.Behavior.MinAngle = 25;
                mesh.Behavior.Convex   = false;

                var ig = new InputGeometry();

                ig.AddPoint(buildingVertices[0].X, buildingVertices[0].Y);
                for (int v = 1; v < buildingVertices.Count; v++)
                {
                    ig.AddPoint(buildingVertices[v].X, buildingVertices[v].Y);
                    ig.AddSegment(v - 1, v);
                }
                ig.AddSegment(buildingVertices.Count - 1, 0);

                mesh.Triangulate(ig);

                int n = mesh.Vertices.Count;

                mesh.Renumber();

                buildings = new GeoVert[mesh.Triangles.Count * 3];

                int ind = 0;
                foreach (var triangle in mesh.Triangles)
                {
                    buildings[ind++] = new GeoVert {
                        Lon      = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).X),
                        Lat      = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).Y),
                        Position = new Vector3(0.1f, 0.0f, 0.0f),
                        Color    = Color.Green,
                        Tex      = Vector4.Zero
                    };
                    buildings[ind++] = new GeoVert {
                        Lon      = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).X),
                        Lat      = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).Y),
                        Position = new Vector3(0.1f, 0.0f, 0.0f),
                        Color    = Color.Green,
                        Tex      = Vector4.Zero
                    };
                    buildings[ind++] = new GeoVert {
                        Lon      = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).X),
                        Lat      = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).Y),
                        Position = new Vector3(0.1f, 0.0f, 0.0f),
                        Color    = Color.Green,
                        Tex      = Vector4.Zero
                    };
                }

                /////////////////////////////////////////


                k++;
                if (k >= 1)
                {
                    break;
                }
            }

            simpleBuildings  = simple.ToArray();
            contourBuildings = lines.ToArray();

            contourBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), contourBuildings.Length);
            contourBuildingsVB.SetData(contourBuildings, 0, contourBuildings.Length);

            simpleBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), simpleBuildings.Length);
            simpleBuildingsVB.SetData(simpleBuildings, 0, simpleBuildings.Length);


            buildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), buildings.Length);
            buildingsVB.SetData(buildings, 0, buildings.Length);
        }