ClosestPointOnNodeXZ() public method

public ClosestPointOnNodeXZ ( Vector3 _p ) : Vector3
_p UnityEngine.Vector3
return UnityEngine.Vector3
Beispiel #1
0
 // Token: 0x060025F4 RID: 9716 RVA: 0x001A3488 File Offset: 0x001A1688
 private void SearchBoxClosestXZ(int boxi, Vector3 p, ref float closestSqrDist, NNConstraint constraint, ref NNInfoInternal nnInfo)
 {
     BBTree.BBTreeBox bbtreeBox = this.tree[boxi];
     if (bbtreeBox.IsLeaf)
     {
         TriangleMeshNode[] array = this.nodeLookup;
         for (int i = 0; i < 4; i++)
         {
             if (array[bbtreeBox.nodeOffset + i] == null)
             {
                 return;
             }
             TriangleMeshNode triangleMeshNode = array[bbtreeBox.nodeOffset + i];
             if (constraint == null || constraint.Suitable(triangleMeshNode))
             {
                 Vector3 vector = triangleMeshNode.ClosestPointOnNodeXZ(p);
                 float   num    = (vector.x - p.x) * (vector.x - p.x) + (vector.z - p.z) * (vector.z - p.z);
                 if (nnInfo.constrainedNode == null || num < closestSqrDist - 1E-06f || (num <= closestSqrDist + 1E-06f && Mathf.Abs(vector.y - p.y) < Mathf.Abs(nnInfo.constClampedPosition.y - p.y)))
                 {
                     nnInfo.constrainedNode      = triangleMeshNode;
                     nnInfo.constClampedPosition = vector;
                     closestSqrDist = num;
                 }
             }
         }
     }
     else
     {
         int   left  = bbtreeBox.left;
         int   right = bbtreeBox.right;
         float num2;
         float num3;
         this.GetOrderedChildren(ref left, ref right, out num2, out num3, p);
         if (num2 <= closestSqrDist)
         {
             this.SearchBoxClosestXZ(left, p, ref closestSqrDist, constraint, ref nnInfo);
         }
         if (num3 <= closestSqrDist)
         {
             this.SearchBoxClosestXZ(right, p, ref closestSqrDist, constraint, ref nnInfo);
         }
     }
 }
Beispiel #2
0
 private void SearchBoxClosestXZ(int boxi, Vector3 p, ref float closestSqrDist, NNConstraint constraint, ref NNInfoInternal nnInfo)
 {
     BBTree.BBTreeBox bbtreeBox = this.tree[boxi];
     if (bbtreeBox.IsLeaf)
     {
         TriangleMeshNode[] array = this.nodeLookup;
         int num = 0;
         while (num < 4 && array[bbtreeBox.nodeOffset + num] != null)
         {
             TriangleMeshNode triangleMeshNode = array[bbtreeBox.nodeOffset + num];
             if (constraint == null || constraint.Suitable(triangleMeshNode))
             {
                 Vector3 constClampedPosition = triangleMeshNode.ClosestPointOnNodeXZ(p);
                 float   num2 = (constClampedPosition.x - p.x) * (constClampedPosition.x - p.x) + (constClampedPosition.z - p.z) * (constClampedPosition.z - p.z);
                 if (nnInfo.constrainedNode == null || num2 < closestSqrDist - 1E-06f || (num2 <= closestSqrDist + 1E-06f && Mathf.Abs(constClampedPosition.y - p.y) < Mathf.Abs(nnInfo.constClampedPosition.y - p.y)))
                 {
                     nnInfo.constrainedNode      = triangleMeshNode;
                     nnInfo.constClampedPosition = constClampedPosition;
                     closestSqrDist = num2;
                 }
             }
             num++;
         }
     }
     else
     {
         int   left  = bbtreeBox.left;
         int   right = bbtreeBox.right;
         float num3;
         float num4;
         this.GetOrderedChildren(ref left, ref right, out num3, out num4, p);
         if (num3 <= closestSqrDist)
         {
             this.SearchBoxClosestXZ(left, p, ref closestSqrDist, constraint, ref nnInfo);
         }
         if (num4 <= closestSqrDist)
         {
             this.SearchBoxClosestXZ(right, p, ref closestSqrDist, constraint, ref nnInfo);
         }
     }
 }
Beispiel #3
0
        public TriangleMeshNode GetNearestByRasterizer(Int3 position, out Int3 clampedPosition)
        {
            clampedPosition = Int3.zero;
            if (this.rasterizer == null)
            {
                return(null);
            }
            TriangleMeshNode triangleMeshNode = this.GetLocatedByRasterizer(position);

            if (triangleMeshNode != null)
            {
                clampedPosition = position;
                return(triangleMeshNode);
            }
            triangleMeshNode = this.FindNearestByRasterizer(position, -1);
            if (triangleMeshNode == null)
            {
                return(null);
            }
            clampedPosition = triangleMeshNode.ClosestPointOnNodeXZ(position);
            return(triangleMeshNode);
        }
