コード例 #1
0
    private void ConstructPolygon()
    {
        List <PolygonPoint> p2 = new List <PolygonPoint>();
        int i = 0, l = _points.Count;

        for (; i < l; i += 1)
        {
            p2.Add(new PolygonPoint(_points[i].x, _points[i].y));
        }

        _polygon = new Polygon(p2);
        P2T.Triangulate(_polygon);

//        _loom.QueueOnMainThread(ContinueCreatingShape);
        ContinueCreatingShape();
    }
コード例 #2
0
ファイル: Mesh2D.cs プロジェクト: srini2204/MeshTools
        private void ConstructPolygon()
        {
            List <PolygonPoint> p2 = new List <PolygonPoint>();
            int i = 0, l = _points.Count;

            for (; i < l; i += 1)
            {
                p2.Add(new PolygonPoint(_points [i].x, _points [i].y));
            }

            _polygon = new Polygon(p2);
            _polygon.Simplify();
            P2T.Triangulate(_polygon);

            ContinueCreatingShape();
        }
コード例 #3
0
        protected void InitializeVertexData()
        {
            if (primitiveType == PrimitiveType.LineList)
            {
                List <PolygonPoint> points = GetPoints();

                foreach (PolygonPoint point in points)
                {
                    // It seems silly to not just say "VertexPositionColor v = new VertexPositionColor(new Vector3(vertex, 0), color);"
                    // but its actually a JIT optimization to make sure this statement always gets inlined.
                    // Reference: Downloaded powerpoint (Understanding XNA Framework Performance) at http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=16477
                    VertexPositionColor vpc = new VertexPositionColor();
                    vpc.Position.X = (float)point.X;
                    vpc.Position.Y = (float)point.Y;

                    if (vertexPositionColors.Count > 1)
                    {
                        vertexPositionColors.Add(lastVertexPositionColor);
                    }

                    lastVertexPositionColor = vpc;
                    vertexPositionColors.Add(vpc);
                }
            }
            else if (primitiveType == PrimitiveType.TriangleList)
            {
                Polygon polygon = GetPolygon();
                P2T.Triangulate(polygon);
                PolygonCount = polygon.Triangles.Count;

                foreach (DelaunayTriangle triangle in polygon.Triangles)
                {
                    foreach (TriangulationPoint point in triangle.Points)
                    {
                        VertexPositionColor vpc = new VertexPositionColor();
                        vpc.Position.X = (float)point.X;
                        vpc.Position.Y = (float)point.Y;
                        vertexPositionColors.Add(vpc);
                    }
                }
            }

            tranformedVPCs = vertexPositionColors.ToArray();
        }
コード例 #4
0
        /// <summary>
        /// Creates a <see cref="PrimitiveType.TriangleList"/> of vertices which cover the interior of the
        /// specified <paramref name="points"/>. The path must be closed and describe a simple polygon.
        /// </summary>
        /// <param name="points">Points describing the border of a simple polygon.</param>
        /// <param name="zCoord">Z coordinate of the created vertices.</param>
        /// <param name="verts">Returns a <see cref="PrimitiveType.TriangleList"/> of vertices.</param>
        public static void Triangulate(PointF[] points, float zCoord, out PositionColoredTextured[] verts)
        {
            PointF[] pathPoints = AdjustPoints(points);
            if (pathPoints.Length < 3)
            {
                verts = null;
                return;
            }
            if (pathPoints.Length == 3)
            {
                verts = new PositionColoredTextured[3];

                verts[0].Position = new Vector3(pathPoints[0].X, pathPoints[0].Y, zCoord);
                verts[1].Position = new Vector3(pathPoints[1].X, pathPoints[1].Y, zCoord);
                verts[2].Position = new Vector3(pathPoints[2].X, pathPoints[2].Y, zCoord);
                return;
            }

            IList <DelaunayTriangle> polygons;

            try
            {
                // Triangulation can fail (i.e. polygon is self-intersecting)
                var poly = new Poly2Tri.Polygon(pathPoints.Select(p => new PolygonPoint(p.X, p.Y)));
                P2T.Triangulate(poly);
                polygons = poly.Triangles;
            }
            catch (Exception)
            {
                verts = null;
                return;
            }

            verts = new PositionColoredTextured[polygons.Count * 3];
            int offset = 0;

            foreach (DelaunayTriangle triangle in polygons)
            {
                verts[offset++].Position = new Vector3((float)triangle.Points[0].X, (float)triangle.Points[0].Y, zCoord);
                verts[offset++].Position = new Vector3((float)triangle.Points[1].X, (float)triangle.Points[1].Y, zCoord);
                verts[offset++].Position = new Vector3((float)triangle.Points[2].X, (float)triangle.Points[2].Y, zCoord);
            }
        }
コード例 #5
0
        GameObject GenerateCountryRegionSurface(int countryIndex, int regionIndex, Material material, Vector2 textureScale, Vector2 textureOffset, float textureRotation)
        {
            if (countryIndex < 0 || countryIndex >= _countries.Length)
            {
                return(null);
            }
            Country country = _countries [countryIndex];
            Region  region  = country.regions [regionIndex];

            if (region.points.Length < 3)
            {
                return(null);
            }

            Poly2Tri.Polygon poly = new Poly2Tri.Polygon(region.points);
            // Extracts enclaves from main region
            if (_enableEnclaves && regionIndex == country.mainRegionIndex)
            {
                // Remove negative provinces
                if (_showProvinces)
                {
                    CountrySubstractProvinceEnclaves(countryIndex, region, poly);
                }
                else
                {
                    CountrySubstractCountryEnclaves(countryIndex, region, poly);
                }
            }
            P2T.Triangulate(poly);

            // Prepare surface cache entry and deletes older surface if exists
            int    cacheIndex = GetCacheIndexForCountryRegion(countryIndex, regionIndex);
            string id         = cacheIndex.ToString();

            // Creates surface mesh
            GameObject surf = Drawing.CreateSurface(id, poly, material, region.rect2D, textureScale, textureOffset, textureRotation, disposalManager);

            ParentObjectToRegion(id, COUNTRY_SURFACES_ROOT_NAME, surf);
            surfaces [cacheIndex] = surf;

            return(surf);
        }
コード例 #6
0
ファイル: Game1.cs プロジェクト: klutch/MaterialPreview
        private VertexPositionTexture[] createVerticesFromPoints(List <Vector2> points, out int primitiveCount)
        {
            List <PolygonPoint> p2tPoints = new List <PolygonPoint>();
            Polygon             polygon;
            Vector2             topLeft     = points[0];
            Vector2             bottomRight = points[0];

            VertexPositionTexture[] vertices;
            int index = 0;

            foreach (Vector2 v in points)
            {
                p2tPoints.Add(new PolygonPoint(v.X, v.Y));
                topLeft     = Vector2.Min(v, topLeft);
                bottomRight = Vector2.Max(v, bottomRight);
            }

            polygon = new Polygon(p2tPoints);
            P2T.Triangulate(polygon);
            primitiveCount = polygon.Triangles.Count;
            vertices       = new VertexPositionTexture[primitiveCount * 3];

            foreach (DelaunayTriangle triangle in polygon.Triangles)
            {
                Vector2 p1 = new Vector2(triangle.Points[0].Xf, triangle.Points[0].Yf);
                Vector2 p2 = new Vector2(triangle.Points[1].Xf, triangle.Points[1].Yf);
                Vector2 p3 = new Vector2(triangle.Points[2].Xf, triangle.Points[2].Yf);

                vertices[index++] = new VertexPositionTexture(
                    new Vector3(p1, 0),
                    (p1 - topLeft) / (bottomRight - topLeft));
                vertices[index++] = new VertexPositionTexture(
                    new Vector3(p2, 0),
                    (p2 - topLeft) / (bottomRight - topLeft));
                vertices[index++] = new VertexPositionTexture(
                    new Vector3(p3, 0),
                    (p3 - topLeft) / (bottomRight - topLeft));
            }

            return(vertices);
        }
コード例 #7
0
    public void movePillars()
    {
        P1B.GetComponent <Rigidbody2D>().velocity = new Vector2((p1 - pillarSpeed), 0);
        p1T.GetComponent <Rigidbody2D>().velocity = new Vector2((p2 - pillarSpeed), 0);

        P2B.GetComponent <Rigidbody2D>().velocity = new Vector2((p3 - pillarSpeed), 0);
        P2T.GetComponent <Rigidbody2D>().velocity = new Vector2((p4 - pillarSpeed), 0);

        if (P1B.transform.position.x <= -6.35 && p1T.transform.position.x <= -6.35)
        {
            P1 = P2 = false;
            P1B.transform.position = new Vector3(6.31f, (int)UnityEngine.Random.RandomRange(-2f, -5f), -2.1f);
            p1T.transform.position = new Vector3(P1B.transform.position.x + 4f, (int)UnityEngine.Random.RandomRange(3f, 6f), -2.1f);
        }
        if (P2B.transform.position.x <= -6.35 && P2T.transform.position.x <= -6.35)
        {
            P3 = P4 = false;
            P2B.transform.position = new Vector3(6.31f, (int)UnityEngine.Random.RandomRange(-2f, -5f), -2.1f);
            P2T.transform.position = new Vector3(P2B.transform.position.x + 4f, (int)UnityEngine.Random.RandomRange(3f, 6f), -2.1f);
        }
    }
コード例 #8
0
ファイル: Polygon.cs プロジェクト: Smoothstep/VRChat
        // Token: 0x060042B5 RID: 17077 RVA: 0x001556A8 File Offset: 0x00153AA8
        public List <int> Triangulate()
        {
            List <PolygonPoint> list = new List <PolygonPoint>(this.Points.Length);

            foreach (Vector2 vector in this.Points)
            {
                list.Add(new PolygonPoint((double)vector.x, (double)vector.y));
            }
            ThirdParty.P2T.Polygon polygon = new ThirdParty.P2T.Polygon(list);
            foreach (Polygon polygon2 in this.holes)
            {
                List <PolygonPoint> list2 = new List <PolygonPoint>(polygon2.Points.Length);
                foreach (Vector2 vector2 in polygon2.Points)
                {
                    list2.Add(new PolygonPoint((double)vector2.x, (double)vector2.y));
                }
                polygon.AddHole(new ThirdParty.P2T.Polygon(list2));
            }
            P2T.Triangulate(polygon);
            int        count = polygon.Triangles.Count;
            List <int> list3 = new List <int>(count * 3);

            this.Points = new Vector2[count * 3];
            int num = 0;

            for (int k = 0; k < count; k++)
            {
                list3.Add(num);
                list3.Add(num + 1);
                list3.Add(num + 2);
                this.Points[num + 2].x = (float)polygon.Triangles[k].Points._0.X;
                this.Points[num + 2].y = (float)polygon.Triangles[k].Points._0.Y;
                this.Points[num + 1].x = (float)polygon.Triangles[k].Points._1.X;
                this.Points[num + 1].y = (float)polygon.Triangles[k].Points._1.Y;
                this.Points[num].x     = (float)polygon.Triangles[k].Points._2.X;
                this.Points[num].y     = (float)polygon.Triangles[k].Points._2.Y;
                num += 3;
            }
            return(list3);
        }
コード例 #9
0
ファイル: FillerStyle3D.cs プロジェクト: Vince0789/NodeMarkup
        public override IStyleData Calculate(MarkupFiller filler, MarkupLOD lod)
        {
            var contour = filler.IsMedian ? SetMedianOffset(filler) : filler.Contour.Trajectories.ToArray();

            if (NeedReverse(contour))
            {
                contour = contour.Select(t => t.Invert()).Reverse().ToArray();
            }

            var parts = contour.Select(t => StyleHelper.CalculateSolid(t, lod, (tr) => tr, MinAngle, MinLength, MaxLength)).ToArray();

            for (var i = 0; i < parts.Length; i += 1)
            {
                var partI = parts[i];
                var partJ = parts[(i + 1) % parts.Length];

                if (!FindIntersects(partI, partJ, false))
                {
                    FindIntersects(partJ, partI, true);
                }
            }


            var points = parts.SelectMany(p => p).Select(t => t.StartPosition).ToArray();

            if (points.Length < 3)
            {
                return(null);
            }

            var polygon = new Polygon(points.Select(p => new PolygonPoint(p.x, p.z)));

            P2T.Triangulate(polygon);
            var triangles = polygon.Triangles.SelectMany(t => t.Points.Select(p => polygon.IndexOf(p))).ToArray();

            return(new MarkupStylePolygonMesh(filler.Markup.Height, Elevation, parts.Select(g => g.Count).ToArray(), points, triangles, MaterialType));
        }
コード例 #10
0
        /// <summary>
        /// 使用Poly2Tri进行三角剖分
        /// </summary>
        /// <param name="polygons"></param>
        /// <returns></returns>
        private static List <DelaunayTriangle> GenerateTriangles(List <List <IntPoint> > polygons)
        {
            //根据时针方向判断可走区域和障碍
            var walkables = new List <Polygon>();
            var blockeds  = new List <Polygon>();

            for (int i = 0; i < polygons.Count; i++)
            {
                var list = Convert(polygons[i]);
                if (IsCCW(polygons[i]))
                {
                    walkables.Add(new Polygon(list));
                }
                else
                {
                    blockeds.Add(new Polygon(list));
                }
            }

            //可以考虑添加SteinerPoint来避免生成狭长的三角形

            //三角剖分
            List <DelaunayTriangle> triangles = new List <DelaunayTriangle>();

            for (int index = 0; index < walkables.Count; index++)
            {
                for (int i = 0; i < blockeds.Count; i++)
                {
                    walkables[index].AddHole(blockeds[i]);
                }

                P2T.Triangulate(walkables[index]);
                triangles.AddRange(walkables[index].Triangles);
            }

            return(triangles);
        }
