Esempio n. 1
0
		/** Sets the internal navmesh holder for a given graph index.
		 * \warning Internal method
		 */
		public static void SetNavmeshHolder (int graphIndex, INavmeshHolder graph) {
			if (_navmeshHolders.Length <= graphIndex) {
				var gg = new INavmeshHolder[graphIndex+1];
				for (int i=0;i<_navmeshHolders.Length;i++) gg[i] = _navmeshHolders[i];
				_navmeshHolders = gg;
			}
			_navmeshHolders[graphIndex] = graph;
		}
Esempio n. 2
0
 public static void SetNavmeshHolder(int graphIndex, INavmeshHolder graph)
 {
     if (TriangleMeshNode._navmeshHolders.Length <= graphIndex)
     {
         INavmeshHolder[] array = new INavmeshHolder[graphIndex + 1];
         for (int i = 0; i < TriangleMeshNode._navmeshHolders.Length; i++)
         {
             array[i] = TriangleMeshNode._navmeshHolders[i];
         }
         TriangleMeshNode._navmeshHolders = array;
     }
     TriangleMeshNode._navmeshHolders[graphIndex] = graph;
 }
Esempio n. 3
0
 public static void SetNavmeshHolder(int graphIndex, INavmeshHolder graph)
 {
     if (_navmeshHolders.Length <= graphIndex)
     {
         INavmeshHolder[] gg = new INavmeshHolder[graphIndex + 1];
         for (int i = 0; i < _navmeshHolders.Length; i++)
         {
             gg[i] = _navmeshHolders[i];
         }
         _navmeshHolders = gg;
     }
     _navmeshHolders[graphIndex] = graph;
 }
Esempio n. 4
0
 public static void SetNavmeshHolder(int graphIndex, INavmeshHolder graph)
 {
     if (TriangleMeshNode._navmeshHolders.Length <= graphIndex)
     {
         INavmeshHolder[] array = new INavmeshHolder[graphIndex + 1];
         for (int i = 0; i < TriangleMeshNode._navmeshHolders.Length; i++)
         {
             array[i] = TriangleMeshNode._navmeshHolders[i];
         }
         TriangleMeshNode._navmeshHolders = array;
     }
     TriangleMeshNode._navmeshHolders[graphIndex] = graph;
 }
Esempio n. 5
0
        public override VInt3 GetVertex(int i)
        {
            VInt3 result = VInt3.zero;

            try
            {
                INavmeshHolder navmeshHolder = TriangleMeshNode.GetNavmeshHolder(this.DataGroupIndex, base.GraphIndex);
                result = navmeshHolder.GetVertex(this.GetVertexIndex(i));
            }
            catch (Exception)
            {
            }
            return(result);
        }
Esempio n. 6
0
        public override Vector3 RandomPointOnSurface()
        {
            float value;
            float value2;

            do
            {
                value  = UnityEngine.Random.value;
                value2 = UnityEngine.Random.value;
            }while (value + value2 > 1f);
            INavmeshHolder navmeshHolder = TriangleMeshNode.GetNavmeshHolder(base.GraphIndex);

            return((Vector3)(navmeshHolder.GetVertex(this.v1) - navmeshHolder.GetVertex(this.v0)) * value + (Vector3)(navmeshHolder.GetVertex(this.v2) - navmeshHolder.GetVertex(this.v0)) * value2 + (Vector3)navmeshHolder.GetVertex(this.v0));
        }
 /// <summary>
 /// Sets the internal navmesh holder for a given graph index.
 /// Warning: Internal method
 /// </summary>
 public static void SetNavmeshHolder(int graphIndex, INavmeshHolder graph)
 {
     // We need to lock to make sure that
     // the resize operation is thread safe
     lock (lockObject) {
         if (graphIndex >= _navmeshHolders.Length)
         {
             var gg = new INavmeshHolder[graphIndex + 1];
             _navmeshHolders.CopyTo(gg, 0);
             _navmeshHolders = gg;
         }
         _navmeshHolders[graphIndex] = graph;
     }
 }
        public override Vector3 RandomPointOnSurface()
        {
            float num;
            float num2;

            do
            {
                num  = UnityEngine.Random.value;
                num2 = UnityEngine.Random.value;
            }while ((num + num2) > 1f);
            INavmeshHolder navmeshHolder = GetNavmeshHolder(base.GraphIndex);

            return(((Vector3)((((Vector3)(navmeshHolder.GetVertex(this.v1) - navmeshHolder.GetVertex(this.v0))) * num) + (((Vector3)(navmeshHolder.GetVertex(this.v2) - navmeshHolder.GetVertex(this.v0))) * num2))) + ((Vector3)navmeshHolder.GetVertex(this.v0)));
        }
Esempio n. 9
0
        // Token: 0x060025EC RID: 9708 RVA: 0x001A65D4 File Offset: 0x001A47D4
        public static void SetNavmeshHolder(int graphIndex, INavmeshHolder graph)
        {
            object obj = TriangleMeshNode.lockObject;

            lock (obj)
            {
                if (graphIndex >= TriangleMeshNode._navmeshHolders.Length)
                {
                    INavmeshHolder[] array = new INavmeshHolder[graphIndex + 1];
                    TriangleMeshNode._navmeshHolders.CopyTo(array, 0);
                    TriangleMeshNode._navmeshHolders = array;
                }
                TriangleMeshNode._navmeshHolders[graphIndex] = graph;
            }
        }
Esempio n. 10
0
        public bool IsVertex(VInt3 p, out int index)
        {
            INavmeshHolder navmeshHolder = GetNavmeshHolder(base.DataGroupIndex, base.GraphIndex);

            index = -1;
            if (navmeshHolder.GetVertex(this.v0).IsEqualXZ(ref p))
            {
                index = 0;
            }
            else if (navmeshHolder.GetVertex(this.v1).IsEqualXZ(ref p))
            {
                index = 1;
            }
            else if (navmeshHolder.GetVertex(this.v2).IsEqualXZ(ref p))
            {
                index = 2;
            }
            return(index != -1);
        }
Esempio n. 11
0
        public override Vector3 ClosestPointOnNodeXZ(Vector3 p)
        {
            // Get the object holding the vertex data for this node
            // This is usually a graph or a recast graph tile
            INavmeshHolder g = GetNavmeshHolder(GraphIndex);

            // Get all 3 vertices for this node
            Int3 tp1 = g.GetVertex(v0);
            Int3 tp2 = g.GetVertex(v1);
            Int3 tp3 = g.GetVertex(v2);

            Vector2 closest = Polygon.ClosestPointOnTriangle(
                new Vector2(tp1.x * Int3.PrecisionFactor, tp1.z * Int3.PrecisionFactor),
                new Vector2(tp2.x * Int3.PrecisionFactor, tp2.z * Int3.PrecisionFactor),
                new Vector2(tp3.x * Int3.PrecisionFactor, tp3.z * Int3.PrecisionFactor),
                new Vector2(p.x, p.z)
                );

            return(new Vector3(closest.x, p.y, closest.y));
        }