Beispiel #4
0
        void FindWalls(int nodeIndex, List <Vector3> wallBuffer, Vector3 position, float range)
        {
            if (range <= 0)
            {
                return;
            }

            bool negAbort = false;
            bool posAbort = false;

            range *= range;

            position.y = 0;
            //Looping as 0,-1,1,-2,2,-3,3,-4,4 etc. Avoids code duplication by keeping it to one loop instead of two
            for (int i = 0; !negAbort || !posAbort; i = i < 0 ? -i : -i - 1)
            {
                if (i < 0 && negAbort)
                {
                    continue;
                }
                if (i > 0 && posAbort)
                {
                    continue;
                }

                if (i < 0 && nodeIndex + i < 0)
                {
                    negAbort = true;
                    continue;
                }

                if (i > 0 && nodeIndex + i >= nodes.Count)
                {
                    posAbort = true;
                    continue;
                }

                TriangleMeshNode prev = nodeIndex + i - 1 < 0 ? null : nodes[nodeIndex + i - 1];
                TriangleMeshNode node = nodes[nodeIndex + i];
                TriangleMeshNode next = nodeIndex + i + 1 >= nodes.Count ? null : nodes[nodeIndex + i + 1];

                if (node.Destroyed)
                {
                    break;
                }

                if ((node.ClosestPointOnNodeXZ(position) - position).sqrMagnitude > range)
                {
                    if (i < 0)
                    {
                        negAbort = true;
                    }
                    else
                    {
                        posAbort = true;
                    }
                    continue;
                }

                for (int j = 0; j < 3; j++)
                {
                    triBuffer[j] = 0;
                }

                for (int j = 0; j < node.connections.Length; j++)
                {
                    var other = node.connections[j] as TriangleMeshNode;
                    if (other == null)
                    {
                        continue;
                    }

                    int va = -1;
                    for (int a = 0; a < 3; a++)
                    {
                        for (int b = 0; b < 3; b++)
                        {
                            if (node.GetVertex(a) == other.GetVertex((b + 1) % 3) && node.GetVertex((a + 1) % 3) == other.GetVertex(b))
                            {
                                va = a;
                                a  = 3;
                                break;
                            }
                        }
                    }
                    if (va == -1)
                    {
                        //No direct connection
                    }
                    else
                    {
                        triBuffer[va] = other == prev || other == next ? 2 : 1;
                    }
                }

                for (int j = 0; j < 3; j++)
                {
                    //Tribuffer values
                    // 0 : Navmesh border, outer edge
                    // 1 : Inner edge, to node inside funnel
                    // 2 : Inner edge, to node outside funnel
                    if (triBuffer[j] == 0)
                    {
                        //Add edge to list of walls
                        wallBuffer.Add((Vector3)node.GetVertex(j));
                        wallBuffer.Add((Vector3)node.GetVertex((j + 1) % 3));
                    }
                }
            }
        }
