/// <summary>Draws a wire cube after being transformed the specified transformation</summary>
            public void DrawWireCube(GraphTransform tr, Bounds bounds, Color color)
            {
                var min = bounds.min;
                var max = bounds.max;

                DrawLine(tr.Transform(new Vector3(min.x, min.y, min.z)), tr.Transform(new Vector3(max.x, min.y, min.z)),
                         color);
                DrawLine(tr.Transform(new Vector3(max.x, min.y, min.z)), tr.Transform(new Vector3(max.x, min.y, max.z)),
                         color);
                DrawLine(tr.Transform(new Vector3(max.x, min.y, max.z)), tr.Transform(new Vector3(min.x, min.y, max.z)),
                         color);
                DrawLine(tr.Transform(new Vector3(min.x, min.y, max.z)), tr.Transform(new Vector3(min.x, min.y, min.z)),
                         color);

                DrawLine(tr.Transform(new Vector3(min.x, max.y, min.z)), tr.Transform(new Vector3(max.x, max.y, min.z)),
                         color);
                DrawLine(tr.Transform(new Vector3(max.x, max.y, min.z)), tr.Transform(new Vector3(max.x, max.y, max.z)),
                         color);
                DrawLine(tr.Transform(new Vector3(max.x, max.y, max.z)), tr.Transform(new Vector3(min.x, max.y, max.z)),
                         color);
                DrawLine(tr.Transform(new Vector3(min.x, max.y, max.z)), tr.Transform(new Vector3(min.x, max.y, min.z)),
                         color);

                DrawLine(tr.Transform(new Vector3(min.x, min.y, min.z)), tr.Transform(new Vector3(min.x, max.y, min.z)),
                         color);
                DrawLine(tr.Transform(new Vector3(max.x, min.y, min.z)), tr.Transform(new Vector3(max.x, max.y, min.z)),
                         color);
                DrawLine(tr.Transform(new Vector3(max.x, min.y, max.z)), tr.Transform(new Vector3(max.x, max.y, max.z)),
                         color);
                DrawLine(tr.Transform(new Vector3(min.x, min.y, max.z)), tr.Transform(new Vector3(min.x, max.y, max.z)),
                         color);
            }
 // Token: 0x06002935 RID: 10549 RVA: 0x001BBE08 File Offset: 0x001BA008
 public GraphTransform(Matrix4x4 matrix)
 {
     this.matrix            = matrix;
     this.inverseMatrix     = matrix.inverse;
     this.identity          = matrix.isIdentity;
     this.onlyTranslational = GraphTransform.MatrixIsTranslational(matrix);
     this.up              = matrix.MultiplyVector(Vector3.up).normalized;
     this.translation     = matrix.MultiplyPoint3x4(Vector3.zero);
     this.i3translation   = (Int3)this.translation;
     this.rotation        = Quaternion.LookRotation(this.TransformVector(Vector3.forward), this.TransformVector(Vector3.up));
     this.inverseRotation = Quaternion.Inverse(this.rotation);
     this.isXY            = (this.rotation == Quaternion.Euler(-90f, 0f, 0f));
     this.isXZ            = (this.rotation == Quaternion.Euler(0f, 0f, 0f));
 }
Esempio n. 3
0
        private static List <TileHandler.Cut> PrepareNavmeshCutsForCutting(List <NavmeshCut> navmeshCuts, GraphTransform transform, IntRect cutSpaceBounds, int perturbate, bool anyNavmeshAdds)
        {
            System.Random random = null;
            if (perturbate > 0)
            {
                random = new System.Random();
            }
            List <List <Vector3> > list = ListPool <List <Vector3> > .Claim();

            List <TileHandler.Cut> list2 = ListPool <TileHandler.Cut> .Claim();

            for (int i = 0; i < navmeshCuts.Count; i++)
            {
                Int2 @int = new Int2(0, 0);
                if (perturbate > 0)
                {
                    @int.x = random.Next() % 6 * perturbate - 3 * perturbate;
                    if (@int.x >= 0)
                    {
                        @int.x++;
                    }
                    @int.y = random.Next() % 6 * perturbate - 3 * perturbate;
                    if (@int.y >= 0)
                    {
                        @int.y++;
                    }
                }
                list.Clear();
                navmeshCuts[i].GetContour(list);
                int num = (int)(navmeshCuts[i].GetY(transform) * 1000f);
                for (int j = 0; j < list.Count; j++)
                {
                    List <Vector3> list3 = list[j];
                    if (list3.Count == 0)
                    {
                        Debug.LogError("A NavmeshCut component had a zero length contour. Ignoring that contour.");
                    }
                    else
                    {
                        List <IntPoint> list4 = ListPool <IntPoint> .Claim(list3.Count);

                        for (int k = 0; k < list3.Count; k++)
                        {
                            Int3 int2 = (Int3)transform.InverseTransform(list3[k]);
                            if (perturbate > 0)
                            {
                                int2.x += @int.x;
                                int2.z += @int.y;
                            }
                            list4.Add(new IntPoint((long)int2.x, (long)int2.z));
                        }
                        IntRect bounds = new IntRect((int)list4[0].X, (int)list4[0].Y, (int)list4[0].X, (int)list4[0].Y);
                        for (int l = 0; l < list4.Count; l++)
                        {
                            IntPoint intPoint = list4[l];
                            bounds = bounds.ExpandToContain((int)intPoint.X, (int)intPoint.Y);
                        }
                        TileHandler.Cut cut  = new TileHandler.Cut();
                        int             num2 = (int)(navmeshCuts[i].height * 0.5f * 1000f);
                        cut.boundsY       = new Int2(num - num2, num + num2);
                        cut.bounds        = bounds;
                        cut.isDual        = navmeshCuts[i].isDual;
                        cut.cutsAddedGeom = navmeshCuts[i].cutsAddedGeom;
                        cut.contour       = list4;
                        list2.Add(cut);
                    }
                }
            }
            ListPool <List <Vector3> > .Release(list);

            return(list2);
        }
Esempio n. 4
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);
        }
Esempio n. 5
0
 /// <summary>Y coordinate of the center of the bounding box in graph space</summary>
 internal float GetY(Pathfinding.Util.GraphTransform transform)
 {
     return(transform.InverseTransform(useRotationAndScale ? tr.TransformPoint(center) : tr.position + center).y);
 }