Esempio n. 12
0
 /** Sets the internal navmesh holder for a given graph index.
  * \warning Internal method
  */
 public static void SetNavmeshHolder(int graphIndex, INavmeshHolder graph)
 {
     if (_navmeshHolders.Length <= graphIndex)
     {
         // We need to lock and then check again to make sure
         // that this the resize operation is thread safe
         lock (lockObject) {
             if (_navmeshHolders.Length <= graphIndex)
             {
                 var gg = new INavmeshHolder[graphIndex + 1];
                 for (int i = 0; i < _navmeshHolders.Length; i++)
                 {
                     gg[i] = _navmeshHolders[i];
                 }
                 _navmeshHolders = gg;
             }
         }
     }
     _navmeshHolders[graphIndex] = graph;
 }
Esempio n. 13
0
        public override Vector3d ClosestPointOnNodeXZ(Vector3d p)
        {
            // Get the object holding the vertex data for this node
            // This is usually a graph or a recast graph tile
            INavmeshHolder g = GetNavmeshHolder(GraphIndex);

            // Get all 3 vertices for this node
            Int3 tp1 = g.GetVertex(v0);
            Int3 tp2 = g.GetVertex(v1);
            Int3 tp3 = g.GetVertex(v2);

            Vector2d closest = Polygon.ClosestPointOnTriangle(
                new Vector2d(((long)tp1.x) * FixedMath.One / 1000, ((long)tp1.z) * FixedMath.One / 1000),
                new Vector2d(((long)tp2.x) * FixedMath.One / 1000, ((long)tp2.z) * FixedMath.One / 1000),
                new Vector2d(((long)tp3.x) * FixedMath.One / 1000, ((long)tp3.z) * FixedMath.One / 1000),
                new Vector2d(p.x, p.z)
                );

            return(new Vector3d(closest.x, 0, closest.y));
        }
Esempio n. 14
0
 public static void SetNavmeshHolder(int graphIndex, INavmeshHolder graph)
 {
     if (_navmeshHolders.Length <= graphIndex)
     {
         object lockObject = TriangleMeshNode.lockObject;
         lock (lockObject)
         {
             if (_navmeshHolders.Length <= graphIndex)
             {
                 INavmeshHolder[] holderArray = new INavmeshHolder[graphIndex + 1];
                 for (int i = 0; i < _navmeshHolders.Length; i++)
                 {
                     holderArray[i] = _navmeshHolders[i];
                 }
                 _navmeshHolders = holderArray;
             }
         }
     }
     _navmeshHolders[graphIndex] = graph;
 }
Esempio n. 15
0
        public override bool ContainsPoint(VInt3 p)
        {
            INavmeshHolder navmeshHolder = GetNavmeshHolder(base.DataGroupIndex, base.GraphIndex);
            VInt3          vertex        = navmeshHolder.GetVertex(this.v0);
            VInt3          num2          = navmeshHolder.GetVertex(this.v1);
            VInt3          num3          = navmeshHolder.GetVertex(this.v2);

            if ((((num2.x - vertex.x) * (p.z - vertex.z)) - ((p.x - vertex.x) * (num2.z - vertex.z))) > 0L)
            {
                return(false);
            }
            if ((((num3.x - num2.x) * (p.z - num2.z)) - ((p.x - num2.x) * (num3.z - num2.z))) > 0L)
            {
                return(false);
            }
            if ((((vertex.x - num3.x) * (p.z - num3.z)) - ((p.x - num3.x) * (vertex.z - num3.z))) > 0L)
            {
                return(false);
            }
            return(true);
        }
Esempio n. 16
0
 public static void SetNavmeshHolder(int dataGroupIndex, int graphIndex, INavmeshHolder graph)
 {
     if (dataGroupIndex >= _navmeshHolders.Count)
     {
         for (int i = _navmeshHolders.Count; i <= dataGroupIndex; i++)
         {
             _navmeshHolders.Add(new INavmeshHolder[0]);
         }
     }
     if (_navmeshHolders[dataGroupIndex].Length <= graphIndex)
     {
         INavmeshHolder[] holderArray  = new INavmeshHolder[graphIndex + 1];
         INavmeshHolder[] holderArray2 = _navmeshHolders[dataGroupIndex];
         for (int j = 0; j < holderArray2.Length; j++)
         {
             holderArray[j] = holderArray2[j];
         }
         _navmeshHolders[dataGroupIndex] = holderArray;
     }
     _navmeshHolders[dataGroupIndex][graphIndex] = (INavmeshHolder[])graph;
 }
Esempio n. 17
0
 public static void SetNavmeshHolder(int dataGroupIndex, int graphIndex, INavmeshHolder graph)
 {
     if (dataGroupIndex >= TriangleMeshNode._navmeshHolders.Count)
     {
         for (int i = TriangleMeshNode._navmeshHolders.Count; i <= dataGroupIndex; i++)
         {
             TriangleMeshNode._navmeshHolders.Add(new INavmeshHolder[0]);
         }
     }
     if (TriangleMeshNode._navmeshHolders[dataGroupIndex].Length <= graphIndex)
     {
         INavmeshHolder[] array  = new INavmeshHolder[graphIndex + 1];
         INavmeshHolder[] array2 = TriangleMeshNode._navmeshHolders[dataGroupIndex];
         for (int j = 0; j < array2.Length; j++)
         {
             array[j] = array2[j];
         }
         TriangleMeshNode._navmeshHolders[dataGroupIndex] = array;
     }
     TriangleMeshNode._navmeshHolders[dataGroupIndex][graphIndex] = graph;
 }