Beispiel #5
0
        public Vector3 Update(Vector3 position, List <Vector3> buffer, int numCorners, out bool lastCorner, out bool requiresRepath)
        {
            lastCorner     = false;
            requiresRepath = false;
            var i3Pos = (Int3)position;

            if (nodes[currentNode].Destroyed)
            {
                requiresRepath = true;
                lastCorner     = false;
                buffer.Add(position);
                return(position);
            }

            // Check if we are in the same node as we were in during the last frame
            if (nodes[currentNode].ContainsPoint(i3Pos))
            {
                // Only check for destroyed nodes every 10 frames
                if (checkForDestroyedNodesCounter >= 10)
                {
                    checkForDestroyedNodesCounter = 0;

                    // Loop through all nodes and check if they are destroyed
                    // If so, we really need a recalculation of our path quickly
                    // since there might be an obstacle blocking our path after
                    // a graph update or something similar
                    for (int i = 0, t = nodes.Count; i < t; i++)
                    {
                        if (nodes[i].Destroyed)
                        {
                            requiresRepath = true;
                            break;
                        }
                    }
                }
                else
                {
                    checkForDestroyedNodesCounter++;
                }
            }
            else
            {
                // This part of the code is relatively seldom called
                // Most of the time we are still on the same node as during the previous frame

                // Otherwise check the 2 nodes ahead and 2 nodes back
                // If they contain the node in XZ space, then we probably moved into those nodes
                bool found = false;

                // 2 nodes ahead
                for (int i = currentNode + 1, t = System.Math.Min(currentNode + 3, nodes.Count); i < t && !found; i++)
                {
                    // If the node is destroyed, make sure we recalculate a new path quickly
                    if (nodes[i].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }

                    // We found a node which contains our current position in XZ space
                    if (nodes[i].ContainsPoint(i3Pos))
                    {
                        currentNode = i;
                        found       = true;
                    }
                }

                // 2 nodes behind
                for (int i = currentNode - 1, t = System.Math.Max(currentNode - 3, 0); i > t && !found; i--)
                {
                    if (nodes[i].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }

                    if (nodes[i].ContainsPoint(i3Pos))
                    {
                        currentNode = i;
                        found       = true;
                    }
                }

                if (!found)
                {
                    int              closestNodeInPath    = 0;
                    int              closestIsNeighbourOf = 0;
                    float            closestDist          = float.PositiveInfinity;
                    bool             closestIsInPath      = false;
                    TriangleMeshNode closestNode          = null;

                    int containingIndex = nodes.Count - 1;

                    // If we still couldn't find a good node
                    // Check all nodes in the whole path

                    // We are checking for if any node is destroyed in the loop
                    // So we can reset this counter
                    checkForDestroyedNodesCounter = 0;

                    for (int i = 0, t = nodes.Count; i < t; i++)
                    {
                        if (nodes[i].Destroyed)
                        {
                            requiresRepath = true;
                            lastCorner     = false;
                            buffer.Add(position);
                            return(position);
                        }

                        Vector3 close = nodes[i].ClosestPointOnNode(position);
                        float   d     = (close - position).sqrMagnitude;
                        if (d < closestDist)
                        {
                            closestDist       = d;
                            closestNodeInPath = i;
                            closestNode       = nodes[i];
                            closestIsInPath   = true;
                        }
                    }

                    // Loop through all neighbours of all nodes in the path
                    // and find the closet point on them
                    // We cannot just look on the ones in the path since it is impossible
                    // to know if we are outside the navmesh completely or if we have just
                    // stepped in to an adjacent node

                    // Need to make a copy here, the JIT will move this variable to the heap
                    // because it is used inside a delegate, if we didn't make a copy here
                    // we would *always* allocate 24 bytes (sizeof(position)) on the heap every time
                    // this method was called
                    // now we only do it when this IF statement is executed
                    var posCopy = position;

                    GraphNodeDelegate del = node => {
                        // Check so that this neighbour we are processing is neither the node after the current node or the node before the current node in the path
                        // This is done for optimization, we have already checked those nodes earlier
                        if (!(containingIndex > 0 && node == nodes[containingIndex - 1]) && !(containingIndex < nodes.Count - 1 && node == nodes[containingIndex + 1]))
                        {
                            // Check if the neighbour was a mesh node
                            var mn = node as TriangleMeshNode;
                            if (mn != null)
                            {
                                // Find the distance to the closest point on it from our current position
                                var   close = mn.ClosestPointOnNode(posCopy);
                                float d     = (close - posCopy).sqrMagnitude;

                                // Is that distance better than the best distance seen so far
                                if (d < closestDist)
                                {
                                    closestDist          = d;
                                    closestIsNeighbourOf = containingIndex;
                                    closestNode          = mn;
                                    closestIsInPath      = false;
                                }
                            }
                        }
                    };

                    // Loop through all the nodes in the path in reverse order
                    // The callback needs to know about the index, so we store it
                    // in a local variable which it can read
                    for (; containingIndex >= 0; containingIndex--)
                    {
                        // Loop through all neighbours of the node
                        nodes[containingIndex].GetConnections(del);
                    }

                    // Check if the closest node
                    // was on the path already or if we need to adjust it
                    if (closestIsInPath)
                    {
                        // If we have found a node
                        // Snap to the closest point in XZ space (keep the Y coordinate)
                        // If we would have snapped to the closest point in 3D space, the agent
                        // might slow down when traversing slopes
                        currentNode = closestNodeInPath;
                        position    = nodes[closestNodeInPath].ClosestPointOnNodeXZ(position);
                    }
                    else
                    {
                        // Snap to the closest point in XZ space on the node
                        position = closestNode.ClosestPointOnNodeXZ(position);

                        // We have found a node containing the position, but it is outside the funnel
                        // Recalculate the funnel to include this node
                        exactStart = position;
                        UpdateFunnelCorridor(closestIsNeighbourOf, closestNode);

                        // Restart from the first node in the updated path
                        currentNode = 0;
                    }
                }
            }

            currentPosition = position;


            if (!FindNextCorners(position, currentNode, buffer, numCorners, out lastCorner))
            {
                Debug.LogError("Oh oh");
                buffer.Add(position);
                return(position);
            }

            return(position);
        }
