예제 #1
0
        private void GeneratePathfinding()
        {
            if (!hasGenerated)
            {
                return;
            }

            NavQueryFilter filter = new NavQueryFilter();

            buildData = new NavMeshBuilder(polyMesh, polyMeshDetail, new SharpNav.Pathfinding.OffMeshConnection[0], settings);

            tiledNavMesh = new TiledNavMesh(buildData);

            for (int i = 0; i < tiledNavMesh.Tiles.Count; ++i)
            {
                for (int j = 0; j < tiledNavMesh.Tiles[i].Verts.Length; ++j)
                {
                    //if (j < tiledNavMesh.Tiles[i].Verts.Length - 1)
                    //    Debug.DrawLine(ExportNavMeshToObj.ToUnityVector(tiledNavMesh.Tiles[i].Verts[j]), ExportNavMeshToObj.ToUnityVector(tiledNavMesh.Tiles[i].Verts[j + 1]), Color.blue, 99);
                }
            }

            navMeshQuery = new NavMeshQuery(tiledNavMesh, 2048);

            //Find random start and end points on the poly mesh

            /*int startRef;
             * navMeshQuery.FindRandomPoint(out startRef, out startPos);*/

            //SVector3 c = new SVector3(10, 0, 0);
            //SVector3 e = new SVector3(5, 5, 5);
            //navMeshQuery.FindNearestPoly(ref c, ref e, out startPt);

            //navMeshQuery.FindRandomPointAroundCircle(ref startPt, 1000, out endPt);

            startPt = navMeshQuery.FindRandomPoint();
            endPt   = navMeshQuery.FindRandomPoint();

            //calculate the overall path, which contains an array of polygon references
            int MAX_POLYS = 256;

            path = new Path();
            navMeshQuery.FindPath(ref startPt, ref endPt, filter, path);

            //find a smooth path over the mesh surface
            int      npolys    = path.Count;
            SVector3 iterPos   = new SVector3();
            SVector3 targetPos = new SVector3();

            navMeshQuery.ClosestPointOnPoly(startPt.Polygon, startPt.Position, ref iterPos);
            navMeshQuery.ClosestPointOnPoly(path[npolys - 1], endPt.Position, ref targetPos);

            smoothPath = new List <SVector3>(2048);
            smoothPath.Add(iterPos);

            float STEP_SIZE = 0.5f;
            float SLOP      = 0.01f;

            while (npolys > 0 && smoothPath.Count < smoothPath.Capacity)
            {
                //find location to steer towards
                SVector3          steerPos     = new SVector3();
                StraightPathFlags steerPosFlag = 0;
                NavPolyId         steerPosRef  = NavPolyId.Null;

                if (!GetSteerTarget(navMeshQuery, iterPos, targetPos, SLOP, path, ref steerPos, ref steerPosFlag, ref steerPosRef))
                {
                    break;
                }

                bool endOfPath         = (steerPosFlag & StraightPathFlags.End) != 0 ? true : false;
                bool offMeshConnection = (steerPosFlag & StraightPathFlags.OffMeshConnection) != 0 ? true : false;

                //find movement delta
                SVector3 delta = steerPos - iterPos;
                float    len   = (float)Math.Sqrt(SVector3.Dot(delta, delta));

                //if steer target is at end of path or off-mesh link
                //don't move past location
                if ((endOfPath || offMeshConnection) && len < STEP_SIZE)
                {
                    len = 1;
                }
                else
                {
                    len = STEP_SIZE / len;
                }

                SVector3 moveTgt = new SVector3();
                VMad(ref moveTgt, iterPos, delta, len);

                //move
                SVector3         result     = new SVector3();
                List <NavPolyId> visited    = new List <NavPolyId>(16);
                NavPoint         startPoint = new NavPoint(path[0], iterPos);
                navMeshQuery.MoveAlongSurface(ref startPoint, ref moveTgt, out result, visited);
                path.FixupCorridor(visited);
                npolys = path.Count;
                float h = 0;
                navMeshQuery.GetPolyHeight(path[0], result, ref h);
                result.Y = h;
                iterPos  = result;

                //handle end of path when close enough
                if (endOfPath && InRange(iterPos, steerPos, SLOP, 1.0f))
                {
                    //reached end of path
                    iterPos = targetPos;
                    if (smoothPath.Count < smoothPath.Capacity)
                    {
                        smoothPath.Add(iterPos);
                    }
                    break;
                }

                //store results
                if (smoothPath.Count < smoothPath.Capacity)
                {
                    smoothPath.Add(iterPos);
                }
            }

            for (int i = 0; i < smoothPath.Count; i++)
            {
                //if (i < smoothPath.Count - 1)
                //    Debug.DrawLine(ExportNavMeshToObj.ToUnityVector(smoothPath[i]), ExportNavMeshToObj.ToUnityVector(smoothPath[i + 1]), Color.red, 99);
            }
        }
