private static bool CheckNearestNodeIntersection(TriangleMeshNode node, VInt3 srcLoc, VInt3 destLoc, ref int edge)
 {
     if (!node.ContainsPoint(destLoc))
     {
         int     num         = 0;
         VInt3[] staticVerts = PathfindingUtility._staticVerts;
         node.GetPoints(out staticVerts[0], out staticVerts[1], out staticVerts[2]);
         float   num2   = 3.40282347E+38f;
         int     num3   = -1;
         Vector3 vector = (Vector3)srcLoc;
         Vector3 end    = (Vector3)destLoc;
         for (int i = 0; i < 3; i++)
         {
             if (Polygon.Intersects(staticVerts[i], staticVerts[(i + 1) % 3], srcLoc, destLoc))
             {
                 num++;
                 bool    inCondition;
                 Vector3 vector2 = Polygon.IntersectionPoint((Vector3)staticVerts[i], (Vector3)staticVerts[(i + 1) % 3], vector, end, out inCondition);
                 DebugHelper.Assert(inCondition);
                 float num4 = vector.XZSqrMagnitude(ref vector2);
                 if (num4 < num2)
                 {
                     num2 = num4;
                     num3 = i;
                 }
             }
         }
         if (num != 2 || num3 == -1)
         {
             return(false);
         }
         edge = num3;
     }
     return(true);
 }
Example #2
0
    // will return false if any part of the line is off the nav mesh
    // if 'clampFromInNavMesh' is true, we make sure the from position is on the nav mesh before doing checks
    // (done in 2d, does not currently support nav meshes on top of one and other)
    public static bool IsVisibleOnNavMeshOptimized(ref Vector3 from, Vector3 to, bool clampFromInNavMesh, NNInfo?nearestInfo, ref Vector3 endPoint, List <TriangleMeshNode> outList)
    {
        endPoint = from;
        if (null == AstarPath.active)
        {
            return(false); // no nav mesh
        }

        NNInfo           fromInfo        = nearestInfo ?? AstarPath.active.GetNearest(from);
        TriangleMeshNode currentTriangle = fromInfo.node as TriangleMeshNode;

        if (null == currentTriangle)
        {
            return(false); // no nav mesh
        }

        if (clampFromInNavMesh)
        {
            endPoint = from = CalculatePointOnNavMeshOptimized(from, 0.1f, fromInfo);
        }
        else if (!currentTriangle.ContainsPoint((Int3)from))
        {
            return(false); // start point is off the nav mesh
        }

        bool isVisible = false;

        AstarPath.active.StartUsingTriangleScratchList();
        while (null != currentTriangle)
        {
            if (null != outList)
            {
                outList.Add(currentTriangle);
            }

            TriangleMeshNode nextTriangle = null;
            if (DoesLineExitTriangle(from, to, currentTriangle, ref AstarPath.active.trianglesHashSet, ref nextTriangle, ref endPoint)) // the end point returned will be on the ground plane (y value zero)
            {
                if (null == nextTriangle)                                                                                               // no next triangle, so the line exits off the edge of the nav mesh ('while' loop will end)
                {
                    VirticalRayPlaneIntersection(new Vector2(endPoint.x, endPoint.z), currentTriangle, ref endPoint);                   // make sure the endPoint is on the plane of the triangle
                    isVisible = false;                                                                                                  // exits the nav mesh
                }
            }
            else // does not exit triangle
            {
                VirticalRayPlaneIntersection(new Vector2(to.x, to.z), currentTriangle, ref endPoint); // make sure the endPoint is on the plane of the triangle
                isVisible = true; // the line cast ends inside this triangle, no nextTriangle, nextTriangle will be null ('while' loop will end)
            }
            AstarPath.active.trianglesHashSet.Add(currentTriangle);
            currentTriangle = nextTriangle;
        }
        AstarPath.active.StopUsingTriangleScratchList();
        return(isVisible);
    }
Example #3
0
 // checks to see if the point is actually inside the closest triangle on the nav mesh
 public static bool IsPointOnNavMeshOptimized(Vector3 point, NNInfo?nearestInfo = null)
 {
     if (null != AstarPath.active)
     {
         NNInfo           pointInfo       = nearestInfo ?? AstarPath.active.GetNearest(point);
         TriangleMeshNode closestTriangle = pointInfo.node as TriangleMeshNode;
         if (null != closestTriangle)
         {
             return(closestTriangle.ContainsPoint((Int3)point));
         }
     }
     return(false);
 }