Beispiel #6
0
        private void FindWalls(int nodeIndex, List <Vector3> wallBuffer, Vector3 position, float range)
        {
            if (range <= 0f)
            {
                return;
            }
            bool flag  = false;
            bool flag2 = false;

            range     *= range;
            position.y = 0f;
            int num = 0;

            while (!flag || !flag2)
            {
                if (num >= 0 || !flag)
                {
                    if (num <= 0 || !flag2)
                    {
                        if (num < 0 && nodeIndex + num < 0)
                        {
                            flag = true;
                        }
                        else if (num > 0 && nodeIndex + num >= this.nodes.Count)
                        {
                            flag2 = true;
                        }
                        else
                        {
                            TriangleMeshNode triangleMeshNode  = (nodeIndex + num - 1 >= 0) ? this.nodes[nodeIndex + num - 1] : null;
                            TriangleMeshNode triangleMeshNode2 = this.nodes[nodeIndex + num];
                            TriangleMeshNode triangleMeshNode3 = (nodeIndex + num + 1 < this.nodes.Count) ? this.nodes[nodeIndex + num + 1] : null;
                            if (triangleMeshNode2.Destroyed)
                            {
                                break;
                            }
                            if ((triangleMeshNode2.ClosestPointOnNodeXZ(position) - position).sqrMagnitude > range)
                            {
                                if (num < 0)
                                {
                                    flag = true;
                                }
                                else
                                {
                                    flag2 = true;
                                }
                            }
                            else
                            {
                                for (int i = 0; i < 3; i++)
                                {
                                    this.triBuffer[i] = 0;
                                }
                                for (int j = 0; j < triangleMeshNode2.connections.Length; j++)
                                {
                                    TriangleMeshNode triangleMeshNode4 = triangleMeshNode2.connections[j].node as TriangleMeshNode;
                                    if (triangleMeshNode4 != null)
                                    {
                                        int num2 = -1;
                                        for (int k = 0; k < 3; k++)
                                        {
                                            for (int l = 0; l < 3; l++)
                                            {
                                                if (triangleMeshNode2.GetVertex(k) == triangleMeshNode4.GetVertex((l + 1) % 3) && triangleMeshNode2.GetVertex((k + 1) % 3) == triangleMeshNode4.GetVertex(l))
                                                {
                                                    num2 = k;
                                                    k    = 3;
                                                    break;
                                                }
                                            }
                                        }
                                        if (num2 != -1)
                                        {
                                            this.triBuffer[num2] = ((triangleMeshNode4 != triangleMeshNode && triangleMeshNode4 != triangleMeshNode3) ? 1 : 2);
                                        }
                                    }
                                }
                                for (int m = 0; m < 3; m++)
                                {
                                    if (this.triBuffer[m] == 0)
                                    {
                                        wallBuffer.Add((Vector3)triangleMeshNode2.GetVertex(m));
                                        wallBuffer.Add((Vector3)triangleMeshNode2.GetVertex((m + 1) % 3));
                                    }
                                }
                            }
                        }
                    }
                }
                num = ((num >= 0) ? (-num - 1) : (-num));
            }
            if (this.path.transform != null)
            {
                for (int n = 0; n < wallBuffer.Count; n++)
                {
                    wallBuffer[n] = this.path.transform.Transform(wallBuffer[n]);
                }
            }
        }