コード例 #11
0
        public static Mesh triangulate(Spline s, AXTexCoords tex)
        {
            Debug.Log("E");
            if (s == null)
            {
                return(null);
            }
            // poly has verts that are delimeted by 8888888 for holes


            // 1. transpose points to poly2tri structures
            // 2. create mesh
            Polygon _polygon = null;

            List <PolygonPoint> _points = new List <PolygonPoint>();


            for (int i = 0; i < s.controlVertices.Count; i++)
            {
                _points.Add(new PolygonPoint((double)s.controlVertices[i].x, (double)s.controlVertices[i].y));
            }


            // POLYGON
            if (_points.Count >= 3)
            {
                _polygon = new Polygon(_points);
            }

            // populate the polygon triangles
            if (_polygon != null)
            {
                P2T.Triangulate(_polygon);
                return(polygon2mesh(_polygon, tex));
            }
            return(null);
        }
コード例 #12
0
        public static List <List <OxyPlot.DataPoint> > TriangulatePolygon(List <OxyPlot.DataPoint> xyPoints)
        {
            int nVertices = xyPoints.Count;

            if (nVertices <= 0)
            {
                return(new List <List <OxyPlot.DataPoint> >());
            }

            var points = new List <PolygonPoint>();

            foreach (var xy in xyPoints)
            {
                points.Add(new PolygonPoint(xy.X, xy.Y));
            }

            Polygon poly = new Polygon(points);

            P2T.Triangulate(poly);

            List <List <OxyPlot.DataPoint> > simpleShapes = new List <List <OxyPlot.DataPoint> >();

            foreach (var triangle in poly.Triangles)
            {
                List <OxyPlot.DataPoint> simple = new System.Collections.Generic.List <OxyPlot.DataPoint>();

                foreach (var pt in triangle.Points)
                {
                    simple.Add(new OxyPlot.DataPoint(pt.X, pt.Y));
                }

                simpleShapes.Add(simple);
            }

            return(simpleShapes);
        }
コード例 #13
0
        public void triangulate()
        {
            List <PolygonPoint> points  = new List <PolygonPoint>();
            PointListNode       current = _headPoint;

            _polygonPosition = current.position;
            while (current != null)
            {
                _polygonPosition = Vector2.Min(current.position, _polygonPosition);
                points.Add(new PolygonPoint(current.position.X, current.position.Y));
                current = current.next;
            }
            Polygon polygon = new Polygon(points);

            P2T.Triangulate(polygon);
            _primitiveCount = polygon.Triangles.Count;

            int index = 0;

            foreach (DelaunayTriangle triangle in polygon.Triangles)
            {
                for (int i = 0; i < 3; i++)
                {
                    _vertices[index++] = new VertexPositionColorTexture(
                        new Vector3(triangle.Points[i].Xf, triangle.Points[i].Yf, 0),
                        Color.White,
                        Vector2.Zero);
                }
            }

            if (_polygonTexture != null)
            {
                _polygonTexture.Dispose();
            }
            _polygonTexture = _level.controller.view.renderPolygon(_vertices, _primitiveCount);
        }