Example #4
0
 private static bool CheckNearestNodeIntersection(TriangleMeshNode node, VInt3 srcLoc, VInt3 destLoc, ref int edge)
 {
     if (!node.ContainsPoint(destLoc))
     {
         int     num      = 0;
         VInt3[] numArray = _staticVerts;
         node.GetPoints(out numArray[0], out numArray[1], out numArray[2]);
         float   maxValue = float.MaxValue;
         int     num3     = -1;
         Vector3 vector   = (Vector3)srcLoc;
         Vector3 vector2  = (Vector3)destLoc;
         for (int i = 0; i < 3; i++)
         {
             if (Polygon.Intersects(numArray[i], numArray[(i + 1) % 3], srcLoc, destLoc))
             {
                 bool flag;
                 num++;
                 Vector3 b = Polygon.IntersectionPoint((Vector3)numArray[i], (Vector3)numArray[(i + 1) % 3], vector, vector2, out flag);
                 DebugHelper.Assert(flag);
                 float num5 = vector.XZSqrMagnitude(ref b);
                 if (num5 < maxValue)
                 {
                     maxValue = num5;
                     num3     = i;
                 }
             }
         }
         if ((num != 2) || (num3 == -1))
         {
             object[] args = new object[] { srcLoc, destLoc, node.NodeIndex, acotrName };
             string   str  = string.Format("Nav: Can't move, src:{0}, dest:{1}, node:{2}, actor:{3}", args);
             return(false);
         }
         edge = num3;
     }
     return(true);
 }
Example #5
0
 private static void MoveFromNode(TriangleMeshNode node, int startEdge, VInt3 srcLoc, VInt3 destLoc, MoveDirectionState state, out VInt3 result)
 {
     result = srcLoc;
     while (node != null)
     {
         int num;
         int num10;
         int count = 2;
         if (node.IsVertex(srcLoc, out num))
         {
             int vertexIndex             = node.GetVertexIndex(num);
             List <TMNodeInfo> nodeInfos = null;
             GetAllNodesByVert(ref nodeInfos, node, vertexIndex);
             TriangleMeshNode node2 = null;
             int vi = -1;
             for (int i = 0; i < nodeInfos.Count; i++)
             {
                 TMNodeInfo info = nodeInfos[i];
                 if ((!checkedNodes.Contains(info.node) && !Polygon.LeftNotColinear(info.v0, info.v2, destLoc)) && Polygon.Left(info.v0, info.v1, destLoc))
                 {
                     node2 = info.node;
                     vi    = info.vi;
                     break;
                 }
             }
             if (node2 != null)
             {
                 node      = node2;
                 startEdge = (vi + 1) % 3;
                 count     = 1;
             }
             else
             {
                 int     num6   = -1;
                 VFactor factor = new VFactor {
                     nom = -2L,
                     den = 1L
                 };
                 for (int j = 0; j < nodeInfos.Count; j++)
                 {
                     TMNodeInfo info2 = nodeInfos[j];
                     if (!checkedNodes.Contains(info2.node))
                     {
                         int     num8;
                         VFactor factor2 = info2.GetCosineAngle(destLoc, state, out num8);
                         if (factor2 > factor)
                         {
                             factor = factor2;
                             num6   = num8;
                             node2  = info2.node;
                         }
                     }
                 }
                 if (node2 != null)
                 {
                     MoveAlongEdge(node2, num6, srcLoc, destLoc, state, out result, true);
                     break;
                 }
             }
         }
         int edge = -1;
         if (startEdge == -1)
         {
             edge = node.EdgeIntersect(srcLoc, destLoc);
         }
         else
         {
             edge = node.EdgeIntersect(srcLoc, destLoc, startEdge, count);
         }
         if (edge == -1)
         {
             if (node.ContainsPoint(destLoc))
             {
                 result = destLoc;
                 if (MoveAxisY)
                 {
                     CalculateY(ref result, node);
                 }
             }
             else
             {
                 edge = node.GetColinearEdge(srcLoc, destLoc);
                 if (edge != -1)
                 {
                     MoveAlongEdge(node, edge, srcLoc, destLoc, state, out result, true);
                 }
             }
             break;
         }
         TriangleMeshNode neighborByEdge = node.GetNeighborByEdge(edge, out num10);
         if (neighborByEdge != null)
         {
             node      = neighborByEdge;
             startEdge = num10 + 1;
             count     = 2;
         }
         else
         {
             MoveAlongEdge(node, edge, srcLoc, destLoc, state, out result, true);
             break;
         }
     }
 }