Beispiel #7
0
        private bool ClampToNavmeshInternalFull(ref Vector3 position)
        {
            int              index           = 0;
            float            closestDist     = float.PositiveInfinity;
            bool             closestIsInPath = false;
            TriangleMeshNode closestNode     = null;

            this.checkForDestroyedNodesCounter = 0;
            int i     = 0;
            int count = this.nodes.Count;

            while (i < count)
            {
                if (this.nodes[i].Destroyed)
                {
                    return(true);
                }
                Vector3 a            = this.nodes[i].ClosestPointOnNode(position);
                float   sqrMagnitude = (a - position).sqrMagnitude;
                if (sqrMagnitude < closestDist)
                {
                    closestDist     = sqrMagnitude;
                    index           = i;
                    closestNode     = this.nodes[i];
                    closestIsInPath = true;
                }
                i++;
            }
            Vector3            posCopy              = position;
            int                containingIndex      = this.nodes.Count - 1;
            int                closestIsNeighbourOf = 0;
            Action <GraphNode> action = delegate(GraphNode node)
            {
                if ((containingIndex <= 0 || node != this.nodes[containingIndex - 1]) && (containingIndex >= this.nodes.Count - 1 || node != this.nodes[containingIndex + 1]))
                {
                    TriangleMeshNode triangleMeshNode = node as TriangleMeshNode;
                    if (triangleMeshNode != null)
                    {
                        Vector3 a2            = triangleMeshNode.ClosestPointOnNode(posCopy);
                        float   sqrMagnitude2 = (a2 - posCopy).sqrMagnitude;
                        if (sqrMagnitude2 < closestDist)
                        {
                            closestDist          = sqrMagnitude2;
                            closestIsNeighbourOf = containingIndex;
                            closestNode          = triangleMeshNode;
                            closestIsInPath      = false;
                        }
                    }
                }
            };

            while (containingIndex >= 0)
            {
                this.nodes[containingIndex].GetConnections(action);
                containingIndex--;
            }
            if (closestIsInPath)
            {
                this.currentNode = index;
                position         = this.nodes[index].ClosestPointOnNodeXZ(position);
            }
            else
            {
                position        = closestNode.ClosestPointOnNodeXZ(position);
                this.exactStart = position;
                this.UpdateFunnelCorridor(closestIsNeighbourOf, closestNode);
                this.currentNode = 0;
            }
            return(false);
        }
Beispiel #8
0
        bool ClampToNavmeshInternalFull(ref Vector3 position)
        {
            int              closestNodeInPath = 0;
            float            closestDist       = float.PositiveInfinity;
            bool             closestIsInPath   = false;
            TriangleMeshNode closestNode       = null;

            // If we still couldn't find a good node
            // Check all nodes in the whole path

            // We are checking for if any node is destroyed in the loop
            // So we can reset this counter
            checkForDestroyedNodesCounter = 0;

            for (int i = 0, t = nodes.Count; i < t; i++)
            {
                if (nodes[i].Destroyed)
                {
                    return(true);
                }

                Vector3 close = nodes[i].ClosestPointOnNode(position);
                float   d     = (close - position).sqrMagnitude;
                if (d < closestDist)
                {
                    closestDist       = d;
                    closestNodeInPath = i;
                    closestNode       = nodes[i];
                    closestIsInPath   = true;
                }
            }

            // Loop through all neighbours of all nodes in the path
            // and find the closet point on them
            // We cannot just look on the ones in the path since it is impossible
            // to know if we are outside the navmesh completely or if we have just
            // stepped in to an adjacent node

            // Need to make a copy because ref parameters cannot be used inside delegates
            var posCopy              = position;
            int containingIndex      = nodes.Count - 1;
            int closestIsNeighbourOf = 0;

            System.Action <GraphNode> del = node => {
                // Check so that this neighbour we are processing is neither the node after the current node or the node before the current node in the path
                // This is done for optimization, we have already checked those nodes earlier
                if (!(containingIndex > 0 && node == nodes[containingIndex - 1]) && !(containingIndex < nodes.Count - 1 && node == nodes[containingIndex + 1]))
                {
                    // Check if the neighbour was a mesh node
                    var triNode = node as TriangleMeshNode;
                    if (triNode != null)
                    {
                        // Find the distance to the closest point on it from our current position
                        var   close = triNode.ClosestPointOnNode(posCopy);
                        float dist  = (close - posCopy).sqrMagnitude;

                        // Is that distance better than the best distance seen so far
                        if (dist < closestDist)
                        {
                            closestDist          = dist;
                            closestIsNeighbourOf = containingIndex;
                            closestNode          = triNode;
                            closestIsInPath      = false;
                        }
                    }
                }
            };

            // Loop through all the nodes in the path in reverse order
            // The callback needs to know about the index, so we store it
            // in a local variable which it can read
            for (; containingIndex >= 0; containingIndex--)
            {
                // Loop through all neighbours of the node
                nodes[containingIndex].GetConnections(del);
            }

            // Check if the closest node
            // was on the path already or if we need to adjust it
            if (closestIsInPath)
            {
                // If we have found a node
                // Snap to the closest point in XZ space (keep the Y coordinate)
                // If we would have snapped to the closest point in 3D space, the agent
                // might slow down when traversing slopes
                currentNode = closestNodeInPath;
                position    = nodes[closestNodeInPath].ClosestPointOnNodeXZ(position);
            }
            else
            {
                // Snap to the closest point in XZ space on the node
                position = closestNode.ClosestPointOnNodeXZ(position);

                // We have found a node containing the position, but it is outside the funnel
                // Recalculate the funnel to include this node
                exactStart = position;
                UpdateFunnelCorridor(closestIsNeighbourOf, closestNode);

                // Restart from the first node in the updated path
                currentNode = 0;
            }

            return(false);
        }