예제 #2
0
        //为了使接口适应而附加的
        public List <Vector2> SmothPathfinding(Vector2 start, Vector2 target)
        {
            Random         rand        = new Random();
            SVector3       startVector = new SVector3(start.x_, 0, start.y_);
            SVector3       endVector   = new SVector3(target.x_, 0, target.y_);
            NavQueryFilter filter      = new NavQueryFilter();
            //buildData = new NavMeshBuilder(polyMesh, polyMeshDetail, new SharpNav.Pathfinding.OffMeshConnection[0], settings);
            //tiledNavMesh = new TiledNavMesh(buildData);
            //navMeshQuery = new NavMeshQuery(tiledNavMesh, 2048);
            SVector3 extents = new SVector3(5, 5, 5);

            navMeshQuery.FindNearestPoly(ref startVector, ref extents, out startPt);
            navMeshQuery.FindNearestPoly(ref endVector, ref extents, out endPt);

            path = new SharpNav.Pathfinding.Path();
            navMeshQuery.FindPath(ref startPt, ref endPt, filter, path);

            //find a smooth path over the mesh surface
            int      npolys    = path.Count;
            SVector3 iterPos   = new SVector3();
            SVector3 targetPos = new SVector3();

            navMeshQuery.ClosestPointOnPoly(startPt.Polygon, startPt.Position, ref iterPos);
            navMeshQuery.ClosestPointOnPoly(path[npolys - 1], endPt.Position, ref targetPos);

            smoothPath = new List <SVector3>(2048);
            smoothPath.Add(iterPos);

            float STEP_SIZE = 2f;
            float SLOP      = 0.1f;

            while (npolys > 0 && smoothPath.Count < smoothPath.Capacity)
            {
                //find location to steer towards
                SVector3          steerPos     = new SVector3();
                StraightPathFlags steerPosFlag = 0;
                NavPolyId         steerPosRef  = NavPolyId.Null;

                if (!GetSteerTarget(navMeshQuery, iterPos, targetPos, SLOP, path, ref steerPos, ref steerPosFlag, ref steerPosRef))
                {
                    break;
                }

                bool endOfPath         = (steerPosFlag & StraightPathFlags.End) != 0 ? true : false;
                bool offMeshConnection = (steerPosFlag & StraightPathFlags.OffMeshConnection) != 0 ? true : false;

                //find movement delta
                SVector3 delta = steerPos - iterPos;
                float    len   = (float)Math.Sqrt(SVector3.Dot(delta, delta));

                //if steer target is at end of path or off-mesh link

                //don't move past location
                if ((endOfPath || offMeshConnection) && len < STEP_SIZE)
                {
                    len = 1;
                }
                else
                {
                    len = STEP_SIZE / len;
                }

                SVector3 moveTgt = new SVector3();
                VMad(ref moveTgt, iterPos, delta, len);

                //move
                SVector3         result     = new SVector3();
                List <NavPolyId> visited    = new List <NavPolyId>(16);
                NavPoint         startPoint = new NavPoint(path[0], iterPos);
                navMeshQuery.MoveAlongSurface(ref startPoint, ref moveTgt, out result, visited);
                path.FixupCorridor(visited);
                npolys = path.Count;
                float h = 0;
                navMeshQuery.GetPolyHeight(path[0], result, ref h);
                result.Y = h;
                iterPos  = result;

                //handle end of path when close enough
                if (endOfPath && InRange(iterPos, steerPos, SLOP, 1.0f))
                {
                    //reached end of path
                    iterPos = targetPos;
                    if (smoothPath.Count < smoothPath.Capacity)
                    {
                        smoothPath.Add(iterPos);
                    }
                    break;
                }

                //store results
                if (smoothPath.Count < smoothPath.Capacity)
                {
                    smoothPath.Add(iterPos);
                }
            }
            List <Vector2> _path = new List <Vector2>();

            for (int i = 0; i < smoothPath.Count; i++)
            {
                _path.Add(new Vector2(smoothPath[i].X, smoothPath[i].Z));
            }
            return(_path);
        }