コード例 #14
0
ファイル: TileHandler.cs プロジェクト: K07H/The-Forest
        private void CutPoly(Int3[] verts, int[] tris, ref Int3[] outVertsArr, ref int[] outTrisArr, out int outVCount, out int outTCount, Int3[] extraShape, Int3 cuttingOffset, Bounds realBounds, TileHandler.CutMode mode = TileHandler.CutMode.CutAll | TileHandler.CutMode.CutDual, int perturbate = -1)
        {
            if (verts.Length == 0 || tris.Length == 0)
            {
                outVCount   = 0;
                outTCount   = 0;
                outTrisArr  = new int[0];
                outVertsArr = new Int3[0];
                return;
            }
            if (perturbate > 10)
            {
                Debug.LogError("Too many perturbations aborting.\nThis may cause a tile in the navmesh to become empty. Try to see see if any of your NavmeshCut or NavmeshAdd components use invalid custom meshes.");
                outVCount   = verts.Length;
                outTCount   = tris.Length;
                outTrisArr  = tris;
                outVertsArr = verts;
                return;
            }
            List <IntPoint> list = null;

            if (extraShape == null && (mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0)
            {
                throw new Exception("extraShape is null and the CutMode specifies that it should be used. Cannot use null shape.");
            }
            if ((mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0)
            {
                list = ListPool <IntPoint> .Claim(extraShape.Length);

                for (int i = 0; i < extraShape.Length; i++)
                {
                    list.Add(new IntPoint((long)(extraShape[i].x + cuttingOffset.x), (long)(extraShape[i].z + cuttingOffset.z)));
                }
            }
            IntRect bounds = new IntRect(verts[0].x, verts[0].z, verts[0].x, verts[0].z);

            for (int j = 0; j < verts.Length; j++)
            {
                bounds = bounds.ExpandToContain(verts[j].x, verts[j].z);
            }
            List <NavmeshCut> list2;

            if (mode == TileHandler.CutMode.CutExtra)
            {
                list2 = ListPool <NavmeshCut> .Claim();
            }
            else
            {
                list2 = NavmeshCut.GetAllInRange(realBounds);
            }
            List <NavmeshAdd> allInRange = NavmeshAdd.GetAllInRange(realBounds);
            List <int>        list3      = ListPool <int> .Claim();

            List <TileHandler.Cut> list4 = TileHandler.PrepareNavmeshCutsForCutting(list2, cuttingOffset, bounds, perturbate, allInRange.Count > 0);
            List <Int3>            list5 = ListPool <Int3> .Claim(verts.Length * 2);

            List <int> list6 = ListPool <int> .Claim(tris.Length);

            Int3[] array  = verts;
            int[]  array2 = tris;
            if (list2.Count == 0 && allInRange.Count == 0 && (mode & ~(TileHandler.CutMode.CutAll | TileHandler.CutMode.CutDual)) == (TileHandler.CutMode) 0 && (mode & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0)
            {
                this.CopyMesh(array, array2, list5, list6);
            }
            else
            {
                List <IntPoint> list7 = ListPool <IntPoint> .Claim();

                Dictionary <TriangulationPoint, int> dictionary = new Dictionary <TriangulationPoint, int>();
                List <PolygonPoint> list8 = ListPool <PolygonPoint> .Claim();

                PolyTree polyTree = new PolyTree();
                List <List <IntPoint> > intermediateResult = new List <List <IntPoint> >();
                Stack <Polygon>         stack = new Stack <Polygon>();
                this.clipper.StrictlySimple  = (perturbate > -1);
                this.clipper.ReverseSolution = true;
                Int3[] array3  = null;
                Int3[] clipOut = null;
                Int2   @int    = default(Int2);
                if (allInRange.Count > 0)
                {
                    array3  = new Int3[7];
                    clipOut = new Int3[7];
                    @int    = new Int2(((Int3)realBounds.extents).x, ((Int3)realBounds.extents).z);
                }
                int num = -1;
                int k   = -3;
                for (;;)
                {
                    k += 3;
                    while (k >= array2.Length)
                    {
                        num++;
                        k = 0;
                        if (num >= allInRange.Count)
                        {
                            array = null;
                            break;
                        }
                        if (array == verts)
                        {
                            array = null;
                        }
                        allInRange[num].GetMesh(cuttingOffset, ref array, out array2);
                    }
                    if (array == null)
                    {
                        break;
                    }
                    Int3 int2 = array[array2[k]];
                    Int3 int3 = array[array2[k + 1]];
                    Int3 int4 = array[array2[k + 2]];
                    if (VectorMath.IsColinearXZ(int2, int3, int4))
                    {
                        Debug.LogWarning("Skipping degenerate triangle.");
                    }
                    else
                    {
                        IntRect a = new IntRect(int2.x, int2.z, int2.x, int2.z);
                        a = a.ExpandToContain(int3.x, int3.z);
                        a = a.ExpandToContain(int4.x, int4.z);
                        int num2 = Math.Min(int2.y, Math.Min(int3.y, int4.y));
                        int num3 = Math.Max(int2.y, Math.Max(int3.y, int4.y));
                        list3.Clear();
                        bool flag = false;
                        for (int l = 0; l < list4.Count; l++)
                        {
                            int x = list4[l].boundsY.x;
                            int y = list4[l].boundsY.y;
                            if (IntRect.Intersects(a, list4[l].bounds) && y >= num2 && x <= num3 && (list4[l].cutsAddedGeom || num == -1))
                            {
                                Int3 int5 = int2;
                                int5.y = x;
                                Int3 int6 = int2;
                                int6.y = y;
                                list3.Add(l);
                                flag |= list4[l].isDual;
                            }
                        }
                        if (list3.Count == 0 && (mode & TileHandler.CutMode.CutExtra) == (TileHandler.CutMode) 0 && (mode & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0 && num == -1)
                        {
                            list6.Add(list5.Count);
                            list6.Add(list5.Count + 1);
                            list6.Add(list5.Count + 2);
                            list5.Add(int2);
                            list5.Add(int3);
                            list5.Add(int4);
                        }
                        else
                        {
                            list7.Clear();
                            if (num == -1)
                            {
                                list7.Add(new IntPoint((long)int2.x, (long)int2.z));
                                list7.Add(new IntPoint((long)int3.x, (long)int3.z));
                                list7.Add(new IntPoint((long)int4.x, (long)int4.z));
                            }
                            else
                            {
                                array3[0] = int2;
                                array3[1] = int3;
                                array3[2] = int4;
                                int num4 = this.ClipAgainstRectangle(array3, clipOut, new Int2(@int.x * 2, @int.y * 2));
                                if (num4 == 0)
                                {
                                    continue;
                                }
                                for (int m = 0; m < num4; m++)
                                {
                                    list7.Add(new IntPoint((long)array3[m].x, (long)array3[m].z));
                                }
                            }
                            dictionary.Clear();
                            for (int n = 0; n < 16; n++)
                            {
                                if ((mode >> (n & 31) & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0)
                                {
                                    if (1 << n == 1)
                                    {
                                        this.CutAll(list7, list3, list4, polyTree);
                                    }
                                    else if (1 << n == 2)
                                    {
                                        if (!flag)
                                        {
                                            goto IL_9A0;
                                        }
                                        this.CutDual(list7, list3, list4, flag, intermediateResult, polyTree);
                                    }
                                    else if (1 << n == 4)
                                    {
                                        this.CutExtra(list7, list, polyTree);
                                    }
                                    for (int num5 = 0; num5 < polyTree.ChildCount; num5++)
                                    {
                                        PolyNode        polyNode = polyTree.Childs[num5];
                                        List <IntPoint> contour  = polyNode.Contour;
                                        List <PolyNode> childs   = polyNode.Childs;
                                        if (childs.Count == 0 && contour.Count == 3 && num == -1)
                                        {
                                            for (int num6 = 0; num6 < 3; num6++)
                                            {
                                                Int3 int7 = new Int3((int)contour[num6].X, 0, (int)contour[num6].Y);
                                                int7.y = TileHandler.SampleYCoordinateInTriangle(int2, int3, int4, int7);
                                                list6.Add(list5.Count);
                                                list5.Add(int7);
                                            }
                                        }
                                        else
                                        {
                                            Polygon polygon = null;
                                            int     num7    = -1;
                                            for (List <IntPoint> list9 = contour; list9 != null; list9 = ((num7 >= childs.Count) ? null : childs[num7].Contour))
                                            {
                                                list8.Clear();
                                                for (int num8 = 0; num8 < list9.Count; num8++)
                                                {
                                                    PolygonPoint polygonPoint = new PolygonPoint((double)list9[num8].X, (double)list9[num8].Y);
                                                    list8.Add(polygonPoint);
                                                    Int3 int8 = new Int3((int)list9[num8].X, 0, (int)list9[num8].Y);
                                                    int8.y = TileHandler.SampleYCoordinateInTriangle(int2, int3, int4, int8);
                                                    dictionary[polygonPoint] = list5.Count;
                                                    list5.Add(int8);
                                                }
                                                Polygon polygon2;
                                                if (stack.Count > 0)
                                                {
                                                    polygon2 = stack.Pop();
                                                    polygon2.AddPoints(list8);
                                                }
                                                else
                                                {
                                                    polygon2 = new Polygon(list8);
                                                }
                                                if (num7 == -1)
                                                {
                                                    polygon = polygon2;
                                                }
                                                else
                                                {
                                                    polygon.AddHole(polygon2);
                                                }
                                                num7++;
                                            }
                                            try
                                            {
                                                P2T.Triangulate(polygon);
                                            }
                                            catch (PointOnEdgeException)
                                            {
                                                Debug.LogWarning("PointOnEdgeException, perturbating vertices slightly.\nThis is usually fine. It happens sometimes because of rounding errors. Cutting will be retried a few more times.");
                                                this.CutPoly(verts, tris, ref outVertsArr, ref outTrisArr, out outVCount, out outTCount, extraShape, cuttingOffset, realBounds, mode, perturbate + 1);
                                                return;
                                            }
                                            try
                                            {
                                                for (int num9 = 0; num9 < polygon.Triangles.Count; num9++)
                                                {
                                                    DelaunayTriangle delaunayTriangle = polygon.Triangles[num9];
                                                    list6.Add(dictionary[delaunayTriangle.Points._0]);
                                                    list6.Add(dictionary[delaunayTriangle.Points._1]);
                                                    list6.Add(dictionary[delaunayTriangle.Points._2]);
                                                }
                                            }
                                            catch (KeyNotFoundException)
                                            {
                                                Debug.LogWarning("KeyNotFoundException, perturbating vertices slightly.\nThis is usually fine. It happens sometimes because of rounding errors. Cutting will be retried a few more times.");
                                                this.CutPoly(verts, tris, ref outVertsArr, ref outTrisArr, out outVCount, out outTCount, extraShape, cuttingOffset, realBounds, mode, perturbate + 1);
                                                return;
                                            }
                                            TileHandler.PoolPolygon(polygon, stack);
                                        }
                                    }
                                }
                                IL_9A0 :;
                            }
                        }
                    }
                }
                ListPool <IntPoint> .Release(list7);

                ListPool <PolygonPoint> .Release(list8);
            }
            this.CompressMesh(list5, list6, ref outVertsArr, ref outTrisArr, out outVCount, out outTCount);
            for (int num10 = 0; num10 < list2.Count; num10++)
            {
                list2[num10].UsedForCut();
            }
            ListPool <Int3> .Release(list5);

            ListPool <int> .Release(list6);

            ListPool <int> .Release(list3);

            for (int num11 = 0; num11 < list4.Count; num11++)
            {
                ListPool <IntPoint> .Release(list4[num11].contour);
            }
            ListPool <TileHandler.Cut> .Release(list4);

            ListPool <NavmeshCut> .Release(list2);
        }
コード例 #15
0
        protected override void OnPaint(PaintEventArgs e)
        {
            var fx = e.Graphics;

            if (string.IsNullOrEmpty(_font))
            {
                return;
            }

            var       ffamilly = new FontFamily(_font);
            FontStyle?fstyle   = null;

            foreach (var style in new[] { FontStyle.Regular, FontStyle.Bold, FontStyle.Italic, FontStyle.Underline, FontStyle.Strikeout })
            {
                if (!ffamilly.IsStyleAvailable(style))
                {
                    continue;
                }
                fstyle = style;
                break;
            }
            if (!fstyle.HasValue)
            {
                return;
            }

            var   strChar = new string(_glyph, 1);
            var   txtEM   = fx.MeasureString("M", _txtFont).Height;
            SizeF szGlyph;

            fx.DrawString("Reference from GDI+", _txtFont, Brushes.Black, 0f, 0f);
            using (var tmpFnt = new Font(ffamilly, GlyphFontSize, fstyle.Value))
            {
                szGlyph = fx.MeasureString(strChar, tmpFnt);
                fx.DrawString(strChar, tmpFnt, Brushes.Black, 0f, txtEM);
                fx.DrawRectangle(Pens.Blue, 0f, txtEM, szGlyph.Width, szGlyph.Height);
            }

            fx.TranslateTransform(0f, szGlyph.Height + txtEM * 2f);
            fx.DrawRectangle(Pens.Blue, 0f, 0f, szGlyph.Width, szGlyph.Height);

            {
                List <List <PolygonPoint> > points_list = new List <List <PolygonPoint> >();
                var polygonList_bottom = GeneratePolygonsFromGlyph(fx, ffamilly, fstyle.Value, "管孟ABC12334455", ref points_list);

                double[] min;
                double[] max;
                GetBoundingBox(ref points_list, out min, out max);

                var polygonList_base = PolygonsInBox(ref polygonList_bottom, min, max);

                var polygonSet_bottom = CreateSetFromList(polygonList_bottom);
                var polygonSet_base   = CreateSetFromList(polygonList_base);

                P2T.Triangulate(polygonSet_bottom);
                P2T.Triangulate(polygonSet_base);

                List <double> triangels = new List <double>();
                double        z_bottom  = -20;
                double        z_base    = 0;
                FromPolygonSetToTriangles(polygonSet_bottom, z_bottom, triangels);
                FromPolygonSetToTriangles(polygonSet_base, z_base, triangels);
                GetTrianglesBetweenTwoZPlane(points_list, z_base, z_bottom, triangels);

                //reverse y
                for (int i = 1; i < triangels.Count; i += 3)
                {
                    triangels[i] = max[1] - triangels[i];
                }
                WriteStl(triangels, "d:\\temp\\triangles_all2.stl");
            }
            try
            {
                List <List <PolygonPoint> > points_list = new List <List <PolygonPoint> >();
                //var polygonList = GeneratePolygonsFromGlyph(fx, ffamilly, fstyle.Value, strChar);
                var polygonList_bottom = GeneratePolygonsFromGlyph(fx, ffamilly, fstyle.Value, "管孟辉", ref points_list);

                double[] min;
                double[] max;
                GetBoundingBox(ref points_list, out min, out max);
                var polygonList_base = PolygonsInBox(ref polygonList_bottom, min, max);

                fx.ResetTransform();
                fx.DrawString(
                    string.Format("{0} Paths from GDI:", polygonList_bottom.Count),
                    _txtFont, Brushes.Black, 0f, szGlyph.Height + txtEM);

                if (polygonList_bottom.Count == 0)
                {
                    fx.DrawString(
                        "Empty Path - Nothing to Tessellate ....",
                        _txtFont, Brushes.DarkGreen, szGlyph.Width + 2 * txtEM, 0f);
                    return;
                }

                var polygonSet_bottom = CreateSetFromList(polygonList_bottom);
                var polygonSet_base   = CreateSetFromList(polygonList_base);

                P2T.Triangulate(polygonSet_bottom);
                P2T.Triangulate(polygonSet_base);

                fx.TranslateTransform(szGlyph.Width + 2 * txtEM, txtEM);

                var sb             = new SolidBrush(Color.FromArgb(128, Color.Gray));
                var ip             = 0;
                var totalTriangles = 0;

                foreach (var pol in polygonSet_bottom.Polygons)
                {
                    var cPen = PathPens[ip % PathPens.Length];
                    ++ip;
                    foreach (var tri in pol.Triangles)
                    {
                        var ptfs = new PointF[]
                        {
                            new PointF(tri.Points[0].Xf * TgMulti, tri.Points[0].Yf * TgMulti)
                            , new PointF(tri.Points[1].Xf * TgMulti, tri.Points[1].Yf * TgMulti)
                            , new PointF(tri.Points[2].Xf * TgMulti, tri.Points[2].Yf * TgMulti)
                        };
                        fx.FillPolygon(sb, ptfs);
                        fx.DrawPolygon(cPen, ptfs);
                        ++totalTriangles;
                    }
                }

                fx.ResetTransform();
                fx.DrawString(
                    string.Format("Polygons: {0} / Total Triangles: {1}",
                                  ((System.Collections.ICollection)polygonSet_bottom.Polygons).Count,
                                  totalTriangles),
                    _txtFont, Brushes.Black, szGlyph.Width + 2 * txtEM, 0f);
            }
            catch (Exception ex)
            {
                fx.ResetTransform();
                fx.DrawString("EXCEPTION!!", _txtFont, Brushes.Red, szGlyph.Width + 2 * txtEM, 0f);
                fx.DrawString(ex.ToString(), _txtFont, Brushes.Red, szGlyph.Width + 2 * txtEM, txtEM);
            }
        }
コード例 #16
0
    void MakeSection(List <Vector3> verts, List <int> facs, PolyNode polyNode)
    {
        if (polyNode.IsHole)
        {
            Debug.LogError("Found a hole where there's not meant to be one.");
            return;
        }
        List <PolygonPoint> polygonPointList = new List <PolygonPoint>();

        foreach (IntPoint Outvertex in polyNode.Contour)
        {
            polygonPointList.Add(new PolygonPoint(Outvertex.X / floatMultiplier, Outvertex.Y / floatMultiplier));
        }
        MakeWalls(verts, facs, polyNode.Contour);
        Polygon poly = new Polygon(polygonPointList);

        foreach (PolyNode holeNode in polyNode.Childs)
        {
            MakeWalls(verts, facs, holeNode.Contour);
            List <PolygonPoint> holePointList = new List <PolygonPoint>();
            foreach (IntPoint Holevertex in holeNode.Contour)
            {
                holePointList.Add(new PolygonPoint(Holevertex.X / floatMultiplier, Holevertex.Y / floatMultiplier));
            }
            Polygon hole = new Polygon(holePointList);
            poly.AddHole(hole);
        }
        P2T.Triangulate(poly);
        IList <DelaunayTriangle>   tris   = poly.Triangles;
        IList <TriangulationPoint> points = poly.Points;

        if (poly.Holes != null)
        {
            foreach (Polygon hole in (poly.Holes))
            {
                foreach (TriangulationPoint point in hole.Points)
                {
                    points.Add(point);
                }
            }
        }
        int startingIndex = verts.Count;

        foreach (TriangulationPoint point in points)
        {
            verts.Add(new Vector3(point.Xf, height, point.Yf));
        }
        foreach (DelaunayTriangle tri in tris)
        {
            facs.Add(points.IndexOf(tri.Points._2) + startingIndex);
            facs.Add(points.IndexOf(tri.Points._1) + startingIndex);
            facs.Add(points.IndexOf(tri.Points._0) + startingIndex);
        }
        foreach (PolyNode holeNode in polyNode.Childs)
        {
            foreach (PolyNode childNode in holeNode.Childs)
            {
                MakeSection(verts, facs, childNode);
            }
        }
    }
コード例 #17
0
        GameObject GenerateProvinceRegionSurface(int provinceIndex, int regionIndex, Material material, Vector2 textureScale, Vector2 textureOffset, float textureRotation, bool temporary)
        {
            if (provinceIndex < 0 || provinceIndex >= provinces.Length)
            {
                return(null);
            }
            if (provinces [provinceIndex].regions == null)
            {
                ReadProvincePackedString(provinces [provinceIndex]);
            }
            if (provinces [provinceIndex].regions == null || regionIndex < 0 || regionIndex >= provinces [provinceIndex].regions.Count)
            {
                return(null);
            }

            Province province = provinces [provinceIndex];
            Region   region   = province.regions [regionIndex];

            if (!temporary)
            {
                region.customMaterial        = material;
                region.customTextureOffset   = textureOffset;
                region.customTextureRotation = textureRotation;
                region.customTextureScale    = textureScale;
                UpdateSurfaceCount();
            }


            // Triangulate to get the polygon vertex indices
            Poly2Tri.Polygon poly = new Poly2Tri.Polygon(region.latlon);

            if (_enableProvinceEnclaves && regionIndex == province.mainRegionIndex)
            {
                ProvinceSubstractProvinceEnclaves(provinceIndex, region, poly);
            }

            // Antarctica, Saskatchewan (Canada), British Columbia (Canada), Krasnoyarsk (Russia) - special cases due to its geometry
            float step = _frontiersDetail == FRONTIERS_DETAIL.High ? 2f : 5f;

            if (steinerPoints == null)
            {
                steinerPoints = new List <TriangulationPoint> (1000);
            }
            else
            {
                steinerPoints.Clear();
            }
            float x0 = region.latlonRect2D.min.x + step / 2f;
            float x1 = region.latlonRect2D.max.x - step / 2f;
            float y0 = region.latlonRect2D.min.y + step / 2f;
            float y1 = region.latlonRect2D.max.y - step / 2f;

            for (float x = x0; x < x1; x += step)
            {
                for (float y = y0; y < y1; y += step)
                {
                    float xp = x + UnityEngine.Random.Range(-0.0001f, 0.0001f);
                    float yp = y + UnityEngine.Random.Range(-0.0001f, 0.0001f);
                    if (region.Contains(xp, yp))
                    {
                        steinerPoints.Add(new TriangulationPoint(xp, yp));
                        //						GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                        //						obj.transform.SetParent(WorldMapGlobe.instance.transform, false);
                        //						obj.transform.localScale = Vector3.one * 0.01f;
                        //						obj.transform.localPosition = Conversion.GetSpherePointFromLatLon(new Vector2(x,y)) * 1.01f;
                    }
                }
            }
            if (steinerPoints.Count > 0)
            {
                poly.AddSteinerPoints(steinerPoints);
            }
            P2T.Triangulate(poly);

            int flip1, flip2;

            if (_earthInvertedMode)
            {
                flip1 = 2;
                flip2 = 1;
            }
            else
            {
                flip1 = 1;
                flip2 = 2;
            }
            int triCount = poly.Triangles.Count;

            Vector3[] revisedSurfPoints = new Vector3[triCount * 3];
            for (int k = 0; k < triCount; k++)
            {
                DelaunayTriangle dt = poly.Triangles [k];
                revisedSurfPoints [k * 3]         = Conversion.GetSpherePointFromLatLon(dt.Points [0].X, dt.Points [0].Y);
                revisedSurfPoints [k * 3 + flip1] = Conversion.GetSpherePointFromLatLon(dt.Points [1].X, dt.Points [1].Y);
                revisedSurfPoints [k * 3 + flip2] = Conversion.GetSpherePointFromLatLon(dt.Points [2].X, dt.Points [2].Y);
            }

            int revIndex = revisedSurfPoints.Length - 1;

            // Generate surface mesh
            int        cacheIndex = GetCacheIndexForProvinceRegion(provinceIndex, regionIndex);
            GameObject surf       = Drawing.CreateSurface(SURFACE_GAMEOBJECT, revisedSurfPoints, revIndex, material, region.rect2Dbillboard, textureScale, textureOffset, textureRotation);

            surf.transform.SetParent(surfacesLayer.transform, false);
            surf.transform.localPosition = Misc.Vector3zero;
            if (_earthInvertedMode)
            {
                surf.transform.localScale = Misc.Vector3one * 0.998f;
            }
            surfaces [cacheIndex] = surf;
            return(surf);
        }
コード例 #18
0
        public static Mesh triangulatePolyNode(PolyNode node, AXTexCoords tex, int seglenBigInt = 1000000)
        {
            //Debug.Log ("D " + seglenBigInt);
            Polygon _polygon = null;

            if (seglenBigInt < 10)
            {
                seglenBigInt = 999999;
            }


            List <Mesh> meshes = new List <Mesh>();

            // Contour is Solid

            PolygonPoints _points = null;

            if (seglenBigInt > 0 && seglenBigInt != 9999999)
            {
                _points = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(node.Contour), seglenBigInt));
            }
            else
            {
                _points = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(node.Contour));
            }

            // POLYGON
            if (_points.Count >= 3)
            {
                _polygon = new Polygon(_points);
            }

            //Debug.Log ("_polygon="+_points.Count);
            // ADD HOLES TO POLYGON
            foreach (PolyNode subnode in node.Childs)
            {
                PolygonPoints hpoints = null;

                if (seglenBigInt > 0 && seglenBigInt != 9999999)
                {
                    hpoints = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(subnode.Contour), seglenBigInt));
                }
                else
                {
                    hpoints = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(subnode.Contour));
                }



                if (hpoints.Count >= 3)
                {
                    _polygon.AddHole(new Polygon(hpoints));
                }
            }

            try {
                // STEINER POINTS

                ClipperOffset co = new ClipperOffset();
                co.AddPath(node.Contour, AXClipperLib.JoinType.jtSquare, AXClipperLib.EndType.etClosedPolygon);

                //addSteinerPointsAtAllOffsets(ref _polygon, ref co, seglenBigInt/AXGeometryTools.Utilities.IntPointPrecision, seglenBigInt);
                addSteinerPointsAtAllOffsets(ref _polygon, ref co, (float)seglenBigInt / ((float)AXGeometryTools.Utilities.IntPointPrecision), seglenBigInt);



                P2T.Triangulate(_polygon);

                meshes.Add(polygon2mesh(_polygon, tex));
            } catch {
                //Debug.Log ("Can't triangulate: probably point on edge.");
            }


            // Continue down the tree...

            /*
             * foreach(PolyNode cnode in node.Childs)
             * {
             *      Mesh submesh = triangulatePolyNode(cnode, tex);
             *      if (submesh != null)
             *              meshes.Add(submesh);
             * }
             */



            CombineInstance[] combine = new CombineInstance[meshes.Count];
            for (int i = 0; i < meshes.Count; i++)
            {
                combine[i].mesh      = meshes[i];
                combine[i].transform = Matrix4x4.identity;
            }



            Mesh mesh = new Mesh();

            mesh.CombineMeshes(combine);

            mesh.RecalculateNormals();

            return(mesh);
        }