Beispiel #9
0
        public Vector3 Update(Vector3 position, List <Vector3> buffer, int numCorners, out bool lastCorner, out bool requiresRepath)
        {
            lastCorner     = false;
            requiresRepath = false;
            Int3 p = (Int3)position;

            if (this.nodes[this.currentNode].Destroyed)
            {
                requiresRepath = true;
                lastCorner     = false;
                buffer.Add(position);
                return(position);
            }
            if (this.nodes[this.currentNode].ContainsPoint(p))
            {
                if (this.checkForDestroyedNodesCounter >= 10)
                {
                    this.checkForDestroyedNodesCounter = 0;
                    int i     = 0;
                    int count = this.nodes.Count;
                    while (i < count)
                    {
                        if (this.nodes[i].Destroyed)
                        {
                            requiresRepath = true;
                            break;
                        }
                        i++;
                    }
                }
                else
                {
                    this.checkForDestroyedNodesCounter++;
                }
            }
            else
            {
                bool flag = false;
                int  num  = this.currentNode + 1;
                int  num2 = Math.Min(this.currentNode + 3, this.nodes.Count);
                while (num < num2 && !flag)
                {
                    if (this.nodes[num].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }
                    if (this.nodes[num].ContainsPoint(p))
                    {
                        this.currentNode = num;
                        flag             = true;
                    }
                    num++;
                }
                int num3 = this.currentNode - 1;
                int num4 = Math.Max(this.currentNode - 3, 0);
                while (num3 > num4 && !flag)
                {
                    if (this.nodes[num3].Destroyed)
                    {
                        requiresRepath = true;
                        lastCorner     = false;
                        buffer.Add(position);
                        return(position);
                    }
                    if (this.nodes[num3].ContainsPoint(p))
                    {
                        this.currentNode = num3;
                        flag             = true;
                    }
                    num3--;
                }
                if (!flag)
                {
                    int              index = 0;
                    int              closestIsNeighbourOf = 0;
                    float            closestDist          = float.PositiveInfinity;
                    bool             closestIsInPath      = false;
                    TriangleMeshNode closestNode          = null;
                    int              containingIndex      = this.nodes.Count - 1;
                    this.checkForDestroyedNodesCounter = 0;
                    int j      = 0;
                    int count2 = this.nodes.Count;
                    while (j < count2)
                    {
                        if (this.nodes[j].Destroyed)
                        {
                            requiresRepath = true;
                            lastCorner     = false;
                            buffer.Add(position);
                            return(position);
                        }
                        Vector3 a            = this.nodes[j].ClosestPointOnNode(position);
                        float   sqrMagnitude = (a - position).sqrMagnitude;
                        if (sqrMagnitude < closestDist)
                        {
                            closestDist     = sqrMagnitude;
                            index           = j;
                            closestNode     = this.nodes[j];
                            closestIsInPath = true;
                        }
                        j++;
                    }
                    Vector3           posCopy = position;
                    GraphNodeDelegate del     = delegate(GraphNode node)
                    {
                        if ((containingIndex <= 0 || node != this.nodes[containingIndex - 1]) && (containingIndex >= this.nodes.Count - 1 || node != this.nodes[containingIndex + 1]))
                        {
                            TriangleMeshNode triangleMeshNode = node as TriangleMeshNode;
                            if (triangleMeshNode != null)
                            {
                                Vector3 a2            = triangleMeshNode.ClosestPointOnNode(posCopy);
                                float   sqrMagnitude2 = (a2 - posCopy).sqrMagnitude;
                                if (sqrMagnitude2 < closestDist)
                                {
                                    closestDist          = sqrMagnitude2;
                                    closestIsNeighbourOf = containingIndex;
                                    closestNode          = triangleMeshNode;
                                    closestIsInPath      = false;
                                }
                            }
                        }
                    };
                    while (containingIndex >= 0)
                    {
                        this.nodes[containingIndex].GetConnections(del);
                        containingIndex--;
                    }
                    if (closestIsInPath)
                    {
                        this.currentNode = index;
                        position         = this.nodes[index].ClosestPointOnNodeXZ(position);
                    }
                    else
                    {
                        position        = closestNode.ClosestPointOnNodeXZ(position);
                        this.exactStart = position;
                        this.UpdateFunnelCorridor(closestIsNeighbourOf, closestNode);
                        this.currentNode = 0;
                    }
                }
            }
            this.currentPosition = position;
            if (!this.FindNextCorners(position, this.currentNode, buffer, numCorners, out lastCorner))
            {
                Debug.LogError("Oh oh");
                buffer.Add(position);
                return(position);
            }
            return(position);
        }
        // Token: 0x060021AA RID: 8618 RVA: 0x0018F7E4 File Offset: 0x0018D9E4
        private bool ClampToNavmeshInternal(ref Vector3 position)
        {
            TriangleMeshNode triangleMeshNode = this.nodes[this.currentNode];

            if (triangleMeshNode.Destroyed)
            {
                return(true);
            }
            if (triangleMeshNode.ContainsPoint(position))
            {
                return(false);
            }
            Queue <TriangleMeshNode> queue = RichFunnel.navmeshClampQueue;
            List <TriangleMeshNode>  list  = RichFunnel.navmeshClampList;
            Dictionary <TriangleMeshNode, TriangleMeshNode> dictionary = RichFunnel.navmeshClampDict;

            triangleMeshNode.TemporaryFlag1 = true;
            dictionary[triangleMeshNode]    = null;
            queue.Enqueue(triangleMeshNode);
            list.Add(triangleMeshNode);
            float            num               = float.PositiveInfinity;
            Vector3          vector            = position;
            TriangleMeshNode triangleMeshNode2 = null;

            while (queue.Count > 0)
            {
                TriangleMeshNode triangleMeshNode3 = queue.Dequeue();
                Vector3          vector2           = triangleMeshNode3.ClosestPointOnNodeXZ(position);
                float            num2 = VectorMath.MagnitudeXZ(vector2 - position);
                if (num2 <= num * 1.05f + 0.001f)
                {
                    if (num2 < num)
                    {
                        num               = num2;
                        vector            = vector2;
                        triangleMeshNode2 = triangleMeshNode3;
                    }
                    for (int i = 0; i < triangleMeshNode3.connections.Length; i++)
                    {
                        TriangleMeshNode triangleMeshNode4 = triangleMeshNode3.connections[i].node as TriangleMeshNode;
                        if (triangleMeshNode4 != null && !triangleMeshNode4.TemporaryFlag1)
                        {
                            triangleMeshNode4.TemporaryFlag1 = true;
                            dictionary[triangleMeshNode4]    = triangleMeshNode3;
                            queue.Enqueue(triangleMeshNode4);
                            list.Add(triangleMeshNode4);
                        }
                    }
                }
            }
            for (int j = 0; j < list.Count; j++)
            {
                list[j].TemporaryFlag1 = false;
            }
            list.ClearFast <TriangleMeshNode>();
            int num3 = this.nodes.IndexOf(triangleMeshNode2);

            position.x = vector.x;
            position.z = vector.z;
            if (num3 == -1)
            {
                List <TriangleMeshNode> list2 = RichFunnel.navmeshClampList;
                while (num3 == -1)
                {
                    list2.Add(triangleMeshNode2);
                    triangleMeshNode2 = dictionary[triangleMeshNode2];
                    num3 = this.nodes.IndexOf(triangleMeshNode2);
                }
                this.exactStart = position;
                this.UpdateFunnelCorridor(num3, list2);
                list2.ClearFast <TriangleMeshNode>();
                this.currentNode = 0;
            }
            else
            {
                this.currentNode = num3;
            }
            dictionary.Clear();
            return(this.currentNode + 1 < this.nodes.Count && this.nodes[this.currentNode + 1].Destroyed);
        }
