/// <summary>
        /// Add a polygon ring to the geometry and make it a hole.
        /// </summary>
        /// <remarks>
        /// WARNING: This works for convex polygons, but not for non-convex regions in general.
        /// </remarks>
        /// <param name="points">List of points which make up the hole.</param>
        /// <param name="mark">Common boundary mark for all segments of the hole.</param>
        public static void AddRingAsHole(this InputGeometry geometry, IEnumerable<TriangleNet.Geometry.Point> points, int mark = 0)
        {
            // Save the current number of points.
            int N = geometry.Count;
            int m = 0;

            foreach (var pt in points)
            {
                geometry.AddPoint(pt.X, pt.Y, pt.Boundary, pt.Attributes);
                m++;
            }

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

            //a lényeg az hogy kell egy a lyukon lévő pont,hogy jelezze hogy az egy lyuk poligon... a legegyszerübb trükk a következő, az egybefüggő (akár konkáv) poligont háromszögesítem, ezzel nincs gond, ezután kiválasztok egy testzőleges háromszöget, és veszem annak a középpontját..ez már tuti hogy a nagy poligon belső pontja
            TriangleNetMesh mesh = new TriangleNetMesh();
            var inputGeometry = new InputGeometry();
            inputGeometry.AddRing(points);
            mesh.Triangulate(inputGeometry);
            var firstTriangle = new List<Triangle>(mesh.Triangles)[0];

            double x = 0.0;
            double y = 0.0;
            for (int iii = 0; iii < 3; iii++)
            {
                var vertex = firstTriangle.GetVertex(iii);
                x += vertex.X;
                y += vertex.Y;
            }

            geometry.AddHole(x / 3, y / 3);
        }
Ejemplo n.º 2
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);
            }
        }
Ejemplo n.º 3
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);
            }
        }
        */
    }