コード例 #19
0
        public void CreateMesh(Vector2[] vertsToCopy, Transform transform, int triangleIndex)
        {
            List <Vector3> resultsLocal                   = new List <Vector3>();
            List <int>     resultsTriIndexesLocal         = new List <int>();
            List <int>     resultsTriIndexesReversedLocal = new List <int>();
            List <Vector2> uvsLocal     = new List <Vector2>();
            List <Vector3> normalsLocal = new List <Vector3>();


            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;

            List <PolygonPoint> p2 = new List <PolygonPoint>();

            if (triangleIndex > 0)
            {
                vertsToCopy = CreateSubVertPoints(spr.bounds, vertsToCopy.ToList(), triangleIndex).ToArray();
            }

            int i = 0;

            for (i = 0; i < vertsToCopy.Count(); i++)
            {
                p2.Add(new PolygonPoint(vertsToCopy[i].x, vertsToCopy[i].y));
            }

            Polygon _polygon = new Polygon(p2);

            if (triangleIndex > 0)
            {
                List <TriangulationPoint> triPoints = GenerateGridPoints(spr.bounds, triangleIndex, _polygon);
                _polygon.AddSteinerPoints(triPoints);
            }

            P2T.Triangulate(_polygon);


            int idx = 0;

            foreach (DelaunayTriangle triangle in _polygon.Triangles)
            {
                Vector3 v = new Vector3();
                foreach (TriangulationPoint p in triangle.Points)
                {
                    v = new Vector3((float)p.X, (float)p.Y, 0);
                    if (!resultsLocal.Contains(v))
                    {
                        resultsLocal.Add(v);
                        resultsTriIndexesLocal.Add(idx);

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

                        newUv.x *= rec.width / spr.texture.width;
                        newUv.y *= rec.height / spr.texture.height;

                        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 k = 0; k < smdArray.Length; k++)
                        {
                            if (smdArray[k].name == spr.name)
                            {
                                switch (smdArray[k].alignment)
                                {
                                case (0):
                                    smdArray[k].pivot = Vector2.zero;
                                    break;

                                case (1):
                                    smdArray[k].pivot = new Vector2(0f, 1f) - new Vector2(.5f, .5f);
                                    break;

                                case (2):
                                    smdArray[k].pivot = new Vector2(0.5f, 1f) - new Vector2(.5f, .5f);
                                    break;

                                case (3):
                                    smdArray[k].pivot = new Vector2(1f, 1f) - new Vector2(.5f, .5f);
                                    break;

                                case (4):
                                    smdArray[k].pivot = new Vector2(0f, .5f) - new Vector2(.5f, .5f);
                                    break;

                                case (5):
                                    smdArray[k].pivot = new Vector2(1f, .5f) - new Vector2(.5f, .5f);
                                    break;

                                case (6):
                                    smdArray[k].pivot = new Vector2(0f, 0f) - new Vector2(.5f, .5f);
                                    break;

                                case (7):
                                    smdArray[k].pivot = new Vector2(0.5f, 0f) - new Vector2(.5f, .5f);
                                    break;

                                case (8):
                                    smdArray[k].pivot = new Vector2(1f, 0f) - new Vector2(.5f, .5f);
                                    break;

                                case (9):
                                    smdArray[k].pivot -= new Vector2(.5f, .5f);
                                    break;
                                }
                                pivot = smdArray[k].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;


                        uvsLocal.Add(newUv);
                        normalsLocal.Add(new Vector3(0, 0, -1));
                        idx++;
                    }
                    else
                    {
                        resultsTriIndexesLocal.Add(resultsLocal.LastIndexOf(v));
                    }
                }
            }



            for (int j = resultsTriIndexesLocal.Count - 1; j >= 0; j--)
            {
                resultsTriIndexesReversedLocal.Add(resultsTriIndexesLocal[j]);
            }

            results.AddRange(resultsLocal);
            resultsTriIndexes.AddRange(resultsTriIndexesLocal);
            resultsTriIndexesReversed.AddRange(resultsTriIndexesReversedLocal);
            uvs.AddRange(uvsLocal);
            normals.AddRange(normalsLocal);

            resultsLocal.Clear();
            resultsTriIndexesLocal.Clear();
            resultsTriIndexesReversedLocal.Clear();
            uvsLocal.Clear();
            normalsLocal.Clear();

            finalVertices = results.ToArray();

            finalNormals = normals.ToArray();
            finalUvs     = uvs.ToArray();

            finalTriangles = resultsTriIndexesReversed.ToArray();
        }
コード例 #20
0
        /// <summary>
        /// This decomposites the provided ground chunk, supporting holes too.
        /// This will convert the ground chunk into a Polygon object that is then
        /// passed to the Poly2Tri library which returns the triangle arrays of
        /// decomposition.
        /// </summary>
        /// <param name="chunk"></param>
        private void Decomp(GroundChunk chunk)
        {
            List <PolygonPoint> edge = new List <PolygonPoint>();

            for (int i = 0; i < chunk.Edge.Count; i++)
            {
                edge.Add(new PolygonPoint(chunk.Edge[i].x, chunk.Edge[i].y));
            }

            List <Polygon> holes = new List <Polygon>();

            if (chunk.Holes != null)
            {
                for (int i = 0; i < chunk.Holes.Count; i++)
                {
                    List <PolygonPoint> hole = new List <PolygonPoint>();
                    for (int j = 0; j < chunk.Holes[i].Count; j++)
                    {
                        hole.Add(new PolygonPoint(chunk.Holes[i][j].x, chunk.Holes[i][j].y));
                    }

                    holes.Add(new Polygon(hole));
                }
            }

            Polygon poly = new Polygon(edge);

            for (int i = 0; i < holes.Count; i++)
            {
                poly.AddHole(holes[i]);
            }


            //Triangulate!
            P2T.Triangulate(poly);
            IList <TriangulationPoint> points = poly.Points;
            IList <DelaunayTriangle>   tris   = poly.Triangles;

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

            int[] finalTris = new int[tris.Count * 3];
            Dictionary <TriangulationPoint, int> pointToIndex = new Dictionary <TriangulationPoint, int>();

            for (int t = 0; t < tris.Count; t++)
            {
                DelaunayTriangle tri = tris[t];
                for (int i = 0; i < 3; i++)
                {
                    //check if the points are in the dictionary, if not add it with the next index
                    int val = 0;
                    if (pointToIndex.TryGetValue(tri.Points[i], out val))
                    {
                        finalTris[t * 3 + i] = val;
                    }
                    else
                    {
                        finalPoints.Add(new Vector2()
                        {
                            x = tri.Points[i].Xf, y = tri.Points[i].Yf
                        });
                        pointToIndex[tri.Points[i]] = finalPoints.Count - 1;
                        finalTris[t * 3 + i]        = finalPoints.Count - 1;
                    }
                }
            }

            Decomp result = new Decomp();

            result.Points = finalPoints;
            result.Tris   = finalTris;
            chunk.Poly    = result;
        }
コード例 #21
0
        private TileHandler.CuttingResult CutPoly(Int3[] verts, int[] tris, Int3[] extraShape, GraphTransform graphTransform, IntRect tiles, TileHandler.CutMode mode = TileHandler.CutMode.CutAll | TileHandler.CutMode.CutDual, int perturbate = -1)
        {
            if (verts.Length == 0 || tris.Length == 0)
            {
                return(new TileHandler.CuttingResult
                {
                    verts = ArrayPool <Int3> .Claim(0),
                    tris = ArrayPool <int> .Claim(0)
                });
            }
            if (perturbate > 10)
            {
                Debug.LogError("Too many perturbations aborting.\nThis may cause a tile in the navmesh to become empty. Try to see see if any of your NavmeshCut or NavmeshAdd components use invalid custom meshes.");
                return(new TileHandler.CuttingResult
                {
                    verts = verts,
                    tris = tris
                });
            }
            List <IntPoint> list = null;

            if (extraShape == null && (mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0)
            {
                throw new Exception("extraShape is null and the CutMode specifies that it should be used. Cannot use null shape.");
            }
            Bounds         tileBoundsInGraphSpace = this.graph.GetTileBoundsInGraphSpace(tiles);
            Vector3        min             = tileBoundsInGraphSpace.min;
            GraphTransform graphTransform2 = graphTransform * Matrix4x4.TRS(min, Quaternion.identity, Vector3.one);
            Vector2        v = new Vector2(tileBoundsInGraphSpace.size.x, tileBoundsInGraphSpace.size.z);

            if ((mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0)
            {
                list = ListPool <IntPoint> .Claim(extraShape.Length);

                for (int i = 0; i < extraShape.Length; i++)
                {
                    Int3 @int = graphTransform2.InverseTransform(extraShape[i]);
                    list.Add(new IntPoint((long)@int.x, (long)@int.z));
                }
            }
            IntRect cutSpaceBounds = new IntRect(verts[0].x, verts[0].z, verts[0].x, verts[0].z);

            for (int j = 0; j < verts.Length; j++)
            {
                cutSpaceBounds = cutSpaceBounds.ExpandToContain(verts[j].x, verts[j].z);
            }
            List <NavmeshCut> list2;

            if (mode == TileHandler.CutMode.CutExtra)
            {
                list2 = ListPool <NavmeshCut> .Claim();
            }
            else
            {
                list2 = this.cuts.QueryRect <NavmeshCut>(tiles);
            }
            List <NavmeshAdd> list3 = this.cuts.QueryRect <NavmeshAdd>(tiles);
            List <int>        list4 = ListPool <int> .Claim();

            List <TileHandler.Cut> list5 = TileHandler.PrepareNavmeshCutsForCutting(list2, graphTransform2, cutSpaceBounds, perturbate, list3.Count > 0);
            List <Int3>            list6 = ListPool <Int3> .Claim(verts.Length * 2);

            List <int> list7 = ListPool <int> .Claim(tris.Length);

            if (list2.Count == 0 && list3.Count == 0 && (mode & ~(TileHandler.CutMode.CutAll | TileHandler.CutMode.CutDual)) == (TileHandler.CutMode) 0 && (mode & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0)
            {
                TileHandler.CopyMesh(verts, tris, list6, list7);
            }
            else
            {
                List <IntPoint> list8 = ListPool <IntPoint> .Claim();

                Dictionary <TriangulationPoint, int> dictionary = new Dictionary <TriangulationPoint, int>();
                List <PolygonPoint> list9 = ListPool <PolygonPoint> .Claim();

                PolyTree polyTree = new PolyTree();
                List <List <IntPoint> > list10 = ListPool <List <IntPoint> > .Claim();

                Stack <Polygon> stack = StackPool <Polygon> .Claim();

                this.clipper.StrictlySimple  = (perturbate > -1);
                this.clipper.ReverseSolution = true;
                Int3[] array   = null;
                Int3[] clipOut = null;
                Int2   size    = default(Int2);
                if (list3.Count > 0)
                {
                    array   = new Int3[7];
                    clipOut = new Int3[7];
                    size    = new Int2(((Int3)v).x, ((Int3)v).y);
                }
                Int3[] array2 = null;
                for (int k = -1; k < list3.Count; k++)
                {
                    Int3[] array3;
                    int[]  array4;
                    if (k == -1)
                    {
                        array3 = verts;
                        array4 = tris;
                    }
                    else
                    {
                        list3[k].GetMesh(ref array2, out array4, graphTransform2);
                        array3 = array2;
                    }
                    for (int l = 0; l < array4.Length; l += 3)
                    {
                        Int3 int2 = array3[array4[l]];
                        Int3 int3 = array3[array4[l + 1]];
                        Int3 int4 = array3[array4[l + 2]];
                        if (VectorMath.IsColinearXZ(int2, int3, int4))
                        {
                            Debug.LogWarning("Skipping degenerate triangle.");
                        }
                        else
                        {
                            IntRect a = new IntRect(int2.x, int2.z, int2.x, int2.z);
                            a = a.ExpandToContain(int3.x, int3.z);
                            a = a.ExpandToContain(int4.x, int4.z);
                            int num  = Math.Min(int2.y, Math.Min(int3.y, int4.y));
                            int num2 = Math.Max(int2.y, Math.Max(int3.y, int4.y));
                            list4.Clear();
                            bool flag = false;
                            for (int m = 0; m < list5.Count; m++)
                            {
                                int x = list5[m].boundsY.x;
                                int y = list5[m].boundsY.y;
                                if (IntRect.Intersects(a, list5[m].bounds) && y >= num && x <= num2 && (list5[m].cutsAddedGeom || k == -1))
                                {
                                    Int3 int5 = int2;
                                    int5.y = x;
                                    Int3 int6 = int2;
                                    int6.y = y;
                                    list4.Add(m);
                                    flag |= list5[m].isDual;
                                }
                            }
                            if (list4.Count == 0 && (mode & TileHandler.CutMode.CutExtra) == (TileHandler.CutMode) 0 && (mode & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0 && k == -1)
                            {
                                list7.Add(list6.Count);
                                list7.Add(list6.Count + 1);
                                list7.Add(list6.Count + 2);
                                list6.Add(int2);
                                list6.Add(int3);
                                list6.Add(int4);
                            }
                            else
                            {
                                list8.Clear();
                                if (k == -1)
                                {
                                    list8.Add(new IntPoint((long)int2.x, (long)int2.z));
                                    list8.Add(new IntPoint((long)int3.x, (long)int3.z));
                                    list8.Add(new IntPoint((long)int4.x, (long)int4.z));
                                }
                                else
                                {
                                    array[0] = int2;
                                    array[1] = int3;
                                    array[2] = int4;
                                    int num3 = this.ClipAgainstRectangle(array, clipOut, size);
                                    if (num3 == 0)
                                    {
                                        goto IL_9D3;
                                    }
                                    for (int n = 0; n < num3; n++)
                                    {
                                        list8.Add(new IntPoint((long)array[n].x, (long)array[n].z));
                                    }
                                }
                                dictionary.Clear();
                                for (int num4 = 0; num4 < 16; num4++)
                                {
                                    if ((mode >> (num4 & 31) & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0)
                                    {
                                        if (1 << num4 == 1)
                                        {
                                            this.CutAll(list8, list4, list5, polyTree);
                                        }
                                        else if (1 << num4 == 2)
                                        {
                                            if (!flag)
                                            {
                                                goto IL_9C4;
                                            }
                                            this.CutDual(list8, list4, list5, flag, list10, polyTree);
                                        }
                                        else if (1 << num4 == 4)
                                        {
                                            this.CutExtra(list8, list, polyTree);
                                        }
                                        for (int num5 = 0; num5 < polyTree.ChildCount; num5++)
                                        {
                                            PolyNode        polyNode = polyTree.Childs[num5];
                                            List <IntPoint> contour  = polyNode.Contour;
                                            List <PolyNode> childs   = polyNode.Childs;
                                            if (childs.Count == 0 && contour.Count == 3 && k == -1)
                                            {
                                                for (int num6 = 0; num6 < 3; num6++)
                                                {
                                                    Int3 int7 = new Int3((int)contour[num6].X, 0, (int)contour[num6].Y);
                                                    int7.y = TileHandler.SampleYCoordinateInTriangle(int2, int3, int4, int7);
                                                    list7.Add(list6.Count);
                                                    list6.Add(int7);
                                                }
                                            }
                                            else
                                            {
                                                Polygon polygon = null;
                                                int     num7    = -1;
                                                for (List <IntPoint> list11 = contour; list11 != null; list11 = ((num7 >= childs.Count) ? null : childs[num7].Contour))
                                                {
                                                    list9.Clear();
                                                    for (int num8 = 0; num8 < list11.Count; num8++)
                                                    {
                                                        PolygonPoint polygonPoint = new PolygonPoint((double)list11[num8].X, (double)list11[num8].Y);
                                                        list9.Add(polygonPoint);
                                                        Int3 int8 = new Int3((int)list11[num8].X, 0, (int)list11[num8].Y);
                                                        int8.y = TileHandler.SampleYCoordinateInTriangle(int2, int3, int4, int8);
                                                        dictionary[polygonPoint] = list6.Count;
                                                        list6.Add(int8);
                                                    }
                                                    Polygon polygon2;
                                                    if (stack.Count > 0)
                                                    {
                                                        polygon2 = stack.Pop();
                                                        polygon2.AddPoints(list9);
                                                    }
                                                    else
                                                    {
                                                        polygon2 = new Polygon(list9);
                                                    }
                                                    if (num7 == -1)
                                                    {
                                                        polygon = polygon2;
                                                    }
                                                    else
                                                    {
                                                        polygon.AddHole(polygon2);
                                                    }
                                                    num7++;
                                                }
                                                try
                                                {
                                                    P2T.Triangulate(polygon);
                                                }
                                                catch (PointOnEdgeException)
                                                {
                                                    Debug.LogWarning("PointOnEdgeException, perturbating vertices slightly.\nThis is usually fine. It happens sometimes because of rounding errors. Cutting will be retried a few more times.");
                                                    return(this.CutPoly(verts, tris, extraShape, graphTransform, tiles, mode, perturbate + 1));
                                                }
                                                try
                                                {
                                                    for (int num9 = 0; num9 < polygon.Triangles.Count; num9++)
                                                    {
                                                        DelaunayTriangle delaunayTriangle = polygon.Triangles[num9];
                                                        list7.Add(dictionary[delaunayTriangle.Points._0]);
                                                        list7.Add(dictionary[delaunayTriangle.Points._1]);
                                                        list7.Add(dictionary[delaunayTriangle.Points._2]);
                                                    }
                                                }
                                                catch (KeyNotFoundException)
                                                {
                                                    Debug.LogWarning("KeyNotFoundException, perturbating vertices slightly.\nThis is usually fine. It happens sometimes because of rounding errors. Cutting will be retried a few more times.");
                                                    return(this.CutPoly(verts, tris, extraShape, graphTransform, tiles, mode, perturbate + 1));
                                                }
                                                TileHandler.PoolPolygon(polygon, stack);
                                            }
                                        }
                                    }
                                    IL_9C4 :;
                                }
                            }
                        }
                        IL_9D3 :;
                    }
                }
                if (array2 != null)
                {
                    ArrayPool <Int3> .Release(ref array2, false);
                }
                StackPool <Polygon> .Release(stack);

                ListPool <List <IntPoint> > .Release(list10);

                ListPool <IntPoint> .Release(list8);

                ListPool <PolygonPoint> .Release(list9);
            }
            TileHandler.CuttingResult result = default(TileHandler.CuttingResult);
            Polygon.CompressMesh(list6, list7, out result.verts, out result.tris);
            for (int num10 = 0; num10 < list2.Count; num10++)
            {
                list2[num10].UsedForCut();
            }
            ListPool <Int3> .Release(list6);

            ListPool <int> .Release(list7);

            ListPool <int> .Release(list4);

            for (int num11 = 0; num11 < list5.Count; num11++)
            {
                ListPool <IntPoint> .Release(list5[num11].contour);
            }
            ListPool <TileHandler.Cut> .Release(list5);

            ListPool <NavmeshCut> .Release(list2);

            return(result);
        }
コード例 #22
0
        // Token: 0x060005E2 RID: 1506 RVA: 0x000360CC File Offset: 0x000344CC
        private void CutPoly(Int3[] verts, int[] tris, ref Int3[] outVertsArr, ref int[] outTrisArr, out int outVCount, out int outTCount, Int3[] extraShape, Int3 cuttingOffset, Bounds realBounds, TileHandler.CutMode mode = (TileHandler.CutMode) 3, int perturbate = 0)
        {
            if (verts.Length == 0 || tris.Length == 0)
            {
                outVCount   = 0;
                outTCount   = 0;
                outTrisArr  = new int[0];
                outVertsArr = new Int3[0];
                return;
            }
            List <IntPoint> list = null;

            if (extraShape == null && (mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0)
            {
                throw new Exception("extraShape is null and the CutMode specifies that it should be used. Cannot use null shape.");
            }
            if ((mode & TileHandler.CutMode.CutExtra) != (TileHandler.CutMode) 0)
            {
                list = new List <IntPoint>(extraShape.Length);
                for (int i = 0; i < extraShape.Length; i++)
                {
                    list.Add(new IntPoint((long)(extraShape[i].x + cuttingOffset.x), (long)(extraShape[i].z + cuttingOffset.z)));
                }
            }
            List <IntPoint> list2 = new List <IntPoint>(5);
            Dictionary <TriangulationPoint, int> dictionary = new Dictionary <TriangulationPoint, int>();
            List <PolygonPoint> list3 = new List <PolygonPoint>();
            IntRect             b     = new IntRect(verts[0].x, verts[0].z, verts[0].x, verts[0].z);

            for (int j = 0; j < verts.Length; j++)
            {
                b = b.ExpandToContain(verts[j].x, verts[j].z);
            }
            List <Int3> list4 = ListPool <Int3> .Claim(verts.Length * 2);

            List <int> list5 = ListPool <int> .Claim(tris.Length);

            PolyTree polyTree             = new PolyTree();
            List <List <IntPoint> > list6 = new List <List <IntPoint> >();
            Stack <Polygon>         stack = new Stack <Polygon>();

            if (this.clipper == null)
            {
                this.clipper = new Clipper(0);
            }
            this.clipper.ReverseSolution = true;
            List <NavmeshCut> list7;

            if (mode == TileHandler.CutMode.CutExtra)
            {
                list7 = ListPool <NavmeshCut> .Claim();
            }
            else
            {
                list7 = NavmeshCut.GetAllInRange(realBounds);
            }
            List <int> list8 = ListPool <int> .Claim();

            List <IntRect> list9 = ListPool <IntRect> .Claim();

            List <Int2> list10 = ListPool <Int2> .Claim();

            List <List <IntPoint> > list11 = new List <List <IntPoint> >();
            List <bool>             list12 = ListPool <bool> .Claim();

            List <bool> list13 = ListPool <bool> .Claim();

            if (perturbate > 10)
            {
                Debug.LogError("Too many perturbations aborting : " + mode);
                Debug.Break();
                outVCount   = verts.Length;
                outTCount   = tris.Length;
                outTrisArr  = tris;
                outVertsArr = verts;
                return;
            }
            System.Random random = null;
            if (perturbate > 0)
            {
                random = new System.Random();
            }
            for (int k = 0; k < list7.Count; k++)
            {
                Bounds  bounds = list7[k].GetBounds();
                Int3    @int   = (Int3)bounds.min + cuttingOffset;
                Int3    int2   = (Int3)bounds.max + cuttingOffset;
                IntRect a      = new IntRect(@int.x, @int.z, int2.x, int2.z);
                if (IntRect.Intersects(a, b))
                {
                    Int2 int3 = new Int2(0, 0);
                    if (perturbate > 0)
                    {
                        int3.x = random.Next() % 6 * perturbate - 3 * perturbate;
                        if (int3.x >= 0)
                        {
                            int3.x++;
                        }
                        int3.y = random.Next() % 6 * perturbate - 3 * perturbate;
                        if (int3.y >= 0)
                        {
                            int3.y++;
                        }
                    }
                    int count = list11.Count;
                    list7[k].GetContour(list11);
                    for (int l = count; l < list11.Count; l++)
                    {
                        List <IntPoint> list14 = list11[l];
                        if (list14.Count == 0)
                        {
                            Debug.LogError("Zero Length Contour");
                            list9.Add(default(IntRect));
                            list10.Add(new Int2(0, 0));
                        }
                        else
                        {
                            IntRect item = new IntRect((int)list14[0].X + cuttingOffset.x, (int)list14[0].Y + cuttingOffset.y, (int)list14[0].X + cuttingOffset.x, (int)list14[0].Y + cuttingOffset.y);
                            for (int m = 0; m < list14.Count; m++)
                            {
                                IntPoint value = list14[m];
                                value.X += (long)cuttingOffset.x;
                                value.Y += (long)cuttingOffset.z;
                                if (perturbate > 0)
                                {
                                    value.X += (long)int3.x;
                                    value.Y += (long)int3.y;
                                }
                                list14[m] = value;
                                item      = item.ExpandToContain((int)value.X, (int)value.Y);
                            }
                            list10.Add(new Int2(@int.y, int2.y));
                            list9.Add(item);
                            list12.Add(list7[k].isDual);
                            list13.Add(list7[k].cutsAddedGeom);
                        }
                    }
                }
            }
            List <NavmeshAdd> allInRange = NavmeshAdd.GetAllInRange(realBounds);

            Int3[] array  = verts;
            int[]  array2 = tris;
            int    num    = -1;
            int    n      = -3;

            Int3[] array3 = null;
            Int3[] array4 = null;
            Int3   int4   = Int3.zero;

            if (allInRange.Count > 0)
            {
                array3 = new Int3[7];
                array4 = new Int3[7];
                int4   = (Int3)realBounds.extents;
            }
            for (;;)
            {
                n += 3;
                while (n >= array2.Length)
                {
                    num++;
                    n = 0;
                    if (num >= allInRange.Count)
                    {
                        array = null;
                        break;
                    }
                    if (array == verts)
                    {
                        array = null;
                    }
                    allInRange[num].GetMesh(cuttingOffset, ref array, out array2);
                }
                if (array == null)
                {
                    break;
                }
                Int3    int5 = array[array2[n]];
                Int3    int6 = array[array2[n + 1]];
                Int3    int7 = array[array2[n + 2]];
                IntRect a2   = new IntRect(int5.x, int5.z, int5.x, int5.z);
                a2 = a2.ExpandToContain(int6.x, int6.z);
                a2 = a2.ExpandToContain(int7.x, int7.z);
                int num2 = Math.Min(int5.y, Math.Min(int6.y, int7.y));
                int num3 = Math.Max(int5.y, Math.Max(int6.y, int7.y));
                list8.Clear();
                bool flag = false;
                for (int num4 = 0; num4 < list11.Count; num4++)
                {
                    int x = list10[num4].x;
                    int y = list10[num4].y;
                    if (IntRect.Intersects(a2, list9[num4]) && y >= num2 && x <= num3 && (list13[num4] || num == -1))
                    {
                        Int3 int8 = int5;
                        int8.y = x;
                        Int3 int9 = int5;
                        int9.y = y;
                        list8.Add(num4);
                        flag |= list12[num4];
                    }
                }
                if (list8.Count == 0 && (mode & TileHandler.CutMode.CutExtra) == (TileHandler.CutMode) 0 && (mode & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0 && num == -1)
                {
                    list5.Add(list4.Count);
                    list5.Add(list4.Count + 1);
                    list5.Add(list4.Count + 2);
                    list4.Add(int5);
                    list4.Add(int6);
                    list4.Add(int7);
                }
                else
                {
                    list2.Clear();
                    if (num == -1)
                    {
                        list2.Add(new IntPoint((long)int5.x, (long)int5.z));
                        list2.Add(new IntPoint((long)int6.x, (long)int6.z));
                        list2.Add(new IntPoint((long)int7.x, (long)int7.z));
                    }
                    else
                    {
                        array3[0] = int5;
                        array3[1] = int6;
                        array3[2] = int7;
                        int num5 = Utility.ClipPolygon(array3, 3, array4, 1, 0, 0);
                        if (num5 == 0)
                        {
                            continue;
                        }
                        num5 = Utility.ClipPolygon(array4, num5, array3, -1, 2 * int4.x, 0);
                        if (num5 == 0)
                        {
                            continue;
                        }
                        num5 = Utility.ClipPolygon(array3, num5, array4, 1, 0, 2);
                        if (num5 == 0)
                        {
                            continue;
                        }
                        num5 = Utility.ClipPolygon(array4, num5, array3, -1, 2 * int4.z, 2);
                        if (num5 == 0)
                        {
                            continue;
                        }
                        for (int num6 = 0; num6 < num5; num6++)
                        {
                            list2.Add(new IntPoint((long)array3[num6].x, (long)array3[num6].z));
                        }
                    }
                    dictionary.Clear();
                    Int3 int10 = int6 - int5;
                    Int3 int11 = int7 - int5;
                    Int3 int12 = int10;
                    Int3 int13 = int11;
                    int12.y = 0;
                    int13.y = 0;
                    for (int num7 = 0; num7 < 16; num7++)
                    {
                        if ((mode >> (num7 & 31) & TileHandler.CutMode.CutAll) != (TileHandler.CutMode) 0)
                        {
                            if (1 << num7 == 1)
                            {
                                this.clipper.Clear();
                                this.clipper.AddPolygon(list2, PolyType.ptSubject);
                                for (int num8 = 0; num8 < list8.Count; num8++)
                                {
                                    this.clipper.AddPolygon(list11[list8[num8]], PolyType.ptClip);
                                }
                                polyTree.Clear();
                                this.clipper.Execute(ClipType.ctDifference, polyTree, PolyFillType.pftEvenOdd, PolyFillType.pftNonZero);
                            }
                            else if (1 << num7 == 2)
                            {
                                if (!flag)
                                {
                                    goto IL_1161;
                                }
                                this.clipper.Clear();
                                this.clipper.AddPolygon(list2, PolyType.ptSubject);
                                for (int num9 = 0; num9 < list8.Count; num9++)
                                {
                                    if (list12[list8[num9]])
                                    {
                                        this.clipper.AddPolygon(list11[list8[num9]], PolyType.ptClip);
                                    }
                                }
                                list6.Clear();
                                this.clipper.Execute(ClipType.ctIntersection, list6, PolyFillType.pftEvenOdd, PolyFillType.pftNonZero);
                                this.clipper.Clear();
                                for (int num10 = 0; num10 < list6.Count; num10++)
                                {
                                    this.clipper.AddPolygon(list6[num10], (!Clipper.Orientation(list6[num10])) ? PolyType.ptSubject : PolyType.ptClip);
                                }
                                for (int num11 = 0; num11 < list8.Count; num11++)
                                {
                                    if (!list12[list8[num11]])
                                    {
                                        this.clipper.AddPolygon(list11[list8[num11]], PolyType.ptClip);
                                    }
                                }
                                polyTree.Clear();
                                this.clipper.Execute(ClipType.ctDifference, polyTree, PolyFillType.pftEvenOdd, PolyFillType.pftNonZero);
                            }
                            else if (1 << num7 == 4)
                            {
                                this.clipper.Clear();
                                this.clipper.AddPolygon(list2, PolyType.ptSubject);
                                this.clipper.AddPolygon(list, PolyType.ptClip);
                                polyTree.Clear();
                                this.clipper.Execute(ClipType.ctIntersection, polyTree, PolyFillType.pftEvenOdd, PolyFillType.pftNonZero);
                            }
                            for (int num12 = 0; num12 < polyTree.ChildCount; num12++)
                            {
                                PolyNode        polyNode = polyTree.Childs[num12];
                                List <IntPoint> contour  = polyNode.Contour;
                                List <PolyNode> childs   = polyNode.Childs;
                                if (childs.Count == 0 && contour.Count == 3 && num == -1)
                                {
                                    for (int num13 = 0; num13 < contour.Count; num13++)
                                    {
                                        Int3   item2 = new Int3((int)contour[num13].X, 0, (int)contour[num13].Y);
                                        double num14 = (double)(int6.z - int7.z) * (double)(int5.x - int7.x) + (double)(int7.x - int6.x) * (double)(int5.z - int7.z);
                                        if (num14 == 0.0)
                                        {
                                            Debug.LogWarning("Degenerate triangle");
                                        }
                                        else
                                        {
                                            double num15 = ((double)(int6.z - int7.z) * (double)(item2.x - int7.x) + (double)(int7.x - int6.x) * (double)(item2.z - int7.z)) / num14;
                                            double num16 = ((double)(int7.z - int5.z) * (double)(item2.x - int7.x) + (double)(int5.x - int7.x) * (double)(item2.z - int7.z)) / num14;
                                            item2.y = (int)Math.Round(num15 * (double)int5.y + num16 * (double)int6.y + (1.0 - num15 - num16) * (double)int7.y);
                                            list5.Add(list4.Count);
                                            list4.Add(item2);
                                        }
                                    }
                                }
                                else
                                {
                                    Polygon polygon = null;
                                    int     num17   = -1;
                                    for (List <IntPoint> list15 = contour; list15 != null; list15 = ((num17 >= childs.Count) ? null : childs[num17].Contour))
                                    {
                                        list3.Clear();
                                        for (int num18 = 0; num18 < list15.Count; num18++)
                                        {
                                            PolygonPoint polygonPoint = new PolygonPoint((double)list15[num18].X, (double)list15[num18].Y);
                                            list3.Add(polygonPoint);
                                            Int3   item3 = new Int3((int)list15[num18].X, 0, (int)list15[num18].Y);
                                            double num19 = (double)(int6.z - int7.z) * (double)(int5.x - int7.x) + (double)(int7.x - int6.x) * (double)(int5.z - int7.z);
                                            if (num19 == 0.0)
                                            {
                                                Debug.LogWarning("Degenerate triangle");
                                            }
                                            else
                                            {
                                                double num20 = ((double)(int6.z - int7.z) * (double)(item3.x - int7.x) + (double)(int7.x - int6.x) * (double)(item3.z - int7.z)) / num19;
                                                double num21 = ((double)(int7.z - int5.z) * (double)(item3.x - int7.x) + (double)(int5.x - int7.x) * (double)(item3.z - int7.z)) / num19;
                                                item3.y = (int)Math.Round(num20 * (double)int5.y + num21 * (double)int6.y + (1.0 - num20 - num21) * (double)int7.y);
                                                dictionary[polygonPoint] = list4.Count;
                                                list4.Add(item3);
                                            }
                                        }
                                        Polygon polygon2;
                                        if (stack.Count > 0)
                                        {
                                            polygon2 = stack.Pop();
                                            polygon2.AddPoints(list3);
                                        }
                                        else
                                        {
                                            polygon2 = new Polygon(list3);
                                        }
                                        if (polygon == null)
                                        {
                                            polygon = polygon2;
                                        }
                                        else
                                        {
                                            polygon.AddHole(polygon2);
                                        }
                                        num17++;
                                    }
                                    try
                                    {
                                        P2T.Triangulate(polygon);
                                    }
                                    catch (PointOnEdgeException)
                                    {
                                        Debug.LogWarning(string.Concat(new object[]
                                        {
                                            "PointOnEdgeException, perturbating vertices slightly ( at ",
                                            num7,
                                            " in ",
                                            mode,
                                            ")"
                                        }));
                                        this.CutPoly(verts, tris, ref outVertsArr, ref outTrisArr, out outVCount, out outTCount, extraShape, cuttingOffset, realBounds, mode, perturbate + 1);
                                        return;
                                    }
                                    for (int num22 = 0; num22 < polygon.Triangles.Count; num22++)
                                    {
                                        DelaunayTriangle delaunayTriangle = polygon.Triangles[num22];
                                        list5.Add(dictionary[delaunayTriangle.Points._0]);
                                        list5.Add(dictionary[delaunayTriangle.Points._1]);
                                        list5.Add(dictionary[delaunayTriangle.Points._2]);
                                    }
                                    if (polygon.Holes != null)
                                    {
                                        for (int num23 = 0; num23 < polygon.Holes.Count; num23++)
                                        {
                                            polygon.Holes[num23].Points.Clear();
                                            polygon.Holes[num23].ClearTriangles();
                                            if (polygon.Holes[num23].Holes != null)
                                            {
                                                polygon.Holes[num23].Holes.Clear();
                                            }
                                            stack.Push(polygon.Holes[num23]);
                                        }
                                    }
                                    polygon.ClearTriangles();
                                    if (polygon.Holes != null)
                                    {
                                        polygon.Holes.Clear();
                                    }
                                    polygon.Points.Clear();
                                    stack.Push(polygon);
                                }
                            }
                        }
                        IL_1161 :;
                    }
                }
            }
            Dictionary <Int3, int> dictionary2 = this.cached_Int3_int_dict;

            dictionary2.Clear();
            if (this.cached_int_array.Length < list4.Count)
            {
                this.cached_int_array = new int[Math.Max(this.cached_int_array.Length * 2, list4.Count)];
            }
            int[] array5 = this.cached_int_array;
            int   num24  = 0;

            for (int num25 = 0; num25 < list4.Count; num25++)
            {
                int num26;
                if (!dictionary2.TryGetValue(list4[num25], out num26))
                {
                    dictionary2.Add(list4[num25], num24);
                    array5[num25] = num24;
                    list4[num24]  = list4[num25];
                    num24++;
                }
                else
                {
                    array5[num25] = num26;
                }
            }
            outTCount = list5.Count;
            if (outTrisArr == null || outTrisArr.Length < outTCount)
            {
                outTrisArr = new int[outTCount];
            }
            for (int num27 = 0; num27 < outTCount; num27++)
            {
                outTrisArr[num27] = array5[list5[num27]];
            }
            outVCount = num24;
            if (outVertsArr == null || outVertsArr.Length < outVCount)
            {
                outVertsArr = new Int3[outVCount];
            }
            for (int num28 = 0; num28 < outVCount; num28++)
            {
                outVertsArr[num28] = list4[num28];
            }
            for (int num29 = 0; num29 < list7.Count; num29++)
            {
                list7[num29].UsedForCut();
            }
            ListPool <Int3> .Release(list4);

            ListPool <int> .Release(list5);

            ListPool <int> .Release(list8);

            ListPool <Int2> .Release(list10);

            ListPool <bool> .Release(list12);

            ListPool <bool> .Release(list13);

            ListPool <IntRect> .Release(list9);

            ListPool <NavmeshCut> .Release(list7);
        }
コード例 #23
0
        /// <summary>
        /// Update mesh according to internally stored polygons
        /// </summary>
        void UpdateMap()
        {
            polygonCollider.pathCount = this.polygons.Count;

            Mesh mesh = GetComponent <MeshFilter>().mesh;

            mesh.Clear();
            #region Triangulation
            List <IntPolygon> polyList = new List <IntPolygon>();
            int indexCount             = 0;
            foreach (Path p in this.polygons)
            {
                indexCount += p.Count;
                polyList.Add(new IntPolygon(IntPolygon.toPolygonPoints(p)));
                P2T.Triangulate(polyList[polyList.Count - 1]);
            }
            #endregion

            #region vertices and triangles
            Vector3[] vertices    = new Vector3[indexCount];
            int[][]   triangless  = new int[polyList.Count][];
            int       indexOffset = 0;
            //UnityEngine.Debug.Log("polygon count = " + polyList.Count);

            // join vertices to form an array of vertices
            for (int i = 0; i < polyList.Count; i++)
            {
                polyList[i].getVerticesVector3(MAP_SCALE).CopyTo(vertices, indexOffset);
                // also set collider paths (Vector3 implicitly converts to Vector2)
                polygonCollider.SetPath(i, polyList[i].getVerticesVector2(MAP_SCALE));
                // retrieve triangles for each polygons
                triangless[i] = polyList[i].getTriangles(indexOffset);
                indexOffset  += this.polygons[i].Count;
            }
            mesh.vertices = vertices;

            // count the total number of triangles
            int triangleCount = 0;
            foreach (int[] tri in triangless)
            {
                triangleCount += tri.Length;
            }
            // join triangles to form an array of triangles
            int   triangleOffset = 0;
            int[] triangles      = new int[triangleCount];
            for (int i = 0; i < polyList.Count; i++)
            {
                triangless[i].CopyTo(triangles, triangleOffset);
                triangleOffset += triangless[i].Length;
            }

            mesh.triangles = triangles;
            #endregion

            #region UVs
            Vector2[] uv = new Vector2[mesh.vertices.Length];
            for (int i = 0; i < mesh.vertices.Length; i++)
            {
                uv[i].Set(mesh.vertices[i].x, mesh.vertices[i].y);
            }
            mesh.uv = uv;
            #endregion

            Vector3[] normals = new Vector3[indexCount];
            for (int i = 0; i < normals.Length; i++)
            {
                normals[i] = Vector3.back;
            }
            mesh.normals = normals;

            mesh.Optimize();
        }
コード例 #24
0
        public static Mesh triangulate(AXSpline poly, float height, AXTexCoords tex)
        {
            // poly has verts that are delimeted by 8888888 for holes

            //Debug.Log ("F");
            // 1. transpose points to poly2tri structures
            // 2. create mesh
            Polygon _polygon = null;

            List <AXSpline> parts = poly.getSolidAndHoles();

            if (parts == null || parts.Count == 0)
            {
                return(null);
            }

            // CONTOUR
            AXSpline contour = parts[0];

            List <PolygonPoint> _points = new List <PolygonPoint>();

            for (int ii = 0; ii < contour.vertCount; ii++)
            {
                _points.Add(new PolygonPoint((double)contour.verts[ii].x, (double)contour.verts[ii].y));
            }


            // POLYGON
            if (_points.Count >= 3)
            {
                _polygon = new Polygon(_points);


                // HOLES?
                if (parts.Count > 1)
                {
                    for (int i = 1; i < parts.Count; i++)
                    {
                        List <PolygonPoint> _holepoints = new List <PolygonPoint>();
                        for (int ii = 0; ii < parts[i].vertCount; ii++)
                        {
                            _holepoints.Add(new PolygonPoint((double)parts[i].verts[ii].x, (double)parts[i].verts[ii].y));
                        }
                        if (_holepoints.Count >= 3)
                        {
                            Polygon _hole = new Polygon(_holepoints);
                            _polygon.AddHole(_hole);
                        }
                    }
                }
            }

            // populate the polygon triangles
            if (_polygon != null)
            {
                P2T.Triangulate(_polygon);

                return(polygon2mesh(_polygon, tex));
            }
            return(null);
        }
コード例 #25
0
ファイル: TextBrush.cs プロジェクト: Bananaman043/cbre
        public IEnumerable <MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
        {
            var width   = box.Width;
            var length  = Math.Max(1, Math.Abs((int)box.Length));
            var height  = box.Height;
            var flatten = (float)_flattenFactor.Value;
            var text    = _text.GetValue();

            var family = _fontChooser.GetFontFamily();
            var style  = Enum.GetValues(typeof(FontStyle)).OfType <FontStyle>().FirstOrDefault(fs => family.IsStyleAvailable(fs));

            if (!family.IsStyleAvailable(style))
            {
                family = FontFamily.GenericSansSerif;
            }

            var set = new PolygonSet();

            var sizes = new List <RectangleF>();

            using (var bmp = new Bitmap(1, 1))
            {
                using (var g = System.Drawing.Graphics.FromImage(bmp))
                {
                    using (var font = new Font(family, length, style, GraphicsUnit.Pixel))
                    {
                        for (var i = 0; i < text.Length; i += 32)
                        {
                            using (var sf = new StringFormat(StringFormat.GenericTypographic))
                            {
                                var rem   = Math.Min(text.Length, i + 32) - i;
                                var range = Enumerable.Range(0, rem).Select(x => new CharacterRange(x, 1)).ToArray();
                                sf.SetMeasurableCharacterRanges(range);
                                var reg = g.MeasureCharacterRanges(text.Substring(i, rem), font, new RectangleF(0, 0, float.MaxValue, float.MaxValue), sf);
                                sizes.AddRange(reg.Select(x => x.GetBounds(g)));
                            }
                        }
                    }
                }
            }

            var xOffset = box.Start.DX;
            var yOffset = box.End.DY;

            for (var ci = 0; ci < text.Length; ci++)
            {
                var c    = text[ci];
                var size = sizes[ci];

                var gp = new GraphicsPath();
                gp.AddString(c.ToString(CultureInfo.InvariantCulture), family, (int)style, length, new PointF(0, 0), StringFormat.GenericTypographic);
                gp.Flatten(new System.Drawing.Drawing2D.Matrix(), flatten);

                var polygons = new List <Polygon>();
                var poly     = new List <PolygonPoint>();

                for (var i = 0; i < gp.PointCount; i++)
                {
                    var type  = gp.PathTypes[i];
                    var point = gp.PathPoints[i];

                    poly.Add(new PolygonPoint(point.X + xOffset, -point.Y + yOffset));

                    if ((type & 0x80) == 0x80)
                    {
                        polygons.Add(new Polygon(poly));
                        poly.Clear();
                    }
                }

                var     tri     = new List <Polygon>();
                Polygon polygon = null;
                foreach (var p in polygons)
                {
                    if (polygon == null)
                    {
                        polygon = p;
                        tri.Add(p);
                    }
                    else if (p.CalculateWindingOrder() != polygon.CalculateWindingOrder())
                    {
                        polygon.AddHole(p);
                    }
                    else
                    {
                        polygon = null;
                        tri.Add(p);
                    }
                }

                foreach (var pp in tri)
                {
                    try
                    {
                        P2T.Triangulate(pp);
                        set.Add(pp);
                    }
                    catch
                    {
                        // Ignore
                    }
                }

                xOffset += size.Width;
            }

            var zOffset = box.Start.Z;

            foreach (var polygon in set.Polygons)
            {
                foreach (var t in polygon.Triangles)
                {
                    var points = t.Points.Select(x => new Coordinate((decimal)x.X, (decimal)x.Y, zOffset).Round(roundDecimals)).ToList();

                    var faces = new List <Coordinate[]>();

                    // Add the vertical faces
                    var z = new Coordinate(0, 0, height).Round(roundDecimals);
                    for (var j = 0; j < points.Count; j++)
                    {
                        var next = (j + 1) % points.Count;
                        faces.Add(new[] { points[j], points[j] + z, points[next] + z, points[next] });
                    }
                    // Add the top and bottom faces
                    faces.Add(points.ToArray());
                    faces.Add(points.Select(x => x + z).Reverse().ToArray());

                    // Nothing new here, move along
                    var solid = new Solid(generator.GetNextObjectID())
                    {
                        Colour = Colour.GetRandomBrushColour()
                    };
                    foreach (var arr in faces)
                    {
                        var face = new Face(generator.GetNextFaceID())
                        {
                            Parent  = solid,
                            Plane   = new Plane(arr[0], arr[1], arr[2]),
                            Colour  = solid.Colour,
                            Texture = { Texture = texture }
                        };
                        face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
                        face.UpdateBoundingBox();
                        face.AlignTextureToFace();
                        solid.Faces.Add(face);
                    }
                    solid.UpdateBoundingBox();
                    yield return(solid);
                }
            }
        }
コード例 #26
0
 public static void TriangulateWithHoles(ArrayList vectors, List <ArrayList> holes, ref Mesh mesh, bool ceiling, bool twoSided, float y)
 {
     if (vectors.Count >= 3)
     {
         PolygonPoint[] c           = new PolygonPoint[vectors.Count];
         List <Vector3> list        = new List <Vector3>();
         Vector2[]      vectorArray = new Vector2[vectors.Count];
         List <int>     list2       = null;
         for (int i = 0; i < vectors.Count; i++)
         {
             Vector2 vector = (Vector2)vectors[i];
             c[i] = new PolygonPoint((double)vector.x, (double)vector.y);
             list.Add(new Vector3(vector.x, y, vector.y));
             vectorArray[i] = new Vector2(vector.x, vector.y);
         }
         ArrayList list3 = new ArrayList(c);
         Polygon   p     = new Polygon(c);
         foreach (ArrayList list4 in holes)
         {
             List <PolygonPoint> list5 = new List <PolygonPoint>();
             for (int k = 0; k < list4.Count; k++)
             {
                 Vector2 vector2 = (Vector2)list4[k];
                 list5.Add(new PolygonPoint((double)vector2.x, (double)vector2.y));
                 list.Add(new Vector3(vector2.x, y, vector2.y));
             }
             list3.AddRange(list5);
             p.AddHole(new Polygon(list5));
         }
         P2T.Triangulate(p);
         list2 = new List <int>();
         for (int j = 0; j < p.Triangles.Count; j++)
         {
             if (twoSided)
             {
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._2));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._1));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._0));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._0));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._1));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._2));
             }
             else if (!ceiling)
             {
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._2));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._1));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._0));
             }
             else
             {
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._0));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._1));
                 list2.Add(list3.IndexOf(p.Triangles[j].Points._2));
             }
         }
         list2.TrimExcess();
         list.TrimExcess();
         mesh.vertices  = list.ToArray();
         mesh.triangles = list2.ToArray();
         mesh.RecalculateBounds();
     }
 }