Beispiel #11
0
        private bool ClampToNavmeshInternal(ref Vector3 position)
        {
            if (this.nodes[this.currentNode].Destroyed)
            {
                return(true);
            }
            Int3 p = (Int3)position;

            if (this.nodes[this.currentNode].ContainsPoint(p))
            {
                return(false);
            }
            int i   = this.currentNode + 1;
            int num = Math.Min(this.currentNode + 3, this.nodes.Count);

            while (i < num)
            {
                if (this.nodes[i].Destroyed)
                {
                    return(true);
                }
                if (this.nodes[i].ContainsPoint(p))
                {
                    this.currentNode = i;
                    return(false);
                }
                i++;
            }
            int j    = this.currentNode - 1;
            int num2 = Math.Max(this.currentNode - 3, 0);

            while (j > num2)
            {
                if (this.nodes[j].Destroyed)
                {
                    return(true);
                }
                if (this.nodes[j].ContainsPoint(p))
                {
                    this.currentNode = j;
                    return(false);
                }
                j--;
            }
            int              index = 0;
            int              closestIsNeighbourOf = 0;
            float            closestDist          = float.PositiveInfinity;
            bool             closestIsInPath      = false;
            TriangleMeshNode closestNode          = null;
            int              containingIndex      = this.nodes.Count - 1;

            this.checkForDestroyedNodesCounter = 0;
            int k     = 0;
            int count = this.nodes.Count;

            while (k < count)
            {
                if (this.nodes[k].Destroyed)
                {
                    return(true);
                }
                Vector3 a            = this.nodes[k].ClosestPointOnNode(position);
                float   sqrMagnitude = (a - position).sqrMagnitude;
                if (sqrMagnitude < closestDist)
                {
                    closestDist     = sqrMagnitude;
                    index           = k;
                    closestNode     = this.nodes[k];
                    closestIsInPath = true;
                }
                k++;
            }
            Vector3           posCopy = position;
            GraphNodeDelegate del     = delegate(GraphNode node)
            {
                if ((containingIndex <= 0 || node != this.nodes[containingIndex - 1]) && (containingIndex >= this.nodes.Count - 1 || node != this.nodes[containingIndex + 1]))
                {
                    TriangleMeshNode triangleMeshNode = node as TriangleMeshNode;
                    if (triangleMeshNode != null)
                    {
                        Vector3 a2            = triangleMeshNode.ClosestPointOnNode(posCopy);
                        float   sqrMagnitude2 = (a2 - posCopy).sqrMagnitude;
                        if (sqrMagnitude2 < closestDist)
                        {
                            closestDist          = sqrMagnitude2;
                            closestIsNeighbourOf = containingIndex;
                            closestNode          = triangleMeshNode;
                            closestIsInPath      = false;
                        }
                    }
                }
            };

            while (containingIndex >= 0)
            {
                this.nodes[containingIndex].GetConnections(del);
                containingIndex--;
            }
            if (closestIsInPath)
            {
                this.currentNode = index;
                position         = this.nodes[index].ClosestPointOnNodeXZ(position);
            }
            else
            {
                position        = closestNode.ClosestPointOnNodeXZ(position);
                this.exactStart = position;
                this.UpdateFunnelCorridor(closestIsNeighbourOf, closestNode);
                this.currentNode = 0;
            }
            return(false);
        }