Example #6
0
    private static void MoveAlongEdge(TriangleMeshNode node, int edge, VInt3 srcLoc, VInt3 destLoc, MoveDirectionState state, out VInt3 result, bool checkAnotherEdge = true)
    {
        bool flag;

        DebugHelper.Assert((edge >= 0) && (edge <= 2));
        VInt3 vertex = node.GetVertex(edge);
        VInt3 num2   = node.GetVertex((edge + 1) % 3);
        VInt3 a      = destLoc - srcLoc;

        a.y = 0;
        VInt3 lhs = num2 - vertex;

        lhs.y = 0;
        lhs.NormalizeTo(0x3e8);
        int num5 = 0;

        if (state != null)
        {
            num5 = a.magnitude2D * 0x3e8;
            VInt3 num6 = !state.enabled ? a : state.firstAdjDir;
            if (VInt3.Dot(ref lhs, ref num6) < 0)
            {
                num5 = -num5;
                num6 = -lhs;
            }
            else
            {
                num6 = lhs;
            }
            if (!state.enabled)
            {
                state.enabled     = true;
                state.firstAdjDir = VInt3.Lerp(a, num6, 1, 3);
                state.firstDir    = state.curDir;
                state.adjDir      = num6;
            }
            else if (VInt3.Dot(ref state.adjDir, ref num6) >= 0)
            {
                state.adjDir = num6;
            }
            else
            {
                num5 = 0;
            }
            state.applied = true;
        }
        else
        {
            num5 = (lhs.x * a.x) + (lhs.z * a.z);
        }
        VInt3 rhs = Polygon.IntersectionPoint(ref vertex, ref num2, ref srcLoc, ref destLoc, out flag);

        if (!flag)
        {
            if (!Polygon.IsColinear(vertex, num2, srcLoc) || !Polygon.IsColinear(vertex, num2, destLoc))
            {
                result = srcLoc;
                return;
            }
            if (num5 >= 0)
            {
                int num8 = (lhs.x * (num2.x - vertex.x)) + (lhs.z * (num2.z - vertex.z));
                int num9 = (lhs.x * (destLoc.x - vertex.x)) + (lhs.z * (destLoc.z - vertex.z));
                rhs = (num8 <= num9) ? num2 : destLoc;
                DebugHelper.Assert((num8 >= 0) && (num9 >= 0));
            }
            else
            {
                int num10 = (-lhs.x * (vertex.x - num2.x)) - (lhs.z * (vertex.z - num2.z));
                int num11 = (-lhs.x * (destLoc.x - num2.x)) - (lhs.z * (destLoc.z - num2.z));
                rhs = (Mathf.Abs(num10) <= Mathf.Abs(num11)) ? vertex : destLoc;
                DebugHelper.Assert((num10 >= 0) && (num11 >= 0));
            }
        }
        int num12 = -IntMath.Sqrt(vertex.XZSqrMagnitude(rhs) * 0xf4240L);
        int num13 = IntMath.Sqrt(num2.XZSqrMagnitude(rhs) * 0xf4240L);

        if ((num5 >= num12) && (num5 <= num13))
        {
            result = IntMath.Divide(lhs, (long)num5, 0xf4240L) + rhs;
            if (!node.ContainsPoint(result))
            {
                int     num16;
                int     num17;
                int     num18;
                int     num19;
                Vector3 vector = (Vector3)(num2 - vertex);
                vector.y = 0f;
                vector.Normalize();
                VInt3 num14 = num2 - vertex;
                num14.y = 0;
                num14  *= 0x2710;
                long    magnitude = num14.magnitude;
                VFactor factor    = new VFactor {
                    nom = num5,
                    den = magnitude * 0x3e8L
                };
                getMinMax(out num16, out num18, (long)num14.x, ref factor);
                getMinMax(out num17, out num19, (long)num14.z, ref factor);
                if (!MakePointInTriangle(ref result, node, num16, num18, num17, num19, srcLoc) && !MakePointInTriangle(ref result, node, num16 - 4, num18 + 4, num17 - 4, num19 + 4, srcLoc))
                {
                    result = srcLoc;
                }
            }
            if (MoveAxisY)
            {
                CalculateY(ref result, node);
            }
        }
        else
        {
            int   num20;
            int   num21;
            VInt3 num22;
            int   num24;
            if (num5 < num12)
            {
                num20 = num5 - num12;
                num21 = (edge + 2) % 3;
                num22 = vertex;
            }
            else
            {
                num20 = num5 - num13;
                num21 = (edge + 1) % 3;
                num22 = num2;
            }
            VInt3            num23          = (VInt3)((lhs * num20) / 1000000f);
            TriangleMeshNode neighborByEdge = node.GetNeighborByEdge(num21, out num24);
            if (neighborByEdge != null)
            {
                checkedNodes.Add(node);
                MoveFromNode(neighborByEdge, num24, num22, num23 + num22, state, out result);
            }
            else
            {
                if (checkAnotherEdge)
                {
                    VInt3 num27 = node.GetVertex((edge + 2) % 3) - num22;
                    if (VInt3.Dot(num27.NormalizeTo(0x3e8), num23) > 0)
                    {
                        checkedNodes.Add(node);
                        MoveAlongEdge(node, num21, num22, num23 + num22, state, out result, false);
                        return;
                    }
                }
                result = num22;
            }
        }
    }