Esempio n. 18
0
        public bool GetPortal(GraphNode toNode, System.Collections.Generic.List <Vector3> left, System.Collections.Generic.List <Vector3> right, bool backwards, out int aIndex, out int bIndex)
        {
            aIndex = -1;
            bIndex = -1;

            //If the nodes are in different graphs, this function has no idea on how to find a shared edge.
            if (backwards || toNode.GraphIndex != GraphIndex)
            {
                return(false);
            }

            // Since the nodes are in the same graph, they are both TriangleMeshNodes
            // So we don't need to care about other types of nodes
            var toTriNode = toNode as TriangleMeshNode;
            var edge      = SharedEdge(toTriNode);

            // A connection was found, but it specifically didn't use an edge
            if (edge == 0xFF)
            {
                return(false);
            }

            // No connection was found between the nodes
            // Check if there is a node link that connects them
            if (edge == -1)
            {
#if !ASTAR_NO_POINT_GRAPH
                if (connections != null)
                {
                    for (int i = 0; i < connections.Length; i++)
                    {
                        if (connections[i].node.GraphIndex != GraphIndex)
                        {
                            var mid = connections[i].node as NodeLink3Node;
                            if (mid != null && mid.GetOther(this) == toTriNode)
                            {
                                // We have found a node which is connected through a NodeLink3Node
                                mid.GetPortal(toTriNode, left, right, false);
                                return(true);
                            }
                        }
                    }
                }
#endif

                return(false);
            }

            aIndex = edge;
            bIndex = (edge + 1) % GetVertexCount();

            // Get the vertices of the shared edge for the first node
            Int3 v1a = GetVertex(edge);
            Int3 v1b = GetVertex((edge + 1) % GetVertexCount());

            // Get tile indices
            int tileIndex1 = (GetVertexIndex(0) >> NavmeshBase.TileIndexOffset) & NavmeshBase.TileIndexMask;
            int tileIndex2 = (toTriNode.GetVertexIndex(0) >> NavmeshBase.TileIndexOffset) & NavmeshBase.TileIndexMask;

            if (tileIndex1 != tileIndex2)
            {
                // When the nodes are in different tiles, the edges might not be completely identical
                // so another technique is needed.

                // Get the tile coordinates, from them we can figure out which edge is going to be shared
                int            x1, x2, z1, z2, coord;
                INavmeshHolder nm = GetNavmeshHolder(GraphIndex);
                nm.GetTileCoordinates(tileIndex1, out x1, out z1);
                nm.GetTileCoordinates(tileIndex2, out x2, out z2);

                if (System.Math.Abs(x1 - x2) == 1)
                {
                    coord = 2;
                }
                else if (System.Math.Abs(z1 - z2) == 1)
                {
                    coord = 0;
                }
                else
                {
                    return(false);                 // Tiles are not adjacent. This is likely a custom connection between two nodes.
                }
                var otherEdge = toTriNode.SharedEdge(this);

                // A connection was found, but it specifically didn't use an edge. This is odd since the connection in the other direction did use an edge
                if (otherEdge == 0xFF)
                {
                    throw new System.Exception("Connection used edge in one direction, but not in the other direction. Has the wrong overload of AddConnection been used?");
                }

                // If it is -1 then it must be a one-way connection. Fall back to using the whole edge
                if (otherEdge != -1)
                {
                    // When the nodes are in different tiles, they might not share exactly the same edge
                    // so we clamp the portal to the segment of the edges which they both have.
                    int mincoord = System.Math.Min(v1a[coord], v1b[coord]);
                    int maxcoord = System.Math.Max(v1a[coord], v1b[coord]);

                    // Get the vertices of the shared edge for the second node
                    Int3 v2a = toTriNode.GetVertex(otherEdge);
                    Int3 v2b = toTriNode.GetVertex((otherEdge + 1) % toTriNode.GetVertexCount());

                    mincoord = System.Math.Max(mincoord, System.Math.Min(v2a[coord], v2b[coord]));
                    maxcoord = System.Math.Min(maxcoord, System.Math.Max(v2a[coord], v2b[coord]));

                    if (v1a[coord] < v1b[coord])
                    {
                        v1a[coord] = mincoord;
                        v1b[coord] = maxcoord;
                    }
                    else
                    {
                        v1a[coord] = maxcoord;
                        v1b[coord] = mincoord;
                    }
                }
            }

            if (left != null)
            {
                // All triangles should be laid out in clockwise order so v1b is the rightmost vertex (seen from this node)
                left.Add((Vector3)v1a);
                right.Add((Vector3)v1b);
            }
            return(true);
        }
        public override Vector3 ClosestPointOnNodeXZ(Vector3 _p)
        {
            // Get the object holding the vertex data for this node
            // This is usually a graph or a recast graph tile
            INavmeshHolder g = GetNavmeshHolder(GraphIndex);

            // Get all 3 vertices for this node
            Int3 tp1 = g.GetVertex(v0);
            Int3 tp2 = g.GetVertex(v1);
            Int3 tp3 = g.GetVertex(v2);

            // We need the point as an Int3
            Int3 p = (Int3)_p;

            // Save the original y coordinate, we will return a point with the same y coordinate
            int oy = p.y;

            // Assumes the triangle vertices are laid out in (counter?)clockwise order

            tp1.y = 0;
            tp2.y = 0;
            tp3.y = 0;
            p.y   = 0;

            if ((long)(tp2.x - tp1.x) * (long)(p.z - tp1.z) - (long)(p.x - tp1.x) * (long)(tp2.z - tp1.z) > 0)
            {
                float f = Mathf.Clamp01(AstarMath.NearestPointFactor(tp1, tp2, p));
                return(new Vector3(tp1.x + (tp2.x - tp1.x) * f, oy, tp1.z + (tp2.z - tp1.z) * f) * Int3.PrecisionFactor);
            }
            else if ((long)(tp3.x - tp2.x) * (long)(p.z - tp2.z) - (long)(p.x - tp2.x) * (long)(tp3.z - tp2.z) > 0)
            {
                float f = Mathf.Clamp01(AstarMath.NearestPointFactor(tp2, tp3, p));
                return(new Vector3(tp2.x + (tp3.x - tp2.x) * f, oy, tp2.z + (tp3.z - tp2.z) * f) * Int3.PrecisionFactor);
            }
            else if ((long)(tp1.x - tp3.x) * (long)(p.z - tp3.z) - (long)(p.x - tp3.x) * (long)(tp1.z - tp3.z) > 0)
            {
                float f = Mathf.Clamp01(AstarMath.NearestPointFactor(tp3, tp1, p));
                return(new Vector3(tp3.x + (tp1.x - tp3.x) * f, oy, tp3.z + (tp1.z - tp3.z) * f) * Int3.PrecisionFactor);
            }
            else
            {
                return(_p);
            }

            /*
             * Equivalent to the above, but the above uses manual inlining
             * if (!Polygon.Left (tp1, tp2, p)) {
             *      float f = Mathf.Clamp01 (AstarMath.NearestPointFactor (tp1, tp2, p));
             *      return new Vector3(tp1.x + (tp2.x-tp1.x)*f, oy, tp1.z + (tp2.z-tp1.z)*f)*Int3.PrecisionFactor;
             * } else if (!Polygon.Left (tp2, tp3, p)) {
             *      float f = Mathf.Clamp01 (AstarMath.NearestPointFactor (tp2, tp3, p));
             *      return new Vector3(tp2.x + (tp3.x-tp2.x)*f, oy, tp2.z + (tp3.z-tp2.z)*f)*Int3.PrecisionFactor;
             * } else if (!Polygon.Left (tp3, tp1, p)) {
             *      float f = Mathf.Clamp01 (AstarMath.NearestPointFactor (tp3, tp1, p));
             *      return new Vector3(tp3.x + (tp1.x-tp3.x)*f, oy, tp3.z + (tp1.z-tp3.z)*f)*Int3.PrecisionFactor;
             * } else {
             *      return _p;
             * }*/

            /* Almost equivalent to the above, but this is slower
             * Vector3 tp1 = (Vector3)g.GetVertex(v0);
             * Vector3 tp2 = (Vector3)g.GetVertex(v1);
             * Vector3 tp3 = (Vector3)g.GetVertex(v2);
             * tp1.y = 0;
             * tp2.y = 0;
             * tp3.y = 0;
             * _p.y = 0;
             * return Pathfinding.Polygon.ClosestPointOnTriangle (tp1,tp2,tp3,_p);*/
        }