Beispiel #12
0
 private void FindWalls(int nodeIndex, List <Vector3> wallBuffer, Vector3 position, float range)
 {
     if (range > 0f)
     {
         bool flag  = false;
         bool flag2 = false;
         range     *= range;
         position.y = 0f;
         for (int i = 0; !flag || !flag2; i = (i >= 0) ? (-i - 1) : -i)
         {
             if (((i >= 0) || !flag) && ((i <= 0) || !flag2))
             {
                 if ((i < 0) && ((nodeIndex + i) < 0))
                 {
                     flag = true;
                 }
                 else if ((i > 0) && ((nodeIndex + i) >= this.nodes.Count))
                 {
                     flag2 = true;
                 }
                 else
                 {
                     TriangleMeshNode node  = (((nodeIndex + i) - 1) >= 0) ? this.nodes[(nodeIndex + i) - 1] : null;
                     TriangleMeshNode node2 = this.nodes[nodeIndex + i];
                     TriangleMeshNode node3 = (((nodeIndex + i) + 1) < this.nodes.Count) ? this.nodes[(nodeIndex + i) + 1] : null;
                     if (node2.Destroyed)
                     {
                         break;
                     }
                     Vector3 vector = node2.ClosestPointOnNodeXZ(position) - position;
                     if (vector.sqrMagnitude > range)
                     {
                         if (i < 0)
                         {
                             flag = true;
                         }
                         else
                         {
                             flag2 = true;
                         }
                     }
                     else
                     {
                         for (int j = 0; j < 3; j++)
                         {
                             this.triBuffer[j] = 0;
                         }
                         for (int k = 0; k < node2.connections.Length; k++)
                         {
                             TriangleMeshNode node4 = node2.connections[k] as TriangleMeshNode;
                             if (node4 != null)
                             {
                                 int index = -1;
                                 for (int n = 0; n < 3; n++)
                                 {
                                     for (int num6 = 0; num6 < 3; num6++)
                                     {
                                         if ((node2.GetVertex(n) == node4.GetVertex((num6 + 1) % 3)) && (node2.GetVertex((n + 1) % 3) == node4.GetVertex(num6)))
                                         {
                                             index = n;
                                             n     = 3;
                                             break;
                                         }
                                     }
                                 }
                                 if (index != -1)
                                 {
                                     this.triBuffer[index] = ((node4 != node) && (node4 != node3)) ? 1 : 2;
                                 }
                             }
                         }
                         for (int m = 0; m < 3; m++)
                         {
                             if (this.triBuffer[m] == 0)
                             {
                                 wallBuffer.Add((Vector3)node2.GetVertex(m));
                                 wallBuffer.Add((Vector3)node2.GetVertex((m + 1) % 3));
                             }
                         }
                     }
                 }
             }
         }
     }
 }