Example #7
0
    private static void MoveAlongEdge(TriangleMeshNode node, int edge, VInt3 srcLoc, VInt3 destLoc, out VInt3 result)
    {
        bool flag;

        DebugHelper.Assert((edge >= 0) && (edge <= 2));
        VInt3 vertex = node.GetVertex(edge);
        VInt3 num2   = node.GetVertex((edge + 1) % 3);
        VInt3 num3   = destLoc - srcLoc;

        num3.y = 0;
        VInt3 a = num2 - vertex;

        a.y = 0;
        a.NormalizeTo(0x3e8);
        int   num5 = (a.x * num3.x) + (a.z * num3.z);
        VInt3 rhs  = Polygon.IntersectionPoint(ref vertex, ref num2, ref srcLoc, ref destLoc, out flag);

        if (!flag)
        {
            if (!Polygon.IsColinear(vertex, num2, srcLoc) || !Polygon.IsColinear(vertex, num2, destLoc))
            {
                result = srcLoc;
                return;
            }
            if (num5 >= 0)
            {
                int num7 = (a.x * (num2.x - vertex.x)) + (a.z * (num2.z - vertex.z));
                int num8 = (a.x * (destLoc.x - vertex.x)) + (a.z * (destLoc.z - vertex.z));
                rhs = (num7 <= num8) ? num2 : destLoc;
                DebugHelper.Assert((num7 >= 0) && (num8 >= 0));
            }
            else
            {
                int num9  = (-a.x * (vertex.x - num2.x)) - (a.z * (vertex.z - num2.z));
                int num10 = (-a.x * (destLoc.x - num2.x)) - (a.z * (destLoc.z - num2.z));
                rhs = (Mathf.Abs(num9) <= Mathf.Abs(num10)) ? vertex : destLoc;
                DebugHelper.Assert((num9 >= 0) && (num10 >= 0));
            }
        }
        int num11 = -IntMath.Sqrt(vertex.XZSqrMagnitude(rhs) * 0xf4240L);
        int num12 = IntMath.Sqrt(num2.XZSqrMagnitude(rhs) * 0xf4240L);

        if ((num5 >= num11) && (num5 <= num12))
        {
            result = IntMath.Divide(a, (long)num5, 0xf4240L) + srcLoc;
            if (!node.ContainsPoint(result))
            {
                int     num15;
                int     num16;
                int     num17;
                int     num18;
                Vector3 vector = (Vector3)(num2 - vertex);
                vector.y = 0f;
                vector.Normalize();
                VInt3 num13 = num2 - vertex;
                num13.y = 0;
                num13  *= 0x2710;
                long    magnitude = num13.magnitude;
                VFactor factor    = new VFactor {
                    nom = num5,
                    den = magnitude * 0x3e8L
                };
                getMinMax(out num15, out num17, (long)num13.x, ref factor);
                getMinMax(out num16, out num18, (long)num13.z, ref factor);
                if (!MakePointInTriangle(ref result, node, num15, num17, num16, num18, srcLoc) && !MakePointInTriangle(ref result, node, num15 - 4, num17 + 4, num16 - 4, num18 + 4, srcLoc))
                {
                    result = srcLoc;
                }
            }
            if (MoveAxisY)
            {
                CalculateY(ref result, node);
            }
        }
        else
        {
            int   num19;
            int   num20;
            VInt3 num21;
            int   num22;
            if (num5 < num11)
            {
                num19 = num5 - num11;
                num20 = (edge + 2) % 3;
                num21 = vertex;
            }
            else
            {
                num19 = num5 - num12;
                num20 = (edge + 1) % 3;
                num21 = num2;
            }
            TriangleMeshNode neighborByEdge = node.GetNeighborByEdge(num20, out num22);
            if (neighborByEdge != null)
            {
                VInt3 num23 = ((VInt3)((a * num19) / 1000000f)) + num21;
                checkedNodes.Add(node);
                MoveFromNode(neighborByEdge, num22, num21, num23, out result);
            }
            else
            {
                result = num21;
            }
        }
    }
 private static void MoveFromNode(TriangleMeshNode node, int startEdge, VInt3 srcLoc, VInt3 destLoc, MoveDirectionState state, out VInt3 result)
 {
     result = srcLoc;
     while (node != null)
     {
         int count = 2;
         int i;
         if (node.IsVertex(srcLoc, out i))
         {
             int vertexIndex = node.GetVertexIndex(i);
             List <PathfindingUtility.TMNodeInfo> list = null;
             PathfindingUtility.GetAllNodesByVert(ref list, node, vertexIndex);
             TriangleMeshNode triangleMeshNode = null;
             int num = -1;
             for (int j = 0; j < list.get_Count(); j++)
             {
                 PathfindingUtility.TMNodeInfo tMNodeInfo = list.get_Item(j);
                 if (!PathfindingUtility.checkedNodes.Contains(tMNodeInfo.node) && !Polygon.LeftNotColinear(tMNodeInfo.v0, tMNodeInfo.v2, destLoc) && Polygon.Left(tMNodeInfo.v0, tMNodeInfo.v1, destLoc))
                 {
                     triangleMeshNode = tMNodeInfo.node;
                     num = tMNodeInfo.vi;
                     break;
                 }
             }
             if (triangleMeshNode != null)
             {
                 node      = triangleMeshNode;
                 startEdge = (num + 1) % 3;
                 count     = 1;
             }
             else
             {
                 int     edge = -1;
                 VFactor b    = new VFactor
                 {
                     nom = -2L,
                     den = 1L
                 };
                 for (int k = 0; k < list.get_Count(); k++)
                 {
                     PathfindingUtility.TMNodeInfo tMNodeInfo2 = list.get_Item(k);
                     if (!PathfindingUtility.checkedNodes.Contains(tMNodeInfo2.node))
                     {
                         int     num2;
                         VFactor cosineAngle = tMNodeInfo2.GetCosineAngle(destLoc, state, out num2);
                         if (cosineAngle > b)
                         {
                             b                = cosineAngle;
                             edge             = num2;
                             triangleMeshNode = tMNodeInfo2.node;
                         }
                     }
                 }
                 if (triangleMeshNode != null)
                 {
                     PathfindingUtility.MoveAlongEdge(triangleMeshNode, edge, srcLoc, destLoc, state, out result, true);
                     break;
                 }
             }
         }
         int num3;
         if (startEdge == -1)
         {
             num3 = node.EdgeIntersect(srcLoc, destLoc);
         }
         else
         {
             num3 = node.EdgeIntersect(srcLoc, destLoc, startEdge, count);
         }
         if (num3 == -1)
         {
             if (node.ContainsPoint(destLoc))
             {
                 result = destLoc;
                 if (PathfindingUtility.MoveAxisY)
                 {
                     PathfindingUtility.CalculateY(ref result, node);
                 }
             }
             else
             {
                 num3 = node.GetColinearEdge(srcLoc, destLoc);
                 if (num3 != -1)
                 {
                     PathfindingUtility.MoveAlongEdge(node, num3, srcLoc, destLoc, state, out result, true);
                 }
             }
             break;
         }
         int num4;
         TriangleMeshNode neighborByEdge = node.GetNeighborByEdge(num3, out num4);
         if (neighborByEdge == null)
         {
             PathfindingUtility.MoveAlongEdge(node, num3, srcLoc, destLoc, state, out result, true);
             break;
         }
         node      = neighborByEdge;
         startEdge = num4 + 1;
     }
 }
    private static void MoveAlongEdge(TriangleMeshNode node, int edge, VInt3 srcLoc, VInt3 destLoc, MoveDirectionState state, out VInt3 result, bool checkAnotherEdge = true)
    {
        DebugHelper.Assert(edge >= 0 && edge <= 2);
        VInt3 vertex  = node.GetVertex(edge);
        VInt3 vertex2 = node.GetVertex((edge + 1) % 3);
        VInt3 vInt    = destLoc - srcLoc;

        vInt.y = 0;
        VInt3 vInt2 = vertex2 - vertex;

        vInt2.y = 0;
        vInt2.NormalizeTo(1000);
        int num;

        if (state != null)
        {
            num = vInt.magnitude2D * 1000;
            VInt3 vInt3 = state.enabled ? state.firstAdjDir : vInt;
            if (VInt3.Dot(ref vInt2, ref vInt3) < 0)
            {
                num   = -num;
                vInt3 = -vInt2;
            }
            else
            {
                vInt3 = vInt2;
            }
            if (!state.enabled)
            {
                state.enabled     = true;
                state.firstAdjDir = VInt3.Lerp(vInt, vInt3, 1, 3);
                state.firstDir    = state.curDir;
                state.adjDir      = vInt3;
            }
            else if (VInt3.Dot(ref state.adjDir, ref vInt3) >= 0)
            {
                state.adjDir = vInt3;
            }
            else
            {
                num = 0;
            }
            state.applied = true;
        }
        else
        {
            num = vInt2.x * vInt.x + vInt2.z * vInt.z;
        }
        bool  flag;
        VInt3 rhs = Polygon.IntersectionPoint(ref vertex, ref vertex2, ref srcLoc, ref destLoc, out flag);

        if (!flag)
        {
            if (!Polygon.IsColinear(vertex, vertex2, srcLoc) || !Polygon.IsColinear(vertex, vertex2, destLoc))
            {
                result = srcLoc;
                return;
            }
            if (num >= 0)
            {
                int num2 = vInt2.x * (vertex2.x - vertex.x) + vInt2.z * (vertex2.z - vertex.z);
                int num3 = vInt2.x * (destLoc.x - vertex.x) + vInt2.z * (destLoc.z - vertex.z);
                rhs = ((num2 > num3) ? destLoc : vertex2);
                DebugHelper.Assert(num2 >= 0 && num3 >= 0);
            }
            else
            {
                int num4 = -vInt2.x * (vertex.x - vertex2.x) - vInt2.z * (vertex.z - vertex2.z);
                int num5 = -vInt2.x * (destLoc.x - vertex2.x) - vInt2.z * (destLoc.z - vertex2.z);
                rhs = ((Mathf.Abs(num4) > Mathf.Abs(num5)) ? destLoc : vertex);
                DebugHelper.Assert(num4 >= 0 && num5 >= 0);
            }
        }
        int num6 = -IntMath.Sqrt(vertex.XZSqrMagnitude(rhs) * 1000000L);
        int num7 = IntMath.Sqrt(vertex2.XZSqrMagnitude(rhs) * 1000000L);

        if (num >= num6 && num <= num7)
        {
            result = IntMath.Divide(vInt2, (long)num, 1000000L) + rhs;
            if (!node.ContainsPoint(result))
            {
                Vector3 vector = (Vector3)(vertex2 - vertex);
                vector.y = 0f;
                vector.Normalize();
                VInt3 lhs = vertex2 - vertex;
                lhs.y = 0;
                lhs  *= 10000;
                long    num8    = (long)lhs.magnitude;
                VFactor vFactor = default(VFactor);
                vFactor.nom = (long)num;
                vFactor.den = num8 * 1000L;
                int num9;
                int num10;
                PathfindingUtility.getMinMax(out num9, out num10, (long)lhs.x, ref vFactor);
                int num11;
                int num12;
                PathfindingUtility.getMinMax(out num11, out num12, (long)lhs.z, ref vFactor);
                if (!PathfindingUtility.MakePointInTriangle(ref result, node, num9, num10, num11, num12, srcLoc) && !PathfindingUtility.MakePointInTriangle(ref result, node, num9 - 4, num10 + 4, num11 - 4, num12 + 4, srcLoc))
                {
                    result = srcLoc;
                }
            }
            if (PathfindingUtility.MoveAxisY)
            {
                PathfindingUtility.CalculateY(ref result, node);
            }
        }
        else
        {
            int   rhs2;
            int   edge2;
            VInt3 vInt4;
            if (num < num6)
            {
                rhs2  = num - num6;
                edge2 = (edge + 2) % 3;
                vInt4 = vertex;
            }
            else
            {
                rhs2  = num - num7;
                edge2 = (edge + 1) % 3;
                vInt4 = vertex2;
            }
            VInt3            vInt5 = vInt2 * rhs2 / 1000000f;
            int              startEdge;
            TriangleMeshNode neighborByEdge = node.GetNeighborByEdge(edge2, out startEdge);
            if (neighborByEdge != null)
            {
                PathfindingUtility.checkedNodes.Add(node);
                PathfindingUtility.MoveFromNode(neighborByEdge, startEdge, vInt4, vInt5 + vInt4, state, out result);
            }
            else
            {
                if (checkAnotherEdge)
                {
                    VInt3 vertex3 = node.GetVertex((edge + 2) % 3);
                    VInt3 lhs2    = (vertex3 - vInt4).NormalizeTo(1000);
                    if (VInt3.Dot(lhs2, vInt5) > 0)
                    {
                        PathfindingUtility.checkedNodes.Add(node);
                        PathfindingUtility.MoveAlongEdge(node, edge2, vInt4, vInt5 + vInt4, state, out result, false);
                        return;
                    }
                }
                result = vInt4;
            }
        }
    }