Esempio n. 20
0
        /** This performs a linear search through all polygons returning the closest one.
         * This will fill the NNInfo with .node for the closest node not necessarily complying with the NNConstraint, and .constrainedNode with the closest node
         * complying with the NNConstraint.
         * \see GetNearestForce(Node[],Int3[],Vector3,NNConstraint,bool)
         */
        public static NNInfo GetNearestForceBoth(NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode)
        {
            Int3 pos = (Int3)position;

            float     minDist = -1;
            GraphNode minNode = null;

            float     minConstDist = -1;
            GraphNode minConstNode = null;

            float maxDistSqr = constraint.constrainDistance ? AstarPath.active.maxNearestNodeDistanceSqr : float.PositiveInfinity;

            GraphNodeDelegateCancelable del = delegate(GraphNode _node) {
                TriangleMeshNode node = _node as TriangleMeshNode;

                if (accurateNearestNode)
                {
                    Vector3 closest = node.ClosestPointOnNode(position);
                    float   dist    = ((Vector3)pos - closest).sqrMagnitude;

                    if (minNode == null || dist < minDist)
                    {
                        minDist = dist;
                        minNode = node;
                    }

                    if (dist < maxDistSqr && constraint.Suitable(node))
                    {
                        if (minConstNode == null || dist < minConstDist)
                        {
                            minConstDist = dist;
                            minConstNode = node;
                        }
                    }
                }
                else
                {
                    if (!node.ContainsPoint((Int3)position))
                    {
                        float dist = (node.position - pos).sqrMagnitude;
                        if (minNode == null || dist < minDist)
                        {
                            minDist = dist;
                            minNode = node;
                        }

                        if (dist < maxDistSqr && constraint.Suitable(node))
                        {
                            if (minConstNode == null || dist < minConstDist)
                            {
                                minConstDist = dist;
                                minConstNode = node;
                            }
                        }
                    }
                    else
                    {
                        int dist = AstarMath.Abs(node.position.y - pos.y);

                        if (minNode == null || dist < minDist)
                        {
                            minDist = dist;
                            minNode = node;
                        }

                        if (dist < maxDistSqr && constraint.Suitable(node))
                        {
                            if (minConstNode == null || dist < minConstDist)
                            {
                                minConstDist = dist;
                                minConstNode = node;
                            }
                        }
                    }
                }
                return(true);
            };

            graph.GetNodes(del);

            NNInfo nninfo = new NNInfo(minNode);

            //Find the point closest to the nearest triangle

            if (nninfo.node != null)
            {
                TriangleMeshNode node = nninfo.node as TriangleMeshNode;                //minNode2 as MeshNode;

                Vector3 clP = node.ClosestPointOnNode(position);

                nninfo.clampedPosition = clP;
            }

            nninfo.constrainedNode = minConstNode;
            if (nninfo.constrainedNode != null)
            {
                TriangleMeshNode node = nninfo.constrainedNode as TriangleMeshNode;                //minNode2 as MeshNode;

                Vector3 clP = node.ClosestPointOnNode(position);

                nninfo.constClampedPosition = clP;
            }

            return(nninfo);
        }
        /** Set the position of this node to the average of its 3 vertices */
        public void UpdatePositionFromVertices()
        {
            INavmeshHolder g = GetNavmeshHolder(GraphIndex);

            position = (g.GetVertex(v0) + g.GetVertex(v1) + g.GetVertex(v2)) * 0.333333f;
        }
        public override Vector3 ClosestPointOnNode(Vector3 p)
        {
            INavmeshHolder g = GetNavmeshHolder(GraphIndex);

            return(Pathfinding.Polygon.ClosestPointOnTriangle((Vector3)g.GetVertex(v0), (Vector3)g.GetVertex(v1), (Vector3)g.GetVertex(v2), p));
        }
Esempio n. 23
0
        public void UpdatePositionFromVertices()
        {
            INavmeshHolder navmeshHolder = GetNavmeshHolder(base.DataGroupIndex, base.GraphIndex);

            base.position = (VInt3)(((navmeshHolder.GetVertex(this.v0) + navmeshHolder.GetVertex(this.v1)) + navmeshHolder.GetVertex(this.v2)) * 0.333333f);
        }
Esempio n. 24
0
        public static NNInfo GetNearestForceBoth(NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode)
        {
            Int3      pos                   = (Int3)position;
            float     minDist               = -1f;
            GraphNode minNode               = null;
            float     minConstDist          = -1f;
            GraphNode minConstNode          = null;
            float     maxDistSqr            = (!constraint.constrainDistance) ? float.PositiveInfinity : AstarPath.active.maxNearestNodeDistanceSqr;
            GraphNodeDelegateCancelable del = delegate(GraphNode _node)
            {
                TriangleMeshNode triangleMeshNode3 = _node as TriangleMeshNode;
                if (accurateNearestNode)
                {
                    Vector3 b            = triangleMeshNode3.ClosestPointOnNode(position);
                    float   sqrMagnitude = ((Vector3)pos - b).sqrMagnitude;
                    if (minNode == null || sqrMagnitude < minDist)
                    {
                        minDist = sqrMagnitude;
                        minNode = triangleMeshNode3;
                    }
                    if (sqrMagnitude < maxDistSqr && constraint.Suitable(triangleMeshNode3) && (minConstNode == null || sqrMagnitude < minConstDist))
                    {
                        minConstDist = sqrMagnitude;
                        minConstNode = triangleMeshNode3;
                    }
                }
                else if (!triangleMeshNode3.ContainsPoint((Int3)position))
                {
                    float sqrMagnitude2 = (triangleMeshNode3.position - pos).sqrMagnitude;
                    if (minNode == null || sqrMagnitude2 < minDist)
                    {
                        minDist = sqrMagnitude2;
                        minNode = triangleMeshNode3;
                    }
                    if (sqrMagnitude2 < maxDistSqr && constraint.Suitable(triangleMeshNode3) && (minConstNode == null || sqrMagnitude2 < minConstDist))
                    {
                        minConstDist = sqrMagnitude2;
                        minConstNode = triangleMeshNode3;
                    }
                }
                else
                {
                    int num = AstarMath.Abs(triangleMeshNode3.position.y - pos.y);
                    if (minNode == null || (float)num < minDist)
                    {
                        minDist = (float)num;
                        minNode = triangleMeshNode3;
                    }
                    if ((float)num < maxDistSqr && constraint.Suitable(triangleMeshNode3) && (minConstNode == null || (float)num < minConstDist))
                    {
                        minConstDist = (float)num;
                        minConstNode = triangleMeshNode3;
                    }
                }
                return(true);
            };

            graph.GetNodes(del);
            NNInfo result = new NNInfo(minNode);

            if (result.node != null)
            {
                TriangleMeshNode triangleMeshNode = result.node as TriangleMeshNode;
                Vector3          clampedPosition  = triangleMeshNode.ClosestPointOnNode(position);
                result.clampedPosition = clampedPosition;
            }
            result.constrainedNode = minConstNode;
            if (result.constrainedNode != null)
            {
                TriangleMeshNode triangleMeshNode2    = result.constrainedNode as TriangleMeshNode;
                Vector3          constClampedPosition = triangleMeshNode2.ClosestPointOnNode(position);
                result.constClampedPosition = constClampedPosition;
            }
            return(result);
        }
