示例#1
0
    static bool getSteerTarget(Detour.dtNavMeshQuery navQuery, float[] startPos, float[] endPos,
                               float minTargetDist,
                               dtPolyRef[] path, int pathSize,
                               float[] steerPos, ref byte steerPosFlag, ref dtPolyRef steerPosRef,
                               ref float[] outPoints, ref int outPointCount)
    {
        // Find steer target.
        const int MAX_STEER_POINTS = 3;

        float[]     steerPath      = new float[MAX_STEER_POINTS * 3];
        byte[]      steerPathFlags = new byte[MAX_STEER_POINTS];
        dtPolyRef[] steerPathPolys = new dtPolyRef[MAX_STEER_POINTS];
        int         nsteerPath     = 0;

        navQuery.findStraightPath(startPos, endPos, path, pathSize,
                                  steerPath, steerPathFlags, steerPathPolys, ref nsteerPath, MAX_STEER_POINTS, 0);
        if (nsteerPath == 0)
        {
            return(false);
        }

        //if (outPoints && outPointCount)
        //{
        outPointCount = nsteerPath;
        for (int i = 0; i < nsteerPath; ++i)
        {
            Detour.dtVcopy(outPoints, i * 3, steerPath, i * 3);
        }
        //}


        // Find vertex far enough to steer to.
        int ns = 0;

        while (ns < nsteerPath)
        {
            // Stop at Off-Mesh link or when point is further than slop away.
            if ((steerPathFlags[ns] & (byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0 ||
                !inRange(steerPath, ns * 3, startPos, 0, minTargetDist, 1000.0f))
            {
                break;
            }
            ns++;
        }
        // Failed to find good point to steer to.
        if (ns >= nsteerPath)
        {
            return(false);
        }

        Detour.dtVcopy(steerPos, 0, steerPath, ns * 3);
        steerPos[1]  = startPos[1];
        steerPosFlag = steerPathFlags[ns];
        steerPosRef  = steerPathPolys[ns];

        return(true);
    }
示例#2
0
    public static StraightPath ComputeStraightPath(Detour.dtNavMeshQuery navQuery, float[] startPos, float[] endPos, float distance = 10)
    {
        //m_ComputedPathType = PathType.Straight;

        StraightPath path = new StraightPath();

        float[] extents = new float[3];
        for (int i = 0; i < 3; ++i)
        {
            extents[i] = distance;
        }

        dtPolyRef startRef = 0;
        dtPolyRef endRef   = 0;

        float[] startPt = new float[3];
        float[] endPt   = new float[3];

        Detour.dtQueryFilter filter = new Detour.dtQueryFilter();

        navQuery.findNearestPoly(startPos, extents, filter, ref startRef, ref startPt);
        navQuery.findNearestPoly(endPos, extents, filter, ref endRef, ref endPt);

        int pathCount = -1;

        navQuery.findPath(startRef, endRef, startPt, endPt, filter, path.m_RawPathPolys, ref pathCount, StraightPath.MAX_POLYS);

        path.m_RawPathLength = pathCount;

        if (pathCount > 0)
        {
            // In case of partial path, make sure the end point is clamped to the last polygon.
            float[] epos = new float[3];
            Detour.dtVcopy(epos, endPt);
            if (path.m_RawPathPolys[pathCount - 1] != endRef)
            {
                bool posOverPoly = false;
                navQuery.closestPointOnPoly(path.m_RawPathPolys[pathCount - 1], endPt, epos, ref posOverPoly);
            }

            navQuery.findStraightPath(startPt, endPt, path.m_RawPathPolys, pathCount,
                                      path.m_straightPath, path.m_straightPathFlags,
                                      path.m_straightPathPolys, ref path.m_straightPathCount,
                                      StraightPath.MAX_POLYS, path.m_straightPathOptions);
        }

        return(path);
    }
示例#3
0
    public Queue <Position> FindPathBetween(Position start, Position end, bool useStraightPath = false)
    {
        var path = new Queue <Position>();

        if (dtNavMesh == null)
        {
            return(path);
        }
        var startDetourPosition = start.ToDetourPosition();
        var endDetourPosition   = end.ToDetourPosition();

        var queryFilter  = new Detour.dtQueryFilter();
        var navMeshQuery = new Detour.dtNavMeshQuery();

        var status = navMeshQuery.init(dtNavMesh, MAX_PATH);

        if (Detour.dtStatusFailed(status))
        {
            return(path);
        }
        queryFilter.setIncludeFlags(0xffff);
        queryFilter.setExcludeFlags(0x0);

        uint startRef = 0;
        uint endRef   = 0;

        float[] startNearest = new float[3];
        float[] endNearest   = new float[3];

        float[] extents = new float[] { 10.0F, 25.0F, 10.0F };

        status = navMeshQuery.findNearestPoly(startDetourPosition, extents, queryFilter, ref startRef, ref startNearest);

        if (Detour.dtStatusFailed(status))
        {
            return(path);
        }

        status = navMeshQuery.findNearestPoly(endDetourPosition, extents, queryFilter, ref endRef, ref endNearest);

        if (Detour.dtStatusFailed(status))
        {
            return(path);
        }

        if (!dtNavMesh.isValidPolyRef(startRef) || !dtNavMesh.isValidPolyRef(endRef))
        {
            return(path);
        }

        uint[] pathPolys = new uint[MAX_PATH];
        int    pathCount = 0;

        float[] straightPath      = new float[MAX_PATH * 3];
        byte[]  straightPathFlags = new byte[MAX_PATH];
        uint[]  straightPathPolys = new uint[MAX_PATH];
        int     straightPathCount = 0;

        status = navMeshQuery.findPath(
            startRef,
            endRef,
            startNearest,
            endNearest,
            queryFilter,
            pathPolys,
            ref pathCount,
            MAX_PATH
            );

        if (Detour.dtStatusFailed(status))
        {
            path.Enqueue(start);
            path.Enqueue(end);
            return(path);
        }

        status = navMeshQuery.findStraightPath(
            startNearest,
            endNearest,
            pathPolys,
            pathCount,
            straightPath,
            straightPathFlags,
            straightPathPolys,
            ref straightPathCount,
            MAX_PATH,
            (int)Detour.dtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS
            );

        if (Detour.dtStatusFailed(status))
        {
            path.Enqueue(start);
            path.Enqueue(end);
            return(path);
        }

        if (straightPathCount > 0)
        {
            if (Detour.dtStatusFailed(status))
            {
                return(path);
            }

            for (int i = 3; i < straightPathCount * 3;)
            {
                float[] pathPos = new float[3];
                pathPos[0] = straightPath[i++];
                pathPos[1] = straightPath[i++];
                pathPos[2] = straightPath[i++];

                var position = ToFFXIPosition(pathPos);

                path.Enqueue(position);
            }
        }
        else
        {
            for (int i = 1; i < pathCount; i++)
            {
                float[] pathPos     = new float[3];
                bool    posOverPoly = false;
                if (Detour.dtStatusFailed(navMeshQuery.closestPointOnPoly(pathPolys[i], startDetourPosition, pathPos, ref posOverPoly)))
                {
                    return(path);
                }

                if (path.Count < 1)
                {
                    if (Detour.dtStatusFailed(navMeshQuery.closestPointOnPolyBoundary(pathPolys[i], startDetourPosition, pathPos)))
                    {
                        return(path);
                    }
                }

                var position = ToFFXIPosition(pathPos);

                path.Enqueue(position);
            }
        }

        if (path.Count < 1)
        {
            path.Enqueue(end);
        }

        return(path);
    }
示例#4
0
    public Queue <Position> FindPathBetween(Position start, Position end, bool useStraightPath = false)
    {
        var path = new Queue <Position>();

        if (dtNavMesh == null)
        {
            EasyFarm.ViewModels.LogViewModel.Write("FindPathBetween: Unable to path due to lacking navigation mesh for zone " + _zone.ToString());
            return(path);
        }
        var startDetourPosition = start.ToDetourPosition();
        var endDetourPosition   = end.ToDetourPosition();

        var queryFilter  = new Detour.dtQueryFilter();
        var navMeshQuery = new Detour.dtNavMeshQuery();

        var status = navMeshQuery.init(dtNavMesh, 256);

        if (Detour.dtStatusFailed(status))
        {
            return(path);
        }

        queryFilter.setIncludeFlags(0xffff);
        queryFilter.setExcludeFlags(0x0);

        uint startRef = 0;
        uint endRef   = 0;

        float[] startNearest = new float[3];
        float[] endNearest   = new float[3];

        float[] extents = new float[] { 10.0F, (float)EasyFarm.UserSettings.Config.Instance.HeightThreshold, 10.0F };

        status = navMeshQuery.findNearestPoly(startDetourPosition, extents, queryFilter, ref startRef, ref startNearest);
        if (Detour.dtStatusFailed(status))
        {
            return(path);
        }

        status = navMeshQuery.findNearestPoly(endDetourPosition, extents, queryFilter, ref endRef, ref endNearest);
        if (Detour.dtStatusFailed(status))
        {
            return(path);
        }

        if (!dtNavMesh.isValidPolyRef(startRef) || !dtNavMesh.isValidPolyRef(endRef))
        {
            return(path);
        }

        uint[] pathPolys = new uint[256];

        int pathCount = 0;

        status = navMeshQuery.findPath(startRef, endRef, startNearest, endNearest, queryFilter, pathPolys, ref pathCount, 256);

        if (Detour.dtStatusFailed(status))
        {
            return(path);
        }

        if (path.Count < 1)
        {
            float[] straightPath      = new float[256 * 3];
            byte[]  straightPathFlags = new byte[256];
            uint[]  straightPathPolys = new uint[256];
            int     straightPathCount = 256 * 3;

            status = navMeshQuery.findStraightPath(
                startNearest,
                endNearest,
                pathPolys,
                pathCount,
                straightPath,
                straightPathFlags,
                straightPathPolys,
                ref straightPathCount,
                256,
                0
                );

            if (straightPathCount > 1)
            {
                if (Detour.dtStatusFailed(status))
                {
                    return(path);
                }

                path.Clear();

                // i starts at 3 so the start position is ignored
                for (int i = 3; i < straightPathCount * 3;)
                {
                    float[] pathPos = new float[3];
                    pathPos[0] = straightPath[i++];
                    pathPos[1] = straightPath[i++];
                    pathPos[2] = straightPath[i++];

                    var position = ToFFXIPosition(pathPos);

                    path.Enqueue(position);
                }
            }
        }
        else
        {
            // i starts at 3 so the start position is ignored
            for (int i = 1; i < pathCount; i++)
            {
                float[] pathPos     = new float[3];
                bool    posOverPoly = false;
                if (Detour.dtStatusFailed(navMeshQuery.closestPointOnPoly(pathPolys[i], startDetourPosition, pathPos, ref posOverPoly)))
                {
                    return(path);
                }

                if (path.Count < 1)
                {
                    if (Detour.dtStatusFailed(navMeshQuery.closestPointOnPolyBoundary(pathPolys[i], startDetourPosition, pathPos)))
                    {
                        return(path);
                    }
                }

                var position = ToFFXIPosition(pathPos);

                path.Enqueue(position);
            }
        }

        return(path);
    }