コード例 #27
0
        void Triangulate()
        {
            // fill up the poly2tri container that holds our main mesh vertices
            List <PolygonPoint> points = new List <PolygonPoint>();

            // fill them with our data
            foreach (var point in script.mainMeshVertices.vertices)
            {
                points.Add(new PolygonPoint(point.x, point.z));
            }
            Polygon pointSet = new Polygon(points);

            // add our holes to the pointSet variable
            foreach (var hole in script.meshHoles)
            {
                var holeVerts = hole.vertices;
                if (holeVerts.Count >= 3)
                {
                    List <PolygonPoint> pointsHole = new List <PolygonPoint>();
                    foreach (var point in holeVerts)
                    {
                        pointsHole.Add(new PolygonPoint(point.x, point.z));
                    }
                    pointSet.AddHole(new Polygon(pointsHole));
                }
            }

            P2T.Triangulate(pointSet);

            // to generate correct vertex indices for our triangulation we add all of the triangulation points into a single list ...
            List <TriangulationPoint> triangulationVertices = new List <TriangulationPoint>();

            triangulationVertices.AddRange(pointSet.Points);

            // ... including the holes
            if (pointSet.Holes != null)
            {
                foreach (var holePoints in pointSet.Holes)
                {
                    foreach (var point in holePoints.Points)
                    {
                        triangulationVertices.Add(point);
                    }
                }
            }

            // create mesh
            MeshCollider mc = script.GetComponent <MeshCollider>();

            // remove old mesh if it exists
            DeleteMesh(mc.sharedMesh);

            Mesh mesh = new Mesh();

            mesh.name = "TeleportationAreaMesh_" + GetHashCode();

            List <Vector3> vertices  = new List <Vector3>();
            List <int>     triangles = new List <int>();

            foreach (var point in triangulationVertices)
            {
                vertices.Add(new Vector3(point.Xf, 0.0f, point.Yf));
            }

            foreach (var tri in pointSet.Triangles)
            {
                triangles.Add(triangulationVertices.IndexOf(tri.Points[2]));
                triangles.Add(triangulationVertices.IndexOf(tri.Points[1]));
                triangles.Add(triangulationVertices.IndexOf(tri.Points[0]));
            }

            mesh.vertices  = vertices.ToArray();
            mesh.triangles = triangles.ToArray();

            SaveMesh(mesh);
            mc.sharedMesh = mesh;
            EditorUtility.SetDirty(mc);

            // the SetDirty above doesn't do anything
            // our link to the just created mesh will be lost
            // when we switch scenes so we use this ugly workaround
            // below for now...
            EditorSceneManager.MarkAllScenesDirty();
            EditorSceneManager.SaveOpenScenes();
        }