Esempio n. 25
0
		/** This performs a linear search through all polygons returning the closest one.
		  * This will fill the NNInfo with .node for the closest node not necessarily complying with the NNConstraint, and .constrainedNode with the closest node
		  * complying with the NNConstraint.
		  * \see GetNearestForce(Node[],Int3[],Vector3,NNConstraint,bool)
		  */
		public static NNInfo GetNearestForceBoth (NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode) {
			Int3 pos = (Int3)position;
			
			float minDist = -1;
			GraphNode minNode = null;
			
			float minConstDist = -1;
			GraphNode minConstNode = null;
			
			float maxDistSqr = constraint.constrainDistance ? AstarPath.active.maxNearestNodeDistanceSqr : float.PositiveInfinity;
			
			GraphNodeDelegateCancelable del = delegate (GraphNode _node) {
				TriangleMeshNode node = _node as TriangleMeshNode;
				
				if (accurateNearestNode) {
					
					Vector3 closest = node.ClosestPointOnNode (position);
					float dist = ((Vector3)pos-closest).sqrMagnitude;
					
					if (minNode == null || dist < minDist) {
						minDist = dist;
						minNode = node;
					}
					
					if (dist < maxDistSqr && constraint.Suitable (node)) {
						if (minConstNode == null || dist < minConstDist) {
							minConstDist = dist;
							minConstNode = node;
						}
					}
					
				} else {
					
					if (!node.ContainsPoint ((Int3)position)) {
						
						float dist = (node.position-pos).sqrMagnitude;
						if (minNode == null || dist < minDist) {
							minDist = dist;
							minNode = node;
						}
						
						if (dist < maxDistSqr && constraint.Suitable (node)) {
							if (minConstNode == null || dist < minConstDist) {
								minConstDist = dist;
								minConstNode = node;
							}
						}
						
					} else {
					
#if ASTARDEBUG
						Debug.DrawLine ((Vector3)vertices[node.v0],(Vector3)vertices[node.v1],Color.blue);
						Debug.DrawLine ((Vector3)vertices[node.v1],(Vector3)vertices[node.v2],Color.blue);
						Debug.DrawLine ((Vector3)vertices[node.v2],(Vector3)vertices[node.v0],Color.blue);
#endif
						
						int dist = AstarMath.Abs (node.position.y-pos.y);
						
						if (minNode == null || dist < minDist) {
							minDist = dist;
							minNode = node;
						}
						
						if (dist < maxDistSqr && constraint.Suitable (node)) {
							if (minConstNode == null || dist < minConstDist) {
								minConstDist = dist;
								minConstNode = node;
							}
						}
					}
				}
				return true;
			};
			
			graph.GetNodes (del);
			
			NNInfo nninfo = new NNInfo (minNode);
			
			//Find the point closest to the nearest triangle
				
			if (nninfo.node != null) {
				TriangleMeshNode node = nninfo.node as TriangleMeshNode;//minNode2 as MeshNode;
				
				Vector3 clP = node.ClosestPointOnNode (position);
				
				nninfo.clampedPosition = clP;
			}
			
			nninfo.constrainedNode = minConstNode;
			if (nninfo.constrainedNode != null) {
				TriangleMeshNode node = nninfo.constrainedNode as TriangleMeshNode;//minNode2 as MeshNode;
				
				Vector3 clP = node.ClosestPointOnNode (position);
				
				nninfo.constClampedPosition = clP;
			}
			
			return nninfo;
		}
        public bool GetPortal(GraphNode _other, System.Collections.Generic.List <Vector3> left, System.Collections.Generic.List <Vector3> right, bool backwards, out int aIndex, out int bIndex)
        {
            aIndex = -1;
            bIndex = -1;

            //If the nodes are in different graphs, this function has no idea on how to find a shared edge.
            if (_other.GraphIndex != GraphIndex)
            {
                return(false);
            }

            TriangleMeshNode other = _other as TriangleMeshNode;

            //Get tile indices
            int tileIndex  = (GetVertexIndex(0) >> RecastGraph.TileIndexOffset) & RecastGraph.TileIndexMask;
            int tileIndex2 = (other.GetVertexIndex(0) >> RecastGraph.TileIndexOffset) & RecastGraph.TileIndexMask;

            //When the nodes are in different tiles, the edges might not be completely identical
            //so another technique is needed
            //Only do this on recast graphs
            if (tileIndex != tileIndex2 && (GetNavmeshHolder(GraphIndex) is RecastGraph))
            {
                for (int i = 0; i < connections.Length; i++)
                {
                    if (connections[i].GraphIndex != GraphIndex)
                    {
#if !ASTAR_NO_POINT_GRAPH
                        NodeLink3Node mid = connections[i] as NodeLink3Node;
                        if (mid != null && mid.GetOther(this) == other)
                        {
                            // We have found a node which is connected through a NodeLink3Node

                            if (left != null)
                            {
                                mid.GetPortal(other, left, right, false);
                                return(true);
                            }
                        }
#endif
                    }
                }

                //Get the tile coordinates, from them we can figure out which edge is going to be shared
                int            x1, x2, z1, z2;
                int            coord;
                INavmeshHolder nm = GetNavmeshHolder(GraphIndex);
                nm.GetTileCoordinates(tileIndex, out x1, out z1);
                nm.GetTileCoordinates(tileIndex2, out x2, out z2);

                if (System.Math.Abs(x1 - x2) == 1)
                {
                    coord = 0;
                }
                else if (System.Math.Abs(z1 - z2) == 1)
                {
                    coord = 2;
                }
                else
                {
                    throw new System.Exception("Tiles not adjacent (" + x1 + ", " + z1 + ") (" + x2 + ", " + z2 + ")");
                }

                int av = GetVertexCount();
                int bv = other.GetVertexCount();

                //Try the X and Z coordinate. For one of them the coordinates should be equal for one of the two nodes' edges
                //The midpoint between the tiles is the only place where they will be equal

                int first = -1, second = -1;

                //Find the shared edge
                for (int a = 0; a < av; a++)
                {
                    int va = GetVertex(a)[coord];
                    for (int b = 0; b < bv; b++)
                    {
                        if (va == other.GetVertex((b + 1) % bv)[coord] && GetVertex((a + 1) % av)[coord] == other.GetVertex(b)[coord])
                        {
                            first  = a;
                            second = b;
                            a      = av;
                            break;
                        }
                    }
                }

                aIndex = first;
                bIndex = second;

                if (first != -1)
                {
                    Int3 a = GetVertex(first);
                    Int3 b = GetVertex((first + 1) % av);

                    //The coordinate which is not the same for the vertices
                    int ocoord = coord == 2 ? 0 : 2;

                    //When the nodes are in different tiles, they might not share exactly the same edge
                    //so we clamp the portal to the segment of the edges which they both have.
                    int mincoord = System.Math.Min(a[ocoord], b[ocoord]);
                    int maxcoord = System.Math.Max(a[ocoord], b[ocoord]);

                    mincoord = System.Math.Max(mincoord, System.Math.Min(other.GetVertex(second)[ocoord], other.GetVertex((second + 1) % bv)[ocoord]));
                    maxcoord = System.Math.Min(maxcoord, System.Math.Max(other.GetVertex(second)[ocoord], other.GetVertex((second + 1) % bv)[ocoord]));

                    if (a[ocoord] < b[ocoord])
                    {
                        a[ocoord] = mincoord;
                        b[ocoord] = maxcoord;
                    }
                    else
                    {
                        a[ocoord] = maxcoord;
                        b[ocoord] = mincoord;
                    }

                    if (left != null)
                    {
                        //All triangles should be clockwise so second is the rightmost vertex (seen from this node)
                        left.Add((Vector3)a);
                        right.Add((Vector3)b);
                    }
                    return(true);
                }
            }
            else
            if (!backwards)
            {
                int first  = -1;
                int second = -1;

                int av = GetVertexCount();
                int bv = other.GetVertexCount();

                /** \todo Maybe optimize with pa=av-1 instead of modulus... */
                for (int a = 0; a < av; a++)
                {
                    int va = GetVertexIndex(a);
                    for (int b = 0; b < bv; b++)
                    {
                        if (va == other.GetVertexIndex((b + 1) % bv) && GetVertexIndex((a + 1) % av) == other.GetVertexIndex(b))
                        {
                            first  = a;
                            second = b;
                            a      = av;
                            break;
                        }
                    }
                }

                aIndex = first;
                bIndex = second;

                if (first != -1)
                {
                    if (left != null)
                    {
                        //All triangles should be clockwise so second is the rightmost vertex (seen from this node)
                        left.Add((Vector3)GetVertex(first));
                        right.Add((Vector3)GetVertex((first + 1) % av));
                    }
                }
                else
                {
                    for (int i = 0; i < connections.Length; i++)
                    {
                        if (connections[i].GraphIndex != GraphIndex)
                        {
#if !ASTAR_NO_POINT_GRAPH
                            NodeLink3Node mid = connections[i] as NodeLink3Node;
                            if (mid != null && mid.GetOther(this) == other)
                            {
                                // We have found a node which is connected through a NodeLink3Node

                                if (left != null)
                                {
                                    mid.GetPortal(other, left, right, false);
                                    return(true);
                                }
                            }
#endif
                        }
                    }
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 27
0
        public bool GetPortal(GraphNode _other, List <Vector3> left, List <Vector3> right, bool backwards, out int aIndex, out int bIndex)
        {
            aIndex = -1;
            bIndex = -1;
            if (_other.GraphIndex != base.GraphIndex)
            {
                return(false);
            }
            TriangleMeshNode triangleMeshNode = _other as TriangleMeshNode;
            int num  = this.GetVertexIndex(0) >> 12 & 524287;
            int num2 = triangleMeshNode.GetVertexIndex(0) >> 12 & 524287;

            if (num != num2 && TriangleMeshNode.GetNavmeshHolder(base.GraphIndex) is RecastGraph)
            {
                for (int i = 0; i < this.connections.Length; i++)
                {
                    if (this.connections[i].GraphIndex != base.GraphIndex)
                    {
                        NodeLink3Node nodeLink3Node = this.connections[i] as NodeLink3Node;
                        if (nodeLink3Node != null && nodeLink3Node.GetOther(this) == triangleMeshNode && left != null)
                        {
                            nodeLink3Node.GetPortal(triangleMeshNode, left, right, false);
                            return(true);
                        }
                    }
                }
                INavmeshHolder navmeshHolder = TriangleMeshNode.GetNavmeshHolder(base.GraphIndex);
                int            num3;
                int            num4;
                navmeshHolder.GetTileCoordinates(num, out num3, out num4);
                int num5;
                int num6;
                navmeshHolder.GetTileCoordinates(num2, out num5, out num6);
                int num7;
                if (Math.Abs(num3 - num5) == 1)
                {
                    num7 = 0;
                }
                else
                {
                    if (Math.Abs(num4 - num6) != 1)
                    {
                        throw new Exception(string.Concat(new object[]
                        {
                            "Tiles not adjacent (",
                            num3,
                            ", ",
                            num4,
                            ") (",
                            num5,
                            ", ",
                            num6,
                            ")"
                        }));
                    }
                    num7 = 2;
                }
                int vertexCount  = this.GetVertexCount();
                int vertexCount2 = triangleMeshNode.GetVertexCount();
                int num8         = -1;
                int num9         = -1;
                for (int j = 0; j < vertexCount; j++)
                {
                    int num10 = this.GetVertex(j)[num7];
                    for (int k = 0; k < vertexCount2; k++)
                    {
                        if (num10 == triangleMeshNode.GetVertex((k + 1) % vertexCount2)[num7] && this.GetVertex((j + 1) % vertexCount)[num7] == triangleMeshNode.GetVertex(k)[num7])
                        {
                            num8 = j;
                            num9 = k;
                            j    = vertexCount;
                            break;
                        }
                    }
                }
                aIndex = num8;
                bIndex = num9;
                if (num8 != -1)
                {
                    Int3 vertex  = this.GetVertex(num8);
                    Int3 vertex2 = this.GetVertex((num8 + 1) % vertexCount);
                    int  i2      = (num7 != 2) ? 2 : 0;
                    int  num11   = Math.Min(vertex[i2], vertex2[i2]);
                    int  num12   = Math.Max(vertex[i2], vertex2[i2]);
                    num11 = Math.Max(num11, Math.Min(triangleMeshNode.GetVertex(num9)[i2], triangleMeshNode.GetVertex((num9 + 1) % vertexCount2)[i2]));
                    num12 = Math.Min(num12, Math.Max(triangleMeshNode.GetVertex(num9)[i2], triangleMeshNode.GetVertex((num9 + 1) % vertexCount2)[i2]));
                    if (vertex[i2] < vertex2[i2])
                    {
                        vertex[i2]  = num11;
                        vertex2[i2] = num12;
                    }
                    else
                    {
                        vertex[i2]  = num12;
                        vertex2[i2] = num11;
                    }
                    if (left != null)
                    {
                        left.Add((Vector3)vertex);
                        right.Add((Vector3)vertex2);
                    }
                    return(true);
                }
            }
            else if (!backwards)
            {
                int num13        = -1;
                int num14        = -1;
                int vertexCount3 = this.GetVertexCount();
                int vertexCount4 = triangleMeshNode.GetVertexCount();
                for (int l = 0; l < vertexCount3; l++)
                {
                    int vertexIndex = this.GetVertexIndex(l);
                    for (int m = 0; m < vertexCount4; m++)
                    {
                        if (vertexIndex == triangleMeshNode.GetVertexIndex((m + 1) % vertexCount4) && this.GetVertexIndex((l + 1) % vertexCount3) == triangleMeshNode.GetVertexIndex(m))
                        {
                            num13 = l;
                            num14 = m;
                            l     = vertexCount3;
                            break;
                        }
                    }
                }
                aIndex = num13;
                bIndex = num14;
                if (num13 == -1)
                {
                    for (int n = 0; n < this.connections.Length; n++)
                    {
                        if (this.connections[n].GraphIndex != base.GraphIndex)
                        {
                            NodeLink3Node nodeLink3Node2 = this.connections[n] as NodeLink3Node;
                            if (nodeLink3Node2 != null && nodeLink3Node2.GetOther(this) == triangleMeshNode && left != null)
                            {
                                nodeLink3Node2.GetPortal(triangleMeshNode, left, right, false);
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                if (left != null)
                {
                    left.Add((Vector3)this.GetVertex(num13));
                    right.Add((Vector3)this.GetVertex((num13 + 1) % vertexCount3));
                }
            }
            return(true);
        }
Esempio n. 28
0
		/** This performs a linear search through all polygons returning the closest one */
		public static NNInfo GetNearestForce (NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode) {
			NNInfo nn = GetNearestForceBoth (graph, navmesh,position,constraint,accurateNearestNode);
			nn.node = nn.constrainedNode;
			nn.clampedPosition = nn.constClampedPosition;
			return nn;
		}
Esempio n. 29
0
        public void UpdatePositionFromVertices()
        {
            INavmeshHolder navmeshHolder = TriangleMeshNode.GetNavmeshHolder(base.GraphIndex);

            this.position = (navmeshHolder.GetVertex(this.v0) + navmeshHolder.GetVertex(this.v1) + navmeshHolder.GetVertex(this.v2)) * 0.333333f;
        }
Esempio n. 30
0
 public static NNInfoInternal GetNearestForceBoth(NavGraph graph, INavmeshHolder navmesh, Vector3 position, NNConstraint constraint, bool accurateNearestNode)
 {
Esempio n. 31
0
        public override Vector3 ClosestPointOnNode(Vector3 p)
        {
            INavmeshHolder navmeshHolder = GetNavmeshHolder(base.DataGroupIndex, base.GraphIndex);

            return(Polygon.ClosestPointOnTriangle((Vector3)navmeshHolder.GetVertex(this.v0), (Vector3)navmeshHolder.GetVertex(this.v1), (Vector3)navmeshHolder.GetVertex(this.v2), p));
        }
Esempio n. 32
0
		public BBTree (INavmeshHolder graph) {
			this.graph = graph;
		}
        public override Vector3 ClosestPointOnNodeXZ(Vector3 _p)
        {
            INavmeshHolder g   = GetNavmeshHolder(GraphIndex);
            Int3           tp1 = g.GetVertex(v0);
            Int3           tp2 = g.GetVertex(v1);
            Int3           tp3 = g.GetVertex(v2);

            Int3 p  = (Int3)_p;
            int  oy = p.y;

            // Assumes the triangle vertices are laid out in (counter?)clockwise order

            tp1.y = 0;
            tp2.y = 0;
            tp3.y = 0;
            p.y   = 0;

            if ((long)(tp2.x - tp1.x) * (long)(p.z - tp1.z) - (long)(p.x - tp1.x) * (long)(tp2.z - tp1.z) > 0)
            {
                float f = Mathf.Clamp01(AstarMath.NearestPointFactor(tp1, tp2, p));
                return(new Vector3(tp1.x + (tp2.x - tp1.x) * f, oy, tp1.z + (tp2.z - tp1.z) * f) * Int3.PrecisionFactor);
            }
            else if ((long)(tp3.x - tp2.x) * (long)(p.z - tp2.z) - (long)(p.x - tp2.x) * (long)(tp3.z - tp2.z) > 0)
            {
                float f = Mathf.Clamp01(AstarMath.NearestPointFactor(tp2, tp3, p));
                return(new Vector3(tp2.x + (tp3.x - tp2.x) * f, oy, tp2.z + (tp3.z - tp2.z) * f) * Int3.PrecisionFactor);
            }
            else if ((long)(tp1.x - tp3.x) * (long)(p.z - tp3.z) - (long)(p.x - tp3.x) * (long)(tp1.z - tp3.z) > 0)
            {
                float f = Mathf.Clamp01(AstarMath.NearestPointFactor(tp3, tp1, p));
                return(new Vector3(tp3.x + (tp1.x - tp3.x) * f, oy, tp3.z + (tp1.z - tp3.z) * f) * Int3.PrecisionFactor);
            }
            else
            {
                return(_p);
            }

            /*
             * Equivalent to the above, but the above uses manual inlining
             * if (!Polygon.Left (tp1, tp2, p)) {
             *      float f = Mathf.Clamp01 (AstarMath.NearestPointFactor (tp1, tp2, p));
             *      return new Vector3(tp1.x + (tp2.x-tp1.x)*f, oy, tp1.z + (tp2.z-tp1.z)*f)*Int3.PrecisionFactor;
             * } else if (!Polygon.Left (tp2, tp3, p)) {
             *      float f = Mathf.Clamp01 (AstarMath.NearestPointFactor (tp2, tp3, p));
             *      return new Vector3(tp2.x + (tp3.x-tp2.x)*f, oy, tp2.z + (tp3.z-tp2.z)*f)*Int3.PrecisionFactor;
             * } else if (!Polygon.Left (tp3, tp1, p)) {
             *      float f = Mathf.Clamp01 (AstarMath.NearestPointFactor (tp3, tp1, p));
             *      return new Vector3(tp3.x + (tp1.x-tp3.x)*f, oy, tp3.z + (tp1.z-tp3.z)*f)*Int3.PrecisionFactor;
             * } else {
             *      return _p;
             * }*/

            /* Almost equivalent to the above, but this is slower
             * Vector3 tp1 = (Vector3)g.GetVertex(v0);
             * Vector3 tp2 = (Vector3)g.GetVertex(v1);
             * Vector3 tp3 = (Vector3)g.GetVertex(v2);
             * tp1.y = 0;
             * tp2.y = 0;
             * tp3.y = 0;
             * _p.y = 0;
             * return Pathfinding.Polygon.ClosestPointOnTriangle (tp1,tp2,tp3,_p);*/
        }
        public static void UpdateArea(GraphUpdateObject o, INavmeshHolder graph)
        {
            Bounds bounds = graph.transform.InverseTransform(o.bounds);

            // Bounding rectangle with integer coordinates
            var irect = new IntRect(
                Mathf.FloorToInt(bounds.min.x * Int3.Precision),
                Mathf.FloorToInt(bounds.min.z * Int3.Precision),
                Mathf.CeilToInt(bounds.max.x * Int3.Precision),
                Mathf.CeilToInt(bounds.max.z * Int3.Precision)
                );

            // Corners of the bounding rectangle
            var a = new Int3(irect.xmin, 0, irect.ymin);
            var b = new Int3(irect.xmin, 0, irect.ymax);
            var c = new Int3(irect.xmax, 0, irect.ymin);
            var d = new Int3(irect.xmax, 0, irect.ymax);

            var ymin = ((Int3)bounds.min).y;
            var ymax = ((Int3)bounds.max).y;

            // Loop through all nodes and check if they intersect the bounding box
            graph.GetNodes(_node =>
            {
                var node = _node as TriangleMeshNode;

                bool inside = false;

                int allLeft   = 0;
                int allRight  = 0;
                int allTop    = 0;
                int allBottom = 0;

                // Check bounding box rect in XZ plane
                for (int v = 0; v < 3; v++)
                {
                    Int3 p = node.GetVertexInGraphSpace(v);

                    if (irect.Contains(p.x, p.z))
                    {
                        inside = true;
                        break;
                    }

                    if (p.x < irect.xmin)
                    {
                        allLeft++;
                    }
                    if (p.x > irect.xmax)
                    {
                        allRight++;
                    }
                    if (p.z < irect.ymin)
                    {
                        allTop++;
                    }
                    if (p.z > irect.ymax)
                    {
                        allBottom++;
                    }
                }

                if (!inside && (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3))
                {
                    return;
                }

                // Check if the polygon edges intersect the bounding rect
                for (int v = 0; v < 3; v++)
                {
                    int v2 = v > 1 ? 0 : v + 1;

                    Int3 vert1 = node.GetVertexInGraphSpace(v);
                    Int3 vert2 = node.GetVertexInGraphSpace(v2);

                    if (VectorMath.SegmentsIntersectXZ(a, b, vert1, vert2))
                    {
                        inside = true;
                        break;
                    }

                    if (VectorMath.SegmentsIntersectXZ(a, c, vert1, vert2))
                    {
                        inside = true;
                        break;
                    }

                    if (VectorMath.SegmentsIntersectXZ(c, d, vert1, vert2))
                    {
                        inside = true;
                        break;
                    }

                    if (VectorMath.SegmentsIntersectXZ(d, b, vert1, vert2))
                    {
                        inside = true;
                        break;
                    }
                }

                // Check if the node contains any corner of the bounding rect
                if (inside || node.ContainsPointInGraphSpace(a) || node.ContainsPointInGraphSpace(b) ||
                    node.ContainsPointInGraphSpace(c) || node.ContainsPointInGraphSpace(d))
                {
                    inside = true;
                }

                if (!inside)
                {
                    return;
                }

                int allAbove = 0;
                int allBelow = 0;

                // Check y coordinate
                for (int v = 0; v < 3; v++)
                {
                    Int3 p = node.GetVertexInGraphSpace(v);
                    if (p.y < ymin)
                    {
                        allBelow++;
                    }
                    if (p.y > ymax)
                    {
                        allAbove++;
                    }
                }

                // Polygon is either completely above the bounding box or completely below it
                if (allBelow == 3 || allAbove == 3)
                {
                    return;
                }

                // Triangle is inside the bounding box!
                // Update it!
                o.WillUpdateNode(node);
                o.Apply(node);
            });
        }
Esempio n. 35
0
        public bool GetPortal(GraphNode _other, List <VInt3> left, List <VInt3> right, bool backwards, out int aIndex, out int bIndex)
        {
            aIndex = -1;
            bIndex = -1;
            if (_other.GraphIndex != base.GraphIndex)
            {
                return(false);
            }
            TriangleMeshNode node = _other as TriangleMeshNode;
            int tileIndex         = (this.GetVertexIndex(0) >> 12) & 0x7ffff;
            int num2 = (node.GetVertexIndex(0) >> 12) & 0x7ffff;

            if ((tileIndex != num2) && (GetNavmeshHolder(base.DataGroupIndex, base.GraphIndex) is RecastGraph))
            {
                int            num3;
                int            num4;
                int            num5;
                int            num6;
                int            num7;
                INavmeshHolder navmeshHolder = GetNavmeshHolder(base.DataGroupIndex, base.GraphIndex);
                navmeshHolder.GetTileCoordinates(tileIndex, out num3, out num5);
                navmeshHolder.GetTileCoordinates(num2, out num4, out num6);
                if (Math.Abs((int)(num3 - num4)) == 1)
                {
                    num7 = 0;
                }
                else if (Math.Abs((int)(num5 - num6)) == 1)
                {
                    num7 = 2;
                }
                else
                {
                    object[] objArray1 = new object[] { "Tiles not adjacent (", num3, ", ", num5, ") (", num4, ", ", num6, ")" };
                    throw new Exception(string.Concat(objArray1));
                }
                int vertexCount = this.GetVertexCount();
                int num9        = node.GetVertexCount();
                int i           = -1;
                int num11       = -1;
                for (int j = 0; j < vertexCount; j++)
                {
                    int num13 = this.GetVertex(j)[num7];
                    for (int k = 0; k < num9; k++)
                    {
                        if ((num13 == node.GetVertex((k + 1) % num9)[num7]) && (this.GetVertex((j + 1) % vertexCount)[num7] == node.GetVertex(k)[num7]))
                        {
                            i     = j;
                            num11 = k;
                            j     = vertexCount;
                            break;
                        }
                    }
                }
                aIndex = i;
                bIndex = num11;
                if (i != -1)
                {
                    VInt3 vertex = this.GetVertex(i);
                    VInt3 item   = this.GetVertex((i + 1) % vertexCount);
                    int   num17  = (num7 != 2) ? 2 : 0;
                    int   num18  = Math.Min(vertex[num17], item[num17]);
                    int   num19  = Math.Max(vertex[num17], item[num17]);
                    num18 = Math.Max(num18, Math.Min(node.GetVertex(num11)[num17], node.GetVertex((num11 + 1) % num9)[num17]));
                    num19 = Math.Min(num19, Math.Max(node.GetVertex(num11)[num17], node.GetVertex((num11 + 1) % num9)[num17]));
                    if (vertex[num17] < item[num17])
                    {
                        vertex[num17] = num18;
                        item[num17]   = num19;
                    }
                    else
                    {
                        vertex[num17] = num19;
                        item[num17]   = num18;
                    }
                    if (left != null)
                    {
                        left.Add(vertex);
                        right.Add(item);
                    }
                    return(true);
                }
            }
            else if (!backwards)
            {
                int num20 = -1;
                int num21 = -1;
                int num22 = this.GetVertexCount();
                int num23 = node.GetVertexCount();
                for (int m = 0; m < num22; m++)
                {
                    int vertexIndex = this.GetVertexIndex(m);
                    for (int n = 0; n < num23; n++)
                    {
                        if ((vertexIndex == node.GetVertexIndex((n + 1) % num23)) && (this.GetVertexIndex((m + 1) % num22) == node.GetVertexIndex(n)))
                        {
                            num20 = m;
                            num21 = n;
                            m     = num22;
                            break;
                        }
                    }
                }
                aIndex = num20;
                bIndex = num21;
                if (num20 == -1)
                {
                    return(false);
                }
                if (left != null)
                {
                    left.Add(this.GetVertex(num20));
                    right.Add(this.GetVertex((num20 + 1) % num22));
                }
            }
            return(true);
        }