Example #10
0
    // this is a utility function used by IsVisibleOnNavMeshOptimized, before calling this function is should be determined that the line 'from' -> 'to' starts outside
    // the triangle, and enters the triangle, this function will then determine if the line exits the triangle
    // the exitPoint returned will be on the ground plane
    private static bool DoesLineExitTriangle(Vector3 from, Vector3 to, TriangleMeshNode currentTriangle, ref HashSet <TriangleMeshNode> previousTriangles, ref TriangleMeshNode nextTriangle, ref Vector3 exitPoint)
    {
        if (currentTriangle.ContainsPoint((Int3)to)) // does the line end in this triangle
        {
            return(false);                           // the line does not exit this triangle
        }

        const int NumVerts = 3;

        if (null != currentTriangle.connections)
        {
            for (int connect = 0; connect < currentTriangle.connections.Length; connect++) // go through all our connections
            {
                TriangleMeshNode other = currentTriangle.connections[connect] as TriangleMeshNode;

                int edge      = -1;
                int otherEdge = -1;
                if (other != null && !previousTriangles.Contains(other) && SharedEdge(currentTriangle, other, ref edge, ref otherEdge)) // get the connecting edge
                {
                    bool intersectsEdge      = false;
                    bool intersectsOtherEdge = true;
                    // check to see if the line enters the other triangle through this edge
                    exitPoint = VectorMath.SegmentIntersectionPointXZ(from, to, (Vector3)currentTriangle.GetVertex(edge), (Vector3)currentTriangle.GetVertex((edge + 1) % NumVerts), out intersectsEdge);

                    int tileIndex      = (currentTriangle.GetVertexIndex(0) >> RecastGraph.TileIndexOffset) & RecastGraph.TileIndexMask;
                    int otherTileIndex = (other.GetVertexIndex(0) >> RecastGraph.TileIndexOffset) & RecastGraph.TileIndexMask;
                    if (tileIndex != otherTileIndex) // if the edjoining triangles are on different tiles, the edges may not match exactly, so we need to be sure that both triangles edges are intersected
                    {
                        exitPoint = VectorMath.SegmentIntersectionPointXZ(from, to, (Vector3)other.GetVertex(otherEdge), (Vector3)other.GetVertex((otherEdge + 1) % NumVerts), out intersectsOtherEdge);
                    }
                    if (intersectsEdge && intersectsOtherEdge)
                    {
                        nextTriangle = other;
                        return(true);
                    }
                }
            }
        }

        Vector3 prevVertPos             = (Vector3)currentTriangle.GetVertex(0);
        float   farthestIntersectionSqr = -1f;

        for (int vert = 1; vert <= NumVerts; ++vert) // go over all the edges, to see which one the line passes out of, so we can calculate the triangle exit point
        {
            Vector3 vertPos = (Vector3)currentTriangle.GetVertex(vert % NumVerts);

            bool    intersects         = false;
            Vector3 potentialExitPoint = VectorMath.SegmentIntersectionPointXZ(from, to, prevVertPos, vertPos, out intersects);
            if (intersects)
            {
                float intersectionSqr = (potentialExitPoint - from).sqrMagnitude;
                // we're looking for the farthest intersection, as the nearest intersection would have been the edge intersected when the line entered the triangle
                if (intersectionSqr > farthestIntersectionSqr)
                {
                    farthestIntersectionSqr = intersectionSqr;
                    exitPoint = potentialExitPoint;
                }
            }
            prevVertPos = vertPos;
        }
        return(farthestIntersectionSqr > 0f);
    }
    private static void MoveAlongEdge(TriangleMeshNode node, int edge, Int3 srcLoc, Int3 destLoc, out Int3 result, bool checkAnotherEdge = true)
    {
        Int3 vertex  = node.GetVertex(edge);
        Int3 vertex2 = node.GetVertex((edge + 1) % 3);
        Int3 vInt    = destLoc - srcLoc;

        vInt.y = 0;
        Int3 vInt2 = vertex2 - vertex;

        vInt2.y = 0;
        vInt2.NormalizeTo(1000);
        int num;

        num = vInt2.x * vInt.x + vInt2.z * vInt.z;

        bool flag;
        Int3 rhs = Polygon.IntersectionPoint(ref vertex, ref vertex2, ref srcLoc, ref destLoc, out flag);

        if (!flag)
        {
            if (!Polygon.IsColinear(vertex, vertex2, srcLoc) || !Polygon.IsColinear(vertex, vertex2, destLoc))
            {
                result = srcLoc;
                return;
            }
            if (num >= 0)
            {
                int num2 = vInt2.x * (vertex2.x - vertex.x) + vInt2.z * (vertex2.z - vertex.z);
                int num3 = vInt2.x * (destLoc.x - vertex.x) + vInt2.z * (destLoc.z - vertex.z);
                rhs = ((num2 <= num3) ? vertex2 : destLoc);
            }
            else
            {
                int num4 = -vInt2.x * (vertex.x - vertex2.x) - vInt2.z * (vertex.z - vertex2.z);
                int num5 = -vInt2.x * (destLoc.x - vertex2.x) - vInt2.z * (destLoc.z - vertex2.z);
                rhs = ((Mathf.Abs(num4) <= Mathf.Abs(num5)) ? vertex : destLoc);
            }
        }
        int num6 = -IntMath.Sqrt(vertex.XZSqrMagnitude(rhs) * 1000000L);
        int num7 = IntMath.Sqrt(vertex2.XZSqrMagnitude(rhs) * 1000000L);

        if (num >= num6 && num <= num7)
        {
            result = IntMath.Divide(vInt2, (long)num, 1000000L) + rhs;
            if (!node.ContainsPoint(result))
            {
                Vector3 vector = (Vector3)(vertex2 - vertex);
                vector.y = 0f;
                vector.Normalize();
                Int3 lhs = vertex2 - vertex;
                lhs.y = 0;
                lhs  *= 10000;
                long      num8    = (long)lhs.magnitude;
                IntFactor vFactor = default(IntFactor);
                vFactor.numerator   = (long)num;
                vFactor.denominator = num8 * 1000L;
                int num9;
                int num10;
                PathfindingUtility.getMinMax(out num9, out num10, (long)lhs.x, ref vFactor);
                int num11;
                int num12;
                PathfindingUtility.getMinMax(out num11, out num12, (long)lhs.z, ref vFactor);
                if (!PathfindingUtility.MakePointInTriangle(ref result, node, num9, num10, num11, num12, srcLoc) && !PathfindingUtility.MakePointInTriangle(ref result, node, num9 - 4, num10 + 4, num11 - 4, num12 + 4, srcLoc))
                {
                    result = srcLoc;
                }
            }
            if (PathfindingUtility.MoveAxisY)
            {
                PathfindingUtility.CalculateY(ref result, node);
            }
        }
        else
        {
            int  rhs2;
            int  edge2;
            Int3 vInt4;
            if (num < num6)
            {
                rhs2  = num - num6;
                edge2 = (edge + 2) % 3;
                vInt4 = vertex;
            }
            else
            {
                rhs2  = num - num7;
                edge2 = (edge + 1) % 3;
                vInt4 = vertex2;
            }
            Int3             vInt5 = vInt2 * rhs2 / 1000000f;
            int              startEdge;
            TriangleMeshNode neighborByEdge = node.GetNeighborByEdge(edge2, out startEdge);
            if (neighborByEdge != null)
            {
                PathfindingUtility.checkedNodes.Add(node);
                PathfindingUtility.MoveFromNode(neighborByEdge, startEdge, vInt4, vInt5 + vInt4, out result);
            }
            else
            {
                if (checkAnotherEdge)
                {
                    Int3 vertex3 = node.GetVertex((edge + 2) % 3);
                    Int3 lhs2    = (vertex3 - vInt4).NormalizeTo(1000);
                    if (Int3.Dot(lhs2, vInt5) > 0)
                    {
                        PathfindingUtility.checkedNodes.Add(node);
                        PathfindingUtility.MoveAlongEdge(node, edge2, vInt4, vInt5 + vInt4, out result, false);
                        return;
                    }
                }
                result = vInt4;
            }
        }
    }