コード例 #28
0
    /// <summary>
    /// Creates a triangulation of the vertices given, and gives you the indices of it.
    /// </summary>
    /// <param name="aPoints">A list of points to triangulate.</param>
    /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param>
    /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param>
    /// <param name="aInvertBorderSize">When inverted, how large should the border be in each direction?</param>
    /// <returns>A magical list of indices describing the triangulation!</returns>
    public static List <int> GetIndices(ref List <Vector2> aPoints, bool aTreatAsPath, bool aInvert, Vector2 aInvertBorderSize, float aVertGridSpacing = 0)
    {
        Vector4 bounds = GetBounds(aPoints);

        if (aVertGridSpacing > 0)
        {
            SplitEdges(ref aPoints, aVertGridSpacing);
        }

        List <PolygonPoint> verts = new List <PolygonPoint>(aPoints.Count);

        for (int i = 0; i < aPoints.Count; i++)
        {
            verts.Add(new PolygonPoint(aPoints[i].x, aPoints[i].y));
        }

        Polygon poly;

        if (aInvert)
        {
            float width  = aInvertBorderSize.x == 0 ? (bounds.z - bounds.x) : aInvertBorderSize.x;
            float height = aInvertBorderSize.y == 0 ? (bounds.y - bounds.w) : aInvertBorderSize.y;
            aPoints.Add(new Vector2(bounds.x - width, bounds.w - height));
            aPoints.Add(new Vector2(bounds.z + width, bounds.w - height));
            aPoints.Add(new Vector2(bounds.z + width, bounds.y + height));
            aPoints.Add(new Vector2(bounds.x - width, bounds.y + height));

            List <PolygonPoint> outer = new List <PolygonPoint>(4);
            for (int i = 0; i < 4; i++)
            {
                outer.Add(new PolygonPoint(aPoints[(aPoints.Count - 4) + i].x, aPoints[(aPoints.Count - 4) + i].y));
            }
            poly = new Polygon(outer);
            poly.AddHole(new Polygon(verts));
        }
        else
        {
            poly = new Polygon(verts);
        }

        if (aVertGridSpacing > 0)
        {
            if (aInvert)
            {
                bounds = GetBounds(aPoints);
            }
            for (float y = bounds.w + aVertGridSpacing; y <= bounds.y; y += aVertGridSpacing)
            {
                for (float x = bounds.x + aVertGridSpacing; x <= bounds.z; x += aVertGridSpacing)
                {
                    TriangulationPoint pt = new TriangulationPoint(x, y);
                    bool inside           = poly.IsPointInside(pt);
                    if (inside)
                    {
                        poly.AddSteinerPoint(pt);
                    }
                }
            }
        }
        P2T.Triangulate(poly);

        aPoints.Clear();
        List <int> result = new List <int>(poly.Triangles.Count * 3);
        int        ind    = 0;

        foreach (DelaunayTriangle triangle in poly.Triangles)
        {
            TriangulationPoint p1 = triangle.Points[0];
            TriangulationPoint p2 = triangle.PointCWFrom(p1);
            TriangulationPoint p3 = triangle.PointCWFrom(p2);

            aPoints.Add(new Vector2(p1.Xf, p1.Yf));
            aPoints.Add(new Vector2(p2.Xf, p2.Yf));
            aPoints.Add(new Vector2(p3.Xf, p3.Yf));
            result.Add(ind++);
            result.Add(ind++);
            result.Add(ind++);
        }
        return(result);
    }
