public static Int3 FindValidTarget(Actor actor, Int3 start, Int3 end, int radius, out bool bResult)
    {
        long num  = (long)radius * (long)radius;
        long num2 = start.XZSqrMagnitude(ref end);

        if (num2 < num)
        {
            return(PathfindingUtility.FindValidTarget(actor, start, end, out bResult));
        }
        Int3 vInt = end - start;
        Int3 end2 = start + vInt.NormalizeTo(radius);

        return(PathfindingUtility.FindValidTarget(actor, start, end2, out bResult));
    }
Esempio n. 2
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="node">所在node</param>
    /// <param name="edge">所沿着的边</param>
    /// <param name="srcLoc">from</param>
    /// <param name="destLoc">to</param>
    /// <param name="result">实际可到达的点</param>
    private static void MoveAlongEdge(NavMeshNode node, int edge, Int3 srcLoc, Int3 destLoc, out Int3 result, bool checkAnotherEdge = true)
    {
        bool flag;
        //DebugHelper.Assert((edge >= 0) && (edge <= 2));
        Int3 vertex = node.GetVertex(edge);
        Int3 num2   = node.GetVertex((edge + 1) % 3);
        Int3 a      = destLoc - srcLoc;

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

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

        // 点乘移动向量和边向量
        num5 = (lhs.x * a.x) + (lhs.z * a.z);

        // 移动向量和边向量的交点
        Int3 rhs = Polygon.IntersectionPoint(ref vertex, ref num2, ref srcLoc, ref destLoc, out flag);

        // 不相交?
        if (!flag)
        {
            // 边和from to存在不共线,则不能移动
            if (!VectorMath.IsColinearXZ(vertex, num2, srcLoc) || !VectorMath.IsColinearXZ(vertex, num2, destLoc))
            {
                result = srcLoc;
                return;
            }

            // 计算本三角形内可移动到的点 rhs
            // 移动向量和边向量 同向
            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));
            }
        }

        // 计算交点到边的顶点的距离1000倍
        int num12 = -IntMath.Sqrt(vertex.XZSqrMagnitude(rhs) * 0xf4240L);        // 一百万
        int num13 = IntMath.Sqrt(num2.XZSqrMagnitude(rhs) * 0xf4240L);

        // num5是在边上的投影

        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();
                Int3 num14 = num2 - vertex;
                num14.y = 0;
                num14  *= 10000;
                long    magnitude = num14.magnitude;
                VFactor factor    = new VFactor();
                factor.nom = num5;
                factor.den = magnitude * 1000L;
                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;
            Int3 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;
            }
            Int3        num23          = (Int3)((lhs * num20) / 1000000f);
            NavMeshNode neighborByEdge = node.GetNeighborByEdge(num21, out num24);
            if (neighborByEdge != null)
            {
                checkedNodes.Add(node);
                MoveFromNode(neighborByEdge, num24, num22, num23 + num22, out result);
            }
            else
            {
                if (checkAnotherEdge)
                {
                    Int3 num27 = node.GetVertex((edge + 2) % 3) - num22;
                    if (Int3.Dot(num27.NormalizeTo(1000), num23) > 0)
                    {
                        checkedNodes.Add(node);
                        MoveAlongEdge(node, num21, num22, num23 + num22, out result, false);
                        return;
                    }
                }
                result = num22;
            }
        }
    }
    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;
            }
        }
    }