예제 #3
0
        private void GeneratePathfinding()
        {
            if (!hasGenerated)
            {
                return;
            }

            Random rand = new Random();

            buildData = new NavMeshBuilder(polyMesh, polyMeshDetail, new SharpNav.Pathfinding.OffMeshConnection[0], settings);

            tiledNavMesh = new TiledNavMesh(buildData);
            navMeshQuery = new NavMeshQuery(tiledNavMesh, 2048);

            //Find random start and end points on the poly mesh

            /*int startRef;
             * navMeshQuery.FindRandomPoint(out startRef, out startPos);*/

            SVector3 c = new SVector3(10, 0, 0);
            SVector3 e = new SVector3(5, 5, 5);

            navMeshQuery.FindNearestPoly(ref c, ref e, out startPt);

            navMeshQuery.FindRandomPointAroundCircle(startPt, 1000, out endPt);

            //calculate the overall path, which contains an array of polygon references
            int MAX_POLYS = 256;

            path = new List <PolyId>(MAX_POLYS);
            navMeshQuery.FindPath(ref startPt, ref endPt, path);

            //find a smooth path over the mesh surface
            int npolys = path.Count;

            PolyId[] polys     = path.ToArray();
            SVector3 iterPos   = new SVector3();
            SVector3 targetPos = new SVector3();

            navMeshQuery.ClosestPointOnPoly(startPt.Polygon, startPt.Position, ref iterPos);
            navMeshQuery.ClosestPointOnPoly(polys[npolys - 1], endPt.Position, ref targetPos);

            smoothPath = new List <SVector3>(2048);
            smoothPath.Add(iterPos);

            float STEP_SIZE = 0.5f;
            float SLOP      = 0.01f;

            while (npolys > 0 && smoothPath.Count < smoothPath.Capacity)
            {
                //find location to steer towards
                SVector3 steerPos     = new SVector3();
                int      steerPosFlag = 0;
                PolyId   steerPosRef  = PolyId.Null;

                if (!GetSteerTarget(navMeshQuery, iterPos, targetPos, SLOP, polys, npolys, ref steerPos, ref steerPosFlag, ref steerPosRef))
                {
                    break;
                }

                bool endOfPath         = (steerPosFlag & PathfindingCommon.STRAIGHTPATH_END) != 0 ? true : false;
                bool offMeshConnection = (steerPosFlag & PathfindingCommon.STRAIGHTPATH_OFFMESH_CONNECTION) != 0 ? true : false;

                //find movement delta
                SVector3 delta = steerPos - iterPos;
                float    len   = (float)Math.Sqrt(SVector3.Dot(delta, delta));

                //if steer target is at end of path or off-mesh link
                //don't move past location
                if ((endOfPath || offMeshConnection) && len < STEP_SIZE)
                {
                    len = 1;
                }
                else
                {
                    len = STEP_SIZE / len;
                }

                SVector3 moveTgt = new SVector3();
                VMad(ref moveTgt, iterPos, delta, len);

                //move
                SVector3      result  = new SVector3();
                List <PolyId> visited = new List <PolyId>(16);
                navMeshQuery.MoveAlongSurface(new NavPoint(polys[0], iterPos), moveTgt, ref result, visited);
                npolys = FixupCorridor(polys, npolys, MAX_POLYS, visited);
                float h = 0;
                navMeshQuery.GetPolyHeight(polys[0], result, ref h);
                result.Y = h;
                iterPos  = result;

                //handle end of path when close enough
                if (endOfPath && InRange(iterPos, steerPos, SLOP, 1.0f))
                {
                    //reached end of path
                    iterPos = targetPos;
                    if (smoothPath.Count < smoothPath.Capacity)
                    {
                        smoothPath.Add(iterPos);
                    }
                    break;
                }

                //store results
                if (smoothPath.Count < smoothPath.Capacity)
                {
                    smoothPath.Add(iterPos);
                }
            }
        }
        public Microsoft.Xna.Framework.Vector2[] GetPath(Microsoft.Xna.Framework.Vector2 start, Microsoft.Xna.Framework.Vector2 end)
        {
            NavPoint startPt = navMeshQuery.FindNearestPoly(new SVector3(-start.X, 0, start.Y), new SharpNav.Geometry.Vector3(2f, 2f, 2f));
            NavPoint endPt   = navMeshQuery.FindNearestPoly(new SVector3(-end.X, 0, end.Y), new SharpNav.Geometry.Vector3(2f, 2f, 2f));
            Path     path    = new Path();

            navMeshQuery.FindPath(ref startPt, ref endPt, new NavQueryFilter(), path);

            List <SVector3> smoothPath;

            //find a smooth path over the mesh surface
            int      npolys    = path.Count;
            SVector3 iterPos   = new SVector3();
            SVector3 targetPos = new SVector3();

            navMeshQuery.ClosestPointOnPoly(startPt.Polygon, startPt.Position, ref iterPos);
            navMeshQuery.ClosestPointOnPoly(path[npolys - 1], endPt.Position, ref targetPos);

            smoothPath = new List <SVector3>(2048);
            smoothPath.Add(iterPos);

            float STEP_SIZE = 0.5f;
            float SLOP      = 0.01f;

            while (npolys > 0 && smoothPath.Count < smoothPath.Capacity)
            {
                //find location to steer towards
                SVector3          steerPos     = new SVector3();
                StraightPathFlags steerPosFlag = 0;
                NavPolyId         steerPosRef  = NavPolyId.Null;

                if (!GetSteerTarget(navMeshQuery, iterPos, targetPos, SLOP, path, ref steerPos, ref steerPosFlag, ref steerPosRef))
                {
                    break;
                }

                bool endOfPath         = (steerPosFlag & StraightPathFlags.End) != 0 ? true : false;
                bool offMeshConnection = (steerPosFlag & StraightPathFlags.OffMeshConnection) != 0 ? true : false;

                //find movement delta
                SVector3 delta = steerPos - iterPos;
                float    len   = (float)Math.Sqrt(SVector3.Dot(delta, delta));

                //if steer target is at end of path or off-mesh link
                //don't move past location
                if ((endOfPath || offMeshConnection) && len < STEP_SIZE)
                {
                    len = 1;
                }
                else
                {
                    len = STEP_SIZE / len;
                }

                SVector3 moveTgt = new SVector3();
                VMad(ref moveTgt, iterPos, delta, len);

                //move
                SVector3         result     = new SVector3();
                List <NavPolyId> visited    = new List <NavPolyId>(16);
                NavPoint         startPoint = new NavPoint(path[0], iterPos);
                navMeshQuery.MoveAlongSurface(ref startPoint, ref moveTgt, out result, visited);
                path.FixupCorridor(visited);
                npolys = path.Count;
                float h = 0;
                navMeshQuery.GetPolyHeight(path[0], result, ref h);
                result.Y = h;
                iterPos  = result;

                //handle end of path when close enough
                if (endOfPath && InRange(iterPos, steerPos, SLOP, 1.0f))
                {
                    //reached end of path
                    iterPos = targetPos;
                    if (smoothPath.Count < smoothPath.Capacity)
                    {
                        smoothPath.Add(iterPos);
                    }
                    break;
                }

                //store results
                if (smoothPath.Count < smoothPath.Capacity)
                {
                    smoothPath.Add(iterPos);
                }
            }

            return(smoothPath.Select(x => new Microsoft.Xna.Framework.Vector2(-x.X, x.Z)).ToArray());
        }