コード例 #29
0
        public Mesh CreateMeshFromVerts(Vector3[] vertsToCopy, Mesh mesh, List <int> pathSplitIds, Transform SpriteGO = null)
        {
            List <Vector3> resultsLocal                   = new List <Vector3>();
            List <int>     resultsTriIndexesLocal         = new List <int>();
            List <int>     resultsTriIndexesReversedLocal = new List <int>();
            List <Vector2> uvsLocal     = new List <Vector2>();
            List <Vector3> normalsLocal = new List <Vector3>();


            Sprite          spr             = null;
            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;
            }

            List <PolygonPoint>       p2          = new List <PolygonPoint>();
            List <TriangulationPoint> extraPoints = new List <TriangulationPoint>();

            int i = 0;

            for (i = 0; i < vertsToCopy.Count(); i++)
            {
                if (i < pathSplitIds[0])
                {
                    p2.Add(new PolygonPoint(vertsToCopy[i].x, vertsToCopy[i].y));
                }
                else
                {
                    extraPoints.Add(new TriangulationPoint(vertsToCopy[i].x, vertsToCopy[i].y));
                }
            }

            Polygon _polygon = new Polygon(p2);

            // this is how to add more points
            _polygon.AddSteinerPoints(extraPoints);

            P2T.Triangulate(_polygon);

            if (spr == null)
            {
                bound = new Vector3((float)(_polygon.Bounds.MaxX - _polygon.Bounds.MinX), (float)(_polygon.Bounds.MaxY - _polygon.Bounds.MinY), 0);
            }

            int idx = 0;

            foreach (DelaunayTriangle triangle in _polygon.Triangles)
            {
                Vector3 v = new Vector3();
                foreach (TriangulationPoint p in triangle.Points)
                {
                    v = new Vector3((float)p.X, (float)p.Y, 0);
                    if (!resultsLocal.Contains(v))
                    {
                        resultsLocal.Add(v);
                        resultsTriIndexesLocal.Add(idx);



                        Vector2 newUv = new Vector2(((v.x - (float)_polygon.Bounds.MinX) / bound.x), ((v.y - (float)_polygon.Bounds.MinY) / bound.y));
                        if (spr != null)
                        {
                            newUv    = new Vector2((v.x / bound.x) + 0.5f, (v.y / bound.y) + 0.5f);
                            newUv.x *= rec.width / spr.texture.width;
                            newUv.y *= rec.height / spr.texture.height;

                            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 k = 0; k < smdArray.Length; k++)
                            {
                                if (smdArray[k].name == spr.name)
                                {
                                    switch (smdArray[k].alignment)
                                    {
                                    case (0):
                                        smdArray[k].pivot = Vector2.zero;
                                        break;

                                    case (1):
                                        smdArray[k].pivot = new Vector2(0f, 1f) - new Vector2(.5f, .5f);
                                        break;

                                    case (2):
                                        smdArray[k].pivot = new Vector2(0.5f, 1f) - new Vector2(.5f, .5f);
                                        break;

                                    case (3):
                                        smdArray[k].pivot = new Vector2(1f, 1f) - new Vector2(.5f, .5f);
                                        break;

                                    case (4):
                                        smdArray[k].pivot = new Vector2(0f, .5f) - new Vector2(.5f, .5f);
                                        break;

                                    case (5):
                                        smdArray[k].pivot = new Vector2(1f, .5f) - new Vector2(.5f, .5f);
                                        break;

                                    case (6):
                                        smdArray[k].pivot = new Vector2(0f, 0f) - new Vector2(.5f, .5f);
                                        break;

                                    case (7):
                                        smdArray[k].pivot = new Vector2(0.5f, 0f) - new Vector2(.5f, .5f);
                                        break;

                                    case (8):
                                        smdArray[k].pivot = new Vector2(1f, 0f) - new Vector2(.5f, .5f);
                                        break;

                                    case (9):
                                        smdArray[k].pivot -= new Vector2(.5f, .5f);
                                        break;
                                    }
                                    pivot = smdArray[k].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;
                        }

                        uvsLocal.Add(newUv);
                        normalsLocal.Add(new Vector3(0, 0, -1));
                        idx++;
                    }
                    else
                    {
                        resultsTriIndexesLocal.Add(resultsLocal.LastIndexOf(v));
                    }
                }
            }



            for (int j = resultsTriIndexesLocal.Count - 1; j >= 0; j--)
            {
                resultsTriIndexesReversedLocal.Add(resultsTriIndexesLocal[j]);
            }

            results.AddRange(resultsLocal);
            resultsTriIndexes.AddRange(resultsTriIndexesLocal);
            resultsTriIndexesReversed.AddRange(resultsTriIndexesReversedLocal);

            uvs.AddRange(uvsLocal);
            normals.AddRange(normalsLocal);

            resultsLocal.Clear();
            resultsTriIndexesLocal.Clear();
            resultsTriIndexesReversedLocal.Clear();
            uvsLocal.Clear();
            normalsLocal.Clear();

            finalVertices = results.ToArray();

            finalNormals = normals.ToArray();
            finalUvs     = uvs.ToArray();

            finalTriangles = resultsTriIndexesReversed.ToArray();

            mesh.vertices  = finalVertices;
            mesh.triangles = finalTriangles;
            mesh.uv        = finalUvs;
            mesh.normals   = finalNormals;
            mesh           = calculateMeshTangents(mesh);
            return(mesh);
        }
コード例 #30
0
        /// <summary>
        /// Creates an extruded version of a given region
        /// </summary>
        /// <returns>The generate extrude game object.</returns>
        /// <param name="name">Name.</param>
        /// <param name="extrusionAmount">Size of the extrusion.</param>
        /// <param name="region">Region.</param>
        /// <param name="material">Material.</param>
        /// <param name="textureScale">Texture scale.</param>
        /// <param name="textureOffset">Texture offset.</param>
        /// <param name="textureRotation">Texture rotation.</param>
        public GameObject RegionGenerateExtrudeGameObject(string name, Region region, float extrusionAmount, Material topMaterial, Material sideMaterial, Vector2 textureScale, Vector2 textureOffset, float textureRotation, bool useRegionRect = true)
        {
            if (region == null || region.points.Length < 3)
            {
                return(null);
            }

            Rect       rect = useRegionRect ? region.rect2D : new Rect(0.5f, 0.5f, 1f, 1f);
            GameObject go   = new GameObject(name);

            go.transform.SetParent(transform, false);

            Poly2Tri.Polygon poly = new Poly2Tri.Polygon(region.points);
            P2T.Triangulate(poly);

            // Creates surface mesh
            GameObject surf = Drawing.CreateSurface("RegionTop", poly, topMaterial, rect, textureScale, textureOffset, textureRotation, null);

            surf.transform.SetParent(go.transform, false);
            surf.transform.localPosition = new Vector3(0, 0, -extrusionAmount);

            // Create side band
            int pointCount = region.points.Length;

            Vector3[] vertices = new Vector3[pointCount * 2];
            int[]     indices = new int[pointCount * 6];
            int       vi = 0, ii = -1;

            for (int k = 0; k < pointCount; k++, vi += 2)
            {
                vertices[vi]       = region.points[k];
                vertices[vi].z     = -extrusionAmount;
                vertices[vi + 1]   = vertices[vi];
                vertices[vi + 1].z = 0;
                if (k == pointCount - 1)
                {
                    indices[++ii] = vi + 1;
                    indices[++ii] = vi;
                    indices[++ii] = 1;
                    indices[++ii] = vi + 1;
                    indices[++ii] = 1;
                    indices[++ii] = 0;
                }
                else
                {
                    indices[++ii] = vi;
                    indices[++ii] = vi + 1;
                    indices[++ii] = vi + 2;
                    indices[++ii] = vi + 1;
                    indices[++ii] = vi + 3;
                    indices[++ii] = vi + 2;
                }
            }

            GameObject band = new GameObject("RegionBand");

            band.transform.SetParent(go.transform, false);
            Mesh mesh = new Mesh();

            mesh.vertices  = vertices;
            mesh.triangles = indices;
            mesh.RecalculateNormals();
            MeshFilter mf = band.AddComponent <MeshFilter>();

            mf.mesh = mesh;
            MeshRenderer mr = band.AddComponent <MeshRenderer>();

            mr.sharedMaterial = sideMaterial;

            if (region.entity.allowHighlight && (region.entity is Country && _enableCountryHighlight || region.entity is Province && _enableProvinceHighlight))
            {
                ExtrudedRegionInteraction interaction = go.AddComponent <ExtrudedRegionInteraction>();
                interaction.map            = this;
                interaction.region         = region;
                interaction.topMaterial    = topMaterial;
                interaction.sideMaterial   = sideMaterial;
                interaction.highlightColor = region.entity is Country ? _fillColor : _provincesFillColor;
            }
            return(go);
        }